Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 *
3
 *
4
 */
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <ctype.h>
10
 
11
#include "hconf.h"
12
 
13
struct variable vartable[MAXVARIABLES];
14
struct menu menutable[MAXMENUS];
15
char *filetable[MAXFILETABLE];
16
int maxfileindex=0;
17
 
18
long varhelp[MAXVARIABLES];
19
char helpfilename[FILENAME_MAX];
20
 
21
#if 0
22
#define printd(fmt,args...) fprintf(stderr,fmt,##args)
23
#else
24
#define printd(fmt,args...)
25
#endif
26
 
27
struct menu *mainmenu=NULL;
28
char *caption=NULL;
29
 
30
/*
31
 *
32
 */
33
 
34
int copystring(char **dstptr, char *src)
35
{
36
  int sz;
37
  if (*dstptr!=NULL) free(*dstptr);
38
  sz=strlen(src)+1;
39
  *dstptr=(char*)malloc(sz);
40
  if (*dstptr==NULL) return -100;
41
  strcpy(*dstptr,src);
42
  return 0;
43
}
44
 
45
/*
46
 *
47
 */
48
 
49
int nextvariable=0;
50
 
51
struct variable *findvar(char *s)
52
{
53
  int i;
54
  i=0;
55
  while (i<nextvariable) {
56
    if (!strcmp(vartable[i].name,s)) return vartable+i;
57
    i++;
58
  }
59
  return NULL;
60
}
61
 
62
int findvarindex(struct variable *var)
63
{
64
  return (var-vartable);
65
}
66
 
67
struct variable *newvar(char *s, int type)
68
{
69
  struct variable *var;
70
 
71
  /* safety test */
72
  var=findvar(s);
73
  if (var!=NULL) {
74
    if (var->type==NOTYPEVAR) var->type=type;
75
    else if (var->type!=type) return NULL;
76
    return var;
77
  }
78
 
79
  if (nextvariable>=MAXVARIABLES) return NULL;
80
 
81
  vartable[nextvariable].name=NULL;
82
  copystring(&vartable[nextvariable].name,s);
83
  vartable[nextvariable].type=type;
84
  vartable[nextvariable].value=NULL;
85
  vartable[nextvariable].flags=0;
86
  vartable[nextvariable].fileindex=NOFILEINDEX;
87
 
88
  return vartable+nextvariable++;
89
}
90
 
91
/* -- */
92
 
93
int nextmenu=0;
94
 
95
struct menu *findmenu(char *s)
96
{
97
  int i;
98
  i=0;
99
  while (i<nextmenu) {
100
    if (!strcmp(menutable[i].name,s)) return menutable+i;
101
    i++;
102
  }
103
  return NULL;
104
}
105
 
106
struct menu *newmenu(char *s)
107
{
108
  if (nextmenu>=MAXMENUS) return NULL;
109
 
110
  menutable[nextmenu].name=NULL;
111
  copystring(&menutable[nextmenu].name,s);
112
  menutable[nextmenu].title=NULL;
113
  menutable[nextmenu].entries=NULL;
114
 
115
  return menutable+nextmenu++;
116
}
117
 
118
/*
119
 *
120
 *
121
 *
122
 */
123
 
124
struct _case *newcase(struct menuentry *menuent)
125
{
126
  struct _case *c;
127
  struct _case *n;
128
  c=malloc(sizeof(struct _case));
129
  if (c==NULL) return NULL;
130
  c->next=NULL;
131
  c->value=NULL;
132
  c->list=NULL;
133
  if (menuent->x._case.list==NULL) {
134
    menuent->x._case.list=c;
135
    return c;
136
  }
137
  n=menuent->x._case.list;
138
  for (;;) {
139
    if (n->next==NULL) {
140
      n->next=c;
141
      return c;
142
    }
143
    n=n->next;
144
  }
145
}
146
 
147
struct choice *newchoice(struct menuentry *menuent)
148
{
149
  struct choice *c;
150
  struct choice *n;
151
  c=malloc(sizeof(struct choice));
152
  if (c==NULL) return NULL;
153
  c->next=NULL;
154
  c->text=NULL;
155
  c->var=NULL;
156
  if (menuent->x.choice.list==NULL) {
157
    menuent->x.choice.list=c;
158
    return c;
159
  }
160
  n=menuent->x.choice.list;
161
  for (;;) {
162
    if (n->next==NULL) {
163
      n->next=c;
164
      return c;
165
    }
166
    n=n->next;
167
  }
168
}
169
 
