ARB
GDE_ParseMenu.cxx
Go to the documentation of this file.
1 #include "GDE_proto.h"
2 
3 #include <aw_window.hxx>
4 #include <MultiFileReader.h>
5 #include <arb_file.h>
6 
7 #include <cctype>
8 
9 /*
10  Copyright (c) 1989, University of Illinois board of trustees. All rights
11  reserved. Written by Steven Smith at the Center for Prokaryote Genome
12  Analysis. Design and implementation guidance by Dr. Gary Olsen and Dr.
13  Carl Woese.
14 
15  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
16  All rights reserved.
17 
18  Changed to fit into ARB by ARB development team.
19 */
20 
21 
22 inline bool only_whitespace(const char *line) {
23  size_t white = strspn(line, " \t");
24  return line[white] == 0; // only 0 after leading whitespace
25 }
26 
27 static char *readableItemname(const GmenuItem& i) {
28  return GBS_global_string_copy("%s/%s", i.parent_menu->label, i.label);
29 }
30 
31 inline __ATTR__NORETURN void throwError(const char *msg) {
32  throw string(msg);
33 }
34 
35 static __ATTR__NORETURN void throwParseError(const char *msg, const LineReader& file) {
36  fprintf(stderr, "\n%s:%zu: %s\n", file.getFilename().c_str(), file.getLineNumber(), msg);
37  fflush(stderr);
38  throwError(msg);
39 }
40 
41 static __ATTR__NORETURN void throwItemError(const GmenuItem& i, const char *error, const LineReader& file) {
42  char *itemName = readableItemname(i);
43  const char *msg = GBS_global_string("[Above this line] Invalid item '%s' defined: %s", itemName, error);
44  free(itemName);
45  throwParseError(msg, file);
46 }
47 
48 static void CheckItemConsistency(const GmenuItem *item, const LineReader& file) {
49  // (incomplete) consistency check.
50  // bailing out with ItemError() here, will make unit-test and arb-startup fail!
51 
52  if (item) {
53  const GmenuItem& I = *item;
54  if (I.seqtype != '-' && I.numinputs<1) {
55  // Such an item would create a window where alignment/species selection is present,
56  // but no sequence export will take place.
57  //
58  // Pressing 'GO' would result in failure or deadlock.
59  throwItemError(I, "item defines seqtype ('seqtype:' <> '-'), but is lacking input-specification ('in:')", file);
60  }
61  if (I.seqtype == '-' && I.numinputs>0) {
62  // Such an item would create a window where alignment/species selection has no GUI-elements,
63  // but sequences are exported (generating a corrupt sequence file)
64  //
65  // Pressing 'GO' would result in failure.
66  throwItemError(I, "item defines no seqtype ('seqtype:' = '-'), but defines input-specification ('in:')", file);
67  }
68  }
69 }
70 
71 #define THROW_IF_NO(ptr,name) do { if (!ptr) throwParseError(GBS_global_string("'%s' used w/o '" name "'", head), in); } while(0)
72 
73 #define THROW_IF_NO_MENU() THROW_IF_NO(thismenu, "menu")
74 #define THROW_IF_NO_ITEM() THROW_IF_NO(thisitem, "item")
75 #define THROW_IF_NO_ARG() THROW_IF_NO(thisarg, "arg")
76 #define THROW_IF_NO_INPUT() THROW_IF_NO(thisinput, "in")
77 #define THROW_IF_NO_OUTPUT() THROW_IF_NO(thisoutput, "out")
78 
79 // --------------------------------------------------------------------------------
80 
81 inline const char *truncate_4000(const char *str) {
82  const int BUFSIZE = 4000;
83  static char buffer[BUFSIZE];
84  strcpy_truncate(buffer, str, BUFSIZE);
85  return buffer;
86 }
87 
88 inline void trim(char *str) {
89  int s = 0;
90  int d = 0;
91 
92  while (isspace(str[s])) ++s;
93  while (str[s]) str[d++] = str[s++];
94 
95  str[d] = 0;
96  while (d>0 && isspace(str[d-1])) str[--d] = 0;
97 }
98 
99 static void splitEntry(const char *input, char *head, char *tail) {
102  const char *colon = strchr(input, ':');
103  if (colon) {
104  int len = colon-input;
105  memcpy(head, input, len);
106  head[len] = 0;
107 
108  strcpy(tail, colon+1);
109 
110  trim(tail);
111  }
112  else {
113  strcpy(head, input);
114  }
115  trim(head);
116 }
117 
118 // --------------------------------------------------------------------------------
119 
120 static void ParseMenus(LineReader& in) {
121  /* parses menus via LineReader (contains ALL found menu-files) and
122  * assemble an internal representation of the menu/menu-item hierarchy.
123  *
124  * please document changes in ../HELP_SOURCE/oldhelp/gde_menus.hlp
125  */
126 
127  memset((char*)&menu[0], 0, sizeof(Gmenu)*GDEMAXMENU);
128 
129  int curarg = 0;
130  int curinput = 0;
131  int curoutput = 0;
132 
133  Gmenu *thismenu = NULp;
134  GmenuItem *thisitem = NULp;
135  GmenuItemArg *thisarg = NULp;
136  GfileFormat *thisinput = NULp;
137  GfileFormat *thisoutput = NULp;
138 
139  bool thismenu_firstOccurrence = true;
140 
141  int j;
142  char temp[GBUFSIZ];
143  char head[GBUFSIZ];
144  char tail[GBUFSIZ];
145 
146  string lineStr;
147 
148  while (in.getLine(lineStr)) {
149  gde_assert(lineStr.length()<GBUFSIZ); // otherwise buffer usage may fail
150 
151  const char *in_line = lineStr.c_str();
152  if (in_line[0] == '#' || (in_line[0] && in_line[1] == '#')) {
153  ; // skip line
154  }
155  else if (only_whitespace(in_line)) {
156  ; // skip line
157  }
158  else {
159  splitEntry(in_line, head, temp);
160 
161  // menu: chooses menu to use (may occur multiple times with same label!)
162  if (strcmp(head, "menu") == 0) {
163  int curmenu = -1;
164  for (j=0; j<num_menus && curmenu == -1; j++) {
165  if (strcmp(temp, menu[j].label) == 0) curmenu=j;
166  }
167 
168  thismenu_firstOccurrence = curmenu == -1;
169 
170  // If menu not found, make a new one
171  if (thismenu_firstOccurrence) {
172  curmenu = num_menus++;
173  thismenu = &menu[curmenu];
174  thismenu->label = ARB_strdup(temp);
175  thismenu->numitems = 0;
176  thismenu->active_mask = AWM_ALL;
177  }
178  else {
179  thismenu = &menu[curmenu];
180  }
181 
182  CheckItemConsistency(thisitem, in);
183  thisitem = NULp;
184  thisarg = NULp;
185  thisoutput = NULp;
186  thisinput = NULp;
187  }
188  else if (strcmp(head, "menumask") == 0) {
190  AW_active wanted_mask = strcmp("expert", temp) == 0 ? AWM_EXP : AWM_ALL;
191  if (!thismenu_firstOccurrence && thismenu->active_mask != wanted_mask) {
192  throwParseError(GBS_global_string("menumask has inconsistent definitions (in different definitions of menu '%s')", thismenu->label), in);
193  }
194  thismenu->active_mask = wanted_mask;
195  }
196  else if (strcmp(head, "menumeta") == 0) {
198  char wanted_meta = temp[0];
199  if (!thismenu_firstOccurrence && thismenu->meta != wanted_meta) {
200  if (wanted_meta != 0) {
201  if (thismenu->meta != 0) {
202  throwParseError(GBS_global_string("menumeta has inconsistent definitions (in different definitions of menu '%s')", thismenu->label), in);
203  }
204  else {
205  thismenu->meta = wanted_meta;
206  }
207  }
208  }
209  else {
210  thismenu->meta = wanted_meta;
211  }
212  }
213  // item: chooses menu item to use
214  else if (strcmp(head, "item") == 0) {
215  CheckItemConsistency(thisitem, in);
216 
218 
219  curarg = -1;
220  curinput = -1;
221  curoutput = -1;
222 
223  int curitem = thismenu->numitems++;
224 
225  // Resize the item list for this menu (add one item)
226  if (curitem == 0) {
227  ARB_alloc(thismenu->item, 1);
228  }
229  else {
230  ARB_realloc(thismenu->item, thismenu->numitems);
231  }
232 
233  thisitem = &(thismenu->item[curitem]);
234 
235  thisitem->numargs = 0;
236  thisitem->numoutputs = 0;
237  thisitem->numinputs = 0;
238  thisitem->label = ARB_strdup(temp);
239  thisitem->method = NULp;
240  thisitem->input = NULp;
241  thisitem->output = NULp;
242  thisitem->arg = NULp;
243  thisitem->meta = '\0';
244  thisitem->seqtype = '-'; // no default sequence export
245  thisitem->aligned = false;
246  thisitem->help = NULp;
247 
248  thisitem->parent_menu = thismenu;
249  thisitem->aws = NULp; // no window opened yet
250  thisitem->active_mask = AWM_ALL;
251  thisitem->popup = NULp;
252 
253  for (int i = 0; i<curitem; ++i) {
254  if (strcmp(thismenu->item[i].label, thisitem->label) == 0) {
255  throwParseError(GBS_global_string("Duplicated item label '%s'", thisitem->label), in);
256  }
257  }
258 
259  thisarg = NULp;
260  }
261 
262  // itemmethod: generic command line generated by this item
263  else if (strcmp(head, "itemmethod") == 0) {
265  ARB_calloc(thisitem->method, strlen(temp)+1);
266 
267  {
268  char *to = thisitem->method;
269  char *from = temp;
270  char last = 0;
271  char c;
272 
273  do {
274  c = *from++;
275  if (c == '@' && last == '@') {
276  // replace "@@" with "'"
277  // [WHY_USE_DOUBLE_AT]
278  // - cant use 1 single quote ("'"). Things inside will not be preprocessed correctly.
279  // - cant use 2 single quotes ("''") any longer. clang fails on OSX.
280  to[-1] = '\'';
281  }
282  else {
283  *to++ = c;
284  }
285  last = c;
286  }
287  while (c!=0);
288  }
289 
290  }
291  // Help file
292  else if (strcmp(head, "itemhelp") == 0) {
294  thisitem->help = GBS_string_eval(temp, "*.help=agde_*1.hlp");
295  }
296  // Meta key equiv
297  else if (strcmp(head, "itemmeta") == 0) {
299  thisitem->meta = temp[0];
300  }
301  else if (strcmp(head, "itemmask") == 0) {
303  if (strcmp("expert", temp) == 0) thisitem->active_mask = AWM_EXP;
304  }
305  // Sequence type restriction
306  else if (strcmp(head, "seqtype") == 0) {
308  thisitem->seqtype = toupper(temp[0]);
309  /* 'A' -> amino acids,
310  * 'N' -> nucleotides,
311  * '-' -> don't select sequences,
312  * otherwise any alignment
313  */
314  }
315  /* arg: defines the symbol for a command line argument.
316  * this is used for substitution into the itemmethod
317  * definition.
318  */
319 
320  else if (strcmp(head, "arg") == 0) {
322 
323  curarg = thisitem->numargs++;
324  ARB_recalloc(thisitem->arg, curarg, thisitem->numargs);
325 
326  thisarg = &(thisitem->arg[curarg]);
327 
328  thisarg->symbol = ARB_strdup(temp);
329  thisarg->type = 0;
330  thisarg->min = 0.0;
331  thisarg->max = 0.0;
332  thisarg->numchoices = 0;
333  thisarg->choice = NULp;
334  thisarg->textvalue = NULp;
335  thisarg->ivalue = 0;
336  thisarg->fvalue = 0.0;
337  thisarg->label = NULp;
338  thisarg->active_mask = AWM_ALL;
339  }
340  // argtype: Defines the type of argument (menu,chooser, text, slider)
341  else if (strcmp(head, "argtype") == 0) {
342  THROW_IF_NO_ARG();
343  int arglen = -1;
344  if (strncmp(temp, "text", (arglen = 4)) == 0) {
345  thisarg->type = TEXTFIELD;
346  freedup(thisarg->textvalue, "");
347 
348  if (temp[arglen] == 0) thisarg->textwidth = TEXTFIELDWIDTH; // only 'text'
349  else {
350  if (temp[arglen] != '(' || temp[strlen(temp)-1] != ')') {
351  sprintf(head, "Unknown argtype '%s' -- syntax: text(width) e.g. text(20)", truncate_4000(temp));
352  throwParseError(head, in);
353  }
354  thisarg->textwidth = atoi(temp+arglen+1);
355  if (thisarg->textwidth<1) {
356  sprintf(head, "Illegal textwidth specified in '%s'", truncate_4000(temp));
357  throwParseError(head, in);
358  }
359  }
360  }
361  else if (strcmp(temp, "choice_list") == 0) thisarg->type = CHOICE_LIST;
362  else if (strcmp(temp, "choice_menu") == 0) thisarg->type = CHOICE_MENU;
363  else if (strcmp(temp, "chooser") == 0) thisarg->type = CHOOSER;
364  else if (strcmp(temp, "filename") == 0) {
365  thisarg->type = FILE_SELECTOR;
366  freedup(thisarg->textvalue, "");
367  }
368  else if (strcmp(temp, "sai") == 0) thisarg->type = CHOICE_SAI;
369  else if (strcmp(temp, "slider") == 0) thisarg->type = SLIDER;
370  else if (strcmp(temp, "tree") == 0) thisarg->type = CHOICE_TREE;
371  else if (strcmp(temp, "weights") == 0) thisarg->type = CHOICE_WEIGHTS;
372  else {
373  sprintf(head, "Unknown argtype '%s'", truncate_4000(temp));
374  throwParseError(head, in);
375  }
376  }
377  /* argtext: The default text value of the symbol.
378  * $argument is replaced by this value if it is not
379  * changed in the dialog box by the user.
380  */
381  else if (strcmp(head, "argtext") == 0) {
382  THROW_IF_NO_ARG();
383  freedup(thisarg->textvalue, temp);
384  }
385  /* arglabel: Text label displayed in the dialog box for
386  * this argument. It should be a descriptive label.
387  */
388  else if (strcmp(head, "arglabel") == 0) {
389  THROW_IF_NO_ARG();
390  thisarg->label = GBS_string_eval(temp, "\\\\n=\\n");
391  }
392  /* Argument choice values use the following notation:
393  *
394  * argchoice:Displayed value:Method
395  *
396  * Where "Displayed value" is the label displayed in the dialog box
397  * and "Method" is the value passed back on the command line.
398  */
399  else if (strcmp(head, "argchoice") == 0) {
400  THROW_IF_NO_ARG();
401  splitEntry(temp, head, tail);
402 
403  int curchoice = thisarg->numchoices++;
404  ARB_recalloc(thisarg->choice, curchoice, thisarg->numchoices);
405 
406  thisarg->choice[curchoice].label = ARB_strdup(head);
407  thisarg->choice[curchoice].method = ARB_strdup(tail);
408  }
409  // argmin: Minimum value for a slider
410  else if (strcmp(head, "argmin") == 0) {
411  THROW_IF_NO_ARG();
412  (void)sscanf(temp, "%lf", &(thisarg->min));
413  }
414  // argmax: Maximum value for a slider
415  else if (strcmp(head, "argmax") == 0) {
416  THROW_IF_NO_ARG();
417  (void)sscanf(temp, "%lf", &(thisarg->max));
418  }
419  // argvalue: default value for a slider
420  else if (strcmp(head, "argvalue") == 0) {
421  THROW_IF_NO_ARG();
422  if (thisarg->type == TEXT) {
423  freedup(thisarg->textvalue, temp);
424  }
425  else {
426  (void)sscanf(temp, "%lf", &(thisarg->fvalue));
427  thisarg->ivalue = (int) thisarg->fvalue;
428  }
429  }
430  else if (strcmp(head, "argmask") == 0) {
431  THROW_IF_NO_ARG();
432  if (strcmp("expert", temp) == 0) thisarg->active_mask = AWM_EXP;
433  }
434  // in: Input file description
435  else if (strcmp(head, "in") == 0) {
437 
438  curinput = (thisitem->numinputs)++;
439  ARB_recalloc(thisitem->input, curinput, thisitem->numinputs);
440 
441  thisinput = &(thisitem->input)[curinput];
442 
443  thisinput->save = false;
444  thisinput->format = 0;
445  thisinput->symbol = ARB_strdup(temp);
446  thisinput->name = NULp;
447  thisinput->typeinfo = BASIC_TYPEINFO;
448  }
449  else if (strcmp(head, "informat") == 0) {
451  if (Find(temp, "genbank")) thisinput->format = GENBANK;
452  else if (Find(temp, "flat")) thisinput->format = NA_FLAT;
453  else throwParseError(GBS_global_string("Unknown informat '%s' (allowed 'genbank' or 'flat')", temp), in);
454  }
455  else if (strcmp(head, "insave") == 0) {
457  thisinput->save = true;
458  }
459  else if (strcmp(head, "intyped") == 0) {
461  if (Find(temp, "detailed")) thisinput->typeinfo = DETAILED_TYPEINFO;
462  else if (Find(temp, "basic")) thisinput->typeinfo = BASIC_TYPEINFO;
463  else throwParseError(GBS_global_string("Unknown value '%s' for 'intyped' (known: 'detailed', 'basic')", temp), in);
464  }
465  // out: Output file description
466  else if (strcmp(head, "out") == 0) {
468 
469  curoutput = (thisitem->numoutputs)++;
470  ARB_recalloc(thisitem->output, curoutput, thisitem->numoutputs);
471 
472  thisoutput = &(thisitem->output)[curoutput];
473 
474  thisoutput->save = false;
475  thisoutput->format = 0;
476  thisoutput->symbol = ARB_strdup(temp);
477  thisoutput->name = NULp;
478  }
479  else if (strcmp(head, "outformat") == 0) {
481  if (Find(temp, "genbank")) thisoutput->format = GENBANK;
482  else if (Find(temp, "gde")) thisoutput->format = GDE;
483  else if (Find(temp, "flat")) thisoutput->format = NA_FLAT;
484  else throwParseError(GBS_global_string("Unknown outformat '%s' (allowed 'genbank', 'gde' or 'flat')", temp), in);
485  }
486  else if (strcmp(head, "outaligned") == 0) {
488  if (Find(temp, "yes")) thisitem->aligned = true;
489  else throwParseError(GBS_global_string("Unknown outaligned '%s' (allowed 'yes' or skip entry)", temp), in);
490  }
491  else if (strcmp(head, "outsave") == 0) {
493  thisoutput->save = true;
494  }
495  else {
496  throwParseError(GBS_global_string("No known GDE-menu-command found (line='%s')", in_line), in);
497  }
498  }
499  }
500 
501  CheckItemConsistency(thisitem, in);
502 
503  gde_assert(num_menus>0); // if this fails, the file arb.menu contained no menus (maybe file has zero size)
504 }
505 
512  GB_ERROR error = NULp;
513  StrArray files;
514  {
515  char *user_menu_dir = ARB_strdup(GB_path_in_arbprop("gde"));
516 
517  if (!GB_is_directory(user_menu_dir)) {
518  error = GB_create_directory(user_menu_dir);
519  }
521 
522  if (!error) {
523  GBS_read_dir(files, user_menu_dir, "/\\.menu$/");
524  GBS_read_dir(files, GB_path_in_ARBLIB("gde"), "/\\.menu$/");
525  error = GB_incur_error();
526  }
527 
528  free(user_menu_dir);
529  }
530 
531  if (!error) {
532  MultiFileReader menus(files);
533  error = menus.get_error();
534  if (!error) {
535  try {
536  ParseMenus(menus);
537  }
538  catch (const string& err) {
539  error = GBS_static_string(err.c_str());
540  }
541  }
542  }
543 
544  if (error) error = GBS_global_string("Error while loading menus: %s", error);
545  return error;
546 }
547 
548 bool Find(const char *target, const char *key) {
549  // Search the target string for the given key
550  return strstr(target, key) ? true : false;
551 }
552 
553 int Find2(const char *target, const char *key) {
554  /* Like Find(), but returns the index of the leftmost
555  * occurrence, and -1 if not found.
556  */
557  const char *found = strstr(target, key);
558  return found ? int(found-target) : -1;
559 }
560 
561 // --------------------------------------------------------------------------------
562 
563 #ifdef UNIT_TESTS
564 #ifndef TEST_UNIT_H
565 #include <test_unit.h>
566 #endif
567 
568 void TEST_load_menu() {
569  // very basic test: just detects failing assertions, crashes and errors
570 
571  gb_getenv_hook old = GB_install_getenv_hook(arb_test::fakeenv);
572  {
573  // ../UNIT_TESTER/run/homefake/
574 
576 
577  // basic check of loaded data (needs to be adapted if menus change):
579 
580  string menus;
581  string menuitems;
582  for (int m = 0; m<num_menus; ++m) {
583  menus = menus + menu[m].label + ";";
584  menuitems += GBS_global_string("%i;", menu[m].numitems);
585  }
586 
587  TEST_EXPECT_EQUAL(menus,
588  "Import;Export;Print;Align;Network;SAI;Incremental phylogeny;Phylogeny Distance Matrix;"
589  "Phylogeny max. parsimony;Phylogeny max. Likelihood EXP;Phylogeny max. Likelihood;Phylogeny (Other);User;");
590  TEST_EXPECT_EQUAL(menuitems, "3;1;2;10;1;1;1;3;2;1;8;5;0;");
591  }
592  TEST_EXPECT_EQUAL((void*)arb_test::fakeenv, (void*)GB_install_getenv_hook(old));
593 }
594 
595 #endif // UNIT_TESTS
596 
597 // --------------------------------------------------------------------------------
598 
static int I
Definition: align.cxx:489
const char * GB_ERROR
Definition: arb_core.h:25
AW_bitset AW_active
Definition: aw_base.hxx:45
static void CheckItemConsistency(const GmenuItem *item, const LineReader &file)
GB_CSTR GB_path_in_arbprop(const char *relative_path)
Definition: adsocket.cxx:1109
char * textvalue
Definition: GDE_menu.h:33
GB_ERROR GB_incur_error()
Definition: arb_msg.h:49
return string(buffer, length)
char * symbol
Definition: GDE_menu.h:51
#define THROW_IF_NO_ARG()
GfileFormat * output
Definition: GDE_menu.h:63
#define THROW_IF_NO_OUTPUT()
int numargs
Definition: GDE_menu.h:57
char * method
Definition: GDE_menu.h:23
int numinputs
Definition: GDE_menu.h:59
double min
Definition: GDE_menu.h:29
#define CHOICE_TREE
Definition: GDE_def.h:23
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
int numitems
Definition: GDE_menu.h:78
char * label
Definition: GDE_menu.h:79
char * name
Definition: GDE_menu.h:52
bool save
Definition: GDE_menu.h:49
struct Gmenu * parent_menu
Definition: GDE_menu.h:71
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
#define CHOOSER
Definition: GDE_def.h:20
GfileFormat * input
Definition: GDE_menu.h:62
bool GB_have_error()
Definition: arb_msg.cxx:349
int num_menus
Definition: GDE.cxx:26
char * GBS_string_eval(const char *insource, const char *icommand)
Definition: admatch.cxx:699
char * method
Definition: GDE_menu.h:61
static void ParseMenus(LineReader &in)
NOT4PERL gb_getenv_hook GB_install_getenv_hook(gb_getenv_hook hook)
Definition: adsocket.cxx:646
AW_window * aws
Definition: GDE_menu.h:72
#define TEXTFIELDWIDTH
Definition: GDE_def.h:15
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
int ivalue
Definition: GDE_menu.h:28
char seqtype
Definition: GDE_menu.h:66
char * symbol
Definition: GDE_menu.h:36
#define GBUFSIZ
Definition: GDE_def.h:14
char * label
Definition: GDE_menu.h:60
static char * readableItemname(const GmenuItem &i)
size_t getLineNumber() const
GB_ERROR LoadMenus()
#define TEXT
Definition: GDE_def.h:43
fflush(stdout)
void strcpy_truncate(char *dest, const char *source, size_t dest_size)
Definition: GDE_def.h:137
#define THROW_IF_NO_MENU()
TYPE * ARB_alloc(size_t nelem)
Definition: arb_mem.h:56
char * label
Definition: GDE_menu.h:35
#define CHOICE_WEIGHTS
Definition: GDE_def.h:25
int numchoices
Definition: GDE_menu.h:32
static __ATTR__NORETURN void throwItemError(const GmenuItem &i, const char *error, const LineReader &file)
#define GDE
Definition: GDE_def.h:29
int textwidth
Definition: GDE_menu.h:34
int format
Definition: GDE_menu.h:50
static void error(const char *msg)
Definition: mkptypes.cxx:96
TypeInfo typeinfo
Definition: GDE_menu.h:53
#define FILE_SELECTOR
Definition: GDE_def.h:26
virtual bool getLine(string &line)
GmenuItem * item
Definition: GDE_menu.h:80
#define GDEMAXMENU
Definition: GDE_extglob.h:20
double max
Definition: GDE_menu.h:30
void ARB_recalloc(TYPE *&tgt, size_t oelem, size_t nelem)
Definition: arb_mem.h:49
int numoutputs
Definition: GDE_menu.h:58
static __ATTR__NORETURN void throwParseError(const char *msg, const LineReader &file)
GargChoice * choice
Definition: GDE_menu.h:37
int Find2(const char *target, const char *key)
const char *(* gb_getenv_hook)(const char *varname)
Definition: arbdb.h:138
GB_CSTR GB_path_in_ARBLIB(const char *relative_path)
Definition: adsocket.cxx:1103
WindowCallback * popup
Definition: GDE_menu.h:74
Definition: fun.h:13
void GBS_read_dir(StrArray &names, const char *dir, const char *mask)
Definition: adfile.cxx:213
void trim(char *str)
char * help
Definition: GDE_menu.h:68
GmenuItemArg * arg
Definition: GDE_menu.h:64
#define THROW_IF_NO_ITEM()
Gmenu menu[GDEMAXMENU]
Definition: GDE.cxx:25
bool Find(const char *target, const char *key)
#define CHOICE_MENU
Definition: GDE_def.h:21
virtual const string & getFilename() const =0
const char * truncate_4000(const char *str)
#define CHOICE_SAI
Definition: GDE_def.h:24
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
#define NA_FLAT
Definition: GDE_def.h:31
double fvalue
Definition: GDE_menu.h:31
#define TEXTFIELD
Definition: GDE_def.h:18
bool GB_is_directory(const char *path)
Definition: arb_file.cxx:176
AW_active active_mask
Definition: GDE_menu.h:39
#define SLIDER
Definition: GDE_def.h:19
void ARB_realloc(TYPE *&tgt, size_t nelem)
Definition: arb_mem.h:43
const char * GBS_static_string(const char *str)
Definition: arb_msg.cxx:213
#define TEST_EXPECT_NO_ERROR(call)
Definition: test_unit.h:1107
bool white(int ch)
AW_active active_mask
Definition: GDE_menu.h:73
static int line
Definition: arb_a2ps.c:296
#define NULp
Definition: cxxforward.h:97
#define __ATTR__NORETURN
Definition: attributes.h:56
#define CHOICE_LIST
Definition: GDE_def.h:22
__ATTR__NORETURN void throwError(const char *msg)
char * label
Definition: GDE_menu.h:22
char meta
Definition: GDE_menu.h:65
Definition: GDE_menu.h:77
AW_active active_mask
Definition: GDE_menu.h:83
#define BUFSIZE
char meta
Definition: GDE_menu.h:82
bool only_whitespace(const char *line)
#define THROW_IF_NO_INPUT()
static void splitEntry(const char *input, char *head, char *tail)
#define TEST_EXPECT_EQUAL(expr, want)
Definition: test_unit.h:1283
#define gde_assert(bed)
Definition: GDE_def.h:12
GB_ERROR GB_create_directory(const char *path)
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:195
bool aligned
Definition: GDE_menu.h:67
const char * label
GB_write_int const char s
Definition: AW_awar.cxx:156