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 | |
---|
20 | static 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 | |
---|
50 | void 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 | */ |
---|
480 | int 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 | |
---|
497 | int 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 | |
---|
520 | void 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 | |
---|
535 | void 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 | } |
---|