170
struct menuentry *newmenuentry(struct menuentry **ptr)
171
{
172
  struct menuentry *n;
173
  struct menuentry *p;
174
  n=malloc(sizeof(struct menuentry));
175
  if (n==NULL) return NULL;
176
  n->next=NULL;
177
  n->type=0;
178
  if (*ptr==NULL) {
179
    *ptr=n;
180
    return n;
181
  }
182
  p=*ptr;
183
  for (;;) {
184
    if (p->next==NULL) {
185
      p->next=n;
186
      return n;
187
    }
188
    p=p->next;
189
  }
190
}
191
 
192
int newfile(char *s)
193
{
194
  if (maxfileindex==MAXFILETABLE) return NOFILEINDEX;
195
  filetable[maxfileindex]=malloc(strlen(s)+1);
196
  if (filetable[maxfileindex]==NULL) return NOFILEINDEX;
197
  strcpy(filetable[maxfileindex],s);
198
  maxfileindex++;
199
  return maxfileindex-1;
200
}
201
 
202
/*
203
 *
204
 *
205
 *
206
 */
207
 
208
/*
209
 *
210
 *
211
 *
212
 */
213
 
214
int parsebool(struct menuentry **ptr);
215
int parsetristate(struct menuentry **ptr);
216
int parserange(struct menuentry **ptr);
217
int parsesubmenu(struct menuentry **ptr);
218
int parsecase(struct menuentry **ptr);
219
int parsechoice(struct menuentry **ptr);
220
int parseseparator(struct menuentry **ptr);
221
 
222
int parsemenufield(struct menuentry **ptr)
223
{
224
  char *s;
225
 
226
  s=gettoken();
227
  if (s==NULL) return -999;
228
 
229
  if (!strcmp(s,"bool")) return parsebool(ptr);
230
  if (!strcmp(s,"tristate")) return parsetristate(ptr);
231
  if (!strcmp(s,"range")) return parserange(ptr);
232
  if (!strcmp(s,"submenu")) return parsesubmenu(ptr);
233
  if (!strcmp(s,"switch")) return parsecase(ptr);
234
  if (!strcmp(s,"choice")) return parsechoice(ptr);
235
  if (!strcmp(s,"separator")) return parseseparator(ptr);
236
 
237
  return -333;
238
}
239
 
240
/* --- */
241
 
242
int parsecase(struct menuentry **ptr)
243
{
244
  char *s;
245
  struct menuentry *ent;
246
  struct _case *cas=NULL;
247
  struct variable *v;
248
  int res;
249
 
250
  printd("start parseswitch()\n");
251
 
252
  ent=newmenuentry(ptr);
253
  if (ent==NULL) return -31;
254
  ent->type=CASEENTRY;
255
  ent->x._case.list=NULL;
256
 
257
  s=gettoken();
258
  if (s==NULL) return -32;
259
  v=findvar(s);
260
  if (v==NULL) return -36;
261
  ent->x._case.var=v;
262
  v->flags|=FLAG_M;
263
 
264
  for (;;) {
265
    s=gettoken();
266
    if (!strcmp(s,"endswitch")) break;
267
 
268
    if (!strcmp(s,"case")) {
269
      cas=newcase(ent);
270
      if (cas==NULL) return -34;
271
      s=gettoken();
272
      if (s==NULL) return -35;
273
      if (*s!='\"') return -35;
274
      cas->value=NULL;
275
      copystring(&cas->value,s+1);
276
      continue;
277
    }
278
 
279
    if (cas==NULL) return -39;
280
 
281
    ungettoken();
282
    res=parsemenufield(&cas->list);
283
    if (res) return res;
284
  }
285
 
286
  return 0;
287
}
288
 
