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