send showerror output to kernel log if neither dos nor intuition are available
[cake.git] / tools / archtools / archtool.c
bloba00553c9ebe6e654ec9ba605e52a8b9516166311
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <unistd.h>
12 #include <time.h>
13 #include <sys/stat.h>
15 /* Prototypes of reusable functions */
17 /* Read in one line from file
18 - mallocs needed space */
19 char *get_line(FILE *file);
21 /* Search for '#Keyword' in string
22 - mallocs needed space
23 - returns 'Keyword' */
24 char *keyword(char *line);
26 /* Searches line for whitespace separated words
27 - outarray = pointer to array of found words (strings)
28 - mallocs needed space
29 - frees previously allocated space before !
30 - for first use pass
31 char **words=NULL; get_words(line,&words) */
32 int get_words(char *line, char ***outarray);
34 /* Converts string to lower case */
35 void strlower(char *string);
37 /* Compares two files
38 returns 0 for equal files,
39 1 for different files,
40 -1 if file1 is not present,
41 -2 if file2 is not present */
42 int filesdiffer( char *file1, char *file2 );
44 /* Compares old and new file,
45 if old file is not found or different from new
46 new file will be renamed to name of old
47 old will be named old.bak */
48 void moveifchanged(char *old, char *new);
50 /* Parses file or lib.conf if file==NULL
51 puts values in struct libconf
52 returns 0 on success */
53 struct libconf * parse_libconf(char *file);
56 char *get_line(FILE *fd)
58 int count,len;
59 char *line;
60 char buffer;
62 len = 0;
65 count = fread(&buffer,1,1,fd);
66 len += count;
67 } while(count!=0 && buffer!='\n');
68 if(len==0 && count==0)
69 return NULL;
70 fseek( fd, -len, SEEK_CUR );
71 line = malloc( (len+1) * sizeof(char) );
72 fread (line,1,len,fd);
73 line[len]=0;
74 len--;
75 while(isspace(line[len])&& len>=0)
77 line[len] = 0;
78 len--;
81 return line;
84 char *keyword(char *line)
86 char *key;
87 int len;
89 if(line[0]=='#')
91 len = 1;
92 while(line[len] && !isspace(line[len]))
93 len++;
94 key = malloc( len * sizeof(char) );
95 strncpy( key, &line[1], len-1 );
96 key[len-1] = 0;
98 return key;
100 else
101 return NULL;
104 int get_words(char *line, char ***outarray)
106 char **array;
107 char *word;
108 int num,len;
110 if(!outarray||!line)
112 fprintf( stderr, "Passed invalid NULL pointer to get_words()!\n" );
113 exit(-1);
115 array = *outarray;
116 if( array )
118 while( *array )
120 free(*array);
121 array++;
123 free(*outarray);
125 array = NULL;
126 num = 0;
127 word = line;
128 while(*word!=0)
130 while( *word && isspace(*word) )
131 word++;
132 len = 0;
133 while( word[len] && !isspace(word[len]) )
134 len++;
135 if(len)
137 num++;
138 array = realloc( array, (num+1) * sizeof(char *) );
139 array[num-1] = malloc( (len+1) * sizeof(char) );
140 strncpy( array[num-1], word, len );
141 array[num-1][len] = 0;
142 word = &word[len];
145 if (array)
146 array[num] = NULL;
148 *outarray = array;
150 return num;
153 void strlower(char *string)
155 while(*string)
157 *string = tolower(*string);
158 string++;
162 int filesdiffer( char *file1, char *file2 )
164 FILE *fd1, *fd2;
165 int cnt1,cnt2;
166 char buffer1[1], buffer2[1];
167 int retval = 0;
169 fd1 = fopen(file1,"rb");
170 if(!fd1)
171 return -1;
172 fd2 = fopen(file2,"rb");
173 if(!fd2)
174 return -2;
177 cnt1 = fread(buffer1,1,1,fd1);
178 cnt2 = fread(buffer2,1,1,fd2);
179 } while( cnt1 && cnt2 && buffer1[0]==buffer2[0] );
180 if( buffer1[0]!=buffer2[0] || cnt1 != cnt2 )
181 retval = 1;
183 fclose(fd1);
184 fclose(fd2);
186 return retval;
189 void moveifchanged(char *old, char *new)
191 struct stat *statold, *statnew;
192 char *bakname;
194 statold = calloc(1, sizeof(struct stat) );
195 statnew = calloc(1, sizeof(struct stat) );
196 if(stat(old,statold))
198 /* Couldn't stat old file -- assume non-existent */
199 rename(new,old);
200 return;
202 if(stat(new,statnew))
204 /* Couldn't stat new file -- this shouldn't happen */
205 fprintf( stderr, "Couldn't stat() file %s!\n", new );
206 exit(-1);
208 bakname = malloc( (strlen(old)+5) * sizeof(char) );
209 sprintf( bakname, "%s.bak", old );
210 if(statold->st_size != statnew->st_size)
212 rename(old,bakname);
213 rename(new,old);
215 else if( filesdiffer(old,new) )
217 rename(old,bakname);
218 rename(new,old);
220 else
221 remove(new);
222 free(bakname);
225 enum libtype
227 t_device = 1,
228 t_library = 2,
229 t_resource = 3,
230 t_hidd = 4,
231 t_gadget = 5,
232 t_image = 6,
233 t_class = 7,
234 t_datatype = 8,
235 t_usbclass = 9
238 enum liboption
240 o_noexpunge = 1,
241 o_rom = 2,
242 o_unique = 4,
243 o_nolibheader = 8,
244 o_hasrt = 16
247 struct libconf
249 char *libname;
250 char *basename;
251 char *libbase;
252 char *libbasetype;
253 char *libbasetypeptr;
254 int version, revision;
255 char *copyright;
256 char *define;
257 int type;
258 int option;
262 struct libconf * parse_libconf(char *file)
264 FILE *fd;
265 int num, len, i;
266 char *line, *word;
267 char **words = NULL;
268 struct libconf * lc = calloc (1, sizeof (struct libconf));
270 fd = fopen((file?file:"lib.conf"),"rb");
271 if(!fd)
273 fprintf( stderr, "Couldn't open %s!\n", (file?file:"lib.conf") );
274 return NULL;
276 while( (line = get_line(fd)) )
278 num = get_words(line,&words);
279 if( num > 1 )
281 if( strcmp(words[0],"name")==0 )
283 strlower(words[1]);
284 len = strlen(words[1]);
285 lc->libname = strdup(words[1]);
287 else if( strcmp(words[0],"libname")==0 )
289 free(lc->libname);
290 lc->libname = strdup(words[1]);
292 else if( strcmp(words[0],"basename")==0 )
294 len = strlen(words[1]);
295 free(lc->basename);
296 lc->basename = strdup(words[1]);
298 else if( strcmp(words[0],"libbase")==0 )
300 len = strlen(words[1]);
301 free(lc->libbase);
302 lc->libbase = strdup(words[1]);
304 else if( strcmp(words[0],"libbasetype")==0 )
306 len = 0;
307 for( i=1 ; i<num ; i++ )
308 len += strlen(words[i]);
309 len += num-1;
310 free(lc->libbasetype);
311 lc->libbasetype = malloc( len * sizeof(char) );
312 strcpy(lc->libbasetype, words[1] );
313 for( i=2 ; i<num ; i++ )
315 strcat( lc->libbasetype, " " );
316 strcat( lc->libbasetype, words[i] );
319 else if( strcmp(words[0],"libbasetypeptr")==0 )
321 len = 0;
322 for( i=1 ; i<num ; i++ )
323 len += strlen(words[i]);
324 len += num-1;
325 free(lc->libbasetypeptr);
326 lc->libbasetypeptr = malloc( len * sizeof(char) );
327 strcpy(lc->libbasetypeptr, words[1]);
328 for( i=2 ; i<num ; i++ )
330 strcat( lc->libbasetypeptr, " " );
331 strcat( lc->libbasetypeptr, words[i] );
334 else if( strcmp(words[0],"version")==0 )
336 i = 0;
337 while( words[1][i] && words[1][i]!='.' )
338 i++;
339 lc->revision = (words[1][i]==0?0:atoi(&words[1][i+1]));
340 if( i==0 )
342 lc->version = 0;
344 else
346 words[1][i] = 0;
347 lc->version = atoi(words[1]);
350 else if( strcmp(words[0],"copyright")==0 )
352 word = &line[9];
353 while( *word && isspace(*word) )
354 word++;
355 free(lc->copyright);
356 lc->copyright = strdup(word);
358 else if( strcmp(words[0],"define")==0 )
360 free(lc->define);
361 lc->define = strdup(words[1]);
363 else if( strcmp(words[0],"type")==0 )
365 if( strcmp(words[1],"device")==0 )
366 lc->type = t_device;
367 else if( strcmp(words[1],"library")==0 )
368 lc->type = t_library;
369 else if( strcmp(words[1],"resource")==0 )
370 lc->type = t_resource;
371 else if( strcmp(words[1],"hidd")==0 )
372 lc->type = t_hidd;
373 else if( strcmp(words[1],"gadget")==0 )
374 lc->type = t_gadget;
375 else if( strcmp(words[1],"image")==0 )
376 lc->type = t_image;
377 else if( strcmp(words[1],"class")==0 )
378 lc->type = t_class;
379 else if( strcmp(words[1],"datatype")==0 )
380 lc->type = t_datatype;
381 else if( strcmp(words[1],"usbclass")==0 )
382 lc->type = t_usbclass;
384 else if( strcmp(words[0],"options")==0 || strcmp(words[0],"option")==0 )
386 for( i=1 ; i<num ; i++ )
388 if( strcmp(words[i],"noexpunge")==0 )
389 lc->option |= o_noexpunge;
390 else if( strcmp(words[i],"rom")==0 )
391 lc->option |= o_rom;
392 else if( strcmp(words[i],"unique")==0 )
393 lc->option |= o_unique;
394 else if( strcmp(words[i],"nolibheader")==0 )
395 lc->option |= o_nolibheader;
396 else if( strcmp(words[i],"hasrt")==0 )
397 lc->option |= o_hasrt;
401 free(line);
404 if( lc->libname == NULL )
406 fprintf( stderr, "Missing field \"name\" in lib.conf!\n" );
407 return NULL;
409 if( lc->basename == NULL )
411 lc->basename = strdup(lc->libname);
412 lc->basename[0] = toupper(lc->basename[0]);
414 if( lc->libbase == NULL )
416 lc->libbase = malloc( (strlen(lc->basename)+5) * sizeof(char) );
417 sprintf( lc->libbase, "%sBase", lc->basename );
419 if( lc->libbasetype == NULL )
421 lc->libbasetype = malloc( (strlen(lc->libbase)+8) * sizeof(char) );
422 sprintf( lc->libbasetype, "struct %s", lc->libbase );
424 if( lc->libbasetypeptr == NULL )
426 lc->libbasetypeptr = malloc( (strlen(lc->libbasetype)+3) * sizeof(char) );
427 sprintf( lc->libbasetypeptr, "%s *", lc->libbasetype );
430 if( lc->define == NULL )
431 lc->define = strdup( "_LIBDEFS_H" );
432 if( lc->type == 0 )
433 lc->type = t_library;
435 return lc;
440 # Create libdefs.h from a file lib.conf. lib.conf may contain these options:
442 # name <string> - Init the various fields with reasonable defaults. If
443 # <string> is XXX, then this is the result:
445 # libname xxx
446 # basename Xxx
447 # libbase XxxBase
448 # libbasetype XxxBase
449 # libbasetypeptr XxxBase *
451 # Variables will only be changed if they have not yet been
452 # specified.
454 # libname <string> - Set libname to <string>. This is the name of the
455 # library (ie. you can open it with <string>.library).
456 # It will show up in the version string, too.
457 # basename <string> - Set basename to <string>. The basename is used in
458 # the AROS-LHx macros in the location part (last parameter)
459 # and to specify defaults for libbase and libbasetype
460 # in case they have no value yet. If <string> is xXx, then
461 # libbase will become xXxBase and libbasetype will become
462 # xXxBase.
463 # libbase <string> - Defines the name of the library base (ie. SysBase,
464 # DOSBase, IconBase, etc). If libbasetype is not set, then
465 # it is set to <string>, too.
466 # libbasetype <string> - The type of libbase (with struct), ie.
467 # struct ExecBase, struct DosLibrary, struct IconBase, etc).
468 # libbasetypeptr <string> - Type of a pointer to the libbase. (eg.
469 # struct ExecBase *).
470 # version <version>.<revision> - Specifies the version and revision of the
471 # library. 41.0103 means version 41 and revision 103.
472 # copyright <string> - Copyright string.
473 # define <string> - The define to use to protect the resulting file
474 # against double inclusion (ie. #ifndef <string>...)
475 # The default is _LIBDEFS_H.
476 # type <string> - What kind of library is this ? Valid values
477 # for <string> are: device, library, resource and hidd.
478 # option <string>... - Specify an option. Valid values for <string> are:
480 # noexpunge - Once the lib/dev is loaded, it can't be
481 # removed from memory. Be careful with this
482 # option.
483 # rom - For ROM based libraries. Implies noexpunge and
484 # unique.
485 # unique - Generate unique names for all external
486 # symbols.
487 # nolibheader - We don't want to use the LibHeader prefixed
488 # functions in the function table.
489 # hasrt - This library has resource tracking.
491 # You can specify more than one option in a config file and
492 # more than one option per option line. Separate options by
493 # space.
496 int genlibdefs(int argc, char **argv)
498 struct libconf *lc;
499 FILE *fd;
500 char *date, *filename, *conffile;
501 struct tm *tm;
502 time_t t;
503 int i;
505 filename = "libdefs.h";
506 conffile = "lib.conf";
507 for (i=2; i<=argc; i++)
509 if (strcmp(argv[i-1],"-o")==0)
511 filename = argv[i];
512 i++;
514 else
515 conffile = argv[i-1];
517 time(&t);
518 tm = localtime(&t);
519 date = malloc( 11 * sizeof(char) );
520 sprintf( date, "%02d.%02d.%4d", tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900 );
521 fd = fopen(filename,"w");
522 if(!fd)
524 fprintf( stderr, "Couldn't open file %s!\n", "libdefs.h.new" );
525 return -1;
527 if(!(lc = parse_libconf(conffile)) )
528 return(-1);
529 if( lc->copyright == NULL )
531 lc->copyright = strdup("");
533 fprintf( fd, "/* *** Automatic generated file. Do not edit *** */\n\n");
534 fprintf( fd, "#ifndef %s\n#define %s\n", lc->define, lc->define );
536 if (lc->type == t_library)
538 fprintf( fd, "#define NAME_STRING \"%s.library\"\n", lc->libname );
539 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
541 else if (lc->type == t_device)
543 fprintf( fd, "#define NAME_STRING \"%s.device\"\n", lc->libname );
544 fprintf( fd, "#define NT_TYPE NT_DEVICE\n" );
546 else if (lc->type == t_resource)
548 fprintf( fd, "#define NAME_STRING \"%s.resource\"\n", lc->libname );
549 fprintf( fd, "#define NT_TYPE NT_RESOURCE\n" );
551 else if (lc->type == t_hidd)
553 fprintf( fd, "#define NAME_STRING \"%s.hidd\"\n", lc->libname );
554 fprintf( fd, "#define NT_TYPE NT_HIDD\n" );
556 else if (lc->type == t_gadget)
558 fprintf( fd, "#define NAME_STRING \"%s.gadget\"\n", lc->libname );
559 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
561 else if (lc->type == t_image)
563 fprintf( fd, "#define NAME_STRING \"%s.image\"\n", lc->libname );
564 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
566 else if (lc->type == t_class)
568 fprintf( fd, "#define NAME_STRING \"%s.class\"\n", lc->libname );
569 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
571 else if (lc->type == t_datatype)
573 fprintf( fd, "#define NAME_STRING \"%s.datatype\"\n", lc->libname );
574 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
576 else if (lc->type == t_usbclass)
578 fprintf( fd, "#define NAME_STRING \"%s.class\"\n", lc->libname );
579 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
582 if (lc->option & o_rom)
583 lc->option |= o_noexpunge;
585 if (lc->option & o_noexpunge)
586 fprintf( fd, "#define NOEXPUNGE\n" );
587 if (lc->option & o_rom)
588 fprintf( fd, "#define ROMBASED\n" );
589 if (lc->option & o_nolibheader)
590 fprintf( fd, "#define NOLIBHEADER\n" );
592 if (lc->option & o_rom || lc->option & o_unique)
594 fprintf( fd, "#define LC_UNIQUE_PREFIX %s\n", lc->basename );
595 fprintf( fd, "#define LC_BUILDNAME(n) %s ## n\n", lc->basename );
597 else
599 fprintf( fd, "#define LC_BUILDNAME(n) n\n" );
602 fprintf( fd, "#define LIBBASE %s\n", lc->libbase );
603 fprintf( fd, "#define LIBBASETYPE %s\n", lc->libbasetype );
604 fprintf( fd, "#define LIBBASETYPEPTR %s\n", lc->libbasetypeptr );
605 fprintf( fd, "#define VERSION_NUMBER %d\n", lc->version );
606 fprintf( fd, "#define REVISION_NUMBER %d\n", lc->revision );
607 fprintf( fd, "#define BASENAME %s\n", lc->basename );
608 fprintf( fd, "#define BASENAME_STRING \"%s\"\n", lc->basename );
609 fprintf( fd, "#define VERSION_STRING \"$VER: %s %d.%d (%s)\\r\\n\"\n", lc->libname, lc->version, lc->revision , date );
610 fprintf( fd, "#define LIBEND %s_end\n", lc->basename );
611 fprintf( fd, "#define LIBFUNCTABLE %s_functable\n", lc->basename );
612 fprintf( fd, "#define COPYRIGHT_STRING \"%s\"\n", lc->copyright );
613 fprintf( fd, "#endif /* %s */\n", lc->define );
615 fclose(fd);
617 return 0;
620 void emit(FILE *out, struct libconf *lc, char **names, int number)
622 int i;
624 fprintf( out, "/*\n" );
625 fprintf( out, " Copyright © 1995-1998, The AROS Development Team. All rights reserved.\n" );
626 fprintf( out, " *** Automatic generated file. Do not edit ***\n" );
627 fprintf( out, " Desc: Function table for %s\n", lc->basename );
628 fprintf( out, " Lang: english\n" );
629 fprintf( out, "*/\n" );
630 fprintf( out, "#ifndef LIBCORE_COMPILER_H\n" );
631 fprintf( out, "# include <libcore/compiler.h>\n" );
632 fprintf( out, "#endif\n" );
633 fprintf( out, "#ifndef NULL\n" );
634 fprintf( out, "#define NULL ((void *)0)\n" );
635 fprintf( out, "#endif\n\n" );
636 fprintf( out, "#ifndef LC_LIBDEFS_FILE\n" );
637 fprintf( out, "#define LC_LIBDEFS_FILE \"libdefs.h\"\n" );
638 fprintf( out, "#endif\n" );
639 fprintf( out, "#include LC_LIBDEFS_FILE\n" );
640 if(lc->option & o_nolibheader)
642 fprintf( out, "extern void AROS_SLIB_ENTRY(open,BASENAME) (void);\n" );
643 fprintf( out, "extern void AROS_SLIB_ENTRY(close,BASENAME) (void);\n" );
644 fprintf( out, "extern void AROS_SLIB_ENTRY(expunge,BASENAME) (void);\n" );
645 fprintf( out, "extern void AROS_SLIB_ENTRY(null,BASENAME) (void);\n" );
647 else
649 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader) (void);\n" );
650 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader) (void);\n" );
651 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader) (void);\n" );
652 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader) (void);\n" );
654 for( i = 0 ; i < number-4 ; i++ )
656 if(names[i])
657 fprintf( out, "extern void AROS_SLIB_ENTRY(%s,BASENAME) (void);\n", names[i] );
659 fprintf( out, "\nvoid *const LIBFUNCTABLE[]=\n{\n" );
660 if(lc->option & o_nolibheader)
662 fprintf( out, " AROS_SLIB_ENTRY(open, BASENAME),\n" );
663 fprintf( out, " AROS_SLIB_ENTRY(close, BASENAME),\n" );
664 fprintf( out, " AROS_SLIB_ENTRY(expunge, BASENAME),\n" );
665 fprintf( out, " AROS_SLIB_ENTRY(null, BASENAME),\n" );
667 else
669 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader),\n" );
670 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader),\n" );
671 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader),\n" );
672 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader),\n" );
674 for( i = 0 ; i < number-4 ; i++ )
676 if(names[i])
677 fprintf( out, " AROS_SLIB_ENTRY(%s,BASENAME), /* %d */\n", names[i], i+5 );
678 else
679 fprintf( out, " NULL, /* %d */\n", i+5 );
681 fprintf( out, " (void *)-1L\n};\n" );
684 int genfunctable(int argc, char **argv)
686 FILE *fd = NULL, *fdo;
687 struct libconf *lc;
688 char *line = 0;
689 char *word, **words = NULL;
690 int in_archive, in_header, in_function, in_autodoc, in_code;
691 int num;
692 char *funcname = NULL, **funcnames = NULL;
694 /* Well, there are already 4 functions (open,close,expunge,null) */
695 int numfuncs = 4;
697 int has_arch = 1;
700 /* First check if we have a HIDD which does not have an archive */
701 if(!(lc=parse_libconf(NULL)))
702 return(-1);
704 if (lc->type == t_hidd || lc->type == t_gadget || lc->type == t_class || lc->type == t_usbclass)
705 has_arch = 0;
707 if(has_arch)
709 if(argc == 2)
711 fd = fopen(argv[1],"rb");
712 if(!fd)
714 fprintf( stderr, "Couldn't open file %s!\n", argv[1] );
715 exit(-1);
718 else if (argc == 1)
720 has_arch = 0;
722 else
724 fprintf( stderr, "Usage: %s <archfile>\n", argv[0] );
725 exit(-1);
728 fdo = fopen("functable.c.new","w");
729 if(!fdo)
731 fprintf( stderr, "Couldn't open file %s!\n", "functable.c.new" );
732 exit(-1);
735 if(has_arch)
737 in_archive = 0;
738 in_function = 0;
739 in_autodoc = 0;
740 in_code = 0;
741 in_header = 0;
742 while( (line = get_line(fd)) )
744 word = keyword(line);
745 if( word )
747 if( strcmp(word,"Archive")==0 && !in_archive )
748 in_archive = 1;
749 else if( strcmp(word,"/Archive")==0 && in_archive && ! in_function )
750 break;
751 else if( strcmp(word,"AutoDoc")==0 && in_function && !in_autodoc && !in_code )
752 in_autodoc = 1;
753 else if( strcmp(word,"/AutoDoc")==0 && in_autodoc )
754 in_autodoc = 0;
755 else if( strcmp(word,"Code")==0 && in_function && !in_code && !in_autodoc )
756 in_code = 1;
757 else if( strcmp(word,"/Code")==0 && in_code )
758 in_code = 0;
759 else if( strcmp(word,"Header")==0 && in_archive && !in_function )
760 in_header = 1;
761 else if( strcmp(word,"/Header")==0 && in_header )
762 in_header = 0;
763 else if( strcmp(word,"Function")==0 && in_archive && !in_function && !in_header )
765 num = get_words(line,&words);
766 funcname = strdup(words[num-1]);
767 in_function = 1;
769 else if( strcmp(word,"/Function")==0 && in_function && !in_autodoc && !in_code )
770 in_function = 0;
771 else if( strcmp(word,"LibOffset")==0 && in_function && !in_autodoc && !in_code )
773 get_words(line,&words);
774 num = atoi(words[1]);
775 if( num>numfuncs )
777 funcnames = realloc( funcnames, (num-4) * sizeof(char *));
778 /* initialize new memory */
779 for( ;numfuncs<num; numfuncs++)
780 funcnames[numfuncs-4] = NULL;
782 funcnames[num-5] = funcname;
785 free(word);
787 free(line);
790 emit(fdo,lc,funcnames,numfuncs);
791 fclose(fdo);
792 if(has_arch)
794 fclose(fd);
796 moveifchanged("functable.c","functable.c.new");
797 free(lc);
799 return 0;
803 const char * m68k_registers[] = {
804 "D0",
805 "D1",
806 "D2",
807 "D3",
808 "D4",
809 "D5",
810 "D6",
811 "D7",
812 "A0",
813 "A1",
814 "A2",
815 "A3",
816 "A4",
817 "A5",
818 "A6",
819 "A7",
822 struct pragma_description
824 struct pragma_description *next;
825 char basename[200];
826 char funcname[200];
827 unsigned short offset;
828 int numargs;
829 int args[16];
832 char * skipstr(char * line, char skipper,int direction)
834 while (line[0] == skipper) {
835 line += direction;
837 return line;
840 void free_pragma_description(struct pragma_description * pd)
842 struct pragma_description * _pd;
843 while (pd != NULL) {
844 _pd = pd -> next;
845 free(pd);
846 pd = _pd;
851 struct pragma_description * find_pragma_description(struct pragma_description * pd,
852 char * funcname)
854 while (NULL != pd) {
855 if (0 == strcmp(pd->funcname,
856 funcname))
857 return pd;
858 pd = pd->next;
860 return NULL;
863 struct pragma_description * parse_pragmas(char * filename)
865 FILE *fdi =NULL;
866 char *line;
867 struct pragma_description * base_pd = NULL;
868 fdi = fopen(filename,"r");
870 if (!fdi){
871 fprintf(stderr, "Couldn't open file %s!\n",filename);
872 return NULL;
875 while( (line = get_line(fdi))) {
876 char * substr;
877 //printf("%s\n",line);
879 * look for '#', then 'pragma'.
881 substr = skipstr(line,' ',1);
883 if (substr[0] == '#'){
884 substr++;
885 substr = skipstr(substr, ' ',1);
886 //printf("1. %s\n",substr);
887 if (0 == strncmp(substr, "pragma",6)) {
888 substr += 6;
889 substr = skipstr(substr,' ',1);
890 //printf("2. %s\n",substr);
891 if (!strncmp(substr, "amicall",7)) {
892 substr += 7;
893 substr = skipstr(substr,' ',1);
895 if (substr[0] == '(') {
896 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
897 substr += 1;
898 substr = skipstr(substr,' ',1);
899 if (NULL != pd) {
900 char * comma;
901 char * lastchar;
902 pd->next = base_pd;
903 base_pd = pd;
905 * Now read the name of the base
906 * of the library!
908 comma = strchr(substr, ',');
909 lastchar = skipstr(comma-1,' ',-1);
911 strncpy(&pd->basename[0],
912 substr,
913 lastchar-substr+1);
914 //printf("basename: %s\n",pd->basename);
917 * after the comma comes the offset in HEX!
919 pd->offset = strtol(comma+1,&lastchar,16)/6;
920 //printf("Offset : %x\n",pd->offset);
923 * Now for the next ','
925 comma = strchr(lastchar, ',');
926 comma = skipstr(comma+1,' ',1);
927 //printf("%s\n",comma);
929 if ( NULL == comma) {
930 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
931 free_pragma_description(base_pd);
932 fclose(fdi);
933 exit(-1);
937 * Now the name of the function
939 lastchar = strchr(comma+1, '(');
940 if ( NULL == lastchar) {
941 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
942 free_pragma_description(base_pd);
943 fclose(fdi);
944 exit(-1);
948 strncpy(&pd->funcname[0],
949 comma,
950 skipstr(lastchar,' ',-1)-comma);
951 //printf("funcname: %s\n",pd->funcname);
953 substr = lastchar + 1;
954 //printf("%s\n",substr);
955 lastchar = strchr(substr,')');
957 * Now read the CPU registers.
960 while (substr < lastchar) {
961 int r = 0;
962 substr = skipstr(substr, ' ',1);
964 if (substr[0] == 'a' ||
965 substr[0] == 'A') {
966 r = 8;
967 } else if (substr[0] == 'd' ||
968 substr[0] == 'D') {
969 } else {
970 fprintf(stderr, "Wrong register (letter) in pragma file!\n");
971 free_pragma_description(base_pd);
972 fclose(fdi);
973 exit(-1);
976 if (substr[1] >= '0' && substr[1] <= '8') {
977 r += substr[1] - '0';
978 } else {
979 fprintf(stderr, "Wrong register (number) in pragma file!\n");
980 free_pragma_description(base_pd);
981 fclose(fdi);
982 exit(-1);
985 printf("r:%d\n",r);
986 printf("parameter %d goes into %s\n",
987 pd->numargs+1,
988 m68k_registers[r]);
990 pd->args[pd->numargs] = r;
991 pd->numargs++;
993 substr+=2;
994 skipstr(substr, ' ', 1);
995 substr+=1;
1001 } else if (!strncmp(substr, "libcall",7)) {
1002 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
1003 substr += 7;
1004 //substr = skipstr(substr,' ',1);
1005 if (NULL != pd) {
1006 char offset_s[10];
1007 char parameters_s[20];
1008 char hex[3]={0,0,0};
1009 int i,c;
1011 * Read in the description of the
1012 * function
1014 sscanf(substr, "%s %s %s %s",
1015 &pd->basename[0],
1016 &pd->funcname[0],
1017 offset_s,
1018 parameters_s);
1019 pd->offset = strtol(offset_s,NULL,16)/6;
1020 #if 1
1021 printf("|%s| |%s| %d %s[%zd]\t",
1022 pd->basename,
1023 pd->funcname,
1024 pd->offset,
1025 parameters_s,
1026 strlen(parameters_s));
1027 #endif
1029 * Process the parameters.
1031 i = strlen(parameters_s)-1;
1032 hex[0] = parameters_s[i-1];
1033 hex[1] = parameters_s[i];
1034 i -= 2;
1035 pd->numargs = strtol(hex,NULL,16);
1036 c = 0;
1037 hex[1] = 0;
1038 while (i >= 0) {
1039 hex[0] = parameters_s[i];
1040 pd->args[c] = strtol(hex,NULL,16);
1041 printf("%s ",m68k_registers[pd->args[c]]);
1042 i--;
1043 c++;
1045 printf("\n");
1047 pd->next = base_pd;
1048 base_pd = pd;
1050 } else if(!strncmp(substr, "usrcall",7)) {
1051 substr += 7;
1052 substr = skipstr(substr,' ',1);
1054 if (substr[0] == '(') {
1055 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
1056 pd->offset = 0xffff; // sign for user function
1057 substr += 1;
1058 substr = skipstr(substr,' ',1);
1059 if (NULL != pd) {
1060 char * lastchar;
1061 pd->next = base_pd;
1062 base_pd = pd;
1064 * Now the name of the function
1066 printf("%s\n",substr);
1067 lastchar = strchr(substr+1, '(');
1068 if ( NULL == lastchar) {
1069 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
1070 free_pragma_description(base_pd);
1071 fclose(fdi);
1072 exit(-1);
1076 strncpy(&pd->funcname[0],
1077 substr,
1078 skipstr(lastchar,' ',-1)-substr);
1079 //printf("funcname: %s\n",pd->funcname);
1081 substr = lastchar + 1;
1082 //printf("%s\n",substr);
1083 lastchar = strchr(substr,')');
1085 * Now read the CPU registers.
1088 while (substr < lastchar) {
1089 int r = 0;
1090 substr = skipstr(substr, ' ',1);
1092 if (substr[0] == 'a' ||
1093 substr[0] == 'A') {
1094 r = 8;
1095 } else if (substr[0] == 'd' ||
1096 substr[0] == 'D') {
1097 } else {
1098 fprintf(stderr, "Wrong register (letter) in pragma file!\n");
1099 free_pragma_description(base_pd);
1100 fclose(fdi);
1101 exit(-1);
1104 if (substr[1] >= '0' && substr[1] <= '8') {
1105 r += substr[1] - '0';
1106 } else {
1107 fprintf(stderr, "Wrong register (number) in pragma file!\n");
1108 free_pragma_description(base_pd);
1109 fclose(fdi);
1110 exit(-1);
1113 printf("r:%d\n",r);
1114 printf("parameter %d goes into %s\n",
1115 pd->numargs+1,
1116 m68k_registers[r]);
1118 pd->args[pd->numargs] = r;
1119 pd->numargs++;
1121 substr+=2;
1122 skipstr(substr, ' ', 1);
1123 substr+=1;
1131 free(line);
1135 fclose(fdi);
1136 return base_pd;
1140 int countchars (char * s, char c)
1142 int ctr = 0;
1143 while (s[0] != 0) {
1144 if (s[0] == c)
1145 ctr++;
1146 s++;
1148 return ctr;
1152 * Add a line to the cache. If NULL is added the old cache
1153 * is flushed to the disk.
1154 * If a line is added everything that ended with a ';' up
1155 * to that point will be written into the file and the
1156 * cache will be cut down to everything that was not written
1157 * so far.
1158 * If a 'end-of-comment' is added also everything is flushed to output.
1160 char * addtocache(char * cache, char * newline, int len, FILE * fdo)
1162 int cachelen;
1163 char * semic;
1164 char * newcache = NULL;
1165 char * endcomment;
1167 if (NULL == newline) {
1168 if (NULL != cache) {
1169 fprintf(fdo, "%s\n", cache);
1170 free(cache);
1172 return NULL;
1176 semic = strchr(newline, ';');
1177 endcomment = strstr(newline, "*/");
1179 if (NULL != semic || NULL != endcomment) {
1180 int newlinelen = strlen(newline);
1181 int i = newlinelen -1;
1182 char * tmp;
1184 * write the cache and everything up to the
1185 * last ';' in the new line to the file.
1187 if (NULL != cache) {
1188 fprintf(fdo,"%s\n",cache);
1189 //printf("1. Flush: |%s|\n",cache);
1192 if (NULL != endcomment) {
1193 i = endcomment - newline + 1;
1194 } else {
1195 while (newline[i] != ';')
1196 i--;
1200 tmp = malloc(i+2);
1201 memcpy(tmp,newline,i+1);
1202 tmp[i+1] = 0;
1203 fprintf(fdo, "%s",tmp);
1204 //printf("2. Flush: |%s|\n",tmp);
1205 free(tmp);
1207 if (i < newlinelen) {
1208 newcache = malloc(newlinelen-i+1);
1209 memcpy(newcache, &newline[i+1], newlinelen-i);
1210 newcache[newlinelen-i] = 0;
1212 free(cache);
1214 } else {
1216 * ';' could not be found. Enhance the cache.
1218 cachelen = 0;
1219 if (NULL != cache)
1220 cachelen = strlen(cache);
1222 cachelen += strlen(newline)+1+1;
1223 newcache = malloc(cachelen);
1224 if (NULL != cache)
1225 sprintf(newcache,"%s\n%s",cache,newline);
1226 else
1227 sprintf(newcache,"%s",newline);
1228 //printf("cache: %s\tnewcache: %s\n",cache,newcache);
1229 free (cache);
1232 return newcache;
1235 char * clear_cache(char * cache)
1237 free(cache);
1238 return NULL;
1242 * cut out all '\n' '\t' and ' ' at the end and
1243 * beginning of a string
1245 void strtrim(char ** s)
1247 int end = strlen(*s)-1;
1248 int start = 0;
1249 char * newstr;
1250 int end_orig = end;
1252 while ((start < end) && (
1253 '\t' == (*s)[start] ||
1254 '\n' == (*s)[start] ||
1255 ' ' == (*s)[start])) {
1256 start++;
1259 while (end > 0 && (
1260 '\t' == (*s)[end] ||
1261 '\n' == (*s)[end] ||
1262 ' ' == (*s)[end])) {
1263 end--;
1266 if ((end > start) && ((start > 0) || (end_orig != end))) {
1267 newstr = malloc(end-start+2);
1268 strncpy(newstr, (*s)+start, end-start+1);
1269 newstr[end-start+1] = 0;
1270 free(*s);
1271 *s = newstr;
1275 char * getfuncname(char * s)
1277 int i = strlen(s)-1;
1278 int c = 0;
1279 char * name;
1280 int last;
1281 while (i > 0) {
1282 if (')' == s[i])
1283 c++;
1284 else if ('(' == s[i]) {
1285 c--;
1286 if (0 == c) {
1287 i--;
1288 while (i >= 0 && ' ' == s[i])
1289 i--;
1291 if (i == 0)
1292 return NULL;
1294 last = i;
1295 while (i > 0 && ' ' != s[i] && '\n' != s[i])
1296 i--;
1298 if (last == i)
1299 return NULL;
1301 if (s[i+1] == '*')
1302 i++;
1304 name = malloc(last-i+2);
1305 strncpy(name, &s[i+1], last-i);
1306 name[last-i]=0;
1307 strtrim(&name);
1308 return name;
1312 i--;
1314 return NULL;
1317 char * get_returntype(char * pattern, char * funcname)
1319 size_t len;
1320 int c = 0;
1321 char * ret_type;
1322 len = strstr(pattern, funcname) - pattern;
1324 ret_type = malloc(len-c+1);
1325 strncpy(ret_type, pattern+c, len-c);
1326 ret_type[len-c] = 0;
1328 strtrim(&ret_type);
1330 return ret_type;
1333 void get_argument(int num, int max, char * pattern, char ** type, char ** val)
1335 int i = 0;
1336 int _num = num;
1337 while (1) {
1338 if ('(' == pattern[i++]) {
1339 char * start;
1340 int c;
1341 int depth = 0;
1342 int other = 0;
1344 while (_num > 0) {
1345 if (',' == pattern[i])
1346 _num--;
1347 i++;
1350 /* Start of nth argument. */
1351 start = &pattern[i];
1353 //printf("start: %s\n",start);
1355 i = 0;
1356 while (1) {
1357 if (',' == start[i])
1358 break;
1359 else if ('(' == start[i])
1360 depth++;
1361 else if (')' == start[i])
1362 depth--;
1364 if (-1 == depth)
1365 break;
1367 i++;
1370 i--;
1371 //printf("end at %d\n",i);
1373 * Search for the parameter value backwards
1375 c = i;
1376 while (1) {
1377 if (1 == other && (' ' == start[c] || '\t' == start[c] || '\n' == start[c] || '*' == start[c]))
1378 break;
1380 if (' ' != start[c])
1381 other = 1;
1382 c--;
1384 //c++;
1385 //printf("variable at %d\n",c);
1386 *type = malloc(c+2);
1387 strncpy(*type, start, c+1);
1388 (*type)[c+1] = 0;
1389 *val = malloc(i-c+2);
1390 strncpy(*val , start+c+1, i-c);
1391 (*val)[i-c] = 0;
1392 //printf("|%s| |%s|\n",*type,*val);
1394 strtrim(type);
1395 strtrim(val);
1396 return;
1403 * Rewrite a c function to AROS style c function
1405 int rewrite_function(FILE * fdo,
1406 char * pattern,
1407 struct pragma_description * pd,
1408 struct libconf * lc,
1409 FILE * fdefines)
1411 char output[1024];
1412 int i = 0;
1413 char * ret_type;
1414 char * argtype, * argval;
1415 memset(&output[0],0,1024);
1417 printf("must pick ???? from info in: \n%s\n",pattern);
1418 ret_type = get_returntype(pattern,pd->funcname);
1421 if (0xffff != pd->offset) {
1422 fprintf(fdo,
1423 "\nAROS_LH%d(%s, %s,\n",
1424 pd->numargs,
1425 ret_type,
1426 pd->funcname);
1429 while (i < pd->numargs) {
1430 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1431 fprintf(fdo,
1432 " AROS_LHA(%s, %s, %s),\n",
1433 argtype,
1434 argval,
1435 m68k_registers[pd->args[i]]);
1437 free(argtype);
1438 free(argval);
1439 i++;
1442 if (0 != pd->offset) {
1443 fprintf(fdo,
1444 " %s, %s, %d, %s)\n{\n",
1445 lc->libbasetypeptr,
1446 lc->libbase,
1447 pd->offset,
1448 lc->basename);
1449 } else {
1450 fprintf(fdo,
1451 " struct ExecBase *, SysBase, 0, %s)\n{\n",
1452 lc->basename);
1456 * Make the entry in the defines file. Only write
1457 * those functions with offset > 4 (not init,open,close,
1458 * expunge, null)
1460 if (pd->offset > 4) {
1461 fprintf(fdefines, "#ifndef %s\n#define %s(",
1462 pd->funcname,
1463 pd->funcname);
1465 i = 0;
1467 while (i < pd->numargs) {
1468 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1469 fprintf(fdefines,
1470 "%s",
1471 argval);
1472 if (i < pd->numargs-1) {
1473 fprintf(fdefines,",");
1475 free(argtype);
1476 free(argval);
1478 i++;
1481 fprintf(fdefines,") \\\n\tAROS_LC%d(%s,%s, \\\n",
1482 pd->numargs,
1483 ret_type,
1484 pd->funcname);
1486 i = 0;
1487 while (i < pd->numargs) {
1488 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1489 fprintf(fdefines,
1490 "\tAROS_LCA(%s,%s,%s),\\\n",
1491 argtype,
1492 argval,
1493 m68k_registers[pd->args[i]]);
1494 free(argtype);
1495 free(argval);
1497 i++;
1500 fprintf(fdefines,
1501 "\t%s, %s, %d, %s)\n#endif\n\n",
1502 lc->libbasetypeptr,
1503 lc->libbase,
1504 pd->offset,
1505 lc->basename);
1507 free(ret_type);
1509 } else {
1510 fprintf(fdo,
1511 "\nAROS_UFH%d(%s, %s",
1512 pd->numargs,
1513 ret_type,
1514 pd->funcname);
1517 while (i < pd->numargs) {
1518 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1519 strtrim(&argtype);
1520 strtrim(&argval);
1522 fprintf(fdo,
1523 ",\n AROS_UFHA(%s, %s, %s)",
1524 argtype,
1525 argval,
1526 m68k_registers[pd->args[i]]);
1528 free(argtype);
1529 free(argval);
1530 i++;
1532 fprintf(fdo,")\n{\n");
1534 return 0;
1538 * Rewrite a whole c source code file according to the info provided
1539 * from a pragma file.
1541 int rewritecfile(FILE * fdi,
1542 FILE * fdo,
1543 struct pragma_description * pd,
1544 struct libconf * lc,
1545 FILE * fdefines)
1547 char * line;
1548 int depth = 0; // counting '{' and '}'
1549 char * cache = NULL;
1551 while (1) {
1552 line = get_line(fdi);
1553 if (NULL == line) {
1554 cache = addtocache(cache, NULL, 0, fdo);
1555 return 0;
1558 if (0 == depth) {
1559 depth = countchars(line,'{');
1560 if (0 != depth) {
1561 char * funcname;
1563 * A function begins in this line.
1566 cache = addtocache(cache,line,-1,fdo);
1568 //printf("\ncache where to find function: %s\n",cache);
1569 funcname = getfuncname(cache);
1570 if (funcname != NULL) {
1571 struct pragma_description * _pd;
1572 printf("funcname: %s",funcname);
1573 _pd = find_pragma_description(pd, funcname);
1574 if (_pd) {
1575 printf("-> Rewriting!\n");
1576 rewrite_function(fdo,cache,_pd,lc,fdefines);
1578 * Do not throw the cache into the
1579 * file but clear it
1581 cache = clear_cache(cache);
1582 } else
1583 printf("-> Not rewriting!\n");
1584 free(funcname);
1585 } else {
1586 //printf("ADDING 1\n");
1587 // cache = addtocache(cache,line,-1,fdo);
1590 //printf("ADDING 2\n");
1591 cache = addtocache(cache,NULL,0,fdo);
1592 } else {
1593 char * substr;
1595 * No function begins in this line.
1596 * So let's collect it unless it is
1597 * a comment ot starts with a '#'.
1599 substr = skipstr(line, ' ',1);
1601 if ('#' == substr[0] ||
1602 NULL != strstr(line,"//") ) {
1603 cache = addtocache(cache,line,-1,fdo);
1604 cache = addtocache(cache,NULL,0,fdo);
1605 //printf("cache: %p\n",cache);
1606 //fprintf(fdo,"%s\n",line);
1607 } else {
1608 cache = addtocache(cache,line,-1,fdo);
1611 depth -= countchars(line,'}');
1612 } else {
1613 depth += countchars(line,'{');
1614 depth -= countchars(line,'}');
1615 fprintf(fdo,"%s\n",line);
1617 free(line);
1620 return 0;
1623 FILE * create_definesfile(char * filename)
1625 FILE * fdo = fopen(filename, "r");
1628 * If file existed position at end.
1630 if (fdo) {
1631 fclose(fdo);
1632 fdo = fopen(filename, "a+");
1633 return fdo;
1637 * File does not exist, so start it, if possible.
1639 fdo = fopen(filename, "w");
1640 if (NULL != fdo) {
1641 fprintf(fdo, "#include <aros/libcall.h>\n"
1642 "#include <exec/types.h>\n\n");
1646 return fdo;
1650 * Generate AROS source code for a library from the description
1651 * in a pragmas file.
1653 int genarossource(int argc, char **argv)
1655 FILE *fdo =NULL;
1656 FILE *fdi =NULL;
1657 FILE *fdefines = NULL;
1658 char * filename;
1659 char * sourcefile, * destfile;
1660 char * definesfile;
1661 struct libconf *lc;
1662 struct pragma_description * pd;
1665 if (argc !=5) {
1666 fprintf(stderr,"Usage: %s <source pragma file> <source c file> <dest c file> <output defines file>\n", argv[0]);
1667 exit(-1);
1670 if(!(lc = parse_libconf(NULL)) )
1672 return(-1);
1674 filename = malloc( (strlen(argv[1])+strlen(lc->libname)+20) * sizeof(char) );
1675 sprintf( filename, "%s", argv[1]);
1677 sourcefile = argv[2];
1678 destfile = argv[3];
1679 definesfile = argv[4];
1681 pd = parse_pragmas(filename);
1683 if (NULL == pd) {
1684 fprintf(stderr, "Could not read in the pragmas!\n");
1685 exit(-1);
1689 * Now open and parse the C input file and generate an output.
1691 fdi = fopen(sourcefile, "r");
1692 fdo = fopen(destfile, "w");
1693 fdefines = create_definesfile(definesfile);
1695 if (NULL != fdi && NULL != fdo && NULL != fdefines)
1696 rewritecfile(fdi,fdo,pd,lc,fdefines);
1698 if (NULL != fdi)
1699 fclose(fdi);
1700 if (NULL != fdo)
1701 fclose(fdo);
1702 if (NULL != fdefines)
1703 fclose(fdefines);
1705 free_pragma_description(pd);
1707 free(lc);
1708 free(filename);
1709 return 0;
1713 int main(int argc, char **argv)
1715 int retval = 0;
1716 char option;
1718 if( argc < 2 )
1720 fprintf( stderr, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv[0] );
1721 fprintf( stderr, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );
1722 exit(-1);
1725 if( argv[1][0] == '-' )
1727 argc--;
1728 option = argv[1][1];
1729 argv[1] = malloc( (strlen(argv[0])+4) * sizeof(char) );
1730 sprintf( argv[1], "%s -%c", argv[0], option );
1731 switch( option )
1733 case 'R':
1734 retval = genarossource(argc, &argv[1]);
1735 break;
1736 case 't':
1737 retval = genfunctable( argc, &argv[1] );
1738 break;
1739 case 'c':
1740 retval = genlibdefs( argc, &argv[1] );
1741 break;
1742 case 'h':
1743 default:
1744 fprintf( stdout, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv[0] );
1745 fprintf( stdout, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );
1746 break;
1750 return retval;