567 lines
13 KiB
C
567 lines
13 KiB
C
|
#include <stdio.h>
|
||
|
#include <malloc.h>
|
||
|
#include <xview/xview.h>
|
||
|
#include <xview/panel.h>
|
||
|
#include "menudefs.h"
|
||
|
#include "defines.h"
|
||
|
|
||
|
/*
|
||
|
ParseMenus(): Read in the menu config file, and generate the internal
|
||
|
menu structures used by the window system.
|
||
|
|
||
|
Copyright (c) 1989, University of Illinois board of trustees. All rights
|
||
|
reserved. Written by Steven Smith at the Center for Prokaryote Genome
|
||
|
Analysis. Design and implementation guidance by Dr. Gary Olsen and Dr.
|
||
|
Carl Woese.
|
||
|
|
||
|
Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
|
||
|
All rights reserved.
|
||
|
|
||
|
*/
|
||
|
|
||
|
extern Gmenu menu[];
|
||
|
int num_menus;
|
||
|
|
||
|
ParseMenu()
|
||
|
{
|
||
|
int j,curmenu = -1,curitem = 0;
|
||
|
int curchoice = 0 ,curarg = 0,curinput = 0, curoutput = 0;
|
||
|
char Inline[GBUFSIZ],temp[GBUFSIZ],head[GBUFSIZ];
|
||
|
char tail[GBUFSIZ],*home;
|
||
|
Gmenu *thismenu;
|
||
|
GmenuItem *thisitem;
|
||
|
GmenuItemArg *thisarg;
|
||
|
GfileFormat *thisinput,*thisoutput;
|
||
|
FILE *file;
|
||
|
char *resize;
|
||
|
|
||
|
/*
|
||
|
* Open the menu configuration file ".GDEmenus"
|
||
|
* First search the local directory, then the home directory.
|
||
|
*/
|
||
|
file=fopen(".GDEmenus","r");
|
||
|
if(file == NULL)
|
||
|
{
|
||
|
home = (char*)getenv("HOME");
|
||
|
strcpy(temp,home);
|
||
|
strcat(temp,"/.GDEmenus");
|
||
|
|
||
|
file=fopen(temp,"r");
|
||
|
if(file == NULL)
|
||
|
{
|
||
|
home = (char*)getenv("GDE_HELP_DIR");
|
||
|
if(home != NULL)
|
||
|
{
|
||
|
strcpy(temp,home);
|
||
|
strcat(temp,"/.GDEmenus");
|
||
|
file=fopen(temp,"r");
|
||
|
}
|
||
|
if(file == NULL)
|
||
|
Error(
|
||
|
".GDEmenus file not in the home, local, or $GDE_HELP_DIR directory");
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Read the .GDEmenus file, and assemble an internal representation
|
||
|
* of the menu/menu-item hierarchy.
|
||
|
*/
|
||
|
|
||
|
for(;getline(file,Inline) != EOF;)
|
||
|
{
|
||
|
/*
|
||
|
* menu: chooses menu to use
|
||
|
*/
|
||
|
if(Inline[0] == '#');
|
||
|
else if(Find(Inline,"menu:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
curmenu = -1;
|
||
|
for(j=0;j<num_menus;j++)
|
||
|
if(Find(temp,menu[j].label))
|
||
|
curmenu=j;
|
||
|
/*
|
||
|
* If menu not found, make a new one
|
||
|
*/
|
||
|
if(curmenu == -1)
|
||
|
{
|
||
|
curmenu = num_menus++;
|
||
|
thismenu = &menu[curmenu];
|
||
|
thismenu->label =
|
||
|
(char*)calloc(strlen(temp)+1,sizeof(char));
|
||
|
|
||
|
if(thismenu->label == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thismenu->label,temp);
|
||
|
thismenu->numitems = 0;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* item: chooses menu item to use
|
||
|
*/
|
||
|
else if(Find(Inline,"item:"))
|
||
|
{
|
||
|
curarg = -1;
|
||
|
curinput = -1;
|
||
|
curoutput = -1;
|
||
|
crop(Inline,head,temp);
|
||
|
curitem = thismenu->numitems++;
|
||
|
/*
|
||
|
* Resize the item list for this menu (add one item);
|
||
|
*/
|
||
|
if(curitem == 0)
|
||
|
resize = (char*)calloc(1,sizeof(GmenuItem));
|
||
|
else
|
||
|
resize = realloc(thismenu->item,
|
||
|
thismenu -> numitems*sizeof(GmenuItem) );
|
||
|
|
||
|
if(resize == NULL)
|
||
|
Error ("Calloc");
|
||
|
thismenu->item =(GmenuItem*)resize;
|
||
|
|
||
|
thisitem = &(thismenu->item[curitem]);
|
||
|
thisitem->label = (char*)calloc(strlen(temp)+1,
|
||
|
sizeof(char));
|
||
|
thisitem->meta = '\0';
|
||
|
thisitem->numinputs = 0;
|
||
|
thisitem->numoutputs = 0;
|
||
|
thisitem->numargs = 0;
|
||
|
thisitem->X = 0;
|
||
|
thisitem->help = NULL;
|
||
|
|
||
|
/*
|
||
|
* Create new item
|
||
|
*/
|
||
|
|
||
|
if(thisitem->label == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisitem->label,temp);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* itemmethod: generic command line generated by this item
|
||
|
*/
|
||
|
else if(Find(Inline,"itemmethod:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
thisitem->method =
|
||
|
(char*)calloc(strlen(temp)+1,sizeof(char));
|
||
|
if(thisitem->method == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisitem->method,temp);
|
||
|
}
|
||
|
/*
|
||
|
* Help file
|
||
|
*/
|
||
|
else if(Find(Inline,"itemhelp:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
thisitem->help =
|
||
|
(char*)calloc(strlen(temp)+1,sizeof(char));
|
||
|
if(thisitem->method == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisitem->help,temp);
|
||
|
}
|
||
|
/*
|
||
|
* Meta key equiv
|
||
|
*/
|
||
|
else if(Find(Inline,"itemmeta:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
thisitem->meta = temp[0];
|
||
|
}
|
||
|
/*
|
||
|
* arg: defines the symbol for a command line arguement.
|
||
|
* this is used for substitution into the itemmethod
|
||
|
* definition.
|
||
|
*/
|
||
|
|
||
|
else if(Find(Inline,"arg:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
curarg=thisitem->numargs++;
|
||
|
if(curarg == 0)
|
||
|
resize = (char*)calloc(1,sizeof(GmenuItemArg));
|
||
|
else
|
||
|
resize = realloc(thisitem->arg,
|
||
|
thisitem->numargs*sizeof(GmenuItemArg) );
|
||
|
|
||
|
|
||
|
if(resize == NULL)
|
||
|
Error("arg: Realloc");
|
||
|
|
||
|
(thisitem->arg) = (GmenuItemArg*)resize;
|
||
|
thisarg = &(thisitem->arg[curarg]);
|
||
|
thisarg->symbol = (char*)calloc(strlen(temp)+1,
|
||
|
sizeof(char));
|
||
|
if(thisarg->symbol == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisarg->symbol,temp);
|
||
|
thisarg->optional = FALSE;
|
||
|
thisarg->type = 0;
|
||
|
thisarg->min = 0;
|
||
|
thisarg->max = 0;
|
||
|
thisarg->numchoices = 0;
|
||
|
thisarg->choice = NULL;
|
||
|
thisarg->textvalue = NULL;
|
||
|
thisarg->value = 0;
|
||
|
}
|
||
|
/*
|
||
|
* argtype: Defines the type of argument (menu,chooser, text, slider)
|
||
|
*/
|
||
|
else if(Find(Inline,"argtype:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
if(strcmp(temp,"text")==0)
|
||
|
{
|
||
|
thisarg->type=TEXTFIELD;
|
||
|
thisarg->textvalue =
|
||
|
(char*)calloc(GBUFSIZ,sizeof(char));
|
||
|
if(thisarg->textvalue == NULL)
|
||
|
Error("Calloc");
|
||
|
}
|
||
|
else if(strcmp(temp,"choice_list")==0)
|
||
|
thisarg->type=CHOICE_LIST;
|
||
|
else if(strcmp(temp,"choice_menu")==0)
|
||
|
thisarg->type=CHOICE_MENU;
|
||
|
else if(strcmp(temp,"chooser")==0)
|
||
|
thisarg->type=CHOOSER;
|
||
|
else if(strcmp(temp,"slider")==0)
|
||
|
thisarg->type=SLIDER;
|
||
|
else
|
||
|
Error(sprintf(head,"Unknown argtype %s",temp));
|
||
|
}
|
||
|
/*
|
||
|
* argtext: The default text value of the symbol.
|
||
|
* $argument is replaced by this value if it is not
|
||
|
* changed in the dialog box by the user.
|
||
|
*/
|
||
|
else if(Find(Inline,"argtext:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
(void)strcpy(thisarg->textvalue,temp);
|
||
|
}
|
||
|
/*
|
||
|
* arglabel: Text label displayed in the dialog box for
|
||
|
* this argument. It should be a discriptive label.
|
||
|
*/
|
||
|
else if(Find(Inline,"arglabel:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
thisarg->label=(char*)calloc(strlen(temp)+1,
|
||
|
sizeof(char));
|
||
|
if(thisarg->label == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisarg->label,temp);
|
||
|
}
|
||
|
/*
|
||
|
* Argument choice values use the following notation:
|
||
|
*
|
||
|
* argchoice:Displayed value:Method
|
||
|
*
|
||
|
* Where "Displayed value" is the label displayed in the dialog box
|
||
|
* and "Method" is the value passed back on the command line.
|
||
|
*/
|
||
|
else if(Find(Inline,"argchoice:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
crop(temp,head,tail);
|
||
|
curchoice = thisarg->numchoices++;
|
||
|
if(curchoice == 0)
|
||
|
resize = (char*)calloc(1,sizeof(GargChoice));
|
||
|
else
|
||
|
resize = realloc(thisarg->choice,
|
||
|
thisarg->numchoices*sizeof(GargChoice));
|
||
|
|
||
|
if(resize == NULL)
|
||
|
Error("argchoice: Realloc");
|
||
|
thisarg->choice = (GargChoice*)resize;
|
||
|
|
||
|
(thisarg->choice[curchoice].label) = NULL;
|
||
|
(thisarg->choice[curchoice].method) = NULL;
|
||
|
|
||
|
(thisarg->choice[curchoice].label) =
|
||
|
(char*)calloc(strlen(head)+1,sizeof(char));
|
||
|
|
||
|
(thisarg->choice[curchoice].method) =
|
||
|
(char*)calloc(strlen(tail)+1,sizeof(char));
|
||
|
|
||
|
if(thisarg->choice[curchoice].method == NULL ||
|
||
|
thisarg->choice[curchoice].label == NULL)
|
||
|
Error("Calloc");
|
||
|
|
||
|
(void)strcpy(thisarg->choice[curchoice].label,head);
|
||
|
(void)strcpy(thisarg->choice[curchoice].method,tail);
|
||
|
}
|
||
|
/*
|
||
|
* argmin: Minimum value for a slider
|
||
|
*/
|
||
|
else if(Find(Inline,"argmin:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
(void)sscanf(temp,"%d",&(thisarg->min));
|
||
|
}
|
||
|
/*
|
||
|
* argmax: Maximum value for a slider
|
||
|
*/
|
||
|
else if(Find(Inline,"argmax:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
(void)sscanf(temp,"%d",&(thisarg->max));
|
||
|
}
|
||
|
/*
|
||
|
* argmethod: Command line flag associated with this argument.
|
||
|
* Replaces argument in itemmethod description.
|
||
|
*/
|
||
|
else if(Find(Inline,"argmethod:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
thisarg->method = (char*)calloc(GBUFSIZ,strlen(temp));
|
||
|
if(thisarg->method == NULL)
|
||
|
Error("Calloc");
|
||
|
(void)strcpy(thisarg->method,tail);
|
||
|
}
|
||
|
/*
|
||
|
* argvalue: default value for a slider
|
||
|
*/
|
||
|
else if(Find(Inline,"argvalue:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
if(thisarg->type == TEXT)
|
||
|
strcpy(thisarg->textvalue,temp);
|
||
|
else
|
||
|
(void)sscanf(temp,"%d",&(thisarg->value));
|
||
|
}
|
||
|
/*
|
||
|
* argoptional: Flag specifying that an arguement is optional
|
||
|
*/
|
||
|
else if(Find(Inline,"argoptional:"))
|
||
|
thisarg->optional = TRUE;
|
||
|
/*
|
||
|
* in: Input file description
|
||
|
*/
|
||
|
else if(Find(Inline,"in:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
curinput = (thisitem->numinputs)++;
|
||
|
if(curinput == 0)
|
||
|
resize = (char*)calloc(1,sizeof(GfileFormat));
|
||
|
else
|
||
|
resize = realloc(thisitem->input,
|
||
|
(thisitem->numinputs)*sizeof(GfileFormat));
|
||
|
|
||
|
if(resize == NULL)
|
||
|
Error("in: Realloc");
|
||
|
thisitem->input = (GfileFormat*)resize;
|
||
|
thisinput = &(thisitem->input)[curinput];
|
||
|
thisinput->save = FALSE;
|
||
|
thisinput->overwrite = FALSE;
|
||
|
thisinput->maskable = FALSE;
|
||
|
thisinput->format = 0;
|
||
|
thisinput->symbol = String(temp);
|
||
|
thisinput->name = NULL;
|
||
|
thisinput->select = SELECTED;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* out: Output file description
|
||
|
*/
|
||
|
|
||
|
else if(Find(Inline,"out:"))
|
||
|
{
|
||
|
crop(Inline,head,temp);
|
||
|
curoutput = (thisitem->numoutputs)++;
|
||
|
if(curoutput == 0)
|
||
|
resize = (char*)calloc(1,sizeof(GfileFormat));
|
||
|
else
|
||
|
resize = realloc(thisitem->output,
|
||
|
(thisitem->numoutputs)*sizeof(GfileFormat));
|
||
|
|
||
|
if(resize == NULL)
|
||
|
Error("out: Realloc");
|
||
|
thisitem->output = (GfileFormat*)resize;
|
||
|
thisoutput = &(thisitem->output)[curoutput];
|
||
|
thisitem->output = (GfileFormat*)resize;
|
||
|
thisoutput = &(thisitem->output)[curoutput];
|
||
|
thisoutput->save = FALSE;
|
||
|
thisoutput->overwrite = FALSE;
|
||
|
thisoutput->format = 0;
|
||
|
thisoutput->symbol= String(temp);
|
||
|
thisoutput->name = NULL;
|
||
|
}
|
||
|
else if(Find(Inline,"informat:"))
|
||
|
{
|
||
|
if(thisinput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
crop(Inline,head,tail);
|
||
|
if(Find(tail,"genbank"))
|
||
|
thisinput->format = GENBANK;
|
||
|
else if(Find(tail,"gde"))
|
||
|
thisinput->format = GDE;
|
||
|
else if(Find(tail,"na_flat"))
|
||
|
thisinput->format = NA_FLAT;
|
||
|
else if(Find(tail,"colormask"))
|
||
|
thisinput->format = COLORMASK;
|
||
|
else if(Find(tail,"flat"))
|
||
|
thisinput->format = NA_FLAT;
|
||
|
else if(Find(tail,"status"))
|
||
|
thisinput->format = STATUS_FILE;
|
||
|
else fprintf(stderr,"Warning, unknown file format %s\n"
|
||
|
,tail);
|
||
|
}
|
||
|
else if(Find(Inline,"insave:"))
|
||
|
{
|
||
|
if(thisinput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
thisinput->save = TRUE;
|
||
|
}
|
||
|
else if(Find(Inline,"inselect:"))
|
||
|
{
|
||
|
if(thisinput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
crop(Inline,head,tail);
|
||
|
if(Find(tail,"one"))
|
||
|
thisinput->select = SELECT_ONE;
|
||
|
else if(Find(tail,"region"))
|
||
|
thisinput->select = SELECT_REGION;
|
||
|
else if(Find(tail,"all"))
|
||
|
thisinput->select = ALL;
|
||
|
}
|
||
|
else if(Find(Inline,"inmask:"))
|
||
|
{
|
||
|
if(thisinput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
thisinput->maskable = TRUE;
|
||
|
}
|
||
|
else if(Find(Inline,"outformat:"))
|
||
|
{
|
||
|
if(thisoutput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
crop(Inline,head,tail);
|
||
|
if(Find(tail,"genbank"))
|
||
|
thisoutput->format = GENBANK;
|
||
|
else if(Find(tail,"gde"))
|
||
|
thisoutput->format = GDE;
|
||
|
else if(Find(tail,"na_flat"))
|
||
|
thisoutput->format = NA_FLAT;
|
||
|
else if(Find(tail,"flat"))
|
||
|
thisoutput->format = NA_FLAT;
|
||
|
else if(Find(tail,"status"))
|
||
|
thisoutput->format = STATUS_FILE;
|
||
|
else if(Find(tail,"colormask"))
|
||
|
thisoutput->format = COLORMASK;
|
||
|
else fprintf(stderr,"Warning, unknown file format %s\n"
|
||
|
,tail);
|
||
|
}
|
||
|
else if(Find(Inline,"outsave:"))
|
||
|
{
|
||
|
if(thisoutput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
thisoutput->save = TRUE;
|
||
|
}
|
||
|
else if(Find(Inline,"outoverwrite:"))
|
||
|
{
|
||
|
if(thisoutput == NULL)
|
||
|
Error("Problem with .GDEmenus");
|
||
|
thisoutput->overwrite = TRUE;
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
Find(): Search the target string for the given key
|
||
|
*/
|
||
|
Find(target,key)
|
||
|
char *key,*target;
|
||
|
{
|
||
|
int i,j,len1,dif,flag = FALSE;
|
||
|
dif = (strlen(target)) - (len1 = strlen(key)) +1;
|
||
|
|
||
|
if(len1>0)
|
||
|
for(j=0;j<dif && flag == FALSE;j++)
|
||
|
{
|
||
|
flag = TRUE;
|
||
|
for(i=0;i<len1 && flag;i++)
|
||
|
flag = (key[i] == target[i+j])?TRUE:FALSE;
|
||
|
|
||
|
}
|
||
|
return(flag);
|
||
|
}
|
||
|
|
||
|
|
||
|
Find2(target,key)
|
||
|
char *key,*target;
|
||
|
/*
|
||
|
* Like find, but returns the index of the leftmost
|
||
|
* occurence, and -1 if not found.
|
||
|
*/
|
||
|
{
|
||
|
int i,j,len1,dif,flag = FALSE;
|
||
|
dif = (strlen(target)) - (len1 = strlen(key)) +1;
|
||
|
|
||
|
if(len1>0)
|
||
|
for(j=0;j<dif && flag == FALSE;j++)
|
||
|
{
|
||
|
flag = TRUE;
|
||
|
for(i=0;i<len1 && flag;i++)
|
||
|
flag = (key[i] == target[i+j])?TRUE:FALSE;
|
||
|
|
||
|
}
|
||
|
return(flag?j-1:-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
Error(msg)
|
||
|
char *msg;
|
||
|
{
|
||
|
(void)fprintf(stderr,"%s\n",msg);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
int getline(file,string)
|
||
|
FILE *file;
|
||
|
char string[];
|
||
|
{
|
||
|
char c;
|
||
|
int i;
|
||
|
for(i=0;((c=getc(file))!='\n') && (c!=EOF);i++)
|
||
|
string[i]=c;
|
||
|
string[i] = '\0';
|
||
|
if (i==0 && c==EOF) return (EOF);
|
||
|
else return (0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Crop():
|
||
|
Split "this:that[:the_other]"
|
||
|
into: "this" and "that[:the_other]"
|
||
|
*/
|
||
|
|
||
|
crop(input,head,tail)
|
||
|
char input[],head[],tail[];
|
||
|
{
|
||
|
/*
|
||
|
* Crop needs to be fixed so that whitespace is compressed off the end
|
||
|
* of tail
|
||
|
*/
|
||
|
int offset,end,i,j,length;
|
||
|
|
||
|
length=strlen(input);
|
||
|
for(offset=0;offset<length && input[offset] != ':';offset++)
|
||
|
head[offset]=input[offset];
|
||
|
head[offset++] = '\0';
|
||
|
for(;offset<length && input[offset] == ' ';offset++);
|
||
|
for(end=length-1;input[end] ==' ' && end>offset;end--);
|
||
|
|
||
|
for(j=0,i=offset;i<=end;i++,j++)
|
||
|
tail[j]=input[i];
|
||
|
tail[j] = '\0';
|
||
|
return;
|
||
|
}
|