Redefine the default boolean type to gmx_bool.
[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   case eNOVALS:
59     fprintf(stderr,"Not enough values for %s",s);
60     break;
61   case eGRIDEXP:
62     fprintf(stderr,"'grid' expected instead of %s",s);
63     break;
64   case eACCOEXP:
65     fprintf(stderr,"'{' expected instead of %s",s);
66     break;
67   case eACCCEXP:
68     fprintf(stderr,"'}' expected instead of %s",s);
69     break;
70   case eGRPEXP:
71     fprintf(stderr,"'group' expected instead of %s",s);
72     break;
73   case eITEMEXP:
74     fprintf(stderr,"item expected instead of %s",s);
75     break;
76   case eSAMEPOINT:
77     fprintf(stderr,"grid point for %s already in use",s);
78     break;
79   case eTOOWIDE:
80     fprintf(stderr,"grid too wide for %s",s);
81     break;
82   case eTOOHIGH:
83     fprintf(stderr,"grid too high for %s",s);
84     break;
85   case eQUOTE:
86     fprintf(stderr,"quote expected instead of %s",s);
87     break;
88   default:
89     fprintf(stderr,"????");
90     break;
91   }
92   fprintf(stderr," in file %s\n",infile);
93   fprintf(stderr,"C-File: %s, line: %d\n",file,line);
94   exit(1);
95 }
96
97 #define ReadDlgErr(in,er,es) ReadDlgError(in,er,es,__FILE__,__LINE__)
98
99 static void GetBuf(FILE *in, char *buf)
100 {
101   int rc;
102
103   rc=fscanf(in,"%s",buf);
104 }
105
106 static void ReadAccOpen(const char *infile, FILE *in)
107 {
108   char buf[STRLEN];
109   
110   GetBuf(in,buf);
111   if (strcmp(buf,"{")!=0)
112     ReadDlgErr(infile,eACCOEXP,buf);
113 }
114
115 static void ReadAccClose(const char *infile, FILE *in)
116 {
117   char buf[STRLEN];
118   
119   GetBuf(in,buf);
120   if (strcmp(buf,"}")!=0)
121     ReadDlgErr(infile,eACCCEXP,buf);
122 }
123
124 void ReadQuoteString(const char *infile, FILE *in, char *buf)
125 {
126   char c[2];
127   int i=0;
128   
129   /* Read until first quote */
130   while ((c[0]=fgetc(in))!='"') 
131     if (!isspace(c[0])) {
132       c[1]='\0';
133       ReadDlgErr(infile,eQUOTE,c);
134     }
135   /* Read until second quote */
136   while ((c[0]=fgetc(in))!='"')
137     buf[i++]=c[0];
138   buf[i]='\0';
139 }
140
141 static void ReadQuoteStringOrAccClose(FILE *in, char *buf)
142 {
143   char c;
144   int i=0;
145   
146   /* Read until first quote */
147   do {
148     c=fgetc(in);
149     if (c=='}') {
150       buf[0]=c;
151       buf[1]='\0';
152       return;
153     }
154   } while (c != '"');
155   
156   /* Read until second quote */
157   while ((c=fgetc(in))!='"')
158     buf[i++]=c;
159   buf[i]='\0';
160 }
161
162 static gmx_bool bNotAccClose(const char *buf)
163 {
164   return (strcmp(buf,"}")!=0);
165 }
166
167 static t_fitem *NewFItem(void)
168 {
169   t_fitem *fitem;
170   
171   snew(fitem,1);
172   fitem->nname=0;
173   fitem->name=NULL;
174   fitem->set=NULL;
175   fitem->get=NULL;
176   fitem->def=NULL;
177   fitem->help=NULL;
178
179   return fitem;
180 }
181
182 static t_fsimple *NewFSimple(void)
183 {
184   t_fsimple *fsimple;
185   
186   snew(fsimple,1);
187   
188   return fsimple;
189 }
190
191 static void AddFItemName(t_fitem *fitem, char *name)
192 {
193   srenew(fitem->name,++fitem->nname);
194   fitem->name[fitem->nname-1]=strdup(name);
195 }
196
197 static t_fgroup *NewFGroup(void)
198 {
199   t_fgroup *fgroup;
200   
201   snew(fgroup,1);
202   fgroup->name=NULL;
203   fgroup->nfitem=0;
204   fgroup->fitem=NULL;
205   
206   return fgroup;
207 }
208
209 static void AddFGroupFItem(t_fgroup *fgroup, t_fitem *fitem)
210 {
211   srenew(fgroup->fitem,++fgroup->nfitem);
212   fgroup->fitem[fgroup->nfitem-1]=fitem;
213 }
214
215 static t_fgroup *AddFGridFGroup(t_fgrid *fgrid)
216 {
217   srenew(fgrid->fgroup,++fgrid->nfgroup);
218   fgrid->fgroup[fgrid->nfgroup-1]=NewFGroup();
219   return fgrid->fgroup[fgrid->nfgroup-1];
220 }
221
222 static t_fsimple *AddFGridFSimple(t_fgrid *fgrid)
223 {
224   srenew(fgrid->fsimple,++fgrid->nfsimple);
225   fgrid->fsimple[fgrid->nfsimple-1]=NewFSimple();
226   return fgrid->fsimple[fgrid->nfsimple-1];
227 }
228
229 static t_fgrid *NewFGrid(void)
230 {
231   t_fgrid *fgrid;
232   
233   snew(fgrid,1);
234   fgrid->w=0;
235   fgrid->h=0;
236   fgrid->nfgroup=0;
237   fgrid->fgroup=NULL;
238   fgrid->nfsimple=0;
239   fgrid->fsimple=NULL;
240   
241   return fgrid;
242 }
243
244 static void DoneFItem(t_fitem *fitem)
245 {
246   int i;
247   
248   for(i=0; (i<fitem->nname); i++)
249     sfree(fitem->name[i]);
250   sfree(fitem->name);
251   sfree(fitem->set);
252   sfree(fitem->get);
253   sfree(fitem->def);
254   sfree(fitem->help);
255 }
256
257 static void DoneFGroup(t_fgroup *fgroup)
258 {
259   int i;
260   
261   sfree(fgroup->name);
262   for(i=0; (i<fgroup->nfitem); i++)
263     DoneFItem(fgroup->fitem[i]);
264   sfree(fgroup->fitem);
265 }
266
267 static void DoneFSimple(t_fsimple *fsimple)
268 {
269   DoneFItem(fsimple->fitem);
270   sfree(fsimple->fitem);
271 }
272
273 void DoneFGrid(t_fgrid *fgrid)
274 {
275   int i;
276   
277   for(i=0; (i<fgrid->nfgroup); i++) 
278     DoneFGroup(fgrid->fgroup[i]);
279   sfree(fgrid->fgroup);
280   for(i=0; (i<fgrid->nfsimple); i++) 
281     DoneFSimple(fgrid->fsimple[i]);
282   sfree(fgrid->fsimple);
283 }
284
285 static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf)
286 {
287   char set[STRLEN],get[STRLEN],help[STRLEN],def[STRLEN];
288   edlgitem edlg;
289   t_fitem *fitem;
290   
291   fitem=NewFItem();
292   
293   for(edlg=(edlgitem)0; (edlg<edlgNR+1); edlg = (edlgitem)(edlg + 1))
294     if (strcmp(buf,type[edlg])==0)
295       break;
296   if (edlg==edlgNR) {
297     /* Special case */
298     edlg=edlgBN;
299     fitem->bDef=TRUE;
300   }
301   if (edlg==edlgNR+1) {
302     ReadDlgErr(infile,eITEMEXP,buf);
303   }
304   
305   fitem->edlg=edlg;
306   switch (edlg) {
307   case edlgBN:
308   case edlgCB:
309   case edlgET:
310     ReadQuoteString(infile,in,buf);
311     AddFItemName(fitem,buf);
312     break;
313   case edlgST:
314   case edlgRB:
315     ReadAccOpen(infile,in);
316     ReadQuoteStringOrAccClose(in,buf);
317     while (bNotAccClose(buf)) {
318       AddFItemName(fitem,buf);
319       ReadQuoteStringOrAccClose(in,buf);
320     }
321     break;
322   case edlgPM:
323   case edlgGB:
324     ReadDlgErr(infile,eITEMEXP,type[edlg]);
325     break;
326   default:
327     break;
328   }
329   ReadQuoteString(infile,in,set);
330   ReadQuoteString(infile,in,get);
331   ReadQuoteString(infile,in,def);
332   ReadQuoteString(infile,in,help);
333   fitem->set=strdup(set);
334   fitem->get=strdup(get);
335   fitem->def=strdup(def);
336   fitem->help=strdup(help);
337   
338   return fitem;
339 }
340
341 t_fgrid *FGridFromFile(const char *infile)
342 {
343   FILE *in;
344   char buf[STRLEN];
345   char *gmxlib;
346   char newinfile[STRLEN];
347   
348   t_fgrid   *fgrid;
349   t_fgroup  *fgroup;
350   t_fsimple *fsimple;
351   int       gridx,gridy;  
352   
353   in = libopen(infile);
354   GetBuf(in,buf);
355   if (strcmp(buf,"grid")!=0)
356     ReadDlgErr(infile,eGRIDEXP,buf);
357   fgrid=NewFGrid();
358   if ((fscanf(in,"%d%d",&gridx,&gridy))!=2)
359     ReadDlgErr(infile,eNOVALS,"grid w,h");
360   fgrid->w=gridx;
361   fgrid->h=gridy;
362   ReadAccOpen(infile,in);
363   GetBuf(in,buf);
364   while (bNotAccClose(buf)) {
365     if (strcmp(buf,"group")==0) {
366       fgroup=AddFGridFGroup(fgrid);
367       ReadQuoteString(infile,in,buf);
368       fgroup->name=strdup(buf);
369       if ((fscanf(in,"%d%d%d%d",&fgroup->x,&fgroup->y,&fgroup->w,&fgroup->h))!=4)
370         ReadDlgErr(infile,eNOVALS,"group x,y,w,h");
371       if (fgroup->x+fgroup->w > gridx)
372         ReadDlgErr(infile,eTOOWIDE,buf);
373       if (fgroup->y+fgroup->h > gridy)
374         ReadDlgErr(infile,eTOOHIGH,buf);
375       ReadAccOpen(infile,in);
376       GetBuf(in,buf);
377       while (bNotAccClose(buf)) {
378         AddFGroupFItem(fgroup,ScanFItem(infile,in,buf));
379         GetBuf(in,buf);
380       }
381     }
382     else if (strcmp(buf,"simple")==0) {
383       fsimple=AddFGridFSimple(fgrid);
384       if ((fscanf(in,"%d%d%d%d",&fsimple->x,&fsimple->y,&fsimple->w,&fsimple->h))!=4)
385         ReadDlgErr(infile,eNOVALS,"simple x,y,w,h");
386       if (fsimple->x+fsimple->w > gridx)
387         ReadDlgErr(infile,eTOOWIDE,"simple");
388       if (fsimple->y+fsimple->h > gridy)
389         ReadDlgErr(infile,eTOOHIGH,"simple");
390       ReadAccOpen(infile,in);
391       GetBuf(in,buf);
392       fsimple->fitem=ScanFItem(infile,in,buf);
393       ReadAccClose(infile,in);
394     }
395     GetBuf(in,buf);
396   }
397   ffclose(in);
398   
399   return fgrid;
400 }
401
402 static void DumpFItem(t_fitem *fitem)
403 {
404   int i;
405   
406   printf("  type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n  {",
407          type[fitem->edlg],fitem->set,fitem->get,fitem->def,fitem->help);
408   for(i=0; (i<fitem->nname); i++)
409     printf("  '%s'",fitem->name[i]);
410   printf("  }\n");
411 }
412
413 static void DumpFSimple(t_fsimple *fsimple)
414 {
415   printf("Simple %dx%d at %d,%d\n",fsimple->w,fsimple->h,fsimple->x,fsimple->y);
416   DumpFItem(fsimple->fitem);
417 }
418
419 static void DumpFGroup(t_fgroup *fgroup)
420 {
421   int i;
422   
423   printf("Group %dx%d at %d,%d\n",fgroup->w,fgroup->h,fgroup->x,fgroup->y);
424   for(i=0; (i<fgroup->nfitem); i++)
425     DumpFItem(fgroup->fitem[i]);
426 }
427
428 void DumpFGrid(t_fgrid *fgrid)
429 {
430   int i;
431   
432   printf("Grid %dx%d\n",fgrid->w,fgrid->h);
433   for(i=0; (i<fgrid->nfgroup); i++)
434     DumpFGroup(fgrid->fgroup[i]);
435   for(i=0; (i<fgrid->nfsimple); i++)
436     DumpFSimple(fgrid->fsimple[i]);
437 }