289
int parsechoice(struct menuentry **ptr)
290
{
291
  struct menuentry *ent;
292
  struct choice *cho;
293
  struct variable *v;
294
  char *def;
295
  int defdone;
296
  char *s;
297
 
298
  printd("start parsechoice()\n");
299
 
300
  ent=newmenuentry(ptr);
301
  if (ent==NULL) return -31;
302
  ent->type=CHOICEENTRY;
303
  ent->x.choice.list=NULL;
304
  ent->x.choice.act=NULL;
305
  ent->x.choice.numchoices=0;
306
 
307
  s=gettoken();
308
  if (s==NULL) return -32;
309
  if (*s!='\"') return -33;
310
  ent->x.choice.text=NULL;
311
  copystring(&ent->x.choice.text,s+1);
312
 
313
  defdone=0;
314
  def=NULL;
315
  s=gettoken();
316
  if (s==NULL) return -39;
317
  if (*s!='\"') {
318
    copystring(&def,s);
319
  } else
320
    ungettoken();
321
 
322
  for (;;) {
323
    s=gettoken();
324
    if (s==NULL) return -34;
325
    if (!strcmp(s,"endchoice")) {
326
      if (def==NULL||!defdone) return -37;
327
      free(def);
328
      break;
329
    }
330
 
331
    if (*s!='\"') return -38;
332
 
333
    cho=newchoice(ent);
334
    ent->x.choice.numchoices++;
335
    if (cho==NULL) return -33;
336
    cho->text=NULL;
337
    copystring(&cho->text,s+1);
338
 
339
    s=gettoken();
340
    if (s==NULL) return -34;    
341
    v=newvar(s,CHOICEVAR);
342
    if (v==NULL) return -37;
343
    cho->var=v;
344
    v->value=NULL;
345
    copystring(&v->value,"n");
346
 
347
    if (def==NULL) {
348
      ent->x.choice.act=cho;
349
      copystring(&def,s);
350
      defdone=1;
351
    } else if (!strcmp(def,s)) {
352
      ent->x.choice.act=cho;
353
      defdone=1;
354
    }
355
  }
356
 
357
  return 0;
358
}
359
 
360
int parsebool(struct menuentry **ptr)
361
{
362
  struct menuentry *ent;
363
  struct variable *var;
364
  char *s;
365
 
366
  printd("start parsebool()\n");
367
 
368
  ent=newmenuentry(ptr);
369
  if (ent==NULL) return -50;
370
  ent->type=BOOLENTRY;
371
 
372
  s=gettoken();
373
  if (s==NULL) return -51;
374
  if (*s!='\"') return -55;
375
  ent->x.bool.text=NULL;
376
  copystring(&ent->x.bool.text,s+1);
377
 
378
  s=gettoken();
379
  if (s==NULL) return -52;
380
  var=newvar(s,BOOLVAR);
381
  if (var==NULL) return -53;
382
  ent->x.bool.var=var;
383
 
384
  s=gettoken();
385
  if (*s!='\"') {
386
    ungettoken();
387
    var->value=(char *)malloc(2);
388
    var->value[0]='n';
389
    var->value[1]='\0';
390
    return 0;
391
  }
392
  if (*(s+1)=='\0') return -54;
393
  var->value=NULL;
394
  copystring(&var->value,s+1);
395
 
396
  return 0;
397
}
398
 
399
int parseseparator(struct menuentry **ptr)
400
{
401
  struct menuentry *ent;
402
 
403
  printd("start parseseparator()\n");
404
 
405
  ent=newmenuentry(ptr);
406
  if (ent==NULL) return -50;
407
  ent->type=SEPARATORENTRY;
408
 
409
  return 0;
410
}
411
 
412
int parserange(struct menuentry **ptr)
413
{
414
  struct menuentry *ent;
415
  struct variable *var;
416
  char *s;
417
  int v;
418
 
419
  printd("start parserange()\n");
420
 
421
  ent=newmenuentry(ptr);
422
  if (ent==NULL) return -60;
423
  ent->type=RANGEENTRY;
424
 
425
  s=gettoken();
426
  if (s==NULL) return -61;
427
  if (*s!='\"') return -65;
428
  ent->x.range.text=NULL;
429
  copystring(&ent->x.range.text,s+1);
430
 
431
  s=gettoken();
432
  if (s==NULL) return -62;
433
  var=newvar(s,RANGEVAR);
434
  if (var==NULL) return -63;
435
  ent->x.range.var=var;
436
 
437
  s=gettoken();
438
  if (s==NULL) return -66;
439
  ent->x.range.minval=atoi(s);
440
  if (ent->x.range.minval==0&&strcmp(s,"0")) return -67;
441
 
442
  s=gettoken();
443
  if (s==NULL) return -66;
444
  ent->x.range.maxval=atoi(s);
445
  if (ent->x.range.maxval==0&&strcmp(s,"0")) return -68;
446
 
447
  s=gettoken();
448
  if (s==NULL) return -69;
449
  v=atoi(s);
450
  if (v==0&&strcmp(s,"0")) {
451
    ungettoken();
452
    v=ent->x.range.minval;
453
  }
454
 
455
  {
456
    char buffer[256];
457
    sprintf(buffer,"%i",v);
458
    var->value=NULL;
459
    copystring(&var->value,buffer);
460
  }
461
 
462
  return 0;
463
}
464
 
