11
#include <sys/types.h>
17
#include "menu-method.h"
18
#include "menu-tree.h"
20
int show_time=0, verbose=0, dodebug=0;
22
map <String, func *, less<String> > func_data;
26
supportedinfo *supported;
27
int linenumber=-123456;
29
ofstream *genoutputfile=NULL;
30
set<String> outputnames; //all names of files ever written to
33
struct option long_options[] = {
34
{ "showtime", no_argument, &show_time, 1 },
35
{ "verbose", no_argument, &verbose, 1 },
36
{ "debug", no_argument, &dodebug, 1 },
37
{ "help", no_argument, NULL, 'h' },
38
{ "stdin", no_argument, NULL, 'f' },
39
{ NULL, 0, NULL, 0 } };
42
cerr<<"menu-method: generate window-manager 'rc' files (or html docs)"<<endl
43
<<" menu-method gets the menuentries from standard in."<<endl
44
<<" Options to menu-method: "<<endl
45
<<" -h --help : this message"<<endl
46
<<" -d --debug: show debug info"<<endl
47
<<" -showtime : show timeing information"<<endl;
51
func_def::~func_def(){
54
void store_func(func *f){
55
func_data[f->name()]=f;
58
store_func(new prefix_func);
59
store_func(new ifroot_func);
61
store_func(new print_func);
62
store_func(new add_func);
63
store_func(new sub_func);
64
store_func(new mult_func);
65
store_func(new div_func);
66
store_func(new ifempty_func);
67
store_func(new ifnempty_func);
68
store_func(new iffile_func);
69
store_func(new ifelsefile_func);
70
store_func(new ifelse_func);
71
store_func(new catfile_func);
73
store_func(new ifeq_func);
74
store_func(new ifneq_func);
75
store_func(new ifeqelse_func);
77
store_func(new cond_surr_func);
78
store_func(new esc_func);
79
store_func(new escwith_func);
80
store_func(new escfirst_func);
81
store_func(new tolower_func);
82
store_func(new toupper_func);
83
store_func(new replacewith_func);
84
store_func(new nstring_func);
85
store_func(new cppesc_func);
86
store_func(new parent_func);
87
store_func(new basename_func);
88
store_func(new entrycount_func);
89
store_func(new entryindex_func);
90
store_func(new firstentry_func);
91
store_func(new lastentry_func);
92
store_func(new level_func);
94
store_func(new rcfile_func);
95
store_func(new examplercfile_func);
96
store_func(new mainmenutitle_func);
97
store_func(new rootsection_func);
98
store_func(new rootprefix_func);
99
store_func(new userprefix_func);
100
store_func(new treewalk_func);
101
store_func(new postoutput_func);
102
store_func(new preoutput_func);
106
bool empty_String(const String &s){
107
if(s.length()&&(s!=String("none")))
114
cat_str *get_eq_cat_str(parsestream &i){
117
return new cat_str(i);
120
int check_dir(String s){
124
cerr<<"CHECK_DIR: "<<s<<endl;
129
for(; ((unsigned int)i<s.length()) && (s[i]=='/'); i++);
130
s=s.substr(s.begin()+i,s.end());
135
if(chdir(t.c_str())<0){
137
cerr<<"MKDIR "<<t<<endl;
138
if(mkdir(t.c_str(),0755))
139
throw dir_createerror(t);
141
throw dir_createerror(t);
144
cerr<<" dir "<<t<<" already exists "<<endl;
150
void closegenoutput(){
151
set<String>::iterator i;
153
// OK, this will look clumsy in strace output, especially if there's
154
// only output file: first we close, and immediately afterwards we
155
// open and write again. But I don't see an easy and general way
156
// to get round that.
158
delete genoutputfile;
161
for(i=outputnames.begin(); i!=outputnames.end(); i++){
162
ofstream f((*i).c_str(), ios::app);
163
f<<(config->postoutput());
166
void genoutput(const String &s,
167
map<String, String, less<String> > &v){
169
static String lastname="////";
173
name=config->prefix()+"/"+config->genmenu->soutput(v);
175
// cerr<<"GENOUTPUT: name="<<name<<endl;
178
delete genoutputfile;
179
if(outputnames.find(name)==outputnames.end()){
180
outputnames.insert(name);
181
check_dir(String_parent(name));
182
// after opening a file with ios::trunc, all writes seem to fail!
183
//genoutputfile=new ofstream(name.c_str(), ios::trunc);
184
// So, I do it this way instead:
185
unlink(name.c_str());
186
genoutputfile=new ofstream(name.c_str());
187
(*genoutputfile)<<config->preoutput();
189
genoutputfile=new ofstream(name.c_str(),ios::app);
195
/////////////////////////////////////////////////////
201
cat_str::cat_str(parsestream &i){
211
v.push_back(new func_str(i));
213
v.push_back(new const_str(i));
215
v.push_back(new var_str(i));
223
throw char_unexpected(&i, c);
225
}catch(endofline p){};
228
const_str::const_str(parsestream &i){
229
data=i.get_Stringconst();
232
var_str::var_str(parsestream &i){
234
var_name=i.get_name();
237
func_str::func_str(parsestream &i){
240
map <String, func *, less<String> >::iterator j;
243
j=func_data.find(name);
244
if(j==func_data.end()){
245
throw unknown_function(&i);
257
args.push_back(new cat_str(i));
259
} while((c=i.get_char())&&(c==','));
262
if(args.size()!=(unsigned int)f->nargs())
263
throw narg_mismatch(&i, name);
267
/////////////////////////////////////////////////////
271
ostream &const_str::output(ostream &o,
272
map<String, String, less<String> > &/*menuentry*/){
273
// cout<<"IN CONST_STR: data="<<data<<endl;
277
String cat_str::soutput(map<String, String, less<String> > &menuentry){
279
vector <str * >::iterator i;
280
ostrstream s(buf,sizeof(buf));
282
//cout<<"CONFIG->rfc="<<config->rcff()<<endl;
284
for(i=v.begin();i!=v.end();i++){
286
//ostrstream D(Duf,sizeof(buf));
287
(*i)->output(s,menuentry);
288
//(*i)->output(D,menuentry);
290
//cout<<"DDD "<<Duf<<endl;
296
ostream &cat_str::output(ostream &o,
297
map<String, String, less<String> > &menuentry){
298
o<<soutput(menuentry);
301
void cat_str::output(map<String, String, less<String> > &menuentry){
302
genoutput(soutput(menuentry),menuentry);
305
ostream &var_str::output(ostream &o,
306
map<String, String, less<String> > &menuentry){
307
return o<<menuentry[var_name];
309
ostream &func_str::output(ostream &o,
310
map<String, String, less<String> > &menuentry){
311
return f->output(o,args,menuentry);
314
/////////////////////////////////////////////////////
317
ostream &const_str::debuginfo(ostream &o){
318
return o<<"CONST_STR: "<<data<<endl;
320
ostream &cat_str::debuginfo(ostream &o){
321
vector<str *>::iterator i;
322
o<<"CAT_STR: "<<endl;
323
for(i=v.begin();i!=v.end();i++){
328
ostream &var_str::debuginfo(ostream &o){
329
return o<<"VAR_STR: "<<var_name<<endl;
331
ostream &func_str::debuginfo(ostream &o){
332
o<<"FUNC_STR: "<<f->name()<<" ("<<endl;
333
vector<cat_str *>::iterator i;
334
for(i=args.begin();i!=args.end();i++){
342
/////////////////////////////////////////////////////
343
// Function definitions:
346
ostream &prefix_func::output(ostream &o, vector<cat_str *> &,
347
map<String, String, less<String> > &){
349
return o<<config->prefix();
351
ostream &ifroot_func::output(ostream &o, vector<cat_str *> & args,
352
map<String, String, less<String> > &menuentry){
354
args[1]->output(o,menuentry);
356
args[0]->output(o,menuentry);
361
ostream &print_func::output(ostream &o, vector<cat_str *> &args,
362
map<String, String, less<String> > &menuentry){
364
String s=args[0]->soutput(menuentry);
367
cerr<<"Zero-size argument to print function";
368
throw informed_fatal();
372
ostream &ifempty_func::output(ostream &o, vector<cat_str *> &args,
373
map<String, String, less<String> > &menuentry){
375
String s=args[0]->soutput(menuentry);
378
args[1]->output(o,menuentry);
381
ostream &ifnempty_func::output(ostream &o, vector<cat_str *> &args,
382
map<String, String, less<String> > &menuentry){
384
String s=args[0]->soutput(menuentry);
386
args[1]->output(o,menuentry);
389
ostream &iffile_func::output(ostream &o, vector<cat_str *> &args,
390
map<String, String, less<String> > &menuentry){
392
String s=args[0]->soutput(menuentry);
393
ifstream f(s.c_str());
395
args[1]->output(o,menuentry);
398
ostream &ifelsefile_func::output(ostream &o, vector<cat_str *> &args,
399
map<String, String, less<String> > &menuentry){
401
String s=args[0]->soutput(menuentry);
402
ifstream f(s.c_str());
404
args[1]->output(o,menuentry);
406
args[2]->output(o,menuentry);
409
ostream &catfile_func::output(ostream &o, vector<cat_str *> &args,
410
map<String, String, less<String> > &menuentry){
412
String s=args[0]->soutput(menuentry);
413
ifstream f(s.c_str());
421
ostream &esc_func::output(ostream &o, vector<cat_str *> &args,
422
map<String, String, less<String> > &menuentry){
424
return o<<escape_String(args[0]->soutput(menuentry),
425
args[1]->soutput(menuentry));
427
ostream &escwith_func::output(ostream &o, vector<cat_str *> &args,
428
map<String, String, less<String> > &menuentry){
430
return o<<escapewith_String(args[0]->soutput(menuentry),
431
args[1]->soutput(menuentry),
432
args[2]->soutput(menuentry));
434
ostream &escfirst_func::output(ostream &o, vector<cat_str *> &args,
435
map<String, String, less<String> > &menuentry){
437
String s=args[0]->soutput(menuentry);
438
String esc=args[1]->soutput(menuentry);
442
for(i=0;(unsigned int)i!=s.length();i++){
443
if(esc.length() && esc.contains(s[i])){
445
t+=args[2]->soutput(menuentry);
446
t+=s.substr(s.begin()+i,s.end());
453
ostream &tolower_func::output(ostream &o, vector<cat_str *> &args,
454
map<String, String, less<String> > &menuentry){
456
return o<<tolower_String(args[0]->soutput(menuentry));
458
ostream &toupper_func::output(ostream &o, vector<cat_str *> &args,
459
map<String, String, less<String> > &menuentry){
461
return o<<toupper_String(args[0]->soutput(menuentry));
463
ostream &replacewith_func::output(ostream &o, vector<cat_str *> &args,
464
map<String, String, less<String> > &menuentry){
466
return o<<replacewith_String(args[0]->soutput(menuentry),
467
args[1]->soutput(menuentry),
468
args[2]->soutput(menuentry));
470
ostream &nstring_func::output(ostream &o, vector<cat_str *> &args,
471
map<String, String, less<String> > &menuentry){
472
int count= Stringtoi(args[0]->soutput(menuentry));
475
for(i=0; i<count; i++)
476
o<<args[1]->soutput(menuentry);
480
ostream &cppesc_func::output(ostream &o, vector<cat_str *> &args,
481
map<String, String, less<String> > &menuentry){
483
return o<<cppesc_String(args[0]->soutput(menuentry));
486
ostream &add_func::output(ostream &o, vector<cat_str *> &args,
487
map<String, String, less<String> > &menuentry){
489
int x=Stringtoi(args[0]->soutput(menuentry));
490
int y=Stringtoi(args[1]->soutput(menuentry));
492
return o<<itoString(x+y);
494
ostream &sub_func::output(ostream &o, vector<cat_str *> &args,
495
map<String, String, less<String> > &menuentry){
497
int x=Stringtoi(args[0]->soutput(menuentry));
498
int y=Stringtoi(args[1]->soutput(menuentry));
500
return o<<itoString(x-y);
502
ostream &mult_func::output(ostream &o, vector<cat_str *> &args,
503
map<String, String, less<String> > &menuentry){
505
int x=Stringtoi(args[0]->soutput(menuentry));
506
int y=Stringtoi(args[1]->soutput(menuentry));
508
return o<<itoString(x*y);
510
ostream &div_func::output(ostream &o, vector<cat_str *> &args,
511
map<String, String, less<String> > &menuentry){
513
int x=Stringtoi(args[0]->soutput(menuentry));
514
int y=Stringtoi(args[1]->soutput(menuentry));
517
return o<<itoString(x/y);
522
ostream &ifelse_func::output(ostream &o, vector<cat_str *> &args,
523
map<String, String, less<String> > &menuentry){
525
String s=args[0]->soutput(menuentry);
528
args[1]->output(o,menuentry)
530
args[2]->output(o,menuentry);
533
ostream &ifeq_func::output(ostream &o, vector<cat_str *> &args,
534
map<String, String, less<String> > &menuentry){
536
String s=args[0]->soutput(menuentry);
537
String t=args[1]->soutput(menuentry);
539
args[2]->output(o,menuentry);
543
ostream &ifneq_func::output(ostream &o, vector<cat_str *> &args,
544
map<String, String, less<String> > &menuentry){
546
String s=args[0]->soutput(menuentry);
547
String t=args[1]->soutput(menuentry);
549
args[2]->output(o,menuentry);
553
ostream &ifeqelse_func::output(ostream &o, vector<cat_str *> &args,
554
map<String, String, less<String> > &menuentry){
556
String s=args[0]->soutput(menuentry);
557
String t=args[1]->soutput(menuentry);
559
args[2]->output(o,menuentry);
561
args[3]->output(o,menuentry);
566
ostream &cond_surr_func::output(ostream &o, vector<cat_str *> &args,
567
map<String, String, less<String> > &menuentry){
569
String s=args[0]->soutput(menuentry);
571
if(!empty_String(s)){
572
args[1]->output(o,menuentry);
573
args[0]->output(o,menuentry);
574
args[2]->output(o,menuentry);
579
ostream &parent_func::output(ostream &o, vector<cat_str *> &args,
580
map<String, String, less<String> > &menuentry){
582
String s=args[0]->soutput(menuentry);
584
return o<<String_parent(s);
587
ostream &basename_func::output(ostream &o, vector<cat_str *> &args,
588
map<String, String, less<String> > &menuentry){
590
String s=args[0]->soutput(menuentry);
592
return o<<String_basename(s);
594
ostream &entrycount_func::output(ostream &o, vector<cat_str *> &/*args*/,
595
map<String, String, less<String> > &menuentry){
596
return o<<menuentry[PRIVATE_ENTRYCOUNT_VAR];
598
ostream &entryindex_func::output(ostream &o, vector<cat_str *> &/*args*/,
599
map<String, String, less<String> > &menuentry){
600
return o<<menuentry[PRIVATE_ENTRYINDEX_VAR];
602
ostream &firstentry_func::output(ostream &o, vector<cat_str *> &args,
603
map<String, String, less<String> > &menuentry){
604
int index=Stringtoi(menuentry[PRIVATE_ENTRYINDEX_VAR]);
607
args[0]->output(o,menuentry);
611
ostream &lastentry_func::output(ostream &o, vector<cat_str *> &args,
612
map<String, String, less<String> > &menuentry){
614
int index=Stringtoi(menuentry[PRIVATE_ENTRYINDEX_VAR]);
615
int count=Stringtoi(menuentry[PRIVATE_ENTRYCOUNT_VAR]);
618
args[0]->output(o,menuentry);
623
ostream &level_func::output(ostream &o, vector<cat_str *> &/*args*/,
624
map<String, String, less<String> > &menuentry){
625
return o<<menuentry[PRIVATE_LEVEL_VAR];
629
ostream &rcfile_func::output(ostream &o, vector<cat_str *> &/*args*/,
630
map<String, String, less<String> > &menuentry){
631
return o<<config->rcfile();
633
ostream &examplercfile_func::output(ostream &o, vector<cat_str *> &/*args*/,
634
map<String, String, less<String> > &menuentry){
635
return o<<config->examplercfile();
637
ostream &mainmenutitle_func::output(ostream &o, vector<cat_str *> &/*args*/,
638
map<String, String, less<String> > &menuentry){
639
return o<<config->mainmenutitle();
641
ostream &rootsection_func::output(ostream &o, vector<cat_str *> &/*args*/,
642
map<String, String, less<String> > &menuentry){
643
return o<<config->rootsection();
645
ostream &rootprefix_func::output(ostream &o, vector<cat_str *> &/*args*/,
646
map<String, String, less<String> > &menuentry){
647
return o<<config->rootprefix();
649
ostream &userprefix_func::output(ostream &o, vector<cat_str *> &/*args*/,
650
map<String, String, less<String> > &menuentry){
651
return o<<config->userprefix();
653
ostream &treewalk_func::output(ostream &o, vector<cat_str *> &/*args*/,
654
map<String, String, less<String> > &menuentry){
655
return o<<config->treewalk();
657
ostream &postoutput_func::output(ostream &o, vector<cat_str *> &/*args*/,
658
map<String, String, less<String> > &menuentry){
659
return o<<config->postoutput();
661
ostream &preoutput_func::output(ostream &o, vector<cat_str *> &/*args*/,
662
map<String, String, less<String> > &menuentry){
663
return o<<config->preoutput();
667
/////////////////////////////////////////////////////
668
// "defined" function (macro).
671
ostream &func_def::output(ostream &o, vector<cat_str *> &args,
672
map<String, String, less<String> > &menuentry){
676
map<String, String, less<String> > local_menuentry=menuentry;
678
for(i=0; i<args_name.size(); i++)
679
local_menuentry[args_name[i]]=args[i]->soutput(menuentry);
681
f->output(o,local_menuentry);
684
func_def::func_def(parsestream &i){
697
args_name.push_back(i.get_name());
699
} while((c=i.get_char())&&(c==','));
707
/////////////////////////////////////////////////////
711
supportedinfo::supportedinfo(parsestream &i){
719
if(name==String("endsupported"))
723
cerr<<"SUPPORTED_CONSTRUCT: name="<<name<<endl;
726
inf.c=get_eq_cat_str(i);
730
sup[name].c->debuginfo(cerr);
731
i.skip_line(); //read away the final newline
737
void supportedinfo::subst(map<String, String, less<String> > vars){
739
map<String, String, less<String> >::iterator i;
740
map<String, supinf, less<String> >::iterator j;
742
if((i=vars.find(NEEDS_VAR))==vars.end()){
743
cerr<<"Undefined "NEEDS_VAR" variable in menuentries"<<endl;
744
throw informed_fatal();
746
if((j=sup.find(upcase((*i).second)))==sup.end()){
747
cerr<<"Unknown "NEEDS_VAR"=\""<<(*i).second<<"\""<<endl;
748
throw informed_fatal();
750
genoutput((*j).second.c->soutput(vars), vars);
752
int supportedinfo::prec(String &name){
753
map<String, supinf, less<String> >::iterator i;
755
if((i=sup.find(upcase(name)))==sup.end())
760
// cerr<<"PREC: name="<<upcase(name)<<"="<<p<<endl;
764
ostream &supportedinfo::debuginfo(ostream &o){
765
map<String, supinf, less<String> >::iterator i;
766
for(i=sup.begin();i!=sup.end();i++){
767
o<<"SUPPORTED:** name="<<(*i).first<<", prec="
768
<<(*i).second.prec<<" Def="<<endl;
769
(*i).second.c->debuginfo(o);
773
/////////////////////////////////////////////////////
777
void read_forcetree(parsestream &i){
778
Regex r("[a-zA-Z/-_ ]");
789
throw ident_expected(&i);
790
if(name==String("endforcetree"))
793
break_slashes(name,v);
796
m->vars[TITLE_VAR]=v[v.size()-1];
797
menu.add_menuentry_ptr(v,m);
804
/////////////////////////////////////////////////////
807
configinfo::configinfo(parsestream &i){
808
String errmsg("Parse error: String constant expected");
811
sort=prerun=preruntest=postrun=genmenu=
812
hkexclude=startmenu=endmenu=submenutitle=NULL;
814
onlyrunasroot=onlyrunasuser=false;
819
hint_mixedpenalty=15;
820
hint_minhintfreq=0.1;
823
hint_max_iter_hint=5;
829
//hint_toplevel_nopt=5;
831
//keep_sections=true;
833
preout="#Automatically generated file. Do not edit (see /usr/doc/menu/html/index.html)\n\n";
840
if(name==String("supported")){
842
supported=new supportedinfo(i);
843
} else if(name==String("forcetree")){
847
else if(name==String("function"))
848
store_func(new func_def(i));
849
else if(name==String("startmenu"))
850
startmenu=get_eq_cat_str(i);
851
else if(name==String("endmenu"))
852
endmenu=get_eq_cat_str(i);
853
else if(name==String("submenutitle"))
854
submenutitle=get_eq_cat_str(i);
855
else if(name==String("hotkeyexclude"))
856
hkexclude=get_eq_cat_str(i);
857
else if(name==String("genmenu"))
858
genmenu=get_eq_cat_str(i);
859
else if(name==String("postrun"))
860
postrun=get_eq_cat_str(i);
861
else if(name==String("prerun"))
862
prerun=get_eq_cat_str(i);
863
else if(name==String("preruntest"))
864
preruntest=get_eq_cat_str(i);
865
else if(name==String("onlyrunasroot"))
866
onlyrunasroot=i.get_eq_boolean();
867
else if(name==String("onlyrunasuser"))
868
onlyrunasuser=i.get_eq_boolean();
869
else if(name==String("sort"))
870
sort=get_eq_cat_str(i);
872
else if(name==String("compat")){
873
compt=i.get_eq_Stringconst();
874
if(compt==String("menu-1"))
875
i.seteolmode(parsestream::eol_newline);
876
else if(compt==String("menu-2"))
877
i.seteolmode(parsestream::eol_semicolon);
879
throw unknown_compat(&i, compt);
881
else if(name==String("rcfile"))
882
rcf=i.get_eq_Stringconst();
883
else if(name==String("examplercfile"))
884
exrcf=i.get_eq_Stringconst();
885
else if(name==String("mainmenutitle"))
886
mainmt=i.get_eq_Stringconst();
887
else if(name==String("rootsection"))
888
roots=i.get_eq_Stringconst();
889
else if(name==String("rootprefix"))
890
rootpref=i.get_eq_Stringconst();
891
else if(name==String("userprefix"))
892
userpref=i.get_eq_Stringconst();
893
else if(name==String("treewalk"))
894
treew=i.get_eq_Stringconst();
895
else if(name==String("postoutput"))
896
postout=i.get_eq_Stringconst();
897
else if(name==String("preoutput"))
898
preout=i.get_eq_Stringconst();
899
else if(name==String("command")){
900
system((i.get_eq_Stringconst()).c_str());
903
else if(name==String("hotkeycase")){
904
String s=i.get_eq_Stringconst();
905
if(s==String("sensitive"))
907
else if (s==String("insensitive"))
910
cerr<<"install-menus hotkeycase can only be {,in}sensitive"<<endl;
911
throw informed_fatal();
914
else if(name==String("hint_optimize"))
915
hint_optimize=i.get_eq_boolean();
916
else if(name==String("hint_nentry"))
917
hint_nentry=i.get_eq_double();
918
else if(name==String("hint_topnentry"))
919
hint_topnentry=i.get_eq_integer();
920
else if(name==String("hint_mixedpenalty"))
921
hint_mixedpenalty=i.get_eq_double();
922
else if(name==String("hint_minhintfreq"))
923
hint_minhintfreq=i.get_eq_double();
924
else if(name==String("hint_mlpenalty"))
925
hint_mlpenalty=i.get_eq_double();
926
else if(name==String("hint_max_ntry")){
927
hint_max_ntry=i.get_eq_integer();
928
if(hint_max_ntry < 1)
931
else if(name==String("hint_max_iter_hint"))
932
hint_max_iter_hint=i.get_eq_integer();
933
else if(name==String("hint_debug"))
934
hint_debug=i.get_eq_boolean();
936
throw unknown_ident(&i);
937
i.skip_line();//read away final newline
944
void configinfo::check_config(){
945
if(!(genmenu && startmenu && endmenu)){
946
cerr<<"At least one of genmenu, startmenu, endmenu"<<endl
947
<<"is undefined in the config file. All of these have to be "<<endl
948
<<"defined (although they may be equal to \"\")"<<endl;
949
throw informed_fatal();
952
String configinfo::prefix(){
956
return String(getenv("HOME"))+"/"+userprefix();
961
ostream &configinfo::debuginfo(ostream &o){
962
o<<"Using compatibility with:"<<compt<<endl
963
<<"mainmenutitle : "<<mainmt <<endl
964
<<"rootsection : "<<roots <<endl
965
<<"rcfile : "<<rcf <<endl
966
<<"examplercfile : "<<exrcf <<endl
967
<<"root-prefix : "<<rootpref <<endl
968
<<"user-prefix : "<<userpref <<endl
969
<<"startmenu : "<<endl;
971
startmenu->debuginfo(o);
972
o<<"endmenu : "<<endl;
974
endmenu->debuginfo(o);
975
o<<"genmenu : "<<endl;
977
genmenu->debuginfo(o);
978
o<<"submenutitle : "<<endl;
980
submenutitle->debuginfo(o);
981
o<<"mainmenutitle : "<<mainmt <<endl
982
<<"treewalk : "<<treew <<endl;
986
/////////////////////////////////////////////////////
990
map <String, String, less<String> > read_vars(parsestream &i){
991
map <String, String, less<String> > m;
996
val=i.get_eq_Stringconst();
1000
catch(endofline p){};
1004
void check_vars(parsestream &i,
1005
map <String, String, less<String> > &m){
1006
vector <String> need;
1007
map <String, String, less<String> >::iterator j;
1010
need.push_back(SECTION_VAR);
1011
need.push_back(TITLE_VAR);
1012
need.push_back(NEEDS_VAR);
1014
for(k=0;k<need.size();k++){
1016
if((j==m.end())||((*j).second==String("")))
1017
throw missing_tag(&i,need[k]);
1020
void read_input(parsestream &i){
1024
map <String, String, less<String> > m;
1029
// check presence of section,title,needs vars. Later we will blindly
1030
// assume they are defined.
1033
break_slashes(m[SECTION_VAR],sec_vec);
1034
//if(m.find(SORT_VAR)!=m.end())
1035
// sec_vec.push_back(m[SORT_VAR]+":"+m[TITLE_VAR]);
1037
sec_vec.push_back(m[TITLE_VAR]);
1038
if(supported->prec(m[NEEDS_VAR])!=MAXINT)
1039
menu.add_entry(sec_vec,m);
1040
i.skip_line(); //read away the final newline
1043
catch(endoffile p){}
1047
void includemenus(String o, String i,
1048
String rep, String m){
1049
//copy filename i to filename o, replacing the line
1050
//rep with menu-file m
1054
ifstream fi(i.c_str());
1055
ifstream fm(m.c_str());
1058
cerr<<"Cannot open file "<<i<<endl; throw informed_fatal();}
1060
cerr<<"Cannot open file "<<m<<endl; throw informed_fatal();}
1062
ofstream fo(o.c_str());
1065
cerr<<"Cannot open file "<<o<<endl; throw informed_fatal();}
1068
while(fi.get(buf,sizeof(buf))){
1069
if(String(buf).contains(rep,0)){
1070
while(fm.get(buf,sizeof(buf))){
1082
cerr<<"Warning: String \""<<rep
1083
<<"\" didn't occur in example file "<<i<<endl;
1086
int main(int argc, char **argv){
1087
int c, option_index;
1088
char script[MAX_BUF];
1094
strcpy(script, argv[1]);
1096
cerr<<"install-menu: First parameter must be name of script"<<endl;
1097
throw informed_fatal();
1101
c = getopt_long (argc, argv, "fdvh", long_options, &option_index);
1106
cerr<<"Try --help for more information.\n"<<endl;
1107
throw informed_fatal();
1108
case 'd': dodebug=1; break;
1109
case 'v': verbose=1;break;
1110
case 'h': usage(); break;
1116
parsestream ps(script);
1118
cerr<<"Cannot open script "<<script<< " for reading"<<endl;
1119
throw informed_fatal();
1121
config=new configinfo(ps);
1123
config->debuginfo(cerr);
1124
supported->debuginfo(cerr);
1127
system((config->prerun->soutput(menu.vars)).c_str());
1128
if(config->preruntest){
1130
r=system((config->preruntest->soutput(menu.vars)).c_str());
1134
if(config->onlyrunasroot)
1137
if(config->onlyrunasuser)
1140
parsestream psscript(cin);
1141
menu.vars[TITLE_VAR]=config->mainmenutitle();
1143
read_input(psscript);
1144
if(config->hint_optimize){
1146
menu.process_hints(v);
1148
menu.postprocess(1,0, config->rootsection());
1151
if(config->rcfile().length()&&config->examplercfile().length())
1152
includemenus(config->prefix()+"/"+config->rcfile(),
1153
config->prefix()+"/"+config->examplercfile(),
1154
"include-menu-defs",
1155
config->prefix()+"/"+config->genmenu->soutput(menu.vars));
1157
system((config->postrun->soutput(menu.vars)).c_str());
1160
//yes, I know this _should_ be handled in one
1161
//"derived" exception handler, but gcc doesn't like those
1162
// (I'm getting internal compiler errors now quite often
1163
// already, and I remember having them even more frequenly
1164
// with the -frtty stuff -- _I_WANT_gcc-2.8_!).
1165
catch(endoffile p){ p.report(cerr); }
1166
catch(endofline p){ p.report(cerr); }
1167
catch(char_expected p){ p.report(cerr); }
1168
catch(char_unexpected p){ p.report(cerr); }
1169
catch(unexpectedtrailing p){p.report(cerr);}
1170
catch(boolean_expected p){ p.report(cerr); }
1171
catch(ident_expected p){ p.report(cerr); }
1172
catch(narg_mismatch p){ p.report(cerr); }
1173
catch(unknown_function p){ p.report(cerr); }
1174
catch(unknown_ident p){ p.report(cerr); }
1175
catch(ferror_open p){ p.report(cerr); }
1176
catch(missing_tag p){ p.report(cerr); }
1177
catch(unknown_compat p){ p.report(cerr); }
1179
catch(dir_createerror d){
1180
cerr<<": Cannot create directory "<<d.name<<endl;
1182
catch(informed_fatal){};
1184
cerr<<script<<": Aborting"<<endl;