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, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
46 #include "gromacs/utility/cstringutil.h"
47 #include "gromacs/utility/futil.h"
48 #include "gromacs/utility/smalloc.h"
50 static const char *type
[] = {
51 "button", "radiobuttons", "groupbox", "checkbox",
52 "pixmap", "statictext", "edittext", "defbutton"
55 static void ReadDlgError(const char *infile
, eDLGERR err
, const char *s
,
56 const char *file
, int line
)
58 std::fprintf(stderr
, "Error: ");
62 std::fprintf(stderr
, "Not enough values for %s", s
);
65 std::fprintf(stderr
, "'grid' expected instead of %s", s
);
68 std::fprintf(stderr
, "'{' expected instead of %s", s
);
71 std::fprintf(stderr
, "'}' expected instead of %s", s
);
74 std::fprintf(stderr
, "'group' expected instead of %s", s
);
77 std::fprintf(stderr
, "item expected instead of %s", s
);
80 std::fprintf(stderr
, "grid point for %s already in use", s
);
83 std::fprintf(stderr
, "grid too wide for %s", s
);
86 std::fprintf(stderr
, "grid too high for %s", s
);
89 std::fprintf(stderr
, "quote expected instead of %s", s
);
92 std::fprintf(stderr
, "????");
95 std::fprintf(stderr
, " in file %s\n", infile
);
96 std::fprintf(stderr
, "source file: %s, line: %d\n", file
, line
);
100 #define ReadDlgErr(in, er, es) ReadDlgError(in, er, es, __FILE__, __LINE__)
102 static void ReadAccOpen(const char *infile
, FILE *in
)
107 result
= std::fscanf(in
, "%4s", buf
);
108 if ((1 != result
) || std::strcmp(buf
, "{") != 0)
110 ReadDlgErr(infile
, eACCOEXP
, buf
);
114 static void ReadAccClose(const char *infile
, FILE *in
)
119 result
= std::fscanf(in
, "%4s", buf
);
120 if ((1 != result
) || std::strcmp(buf
, "}") != 0)
122 ReadDlgErr(infile
, eACCCEXP
, buf
);
126 void ReadQuoteString(const char *infile
, FILE *in
, char *buf
)
131 /* Read until first quote */
132 while ((c
[0] = std::fgetc(in
)) != '"')
134 if (!std::isspace(c
[0]))
137 ReadDlgErr(infile
, eQUOTE
, c
);
140 /* Read until second quote */
141 while ((c
[0] = std::fgetc(in
)) != '"')
148 static void ReadQuoteStringOrAccClose(FILE *in
, char *buf
)
153 /* Read until first quote */
166 /* Read until second quote */
167 while ((c
= std::fgetc(in
)) != '"')
174 static bool bNotAccClose(const char *buf
)
176 return (std::strcmp(buf
, "}") != 0);
179 static t_fitem
*NewFItem(void)
185 fitem
->name
= nullptr;
186 fitem
->set
= nullptr;
187 fitem
->get
= nullptr;
188 fitem
->def
= nullptr;
189 fitem
->help
= nullptr;
194 static t_fsimple
*NewFSimple(void)
203 static void AddFItemName(t_fitem
*fitem
, char *name
)
205 srenew(fitem
->name
, ++fitem
->nname
);
206 fitem
->name
[fitem
->nname
-1] = gmx_strdup(name
);
209 static t_fgroup
*NewFGroup(void)
214 fgroup
->name
= nullptr;
216 fgroup
->fitem
= nullptr;
221 static void AddFGroupFItem(t_fgroup
*fgroup
, t_fitem
*fitem
)
223 srenew(fgroup
->fitem
, ++fgroup
->nfitem
);
224 fgroup
->fitem
[fgroup
->nfitem
-1] = fitem
;
227 static t_fgroup
*AddFGridFGroup(t_fgrid
*fgrid
)
229 srenew(fgrid
->fgroup
, ++fgrid
->nfgroup
);
230 fgrid
->fgroup
[fgrid
->nfgroup
-1] = NewFGroup();
231 return fgrid
->fgroup
[fgrid
->nfgroup
-1];
234 static t_fsimple
*AddFGridFSimple(t_fgrid
*fgrid
)
236 srenew(fgrid
->fsimple
, ++fgrid
->nfsimple
);
237 fgrid
->fsimple
[fgrid
->nfsimple
-1] = NewFSimple();
238 return fgrid
->fsimple
[fgrid
->nfsimple
-1];
241 static t_fgrid
*NewFGrid(void)
249 fgrid
->fgroup
= nullptr;
251 fgrid
->fsimple
= nullptr;
256 static void DoneFItem(t_fitem
*fitem
)
260 for (i
= 0; (i
< fitem
->nname
); i
++)
262 sfree(fitem
->name
[i
]);
271 static void DoneFGroup(t_fgroup
*fgroup
)
276 for (i
= 0; (i
< fgroup
->nfitem
); i
++)
278 DoneFItem(fgroup
->fitem
[i
]);
280 sfree(fgroup
->fitem
);
283 static void DoneFSimple(t_fsimple
*fsimple
)
285 DoneFItem(fsimple
->fitem
);
286 sfree(fsimple
->fitem
);
289 void DoneFGrid(t_fgrid
*fgrid
)
293 for (i
= 0; (i
< fgrid
->nfgroup
); i
++)
295 DoneFGroup(fgrid
->fgroup
[i
]);
297 sfree(fgrid
->fgroup
);
298 for (i
= 0; (i
< fgrid
->nfsimple
); i
++)
300 DoneFSimple(fgrid
->fsimple
[i
]);
302 sfree(fgrid
->fsimple
);
305 static t_fitem
*ScanFItem(const char *infile
, FILE *in
, char *buf
)
307 char set
[STRLEN
], get
[STRLEN
], help
[STRLEN
], def
[STRLEN
];
313 for (edlg
= 0; (edlg
< edlgNR
+1); edlg
++)
315 if (std::strcmp(buf
, type
[edlg
]) == 0)
326 if (edlg
== edlgNR
+1)
328 ReadDlgErr(infile
, eITEMEXP
, buf
);
331 fitem
->edlg
= (edlgitem
)edlg
;
337 ReadQuoteString(infile
, in
, buf
);
338 AddFItemName(fitem
, buf
);
342 ReadAccOpen(infile
, in
);
343 ReadQuoteStringOrAccClose(in
, buf
);
344 while (bNotAccClose(buf
))
346 AddFItemName(fitem
, buf
);
347 ReadQuoteStringOrAccClose(in
, buf
);
352 ReadDlgErr(infile
, eITEMEXP
, type
[edlg
]);
357 ReadQuoteString(infile
, in
, set
);
358 ReadQuoteString(infile
, in
, get
);
359 ReadQuoteString(infile
, in
, def
);
360 ReadQuoteString(infile
, in
, help
);
361 fitem
->set
= gmx_strdup(set
);
362 fitem
->get
= gmx_strdup(get
);
363 fitem
->def
= gmx_strdup(def
);
364 fitem
->help
= gmx_strdup(help
);
369 t_fgrid
*FGridFromFile(const char *infile
)
380 in
= libopen(infile
);
381 result
= std::fscanf(in
, "%6s", buf
);
382 if ((1 != result
) || std::strcmp(buf
, "grid") != 0)
384 ReadDlgErr(infile
, eGRIDEXP
, buf
);
387 if ((fscanf(in
, "%5d%5d", &gridx
, &gridy
)) != 2)
389 ReadDlgErr(infile
, eNOVALS
, "grid w,h");
393 ReadAccOpen(infile
, in
);
394 result
= std::fscanf(in
, "%15s", buf
);
395 while ((1 == result
) && bNotAccClose(buf
))
397 if (strcmp(buf
, "group") == 0)
399 fgroup
= AddFGridFGroup(fgrid
);
400 ReadQuoteString(infile
, in
, buf
);
401 fgroup
->name
= gmx_strdup(buf
);
402 if ((fscanf(in
, "%5d%5d%5d%5d", &fgroup
->x
, &fgroup
->y
, &fgroup
->w
, &fgroup
->h
)) != 4)
404 ReadDlgErr(infile
, eNOVALS
, "group x,y,w,h");
406 if (fgroup
->x
+fgroup
->w
> gridx
)
408 ReadDlgErr(infile
, eTOOWIDE
, buf
);
410 if (fgroup
->y
+fgroup
->h
> gridy
)
412 ReadDlgErr(infile
, eTOOHIGH
, buf
);
414 ReadAccOpen(infile
, in
);
415 result
= std::fscanf(in
, "%15s", buf
);
416 while ((1 == result
) && bNotAccClose(buf
))
418 AddFGroupFItem(fgroup
, ScanFItem(infile
, in
, buf
));
419 result
= std::fscanf(in
, "%15s", buf
);
422 else if (strcmp(buf
, "simple") == 0)
424 fsimple
= AddFGridFSimple(fgrid
);
425 if ((fscanf(in
, "%5d%5d%5d%5d", &fsimple
->x
, &fsimple
->y
, &fsimple
->w
, &fsimple
->h
)) != 4)
427 ReadDlgErr(infile
, eNOVALS
, "simple x,y,w,h");
429 if (fsimple
->x
+fsimple
->w
> gridx
)
431 ReadDlgErr(infile
, eTOOWIDE
, "simple");
433 if (fsimple
->y
+fsimple
->h
> gridy
)
435 ReadDlgErr(infile
, eTOOHIGH
, "simple");
437 ReadAccOpen(infile
, in
);
438 result
= std::fscanf(in
, "%15s", buf
);
441 fsimple
->fitem
= ScanFItem(infile
, in
, buf
);
442 ReadAccClose(infile
, in
);
447 result
= std::fscanf(in
, "%15s", buf
);
451 /* Since we always read one variable at a time the result from
452 * fscanf should always be 1.
456 ReadDlgErr(infile
, eNOVALS
, "fgrid");
462 static void DumpFItem(t_fitem
*fitem
)
466 std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {",
467 type
[fitem
->edlg
], fitem
->set
, fitem
->get
, fitem
->def
, fitem
->help
);
468 for (i
= 0; (i
< fitem
->nname
); i
++)
470 std::printf(" '%s'", fitem
->name
[i
]);
475 static void DumpFSimple(t_fsimple
*fsimple
)
477 std::printf("Simple %dx%d at %d,%d\n", fsimple
->w
, fsimple
->h
, fsimple
->x
, fsimple
->y
);
478 DumpFItem(fsimple
->fitem
);
481 static void DumpFGroup(t_fgroup
*fgroup
)
485 std::printf("Group %dx%d at %d,%d\n", fgroup
->w
, fgroup
->h
, fgroup
->x
, fgroup
->y
);
486 for (i
= 0; (i
< fgroup
->nfitem
); i
++)
488 DumpFItem(fgroup
->fitem
[i
]);
492 void DumpFGrid(t_fgrid
*fgrid
)
496 std::printf("Grid %dx%d\n", fgrid
->w
, fgrid
->h
);
497 for (i
= 0; (i
< fgrid
->nfgroup
); i
++)
499 DumpFGroup(fgrid
->fgroup
[i
]);
501 for (i
= 0; (i
< fgrid
->nfsimple
); i
++)
503 DumpFSimple(fgrid
->fsimple
[i
]);