465
int parsetristate(struct menuentry **ptr)
466
{
467
  struct menuentry *ent;
468
  struct variable *var;
469
  char *s;
470
 
471
  printd("start parsetristate()\n");
472
 
473
  ent=newmenuentry(ptr);
474
  if (ent==NULL) return -50;
475
  ent->type=TRISTATEENTRY;
476
 
477
  s=gettoken();
478
  if (s==NULL) return -51;
479
  if (*s!='\"') return -55;
480
  ent->x.tristate.text=NULL;
481
  copystring(&ent->x.tristate.text,s+1);
482
 
483
  s=gettoken();
484
  if (s==NULL) return -52;
485
  var=newvar(s,TRISTATEVAR);
486
  if (var==NULL) return -53;
487
  ent->x.tristate.var=var;
488
 
489
  s=gettoken();
490
  if (*s!='\"') {
491
    ungettoken();
492
    var->value=(char *)malloc(2);
493
    var->value[0]='n';
494
    var->value[1]='\0';
495
    return 0;
496
  }
497
  if (*(s+1)=='\0') return -54;
498
  var->value=NULL;
499
  copystring(&var->value,s+1);
500
 
501
  return 0;
502
}
503
 
504
int parsesubmenu(struct menuentry **ptr)
505
{
506
  struct menuentry *ent;
507
  char *s;
508
 
509
  printd("start parsesubmenu()\n");
510
 
511
  ent=newmenuentry(ptr);
512
  if (ent==NULL) return -40;
513
  ent->type=SUBMENUENTRY;
514
 
515
  s=gettoken();
516
  if (s==NULL) return -41;
517
  if (*s!='\"') return -43;
518
  ent->x.submenu.text=NULL;
519
  copystring(&ent->x.submenu.text,s+1);
520
 
521
  s=gettoken();
522
  if (s==NULL) return -42;
523
  ent->x.submenu.menuname=NULL;
524
  ent->x.submenu.menu=NULL;
525
  copystring(&ent->x.submenu.menuname,s);
526
 
527
  return 0;
528
}
529
 
530
int parsetitle(struct menu *ptr)
531
{
532
  char *s;
533
 
534
  printd("start parsetitle()\n");
535
 
536
  s=gettoken();
537
  if (s==NULL) return -71;
538
  ptr->title=NULL;
539
  copystring(&ptr->title,s+1);
540
  return 0;
541
}
542
 
543
int parsecaption(void)
544
{
545
  char *s;
546
 
547
  printd("start parsecaption()\n");
548
 
549
  s=gettoken();
550
  if (s==NULL) return -91;
551
  caption=NULL;
552
  copystring(&caption,s+1);
553
  return 0;
554
}
555
 
556
int parsemenu(void)
557
{
558
  struct menu *ptr;
559
  char *s;
560
  int ret;
561
 
562
  printd("start parsemenu()\n");
563
  ret=0;
564
 
565
  s=gettoken();
566
  if (s==NULL) return -12;
567
  ptr=newmenu(s);
568
  if (ptr==NULL) return -15;
569
 
570
  for (;;) {
571
    s=gettoken();
572
    if (!strcmp(s,"endmenu")) return 0;
573
 
574
    if (!strcmp(s,"title")) {
575
      ret=parsetitle(ptr);
576
      if (ret) return ret;
577
      continue;
578
    }
579
 
580
    ungettoken();
581
    ret=parsemenufield(&ptr->entries);    
582
    if (ret) break;
583
  }
584
 
585
  return ret;
586
}
587
 
