Remove repeat sfree(state->nosehoover_xi)
[alexxy/gromacs.git] / src / ngmx / fgrid.c
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <ctype.h>
43 #include "string2.h"
44 #include "smalloc.h"
45 #include "fgrid.h"
46 #include "futil.h"
47
48 static const char *type[] = {
49     "button", "radiobuttons", "groupbox", "checkbox",
50     "pixmap", "statictext",   "edittext", "defbutton"
51 };
52
53 void ReadDlgError(const char *infile, eDLGERR err, const char *s,
54                   const char *file, int line)
55 {
56     fprintf(stderr, "Error: ");
57     switch (err)
58     {
59         case eNOVALS:
60             fprintf(stderr, "Not enough values for %s", s);
61             break;
62         case eGRIDEXP:
63             fprintf(stderr, "'grid' expected instead of %s", s);
64             break;
65         case eACCOEXP:
66             fprintf(stderr, "'{' expected instead of %s", s);
67             break;
68         case eACCCEXP:
69             fprintf(stderr, "'}' expected instead of %s", s);
70             break;
71         case eGRPEXP:
72             fprintf(stderr, "'group' expected instead of %s", s);
73             break;
74         case eITEMEXP:
75             fprintf(stderr, "item expected instead of %s", s);
76             break;
77         case eSAMEPOINT:
78             fprintf(stderr, "grid point for %s already in use", s);
79             break;
80         case eTOOWIDE:
81             fprintf(stderr, "grid too wide for %s", s);
82             break;
83         case eTOOHIGH:
84             fprintf(stderr, "grid too high for %s", s);
85             break;
86         case eQUOTE:
87             fprintf(stderr, "quote expected instead of %s", s);
88             break;
89         default:
90             fprintf(stderr, "????");
91             break;
92     }
93     fprintf(stderr, " in file %s\n", infile);
94     fprintf(stderr, "C-File: %s, line: %d\n", file, line);
95     exit(1);
96 }
97
98 #define ReadDlgErr(in, er, es) ReadDlgError(in, er, es, __FILE__, __LINE__)
99
100 static void GetBuf(FILE *in, char *buf)
101 {
102     int rc;
103
104     rc = fscanf(in, "%s", buf);
105 }
106
107 static void ReadAccOpen(const char *infile, FILE *in)
108 {
109     char buf[STRLEN];
110
111     GetBuf(in, buf);
112     if (strcmp(buf, "{") != 0)
113     {
114         ReadDlgErr(infile, eACCOEXP, buf);
115     }
116 }
117
118 static void ReadAccClose(const char *infile, FILE *in)
119 {
120     char buf[STRLEN];
121
122     GetBuf(in, buf);
123     if (strcmp(buf, "}") != 0)
124     {
125         ReadDlgErr(infile, eACCCEXP, buf);
126     }
127 }
128
129 void ReadQuoteString(const char *infile, FILE *in, char *buf)
130 {
131     char c[2];
132     int  i = 0;
133
134     /* Read until first quote */
135     while ((c[0] = fgetc(in)) != '"')
136     {
137         if (!isspace(c[0]))
138         {
139             c[1] = '\0';
140             ReadDlgErr(infile, eQUOTE, c);
141         }
142     }
143     /* Read until second quote */
144     while ((c[0] = fgetc(in)) != '"')
145     {
146         buf[i++] = c[0];
147     }
148     buf[i] = '\0';
149 }
150
151 static void ReadQuoteStringOrAccClose(FILE *in, char *buf)
152 {
153     char c;
154     int  i = 0;
155
156     /* Read until first quote */
157     do
158     {
159         c = fgetc(in);
160         if (c == '}')
161         {
162             buf[0] = c;
163             buf[1] = '\0';
164             return;
165         }
166     }
167     while (c != '"');
168
169     /* Read until second quote */
170     while ((c = fgetc(in)) != '"')
171     {
172         buf[i++] = c;
173     }
174     buf[i] = '\0';
175 }
176
177 static gmx_bool bNotAccClose(const char *buf)
178 {
179     return (strcmp(buf, "}") != 0);
180 }
181
182 static t_fitem *NewFItem(void)
183 {
184     t_fitem *fitem;
185
186     snew(fitem, 1);
187     fitem->nname = 0;
188     fitem->name  = NULL;
189     fitem->set   = NULL;
190     fitem->get   = NULL;
191     fitem->def   = NULL;
192     fitem->help  = NULL;
193
194     return fitem;
195 }
196
197 static t_fsimple *NewFSimple(void)
198 {
199     t_fsimple *fsimple;
200
201     snew(fsimple, 1);
202
203     return fsimple;
204 }
205
206 static void AddFItemName(t_fitem *fitem, char *name)
207 {
208     srenew(fitem->name, ++fitem->nname);
209     fitem->name[fitem->nname-1] = strdup(name);
210 }
211
212 static t_fgroup *NewFGroup(void)
213 {
214     t_fgroup *fgroup;
215
216     snew(fgroup, 1);
217     fgroup->name   = NULL;
218     fgroup->nfitem = 0;
219     fgroup->fitem  = NULL;
220
221     return fgroup;
222 }
223
224 static void AddFGroupFItem(t_fgroup *fgroup, t_fitem *fitem)
225 {
226     srenew(fgroup->fitem, ++fgroup->nfitem);
227     fgroup->fitem[fgroup->nfitem-1] = fitem;
228 }
229
230 static t_fgroup *AddFGridFGroup(t_fgrid *fgrid)
231 {
232     srenew(fgrid->fgroup, ++fgrid->nfgroup);
233     fgrid->fgroup[fgrid->nfgroup-1] = NewFGroup();
234     return fgrid->fgroup[fgrid->nfgroup-1];
235 }
236
237 static t_fsimple *AddFGridFSimple(t_fgrid *fgrid)
238 {
239     srenew(fgrid->fsimple, ++fgrid->nfsimple);
240     fgrid->fsimple[fgrid->nfsimple-1] = NewFSimple();
241     return fgrid->fsimple[fgrid->nfsimple-1];
242 }
243
244 static t_fgrid *NewFGrid(void)
245 {
246     t_fgrid *fgrid;
247
248     snew(fgrid, 1);
249     fgrid->w        = 0;
250     fgrid->h        = 0;
251     fgrid->nfgroup  = 0;
252     fgrid->fgroup   = NULL;
253     fgrid->nfsimple = 0;
254     fgrid->fsimple  = NULL;
255
256     return fgrid;
257 }
258
259 static void DoneFItem(t_fitem *fitem)
260 {
261     int i;
262
263     for (i = 0; (i < fitem->nname); i++)
264     {
265         sfree(fitem->name[i]);
266     }
267     sfree(fitem->name);
268     sfree(fitem->set);
269     sfree(fitem->get);
270     sfree(fitem->def);
271     sfree(fitem->help);
272 }
273
274 static void DoneFGroup(t_fgroup *fgroup)
275 {
276     int i;
277
278     sfree(fgroup->name);
279     for (i = 0; (i < fgroup->nfitem); i++)
280     {
281         DoneFItem(fgroup->fitem[i]);
282     }
283     sfree(fgroup->fitem);
284 }
285
286 static void DoneFSimple(t_fsimple *fsimple)
287 {
288     DoneFItem(fsimple->fitem);
289     sfree(fsimple->fitem);
290 }
291
292 void DoneFGrid(t_fgrid *fgrid)
293 {
294     int i;
295
296     for (i = 0; (i < fgrid->nfgroup); i++)
297     {
298         DoneFGroup(fgrid->fgroup[i]);
299     }
300     sfree(fgrid->fgroup);
301     for (i = 0; (i < fgrid->nfsimple); i++)
302     {
303         DoneFSimple(fgrid->fsimple[i]);
304     }
305     sfree(fgrid->fsimple);
306 }
307
308 static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf)
309 {
310     char     set[STRLEN], get[STRLEN], help[STRLEN], def[STRLEN];
311     edlgitem edlg;
312     t_fitem *fitem;
313
314     fitem = NewFItem();
315
316     for (edlg = (edlgitem)0; (edlg < edlgNR+1); edlg = (edlgitem)(edlg + 1))
317     {
318         if (strcmp(buf, type[edlg]) == 0)
319         {
320             break;
321         }
322     }
323     if (edlg == edlgNR)
324     {
325         /* Special case */
326         edlg        = edlgBN;
327         fitem->bDef = TRUE;
328     }
329     if (edlg == edlgNR+1)
330     {
331         ReadDlgErr(infile, eITEMEXP, buf);
332     }
333
334     fitem->edlg = edlg;
335     switch (edlg)
336     {
337         case edlgBN:
338         case edlgCB:
339         case edlgET:
340             ReadQuoteString(infile, in, buf);
341             AddFItemName(fitem, buf);
342             break;
343         case edlgST:
344         case edlgRB:
345             ReadAccOpen(infile, in);
346             ReadQuoteStringOrAccClose(in, buf);
347             while (bNotAccClose(buf))
348             {
349                 AddFItemName(fitem, buf);
350                 ReadQuoteStringOrAccClose(in, buf);
351             }
352             break;
353         case edlgPM:
354         case edlgGB:
355             ReadDlgErr(infile, eITEMEXP, type[edlg]);
356             break;
357         default:
358             break;
359     }
360     ReadQuoteString(infile, in, set);
361     ReadQuoteString(infile, in, get);
362     ReadQuoteString(infile, in, def);
363     ReadQuoteString(infile, in, help);
364     fitem->set  = strdup(set);
365     fitem->get  = strdup(get);
366     fitem->def  = strdup(def);
367     fitem->help = strdup(help);
368
369     return fitem;
370 }
371
372 t_fgrid *FGridFromFile(const char *infile)
373 {
374     FILE      *in;
375     char       buf[STRLEN];
376     char      *gmxlib;
377     char       newinfile[STRLEN];
378
379     t_fgrid   *fgrid;
380     t_fgroup  *fgroup;
381     t_fsimple *fsimple;
382     int        gridx, gridy;
383
384     in = libopen(infile);
385     GetBuf(in, buf);
386     if (strcmp(buf, "grid") != 0)
387     {
388         ReadDlgErr(infile, eGRIDEXP, buf);
389     }
390     fgrid = NewFGrid();
391     if ((fscanf(in, "%d%d", &gridx, &gridy)) != 2)
392     {
393         ReadDlgErr(infile, eNOVALS, "grid w,h");
394     }
395     fgrid->w = gridx;
396     fgrid->h = gridy;
397     ReadAccOpen(infile, in);
398     GetBuf(in, buf);
399     while (bNotAccClose(buf))
400     {
401         if (strcmp(buf, "group") == 0)
402         {
403             fgroup = AddFGridFGroup(fgrid);
404             ReadQuoteString(infile, in, buf);
405             fgroup->name = strdup(buf);
406             if ((fscanf(in, "%d%d%d%d", &fgroup->x, &fgroup->y, &fgroup->w, &fgroup->h)) != 4)
407             {
408                 ReadDlgErr(infile, eNOVALS, "group x,y,w,h");
409             }
410             if (fgroup->x+fgroup->w > gridx)
411             {
412                 ReadDlgErr(infile, eTOOWIDE, buf);
413             }
414             if (fgroup->y+fgroup->h > gridy)
415             {
416                 ReadDlgErr(infile, eTOOHIGH, buf);
417             }
418             ReadAccOpen(infile, in);
419             GetBuf(in, buf);
420             while (bNotAccClose(buf))
421             {
422                 AddFGroupFItem(fgroup, ScanFItem(infile, in, buf));
423                 GetBuf(in, buf);
424             }
425         }
426         else if (strcmp(buf, "simple") == 0)
427         {
428             fsimple = AddFGridFSimple(fgrid);
429             if ((fscanf(in, "%d%d%d%d", &fsimple->x, &fsimple->y, &fsimple->w, &fsimple->h)) != 4)
430             {
431                 ReadDlgErr(infile, eNOVALS, "simple x,y,w,h");
432             }
433             if (fsimple->x+fsimple->w > gridx)
434             {
435                 ReadDlgErr(infile, eTOOWIDE, "simple");
436             }
437             if (fsimple->y+fsimple->h > gridy)
438             {
439                 ReadDlgErr(infile, eTOOHIGH, "simple");
440             }
441             ReadAccOpen(infile, in);
442             GetBuf(in, buf);
443             fsimple->fitem = ScanFItem(infile, in, buf);
444             ReadAccClose(infile, in);
445         }
446         GetBuf(in, buf);
447     }
448     ffclose(in);
449
450     return fgrid;
451 }
452
453 static void DumpFItem(t_fitem *fitem)
454 {
455     int i;
456
457     printf("  type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n  {",
458            type[fitem->edlg], fitem->set, fitem->get, fitem->def, fitem->help);
459     for (i = 0; (i < fitem->nname); i++)
460     {
461         printf("  '%s'", fitem->name[i]);
462     }
463     printf("  }\n");
464 }
465
466 static void DumpFSimple(t_fsimple *fsimple)
467 {
468     printf("Simple %dx%d at %d,%d\n", fsimple->w, fsimple->h, fsimple->x, fsimple->y);
469     DumpFItem(fsimple->fitem);
470 }
471
472 static void DumpFGroup(t_fgroup *fgroup)
473 {
474     int i;
475
476     printf("Group %dx%d at %d,%d\n", fgroup->w, fgroup->h, fgroup->x, fgroup->y);
477     for (i = 0; (i < fgroup->nfitem); i++)
478     {
479         DumpFItem(fgroup->fitem[i]);
480     }
481 }
482
483 void DumpFGrid(t_fgrid *fgrid)
484 {
485     int i;
486
487     printf("Grid %dx%d\n", fgrid->w, fgrid->h);
488     for (i = 0; (i < fgrid->nfgroup); i++)
489     {
490         DumpFGroup(fgrid->fgroup[i]);
491     }
492     for (i = 0; (i < fgrid->nfsimple); i++)
493     {
494         DumpFSimple(fgrid->fsimple[i]);
495     }
496 }