source: tags/arb_5.1/ARB_GDE/GDE_ParseMenu.cxx

Last change on this file was 6069, checked in by westram, 15 years ago
  • changed GDE menu names
  • added hotkeys
  • GDE_load_menu now warns if requested to load an unknown menu or topic (console)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4// #include <malloc.h>
5#include <ctype.h>
6#include <assert.h>
7
8#include <arbdb.h>
9#include <aw_root.hxx>
10#include <aw_device.hxx>
11#include <aw_window.hxx>
12#include <awt.hxx>
13
14#include "gde.hxx"
15#include "GDE_menu.h"
16#include "GDE_def.h"
17#include "GDE_global.h"
18#include "GDE_extglob.h"
19
20static int getline(FILE *file,char *string)
21{
22    int c;
23    int i;
24    for(i=0;(c=getc(file))!='\n';i++){
25        if (c== EOF) break;
26        if (i>= GBUFSIZ -2) break;
27        string[i]=c;
28    }
29    string[i] = '\0';
30    if (i==0 && c==EOF) return (EOF);
31    else return (0);
32}
33
34
35/*
36  ParseMenus(): Read in the menu config file, and generate the internal
37  menu structures used by the window system.
38
39  Copyright (c) 1989, University of Illinois board of trustees.  All rights
40  reserved.  Written by Steven Smith at the Center for Prokaryote Genome
41  Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
42  Carl Woese.
43
44  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
45  All rights reserved.
46
47  Changed to fit into ARB by ARB development team.
48*/
49
50void ParseMenu()
51{
52    int           j,curmenu  = -1,curitem = 0;
53    int           curchoice  = 0 ,curarg = 0,curinput = 0, curoutput = 0;
54    char          in_line[GBUFSIZ],temp[GBUFSIZ],head[GBUFSIZ];
55    char          tail[GBUFSIZ];
56    const char   *home;
57    Gmenu        *thismenu   = NULL;
58    GmenuItem    *thisitem   = NULL;
59    GmenuItemArg *thisarg    = NULL;
60    GfileFormat  *thisinput  = NULL;
61    GfileFormat  *thisoutput = NULL;
62    FILE         *file;
63    char         *resize;
64
65    /*
66     *  Open the menu configuration file "$ARBHOME/GDEHELP/ARB_GDEmenus"
67     *  First search the local directory, then the home directory.
68     */
69    memset((char*)&menu[0],0,sizeof(Gmenu)*GDEMAXMENU);
70    home = GB_getenvARBHOME();
71
72    strcpy(temp,home);
73    strcat(temp,"/GDEHELP/ARB_GDEmenus");
74    file=fopen(temp,"r");
75    if(file == NULL) Error("ARB_GDEmenus file not in the home, local, or $ARBHOME/GDEHELP directory");
76
77    /*
78     *  Read the ARB_GDEmenus file, and assemble an internal representation
79     *  of the menu/menu-item hierarchy.
80     */
81
82    for(;getline(file,in_line) != EOF;)
83    {
84        /*
85         *  menu: chooses menu to use
86         */
87        if (in_line[0] == '#' || (in_line[0] && in_line[1] == '#')) {
88            ; // skip line
89        }
90        else if(Find(in_line,"menu:"))
91        {
92            crop(in_line,head,temp);
93            curmenu = -1;
94            for(j=0;j<num_menus;j++) {
95                if(Find(temp,menu[j].label)) curmenu=j;
96            }
97            /*
98             *  If menu not found, make a new one
99             */
100            if(curmenu == -1)
101            {
102                curmenu         = num_menus++;
103                thismenu        = &menu[curmenu];
104                thismenu->label = (char*)calloc(strlen(temp)+1,sizeof(char));
105
106                if(thismenu->label == NULL) Error("Calloc");
107                (void)strcpy(thismenu->label,temp);
108                thismenu->numitems = 0;
109            }
110        }
111        /*
112         *  item: chooses menu item to use
113         */
114        else if(Find(in_line,"item:"))
115        {
116            curarg    = -1;
117            curinput  = -1;
118            curoutput = -1;
119            crop(in_line,head,temp);
120            curitem   = thismenu->numitems++;
121
122            /*
123             *  Resize the item list for this menu (add one item);
124             */
125            if(curitem == 0) {
126                resize = (char*)GB_calloc(1,sizeof(GmenuItem)); // @@@ calloc->GB_calloc avoids (rui)
127            }
128            else {
129                resize = (char *)realloc((char *)thismenu->item, thismenu->numitems*sizeof(GmenuItem));
130            }
131
132            if (resize == NULL) Error ("Calloc");
133            thismenu->item =(GmenuItem*)resize;
134
135            thisitem              = &(thismenu->item[curitem]);
136            thisitem->label       = strdup(temp);
137            thisitem->meta        = '\0';
138            thisitem->numinputs   = 0;
139            thisitem->numoutputs  = 0;
140            thisitem->numargs     = 0;
141            //thisitem->X         = 0;
142            thisitem->help        = NULL;
143            thisitem->parent_menu = thismenu;
144            thisitem->aws         = NULL; // no window opened yet
145        }
146
147        /*
148         *  itemmethod: generic command line generated by this item
149         */
150        else if(Find(in_line,"itemmethod:"))
151        {
152            crop(in_line,head,temp);
153            thisitem->method =
154                (char*)calloc(strlen(temp)+1,sizeof(char));
155            if(thisitem->method == NULL) Error("Calloc");
156
157            {
158                char *to = thisitem->method;
159                char *from = temp;
160                char last = 0;
161                char c;
162
163                do {
164                    c = *from++;
165                    if (c!=last || c!='\'') { /* replace '' with ' */
166                        *to++ = c;
167                        last = c;
168                    }
169                } while (c!=0);
170            }
171
172            //strcpy(thisitem->method,temp);
173        }
174        /*
175         *  Help file
176         */
177        else if(Find(in_line,"itemhelp:"))
178        {
179            crop(in_line,head,temp);
180            thisitem->help = (char*)calloc(strlen(temp)+1,sizeof(char));
181            if(thisitem->method == NULL) Error("Calloc");
182            (void)strcpy(thisitem->help,temp);
183        }
184        /*
185         *      Meta key equiv
186         */
187        else if(Find(in_line,"itemmeta:"))
188        {
189            crop(in_line,head,temp);
190            thisitem->meta = temp[0];
191        }
192        else if(Find(in_line,"menumeta:"))
193        {
194            crop(in_line,head,temp);
195            thismenu->meta = temp[0];
196        }
197        /*
198         *       Sequence type restriction
199         */
200        else if(Find(in_line,"seqtype:"))
201        {
202            crop(in_line,head,temp);
203            thisitem->seqtype = toupper(temp[0]);
204            /* 'A' -> amino acids,
205             * 'N' -> nucleotides,
206             * '-' -> don't select sequences,
207             * otherwise any alignment
208             */
209        }
210        /*
211         *  arg: defines the symbol for a command line arguement.
212         *      this is used for substitution into the itemmethod
213         *      definition.
214         */
215
216        else if(Find(in_line,"arg:"))
217        {
218            crop(in_line,head,temp);
219            curarg=thisitem->numargs++;
220            if(curarg == 0) resize = (char*)calloc(1,sizeof(GmenuItemArg));
221            else resize = (char *)realloc((char *)thisitem->arg, thisitem->numargs*sizeof(GmenuItemArg) );
222            memset((char *)resize + (thisitem->numargs-1)*sizeof(GmenuItemArg),0, sizeof(GmenuItemArg));
223
224
225            if(resize == NULL) Error("arg: Realloc");
226
227            (thisitem->arg) = (GmenuItemArg*)resize;
228            thisarg         = &(thisitem->arg[curarg]);
229            thisarg->symbol = (char*)calloc(strlen(temp)+1, sizeof(char));
230            if(thisarg->symbol == NULL) Error("Calloc");
231            (void)strcpy(thisarg->symbol,temp);
232
233            thisarg->optional   = FALSE;
234            thisarg->type       = 0;
235            thisarg->min        = 0.0;
236            thisarg->max        = 0.0;
237            thisarg->numchoices = 0;
238            thisarg->choice     = NULL;
239            thisarg->textvalue  = NULL;
240            thisarg->ivalue     = 0;
241            thisarg->fvalue     = 0.0;
242            thisarg->label      = 0;
243        }
244        /*
245         *  argtype: Defines the type of argument (menu,chooser, text, slider)
246         */
247        else if(Find(in_line,"argtype:"))
248        {
249            crop(in_line,head,temp);
250
251            int arglen = -1;
252            if(strncmp(temp,"text", (arglen = 4)) == 0) {
253                thisarg->type      = TEXTFIELD;
254                thisarg->textvalue = (char*)calloc(GBUFSIZ,sizeof(char));
255                if(thisarg->textvalue == NULL) Error("Out of memory");
256
257                if (temp[arglen] == 0) thisarg->textwidth = TEXTFIELDWIDTH; // only 'text'
258                else {
259                    if (temp[arglen] != '(' || temp[strlen(temp)-1] != ')') {
260                        sprintf(head, "Unknown argtype '%s' -- syntax: text(width) e.g. text(20)", temp);
261                        Error(head);
262                    }
263                    thisarg->textwidth = atoi(temp+arglen+1);
264                    if (thisarg->textwidth<1) {
265                        sprintf(head, "Illegal textwidth specified in '%s'", temp);
266                        Error(head);
267                    }
268                }
269            }
270            else if(strcmp(temp,"choice_list") == 0) thisarg->type=CHOICE_LIST;
271            else if(strcmp(temp,"choice_menu") == 0) thisarg->type=CHOICE_MENU;
272            else if(strcmp(temp,"chooser")     == 0) thisarg->type=CHOOSER;
273            else if(strcmp(temp,"tree")        == 0) thisarg->type=CHOICE_TREE;
274            else if(strcmp(temp,"sai")         == 0) thisarg->type=CHOICE_SAI;
275            else if(strcmp(temp,"weights")     == 0) thisarg->type=CHOICE_WEIGHTS;
276            else if(strcmp(temp,"slider")      == 0) thisarg->type=SLIDER;
277            else{
278                sprintf(head,"Unknown argtype '%s'",temp);
279                Error(head);
280            }
281        }
282        /*
283         *  argtext: The default text value of the symbol.
284         *      $argument is replaced by this value if it is not
285         *      changed in the dialog box by the user.
286         */
287        else if(Find(in_line,"argtext:"))
288        {
289            crop(in_line,head,temp);
290            (void)strcpy(thisarg->textvalue,temp);
291        }
292        /*
293         *  arglabel: Text label displayed in the dialog box for
294         *      this argument.  It should be a discriptive label.
295         */
296        else if(Find(in_line,"arglabel:"))
297        {
298            crop(in_line,head,temp);
299            thisarg->label = GBS_string_eval(temp, "\\\\n=\\n", 0);
300        }
301        /*
302         *  Argument choice values use the following notation:
303         *
304         *  argchoice:Displayed value:Method
305         *
306         *  Where "Displayed value" is the label displayed in the dialog box
307         *  and "Method" is the value passed back on the command line.
308         */
309        else if(Find(in_line,"argchoice:"))
310        {
311            crop(in_line,head,temp);
312            crop(temp,head,tail);
313            curchoice = thisarg->numchoices++;
314
315            if(curchoice == 0) resize = (char*)calloc(1,sizeof(GargChoice));
316            else resize               = (char *)realloc((char *)thisarg->choice, thisarg->numchoices*sizeof(GargChoice));
317            if(resize == NULL) Error("argchoice: Realloc");
318            thisarg->choice           = (GargChoice*)resize;
319
320            (thisarg->choice[curchoice].label)  = NULL;
321            (thisarg->choice[curchoice].method) = NULL;
322            (thisarg->choice[curchoice].label)  = (char*)calloc(strlen(head)+1,sizeof(char));
323            (thisarg->choice[curchoice].method) = (char*)calloc(strlen(tail)+1,sizeof(char));
324
325            if(thisarg->choice[curchoice].method == NULL || thisarg->choice[curchoice].label == NULL) Error("Calloc");
326
327            (void)strcpy(thisarg->choice[curchoice].label,head);
328            (void)strcpy(thisarg->choice[curchoice].method,tail);
329        }
330        /*
331         *  argmin: Minimum value for a slider
332         */
333        else if(Find(in_line,"argmin:"))
334        {
335            crop(in_line,head,temp);
336            (void)sscanf(temp,"%lf",&(thisarg->min));
337        }
338        /*
339         *  argmax: Maximum value for a slider
340         */
341        else if(Find(in_line,"argmax:"))
342        {
343            crop(in_line,head,temp);
344            (void)sscanf(temp,"%lf",&(thisarg->max));
345        }
346        /*
347         *  argmethod: Command line flag associated with this argument.
348         *      Replaces argument in itemmethod description.
349         */
350        else if(Find(in_line,"argmethod:"))
351        {
352            crop(in_line,head,temp);
353            thisarg->method = (char*)calloc(GBUFSIZ,strlen(temp));
354            if(thisarg->method == NULL) Error("Calloc");
355            (void)strcpy(thisarg->method,tail);
356        }
357        /*
358         *  argvalue: default value for a slider
359         */
360        else if(Find(in_line,"argvalue:"))
361        {
362            crop(in_line,head,temp);
363            if(thisarg->type == TEXT){
364                strcpy(thisarg->textvalue,temp);
365            }else{
366                (void)sscanf(temp,"%lf",&(thisarg->fvalue));
367                thisarg->ivalue = (int) thisarg->fvalue;
368            }
369        }
370        /*
371         *  argoptional: Flag specifying that an arguement is optional
372         */
373        else if(Find(in_line,"argoptional:"))
374            thisarg->optional = TRUE;
375        /*
376         *  in: Input file description
377         */
378        else if(Find(in_line,"in:"))
379        {
380            crop(in_line,head,temp);
381            curinput                 = (thisitem->numinputs)++;
382            if(curinput == 0) resize = (char*)calloc(1,sizeof(GfileFormat));
383            else resize              = (char *)realloc((char *)thisitem->input, (thisitem->numinputs)*sizeof(GfileFormat));
384            if(resize == NULL) Error("in: Realloc");
385
386            thisitem->input      = (GfileFormat*)resize;
387            thisinput            = &(thisitem->input)[curinput];
388            thisinput->save      = FALSE;
389            thisinput->overwrite = FALSE;
390            thisinput->maskable  = FALSE;
391            thisinput->format    = 0;
392            thisinput->symbol    = strdup(temp);
393            thisinput->name      = NULL;
394            thisinput->select    = SELECTED;
395        }
396
397        /*
398         *  out: Output file description
399         */
400
401        else if(Find(in_line,"out:"))
402        {
403            crop(in_line,head,temp);
404            curoutput = (thisitem->numoutputs)++;
405
406            if(curoutput == 0) resize = (char*)calloc(1,sizeof(GfileFormat));
407            else resize               = (char *)realloc((char *)thisitem->output, (thisitem->numoutputs)*sizeof(GfileFormat));
408            if(resize == NULL) Error("out: Realloc");
409
410            thisitem->output      = (GfileFormat*)resize;
411            thisoutput            = &(thisitem->output)[curoutput];
412            thisitem->output      = (GfileFormat*)resize;
413            thisoutput            = &(thisitem->output)[curoutput];
414            thisoutput->save      = FALSE;
415            thisoutput->overwrite = FALSE;
416            thisoutput->format    = 0;
417            thisoutput->symbol    = strdup(temp);
418            thisoutput->name      = NULL;
419        }
420        else if(Find(in_line,"informat:")) {
421            if(thisinput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
422            crop(in_line,head,tail);
423
424            if(Find(tail,"genbank")) thisinput->format        = GENBANK;
425            else if(Find(tail,"gde")) thisinput->format       = GDE;
426            else if(Find(tail,"na_flat")) thisinput->format   = NA_FLAT;
427            else if(Find(tail,"colormask")) thisinput->format = COLORMASK;
428            else if(Find(tail,"flat")) thisinput->format      = NA_FLAT;
429            else if(Find(tail,"status")) thisinput->format    = STATUS_FILE;
430            else fprintf(stderr,"Warning, unknown file format %s\n" ,tail);
431        }
432        else if(Find(in_line,"insave:")) {
433            if(thisinput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
434            thisinput->save = TRUE;
435        }
436        else if(Find(in_line,"inselect:")) {
437            if(thisinput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
438            crop(in_line,head,tail);
439
440            if(Find(tail,"one")) thisinput->select         = SELECT_ONE;
441            else if(Find(tail,"region")) thisinput->select = SELECT_REGION;
442            else if(Find(tail,"all")) thisinput->select    = ALL;
443        }
444        else if(Find(in_line,"inmask:")) {
445            if(thisinput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
446            thisinput->maskable = TRUE;
447        }
448        else if(Find(in_line,"outformat:")) {
449            if(thisoutput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
450            crop(in_line,head,tail);
451
452            if(Find(tail,"genbank")) thisoutput->format        = GENBANK;
453            else if(Find(tail,"gde")) thisoutput->format       = GDE;
454            else if(Find(tail,"na_flat")) thisoutput->format   = NA_FLAT;
455            else if(Find(tail,"flat")) thisoutput->format      = NA_FLAT;
456            else if(Find(tail,"status")) thisoutput->format    = STATUS_FILE;
457            else if(Find(tail,"colormask")) thisoutput->format = COLORMASK;
458            else fprintf(stderr,"Warning, unknown file format %s\n" ,tail);
459        }
460        else if(Find(in_line,"outsave:")) {
461            if(thisoutput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
462            thisoutput->save = TRUE;
463        }
464        else if(Find(in_line,"outoverwrite:")) {
465            if(thisoutput == NULL) Error("Problem with $ARBHOME/GDEHELP/ARB_GDEmenus");
466            thisoutput->overwrite = TRUE;
467        }
468    }
469
470    assert(num_menus>0); // if this fails, the file ARB_GDEmenus contained no menus (maybe file has zero size)
471
472    return;
473}
474
475
476
477/*
478  Find(): Search the target string for the given key
479*/
480int Find(const char *target,const char *key)
481{
482    int i,j,len1,dif,flag = FALSE;
483    dif = (strlen(target)) - (len1 = strlen(key)) +1;
484
485    if(len1>0)
486        for(j=0;j<dif && flag == FALSE;j++)
487        {
488            flag = TRUE;
489            for(i=0;i<len1 && flag;i++)
490                flag = (key[i] == target[i+j])?TRUE:FALSE;
491
492        }
493    return(flag);
494}
495
496
497int Find2(const char *target,const char *key)
498    /*
499     *   Like find, but returns the index of the leftmost
500     *   occurrence, and -1 if not found.
501     */
502{
503    int i,j,len1,dif,flag = FALSE;
504    dif = (strlen(target)) - (len1 = strlen(key)) +1;
505
506    if(len1>0) {
507        for(j=0;j<dif && flag == FALSE;j++) {
508            flag = TRUE;
509            for(i=0;i<len1 && flag;i++)
510                flag = (key[i] == target[i+j])?TRUE:FALSE;
511        }
512
513        return(flag?j-1:-1);
514    }
515
516    return -1;
517}
518
519
520void Error(const char *msg) {
521    /* goes to header: __ATTR__NORETURN  */
522    (void)fprintf(stderr,"Error in ARB_GDE: %s\n",msg);
523    fflush(stderr);
524    gde_assert(0);
525    exit(1);
526}
527
528
529/*
530  Crop():
531  Split "this:that[:the_other]"
532  into: "this" and "that[:the_other]"
533*/
534
535void crop(char *input,char *head,char *tail)
536{
537    /*
538     *   Crop needs to be fixed so that whitespace is compressed off the end
539     *   of tail
540     */
541    int offset,end,i,j,length;
542
543    length=strlen(input);
544    for(offset=0;offset<length && input[offset] != ':';offset++) {
545        head[offset]=input[offset];
546    }
547    head[offset++] = '\0';
548    for (; offset<length && isspace(input[offset]); offset++) ;
549    for (end=length-1; end>offset && isspace(input[end]); end--) ;
550
551    for(j=0,i=offset;i<=end;i++,j++) {
552        tail[j]=input[i];
553    }
554    tail[j] = '\0';
555    return;
556}
Note: See TracBrowser for help on using the repository browser.