588
int parsefile(void)
589
{
590
  struct variable *var;
591
  char *s;
592
  int index;
593
  int ret;
594
 
595
  printd("start parsefile()\n");
596
  ret=0;
597
 
598
  s=gettoken();
599
  if (s==NULL) return -112;  
600
  index=newfile(s);
601
  if (index==-1) return -115;
602
 
603
  for (;;) {
604
    s=gettoken();
605
    if (!strcmp(s,"endfile")) return 0;
606
 
607
    var=newvar(s,NOTYPEVAR);
608
    if (var==NULL) return -117;
609
    var->fileindex=index;
610
  }
611
 
612
  return ret;
613
}
614
 
615
/*
616
 *
617
 */
618
 
619
int resolvmenuentries(struct menuentry *ptr)
620
{
621
  struct _case *ca;
622
  int res,i;
623
 
624
  while (ptr!=NULL) {
625
    switch(ptr->type) {
626
    case BOOLENTRY:
627
      break;
628
    case TRISTATEENTRY:
629
      break;
630
    case SUBMENUENTRY:
631
      ptr->x.submenu.menu=findmenu(ptr->x.submenu.menuname);
632
      if (ptr->x.submenu.menu==NULL) return -10;
633
      break;
634
    case CHOICEENTRY:
635
      break;
636
    case CASEENTRY:
637
      ca=ptr->x._case.list;
638
      i=1;
639
      while (ca!=NULL) {
640
        res=resolvmenuentries(ca->list);
641
        if (res) return res;
642
        ca=ca->next;
643
        i++;
644
      }
645
      break;
646
    }
647
    ptr=ptr->next;
648
  }
649
 
650
  return 0;
651
}
652
 
653
static int resolv(void)
654
{
655
  int res,i;
656
 
657
  i=0;
658
  while (i<nextmenu) {
659
    res=resolvmenuentries(menutable[i].entries);
660
    if (res) return res;
661
    i++;
662
  }
663
 
664
  return 0;
665
}
666
 
667
/*
668
 *
669
 */
670
 
671
int parse(void)
672
{
673
  char *s;
674
  int ret;
675
  ret=0;
676
  while ((s=gettoken())!=NULL) {
677
    if (!strcmp(s,"menu")) ret=parsemenu();
678
    else if (!strcmp(s,"caption")) ret=parsecaption();
679
    else if (!strcmp(s,"file")) ret=parsefile();
680
    else ret=-1;
681
    if (ret) break;
682
  }
683
  return ret;
684
}
685
 
686
int parsehelp(char *filename)
687
{
688
  struct variable *var;
689
  char buffer[256];
690
  FILE *fin;
691
  char *s;
692
  int i;
693
 
694
  fin=fopen(filename,"rt");
695
  if (fin==NULL) return 0;
696
 
697
  while (fgets(buffer,sizeof(buffer),fin)!=NULL)
698
    if (*buffer=='@') {
699
      s=strchr(buffer,'\n');
700
      if (s!=NULL) *s='\0';
701
      var=findvar(buffer+1);
702
      if (var==NULL) {
703
        fprintf(stderr,"help var %s not found config file",buffer);
704
        return -845;
705
      }
706
      i=findvarindex(var);
707
      varhelp[i]=ftell(fin);
708
    }
709
 
710
  fclose(fin);
711
  return 0;
712
}
713
 
714
int readconfigin(char *filename)
715
{
716
  char *ptr;
717
  int res;
718
 
719
  res=init_tokenizer(filename,0x01);
720
  if (res) return res;
721
 
722
  res=parse();
723
  if (res) return res;
724
 
725
  res=done_tokenizer();
726
  if (res) return res;
727
 
728
  res=resolv();
729
  if (res) return res;
730
 
731
  mainmenu=findmenu("main");
732
  if (mainmenu==NULL) return -97;
733
 
734
  /* -- */
735
 
736
  ptr=strstr(filename,".in");  
737
  if (ptr!=NULL) *ptr='\0';
738
  else {
739
    ptr=strchr(filename,'.');
740
    if (ptr!=NULL) *ptr='\0';
741
  }
742
 
743
  strcpy(helpfilename,filename);
744
  strcat(helpfilename,".hlp");
745
 
746
  res=parsehelp(helpfilename);
747
  if (res) return res;
748
 
749
  return 0;
750
}
751
 
752
/*
753
 *
754
 *
755
 *
756
 */
757
 
