2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2013, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
7 * Copyright (c) 2019,2020, by the GROMACS development team, led by
8 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9 * and including many others, as listed in the AUTHORS file in the
10 * top-level source directory and at http://www.gromacs.org.
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.
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.
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.
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.
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.
47 #include "gromacs/utility/cstringutil.h"
48 #include "gromacs/utility/futil.h"
49 #include "gromacs/utility/smalloc.h"
51 static const char* type
[] = { "button", "radiobuttons", "groupbox", "checkbox",
52 "pixmap", "statictext", "edittext", "defbutton" };
54 static void ReadDlgError(const char* infile
, eDLGERR err
, const char* s
, const char* file
, int line
)
56 std::fprintf(stderr
, "Error: ");
59 case eNOVALS
: std::fprintf(stderr
, "Not enough values for %s", s
); break;
60 case eGRIDEXP
: std::fprintf(stderr
, "'grid' expected instead of %s", s
); break;
61 case eACCOEXP
: std::fprintf(stderr
, "'{' expected instead of %s", s
); break;
62 case eACCCEXP
: std::fprintf(stderr
, "'}' expected instead of %s", s
); break;
63 case eGRPEXP
: std::fprintf(stderr
, "'group' expected instead of %s", s
); break;
64 case eITEMEXP
: std::fprintf(stderr
, "item expected instead of %s", s
); break;
65 case eSAMEPOINT
: std::fprintf(stderr
, "grid point for %s already in use", s
); break;
66 case eTOOWIDE
: std::fprintf(stderr
, "grid too wide for %s", s
); break;
67 case eTOOHIGH
: std::fprintf(stderr
, "grid too high for %s", s
); break;
68 case eQUOTE
: std::fprintf(stderr
, "quote expected instead of %s", s
); break;
69 default: std::fprintf(stderr
, "????"); break;
71 std::fprintf(stderr
, " in file %s\n", infile
);
72 std::fprintf(stderr
, "source file: %s, line: %d\n", file
, line
);
76 #define ReadDlgErr(in, er, es) ReadDlgError(in, er, es, __FILE__, __LINE__)
78 static void ReadAccOpen(const char* infile
, FILE* in
)
83 result
= std::fscanf(in
, "%4s", buf
);
84 if ((1 != result
) || std::strcmp(buf
, "{") != 0)
86 ReadDlgErr(infile
, eACCOEXP
, buf
);
90 static void ReadAccClose(const char* infile
, FILE* in
)
95 result
= std::fscanf(in
, "%4s", buf
);
96 if ((1 != result
) || std::strcmp(buf
, "}") != 0)
98 ReadDlgErr(infile
, eACCCEXP
, buf
);
102 void ReadQuoteString(const char* infile
, FILE* in
, char* buf
)
107 /* Read until first quote */
108 while ((c
[0] = std::fgetc(in
)) != '"')
110 if (!std::isspace(c
[0]))
113 ReadDlgErr(infile
, eQUOTE
, c
);
116 /* Read until second quote */
117 while ((c
[0] = std::fgetc(in
)) != '"')
124 static void ReadQuoteStringOrAccClose(FILE* in
, char* buf
)
129 /* Read until first quote */
141 /* Read until second quote */
142 while ((c
= std::fgetc(in
)) != '"')
149 static bool bNotAccClose(const char* buf
)
151 return (std::strcmp(buf
, "}") != 0);
154 static t_fitem
* NewFItem(void)
160 fitem
->name
= nullptr;
161 fitem
->set
= nullptr;
162 fitem
->get
= nullptr;
163 fitem
->def
= nullptr;
164 fitem
->help
= nullptr;
169 static t_fsimple
* NewFSimple(void)
178 static void AddFItemName(t_fitem
* fitem
, char* name
)
180 srenew(fitem
->name
, ++fitem
->nname
);
181 fitem
->name
[fitem
->nname
- 1] = gmx_strdup(name
);
184 static t_fgroup
* NewFGroup(void)
189 fgroup
->name
= nullptr;
191 fgroup
->fitem
= nullptr;
196 static void AddFGroupFItem(t_fgroup
* fgroup
, t_fitem
* fitem
)
198 srenew(fgroup
->fitem
, ++fgroup
->nfitem
);
199 fgroup
->fitem
[fgroup
->nfitem
- 1] = fitem
;
202 static t_fgroup
* AddFGridFGroup(t_fgrid
* fgrid
)
204 srenew(fgrid
->fgroup
, ++fgrid
->nfgroup
);
205 fgrid
->fgroup
[fgrid
->nfgroup
- 1] = NewFGroup();
206 return fgrid
->fgroup
[fgrid
->nfgroup
- 1];
209 static t_fsimple
* AddFGridFSimple(t_fgrid
* fgrid
)
211 srenew(fgrid
->fsimple
, ++fgrid
->nfsimple
);
212 fgrid
->fsimple
[fgrid
->nfsimple
- 1] = NewFSimple();
213 return fgrid
->fsimple
[fgrid
->nfsimple
- 1];
216 static t_fgrid
* NewFGrid(void)
224 fgrid
->fgroup
= nullptr;
226 fgrid
->fsimple
= nullptr;
231 static void DoneFItem(t_fitem
* fitem
)
235 for (i
= 0; (i
< fitem
->nname
); i
++)
237 sfree(fitem
->name
[i
]);
246 static void DoneFGroup(t_fgroup
* fgroup
)
251 for (i
= 0; (i
< fgroup
->nfitem
); i
++)
253 DoneFItem(fgroup
->fitem
[i
]);
255 sfree(fgroup
->fitem
);
258 static void DoneFSimple(t_fsimple
* fsimple
)
260 DoneFItem(fsimple
->fitem
);
261 sfree(fsimple
->fitem
);
264 void DoneFGrid(t_fgrid
* fgrid
)
268 for (i
= 0; (i
< fgrid
->nfgroup
); i
++)
270 DoneFGroup(fgrid
->fgroup
[i
]);
272 sfree(fgrid
->fgroup
);
273 for (i
= 0; (i
< fgrid
->nfsimple
); i
++)
275 DoneFSimple(fgrid
->fsimple
[i
]);
277 sfree(fgrid
->fsimple
);
280 static t_fitem
* ScanFItem(const char* infile
, FILE* in
, char* buf
)
282 char set
[STRLEN
], get
[STRLEN
], help
[STRLEN
], def
[STRLEN
];
288 for (edlg
= 0; (edlg
< edlgNR
+ 1); edlg
++)
290 if (std::strcmp(buf
, type
[edlg
]) == 0)
301 if (edlg
== edlgNR
+ 1)
303 ReadDlgErr(infile
, eITEMEXP
, buf
);
306 fitem
->edlg
= (edlgitem
)edlg
;
312 ReadQuoteString(infile
, in
, buf
);
313 AddFItemName(fitem
, buf
);
317 ReadAccOpen(infile
, in
);
318 ReadQuoteStringOrAccClose(in
, buf
);
319 while (bNotAccClose(buf
))
321 AddFItemName(fitem
, buf
);
322 ReadQuoteStringOrAccClose(in
, buf
);
326 case edlgGB
: ReadDlgErr(infile
, eITEMEXP
, type
[edlg
]); break;
329 ReadQuoteString(infile
, in
, set
);
330 ReadQuoteString(infile
, in
, get
);
331 ReadQuoteString(infile
, in
, def
);
332 ReadQuoteString(infile
, in
, help
);
333 fitem
->set
= gmx_strdup(set
);
334 fitem
->get
= gmx_strdup(get
);
335 fitem
->def
= gmx_strdup(def
);
336 fitem
->help
= gmx_strdup(help
);
341 t_fgrid
* FGridFromFile(const char* infile
)
351 gmx::FilePtr inGuard
= gmx::openLibraryFile(infile
);
352 FILE* in
= inGuard
.get();
353 result
= std::fscanf(in
, "%6s", buf
);
354 if ((1 != result
) || std::strcmp(buf
, "grid") != 0)
356 ReadDlgErr(infile
, eGRIDEXP
, buf
);
359 if ((fscanf(in
, "%5d%5d", &gridx
, &gridy
)) != 2)
361 ReadDlgErr(infile
, eNOVALS
, "grid w,h");
365 ReadAccOpen(infile
, in
);
366 result
= std::fscanf(in
, "%15s", buf
);
367 while ((1 == result
) && bNotAccClose(buf
))
369 if (strcmp(buf
, "group") == 0)
371 fgroup
= AddFGridFGroup(fgrid
);
372 ReadQuoteString(infile
, in
, buf
);
373 fgroup
->name
= gmx_strdup(buf
);
374 if ((fscanf(in
, "%5d%5d%5d%5d", &fgroup
->x
, &fgroup
->y
, &fgroup
->w
, &fgroup
->h
)) != 4)
376 ReadDlgErr(infile
, eNOVALS
, "group x,y,w,h");
378 if (fgroup
->x
+ fgroup
->w
> gridx
)
380 ReadDlgErr(infile
, eTOOWIDE
, buf
);
382 if (fgroup
->y
+ fgroup
->h
> gridy
)
384 ReadDlgErr(infile
, eTOOHIGH
, buf
);
386 ReadAccOpen(infile
, in
);
387 result
= std::fscanf(in
, "%15s", buf
);
388 while ((1 == result
) && bNotAccClose(buf
))
390 AddFGroupFItem(fgroup
, ScanFItem(infile
, in
, buf
));
391 result
= std::fscanf(in
, "%15s", buf
);
394 else if (strcmp(buf
, "simple") == 0)
396 fsimple
= AddFGridFSimple(fgrid
);
397 if ((fscanf(in
, "%5d%5d%5d%5d", &fsimple
->x
, &fsimple
->y
, &fsimple
->w
, &fsimple
->h
)) != 4)
399 ReadDlgErr(infile
, eNOVALS
, "simple x,y,w,h");
401 if (fsimple
->x
+ fsimple
->w
> gridx
)
403 ReadDlgErr(infile
, eTOOWIDE
, "simple");
405 if (fsimple
->y
+ fsimple
->h
> gridy
)
407 ReadDlgErr(infile
, eTOOHIGH
, "simple");
409 ReadAccOpen(infile
, in
);
410 result
= std::fscanf(in
, "%15s", buf
);
413 fsimple
->fitem
= ScanFItem(infile
, in
, buf
);
414 ReadAccClose(infile
, in
);
419 result
= std::fscanf(in
, "%15s", buf
);
422 /* Since we always read one variable at a time the result from
423 * fscanf should always be 1.
427 ReadDlgErr(infile
, eNOVALS
, "fgrid");
433 static void DumpFItem(t_fitem
* fitem
)
437 std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {", type
[fitem
->edlg
],
438 fitem
->set
, fitem
->get
, fitem
->def
, fitem
->help
);
439 for (i
= 0; (i
< fitem
->nname
); i
++)
441 std::printf(" '%s'", fitem
->name
[i
]);
446 static void DumpFSimple(t_fsimple
* fsimple
)
448 std::printf("Simple %dx%d at %d,%d\n", fsimple
->w
, fsimple
->h
, fsimple
->x
, fsimple
->y
);
449 DumpFItem(fsimple
->fitem
);
452 static void DumpFGroup(t_fgroup
* fgroup
)
456 std::printf("Group %dx%d at %d,%d\n", fgroup
->w
, fgroup
->h
, fgroup
->x
, fgroup
->y
);
457 for (i
= 0; (i
< fgroup
->nfitem
); i
++)
459 DumpFItem(fgroup
->fitem
[i
]);
463 void DumpFGrid(t_fgrid
* fgrid
)
467 std::printf("Grid %dx%d\n", fgrid
->w
, fgrid
->h
);
468 for (i
= 0; (i
< fgrid
->nfgroup
); i
++)
470 DumpFGroup(fgrid
->fgroup
[i
]);
472 for (i
= 0; (i
< fgrid
->nfsimple
); i
++)
474 DumpFSimple(fgrid
->fsimple
[i
]);