758
void dumpvariables(void)
759
{
760
  int i;
761
 
762
  fprintf(stderr,"VARIABLES TABLE\n---------------\n\n");
763
  i=0;
764
  while (i<nextvariable) {
765
    fprintf(stderr,"name:  -%s-\n",vartable[i].name);
766
    if (vartable[i].value!=NULL)
767
      fprintf(stderr,"value: \"%s\"\n",vartable[i].value);
768
    else
769
      fprintf(stderr,"value: NO VALUE\n");
770
    fprintf(stderr,"flags: 0x%04x\n",vartable[i].flags);
771
    fputc('\n',stderr);
772
    i++;
773
  }
774
}
775
 
776
#if 0
777
 
778
void dumpmenuentrytype(struct menuentry *ptr,char *s)
779
{
780
  fprintf(stderr,"%s entry type  : ",s);
781
  switch(ptr->type) {
782
  case BOOLENTRY: fprintf(stderr,"bool\n"); break;
783
  case SUBMENUENTRY: fprintf(stderr,"submenu\n"); break;
784
  case TRISTATEENTRY: fprintf(stderr,"tristate\n"); break;
785
  case CHOICEENTRY: fprintf(stderr,"choice\n"); break;
786
  case CASEENTRY: fprintf(stderr,"case\n"); break;
787
  default: fprintf(stderr,"unknown\n"); break;
788
  }
789
}
790
 
791
void dumpmenuentries(struct menuentry *ptr,int x)
792
{
793
  struct choice *cho;
794
  struct _case *ca;
795
  char blanks[64];
796
  int i;
797
  memset(blanks,' ',sizeof(blanks));
798
  blanks[x-1]='\0';
799
  while (ptr!=NULL) {
800
    dumpmenuentrytype(ptr,blanks);
801
    switch(ptr->type) {
802
    case BOOLENTRY:
803
      fprintf(stderr,"%s text        : '%s'\n",blanks,ptr->x.bool.text);
804
      fprintf(stderr,"%s variable    : %s\n",blanks,ptr->x.bool.var->name);
805
      break;
806
    case TRISTATEENTRY:
807
      fprintf(stderr,"%s text        : '%s'\n",blanks,ptr->x.tristate.text);
808
      fprintf(stderr,"%s variable    : %s\n",blanks,ptr->x.tristate.var->name);
809
      break;
810
    case SUBMENUENTRY:
811
      fprintf(stderr,"%s text        : '%s'\n",blanks,ptr->x.submenu.text);
812
      fprintf(stderr,"%s submenu     : %s\n",blanks,ptr->x.submenu.menu->name);
813
      break;
814
    case CHOICEENTRY:
815
      fprintf(stderr,"%s text        : '%s'\n",blanks,ptr->x.choice.text);
816
      fprintf(stderr,"%s def variable: %s\n",blanks,ptr->x.choice.act->var->name);
817
      i=1;
818
      cho=ptr->x.choice.list;
819
      while (cho!=NULL) {
820
        fprintf(stderr,"%s text %i      : '%s'\n",blanks,i,cho->text);
821
        fprintf(stderr,"%s variable %i  : %s\n",blanks,i,cho->var->name);
822
        i++;
823
        cho=cho->next;
824
      }
825
      break;
826
    case CASEENTRY:
827
      fprintf(stderr,"%s variable    : %s\n",blanks,ptr->x._case.var->name);
828
      fputc('\n',stderr);
829
      ca=ptr->x._case.list;
830
      i=1;
831
      while (ca!=NULL) {
832
        fprintf(stderr,"%s value %i     : '%s'\n",blanks,i,ca->value);
833
        dumpmenuentries(ca->list,x+2);
834
        ca=ca->next;
835
        i++;
836
      }
837
      break;
838
    }
839
    fputc('\n',stderr);
840
    ptr=ptr->next;
841
  }
842
}
843
 
844
void dumpmenus(void)
845
{
846
  int i;
847
 
848
  fprintf(stderr,"MENUS TABLE\n-----------\n\n");
849
  i=0;
850
  while (i<nextmenu) {
851
    fprintf(stderr,"name:  %s\n",menutable[i].name);
852
    fprintf(stderr,"text:  '%s'\n",menutable[i].comment);
853
    fputc('\n',stderr);
854
    dumpmenuentries(menutable[i].entries,2);
855
    //fputc('\n',stderr);
856
    i++;
857
  }
858
}
859
#endif
860
 
861