configure: remove AC_PATH_XTRA macro
[AROS.git] / tools / archtools / archtool.c
blobd28401d412716404e096a47935735fb8fa61ee12
1 /*
2 Copyright © 1995-2015, 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)
172 return -1;
174 fd2 = fopen(file2,"rb");
175 if(!fd2)
177 fclose(fd1);
178 return -2;
182 cnt1 = fread(buffer1,1,1,fd1);
183 cnt2 = fread(buffer2,1,1,fd2);
184 } while( cnt1 && cnt2 && buffer1[0]==buffer2[0] );
185 if( buffer1[0]!=buffer2[0] || cnt1 != cnt2 )
186 retval = 1;
188 fclose(fd1);
189 fclose(fd2);
191 return retval;
194 void moveifchanged(char *old, char *new)
196 struct stat *statold, *statnew;
197 char *bakname;
199 statold = calloc(1, sizeof(struct stat) );
200 statnew = calloc(1, sizeof(struct stat) );
201 if(stat(old,statold))
203 /* Couldn't stat old file -- assume non-existent */
204 rename(new,old);
205 free(statold);
206 free(statnew);
207 return;
209 if(stat(new,statnew))
211 /* Couldn't stat new file -- this shouldn't happen */
212 fprintf( stderr, "Couldn't stat() file %s!\n", new );
213 free(statold);
214 free(statnew);
215 exit(-1);
217 bakname = malloc( (strlen(old)+5) * sizeof(char) );
218 sprintf( bakname, "%s.bak", old );
219 if(statold->st_size != statnew->st_size)
221 rename(old,bakname);
222 rename(new,old);
224 else if( filesdiffer(old,new) )
226 rename(old,bakname);
227 rename(new,old);
229 else
231 remove(new);
233 free(bakname);
234 free(statold);
235 free(statnew);
238 enum libtype
240 t_device = 1,
241 t_library = 2,
242 t_resource = 3,
243 t_hidd = 4,
244 t_gadget = 5,
245 t_image = 6,
246 t_class = 7,
247 t_datatype = 8,
248 t_usbclass = 9
251 enum liboption
253 o_noexpunge = 1,
254 o_rom = 2,
255 o_unique = 4,
256 o_nolibheader = 8,
257 o_hasrt = 16
260 struct libconf
262 char *libname;
263 char *basename;
264 char *libbase;
265 char *libbasetype;
266 char *libbasetypeptr;
267 int version, revision;
268 char *copyright;
269 char *define;
270 int type;
271 int option;
275 struct libconf * parse_libconf(char *file)
277 FILE *fd;
278 int num, len, i;
279 char *line, *word;
280 char **words = NULL;
281 struct libconf * lc;
283 fd = fopen((file?file:"lib.conf"),"rb");
284 if(!fd)
286 fprintf( stderr, "Couldn't open %s!\n", (file?file:"lib.conf") );
287 return NULL;
289 lc = calloc (1, sizeof (struct libconf));
290 while( (line = get_line(fd)) )
292 num = get_words(line,&words);
293 if( num > 1 )
295 if( strcmp(words[0],"name")==0 )
297 strlower(words[1]);
298 len = strlen(words[1]);
299 lc->libname = strdup(words[1]);
301 else if( strcmp(words[0],"libname")==0 )
303 free(lc->libname);
304 lc->libname = strdup(words[1]);
306 else if( strcmp(words[0],"basename")==0 )
308 len = strlen(words[1]);
309 free(lc->basename);
310 lc->basename = strdup(words[1]);
312 else if( strcmp(words[0],"libbase")==0 )
314 len = strlen(words[1]);
315 free(lc->libbase);
316 lc->libbase = strdup(words[1]);
318 else if( strcmp(words[0],"libbasetype")==0 )
320 len = 0;
321 for( i=1 ; i<num ; i++ )
322 len += strlen(words[i]);
323 len += num-1;
324 free(lc->libbasetype);
325 lc->libbasetype = malloc( len * sizeof(char) );
326 strcpy(lc->libbasetype, words[1] );
327 for( i=2 ; i<num ; i++ )
329 strcat( lc->libbasetype, " " );
330 strcat( lc->libbasetype, words[i] );
333 else if( strcmp(words[0],"libbasetypeptr")==0 )
335 len = 0;
336 for( i=1 ; i<num ; i++ )
337 len += strlen(words[i]);
338 len += num-1;
339 free(lc->libbasetypeptr);
340 lc->libbasetypeptr = malloc( len * sizeof(char) );
341 strcpy(lc->libbasetypeptr, words[1]);
342 for( i=2 ; i<num ; i++ )
344 strcat( lc->libbasetypeptr, " " );
345 strcat( lc->libbasetypeptr, words[i] );
348 else if( strcmp(words[0],"version")==0 )
350 i = 0;
351 while( words[1][i] && words[1][i]!='.' )
352 i++;
353 lc->revision = (words[1][i]==0?0:atoi(&words[1][i+1]));
354 if( i==0 )
356 lc->version = 0;
358 else
360 words[1][i] = 0;
361 lc->version = atoi(words[1]);
364 else if( strcmp(words[0],"copyright")==0 )
366 word = &line[9];
367 while( *word && isspace(*word) )
368 word++;
369 free(lc->copyright);
370 lc->copyright = strdup(word);
372 else if( strcmp(words[0],"define")==0 )
374 free(lc->define);
375 lc->define = strdup(words[1]);
377 else if( strcmp(words[0],"type")==0 )
379 if( strcmp(words[1],"device")==0 )
380 lc->type = t_device;
381 else if( strcmp(words[1],"library")==0 )
382 lc->type = t_library;
383 else if( strcmp(words[1],"resource")==0 )
384 lc->type = t_resource;
385 else if( strcmp(words[1],"hidd")==0 )
386 lc->type = t_hidd;
387 else if( strcmp(words[1],"gadget")==0 )
388 lc->type = t_gadget;
389 else if( strcmp(words[1],"image")==0 )
390 lc->type = t_image;
391 else if( strcmp(words[1],"class")==0 )
392 lc->type = t_class;
393 else if( strcmp(words[1],"datatype")==0 )
394 lc->type = t_datatype;
395 else if( strcmp(words[1],"usbclass")==0 )
396 lc->type = t_usbclass;
398 else if( strcmp(words[0],"options")==0 || strcmp(words[0],"option")==0 )
400 for( i=1 ; i<num ; i++ )
402 if( strcmp(words[i],"noexpunge")==0 )
403 lc->option |= o_noexpunge;
404 else if( strcmp(words[i],"rom")==0 )
405 lc->option |= o_rom;
406 else if( strcmp(words[i],"unique")==0 )
407 lc->option |= o_unique;
408 else if( strcmp(words[i],"nolibheader")==0 )
409 lc->option |= o_nolibheader;
410 else if( strcmp(words[i],"hasrt")==0 )
411 lc->option |= o_hasrt;
415 free(line);
417 fclose(fd);
419 if( lc->libname == NULL )
421 fprintf( stderr, "Missing field \"name\" in lib.conf!\n" );
422 return NULL;
424 if( lc->basename == NULL )
426 lc->basename = strdup(lc->libname);
427 lc->basename[0] = toupper(lc->basename[0]);
429 if( lc->libbase == NULL )
431 lc->libbase = malloc( (strlen(lc->basename)+5) * sizeof(char) );
432 sprintf( lc->libbase, "%sBase", lc->basename );
434 if( lc->libbasetype == NULL )
436 lc->libbasetype = malloc( (strlen(lc->libbase)+8) * sizeof(char) );
437 sprintf( lc->libbasetype, "struct %s", lc->libbase );
439 if( lc->libbasetypeptr == NULL )
441 lc->libbasetypeptr = malloc( (strlen(lc->libbasetype)+3) * sizeof(char) );
442 sprintf( lc->libbasetypeptr, "%s *", lc->libbasetype );
445 if( lc->define == NULL )
446 lc->define = strdup( "_LIBDEFS_H" );
447 if( lc->type == 0 )
448 lc->type = t_library;
450 return lc;
455 # Create libdefs.h from a file lib.conf. lib.conf may contain these options:
457 # name <string> - Init the various fields with reasonable defaults. If
458 # <string> is XXX, then this is the result:
460 # libname xxx
461 # basename Xxx
462 # libbase XxxBase
463 # libbasetype XxxBase
464 # libbasetypeptr XxxBase *
466 # Variables will only be changed if they have not yet been
467 # specified.
469 # libname <string> - Set libname to <string>. This is the name of the
470 # library (ie. you can open it with <string>.library).
471 # It will show up in the version string, too.
472 # basename <string> - Set basename to <string>. The basename is used in
473 # the AROS-LHx macros in the location part (last parameter)
474 # and to specify defaults for libbase and libbasetype
475 # in case they have no value yet. If <string> is xXx, then
476 # libbase will become xXxBase and libbasetype will become
477 # xXxBase.
478 # libbase <string> - Defines the name of the library base (ie. SysBase,
479 # DOSBase, IconBase, etc). If libbasetype is not set, then
480 # it is set to <string>, too.
481 # libbasetype <string> - The type of libbase (with struct), ie.
482 # struct ExecBase, struct DosLibrary, struct IconBase, etc).
483 # libbasetypeptr <string> - Type of a pointer to the libbase. (eg.
484 # struct ExecBase *).
485 # version <version>.<revision> - Specifies the version and revision of the
486 # library. 41.0103 means version 41 and revision 103.
487 # copyright <string> - Copyright string.
488 # define <string> - The define to use to protect the resulting file
489 # against double inclusion (ie. #ifndef <string>...)
490 # The default is _LIBDEFS_H.
491 # type <string> - What kind of library is this ? Valid values
492 # for <string> are: device, library, resource and hidd.
493 # option <string>... - Specify an option. Valid values for <string> are:
495 # noexpunge - Once the lib/dev is loaded, it can't be
496 # removed from memory. Be careful with this
497 # option.
498 # rom - For ROM based libraries. Implies noexpunge and
499 # unique.
500 # unique - Generate unique names for all external
501 # symbols.
502 # nolibheader - We don't want to use the LibHeader prefixed
503 # functions in the function table.
504 # hasrt - This library has resource tracking.
506 # You can specify more than one option in a config file and
507 # more than one option per option line. Separate options by
508 # space.
511 int genlibdefs(int argc, char **argv)
513 struct libconf *lc;
514 FILE *fd;
515 char *date, *filename, *conffile;
516 struct tm *tm;
517 time_t t;
518 int i;
520 filename = "libdefs.h";
521 conffile = "lib.conf";
522 for (i=2; i<=argc; i++)
524 if (strcmp(argv[i-1],"-o")==0)
526 filename = argv[i];
527 i++;
529 else
530 conffile = argv[i-1];
532 time(&t);
533 tm = localtime(&t);
534 date = malloc( 11 * sizeof(char) );
535 sprintf( date, "%02d.%02d.%4d", tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900 );
536 fd = fopen(filename,"w");
537 if(!fd)
539 fprintf( stderr, "Couldn't open file %s!\n", "libdefs.h.new" );
540 free(date);
541 return -1;
543 if(!(lc = parse_libconf(conffile)) )
545 fclose(fd);
546 free(date);
547 return(-1);
549 if( lc->copyright == NULL )
551 lc->copyright = strdup("");
553 fprintf( fd, "/* *** Automatic generated file. Do not edit *** */\n\n");
554 fprintf( fd, "#ifndef %s\n#define %s\n", lc->define, lc->define );
556 if (lc->type == t_library)
558 fprintf( fd, "#define NAME_STRING \"%s.library\"\n", lc->libname );
559 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
561 else if (lc->type == t_device)
563 fprintf( fd, "#define NAME_STRING \"%s.device\"\n", lc->libname );
564 fprintf( fd, "#define NT_TYPE NT_DEVICE\n" );
566 else if (lc->type == t_resource)
568 fprintf( fd, "#define NAME_STRING \"%s.resource\"\n", lc->libname );
569 fprintf( fd, "#define NT_TYPE NT_RESOURCE\n" );
571 else if (lc->type == t_hidd)
573 fprintf( fd, "#define NAME_STRING \"%s.hidd\"\n", lc->libname );
574 fprintf( fd, "#define NT_TYPE NT_HIDD\n" );
576 else if (lc->type == t_gadget)
578 fprintf( fd, "#define NAME_STRING \"%s.gadget\"\n", lc->libname );
579 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
581 else if (lc->type == t_image)
583 fprintf( fd, "#define NAME_STRING \"%s.image\"\n", lc->libname );
584 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
586 else if (lc->type == t_class)
588 fprintf( fd, "#define NAME_STRING \"%s.class\"\n", lc->libname );
589 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
591 else if (lc->type == t_datatype)
593 fprintf( fd, "#define NAME_STRING \"%s.datatype\"\n", lc->libname );
594 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
596 else if (lc->type == t_usbclass)
598 fprintf( fd, "#define NAME_STRING \"%s.class\"\n", lc->libname );
599 fprintf( fd, "#define NT_TYPE NT_LIBRARY\n" );
602 if (lc->option & o_rom)
603 lc->option |= o_noexpunge;
605 if (lc->option & o_noexpunge)
606 fprintf( fd, "#define NOEXPUNGE\n" );
607 if (lc->option & o_rom)
608 fprintf( fd, "#define ROMBASED\n" );
609 if (lc->option & o_nolibheader)
610 fprintf( fd, "#define NOLIBHEADER\n" );
612 if (lc->option & o_rom || lc->option & o_unique)
614 fprintf( fd, "#define LC_UNIQUE_PREFIX %s\n", lc->basename );
615 fprintf( fd, "#define LC_BUILDNAME(n) %s ## n\n", lc->basename );
617 else
619 fprintf( fd, "#define LC_BUILDNAME(n) n\n" );
622 fprintf( fd, "#define LIBBASE %s\n", lc->libbase );
623 fprintf( fd, "#define LIBBASETYPE %s\n", lc->libbasetype );
624 fprintf( fd, "#define LIBBASETYPEPTR %s\n", lc->libbasetypeptr );
625 fprintf( fd, "#define VERSION_NUMBER %d\n", lc->version );
626 fprintf( fd, "#define REVISION_NUMBER %d\n", lc->revision );
627 fprintf( fd, "#define BASENAME %s\n", lc->basename );
628 fprintf( fd, "#define BASENAME_STRING \"%s\"\n", lc->basename );
629 fprintf( fd, "#define VERSION_STRING \"$VER: %s %d.%d (%s)\\r\\n\"\n", lc->libname, lc->version, lc->revision , date );
630 fprintf( fd, "#define LIBEND %s_end\n", lc->basename );
631 fprintf( fd, "#define LIBFUNCTABLE %s_functable\n", lc->basename );
632 fprintf( fd, "#define COPYRIGHT_STRING \"%s\"\n", lc->copyright );
633 fprintf( fd, "#endif /* %s */\n", lc->define );
635 free(date);
636 fclose(fd);
638 return 0;
641 void emit(FILE *out, struct libconf *lc, char **names, int number)
643 int i;
645 fprintf( out, "/*\n" );
646 fprintf( out, " Copyright %c 1995-2015, The AROS Development Team. All rights reserved.\n", 0xa9 );
647 fprintf( out, " *** Automatic generated file. Do not edit ***\n" );
648 fprintf( out, " Desc: Function table for %s\n", lc->basename );
649 fprintf( out, " Lang: english\n" );
650 fprintf( out, "*/\n" );
651 fprintf( out, "#ifndef LIBCORE_COMPILER_H\n" );
652 fprintf( out, "# include <libcore/compiler.h>\n" );
653 fprintf( out, "#endif\n" );
654 fprintf( out, "#ifndef NULL\n" );
655 fprintf( out, "#define NULL ((void *)0)\n" );
656 fprintf( out, "#endif\n\n" );
657 fprintf( out, "#ifndef LC_LIBDEFS_FILE\n" );
658 fprintf( out, "#define LC_LIBDEFS_FILE \"libdefs.h\"\n" );
659 fprintf( out, "#endif\n" );
660 fprintf( out, "#include LC_LIBDEFS_FILE\n" );
661 if(lc->option & o_nolibheader)
663 fprintf( out, "extern void AROS_SLIB_ENTRY(open,BASENAME,1) (void);\n" );
664 fprintf( out, "extern void AROS_SLIB_ENTRY(close,BASENAME,2) (void);\n" );
665 fprintf( out, "extern void AROS_SLIB_ENTRY(expunge,BASENAME,3) (void);\n" );
666 fprintf( out, "extern void AROS_SLIB_ENTRY(null,BASENAME,0) (void);\n" );
668 else
670 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader,1) (void);\n" );
671 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader,2) (void);\n" );
672 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader,3) (void);\n" );
673 fprintf( out, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader,4) (void);\n" );
675 for( i = 0 ; i < number-4 ; i++ )
677 if(names[i])
678 fprintf( out, "extern void AROS_SLIB_ENTRY(%s,BASENAME,%d) (void);\n", names[i], i+5 );
680 fprintf( out, "\nvoid *const LIBFUNCTABLE[]=\n{\n" );
681 if(lc->option & o_nolibheader)
683 fprintf( out, " AROS_SLIB_ENTRY(open, BASENAME, 1),\n" );
684 fprintf( out, " AROS_SLIB_ENTRY(close, BASENAME, 2),\n" );
685 fprintf( out, " AROS_SLIB_ENTRY(expunge, BASENAME, 3),\n" );
686 fprintf( out, " AROS_SLIB_ENTRY(null, BASENAME, 0),\n" );
688 else
690 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader,1),\n" );
691 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader,2),\n" );
692 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader,3),\n" );
693 fprintf( out, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader,4),\n" );
695 for( i = 0 ; i < number-4 ; i++ )
697 if(names[i])
698 fprintf( out, " AROS_SLIB_ENTRY(%s,BASENAME,%d), /* %d */\n", names[i], i+5, i+5 );
699 else
700 fprintf( out, " NULL, /* %d */\n", i+5 );
702 fprintf( out, " (void *)-1L\n};\n" );
705 int genfunctable(int argc, char **argv)
707 FILE *fd = NULL, *fdo;
708 struct libconf *lc;
709 char *line = 0;
710 char *word, **words = NULL;
711 int in_archive, in_header, in_function, in_autodoc, in_code;
712 int num;
713 char *funcname = NULL, **funcnames = NULL;
715 /* Well, there are already 4 functions (open,close,expunge,null) */
716 int numfuncs = 4;
718 int has_arch = 1;
721 /* First check if we have a HIDD which does not have an archive */
722 if(!(lc=parse_libconf(NULL)))
723 return(-1);
725 if (lc->type == t_hidd || lc->type == t_gadget || lc->type == t_class || lc->type == t_usbclass)
726 has_arch = 0;
728 if(has_arch)
730 if(argc == 2)
732 fd = fopen(argv[1],"rb");
733 if(!fd)
735 fprintf( stderr, "Couldn't open file %s!\n", argv[1] );
736 exit(-1);
739 else if (argc == 1)
741 has_arch = 0;
743 else
745 fprintf( stderr, "Usage: %s <archfile>\n", argv[0] );
746 exit(-1);
749 fdo = fopen("functable.c.new","w");
750 if(!fdo)
752 fprintf( stderr, "Couldn't open file %s!\n", "functable.c.new" );
753 exit(-1);
756 if(has_arch)
758 in_archive = 0;
759 in_function = 0;
760 in_autodoc = 0;
761 in_code = 0;
762 in_header = 0;
763 while( (line = get_line(fd)) )
765 word = keyword(line);
766 if( word )
768 if( strcmp(word,"Archive")==0 && !in_archive )
769 in_archive = 1;
770 else if( strcmp(word,"/Archive")==0 && in_archive && ! in_function )
771 break;
772 else if( strcmp(word,"AutoDoc")==0 && in_function && !in_autodoc && !in_code )
773 in_autodoc = 1;
774 else if( strcmp(word,"/AutoDoc")==0 && in_autodoc )
775 in_autodoc = 0;
776 else if( strcmp(word,"Code")==0 && in_function && !in_code && !in_autodoc )
777 in_code = 1;
778 else if( strcmp(word,"/Code")==0 && in_code )
779 in_code = 0;
780 else if( strcmp(word,"Header")==0 && in_archive && !in_function )
781 in_header = 1;
782 else if( strcmp(word,"/Header")==0 && in_header )
783 in_header = 0;
784 else if( strcmp(word,"Function")==0 && in_archive && !in_function && !in_header )
786 num = get_words(line,&words);
787 funcname = strdup(words[num-1]);
788 in_function = 1;
790 else if( strcmp(word,"/Function")==0 && in_function && !in_autodoc && !in_code )
791 in_function = 0;
792 else if( strcmp(word,"LibOffset")==0 && in_function && !in_autodoc && !in_code )
794 get_words(line,&words);
795 num = atoi(words[1]);
796 if( num>numfuncs )
798 funcnames = realloc( funcnames, (num-4) * sizeof(char *));
799 /* initialize new memory */
800 for( ;numfuncs<num; numfuncs++)
801 funcnames[numfuncs-4] = NULL;
803 funcnames[num-5] = funcname;
806 free(word);
808 free(line);
811 emit(fdo,lc,funcnames,numfuncs);
812 fclose(fdo);
813 if(has_arch)
815 fclose(fd);
817 moveifchanged("functable.c","functable.c.new");
818 free(lc);
820 return 0;
824 const char * m68k_registers[] = {
825 "D0",
826 "D1",
827 "D2",
828 "D3",
829 "D4",
830 "D5",
831 "D6",
832 "D7",
833 "A0",
834 "A1",
835 "A2",
836 "A3",
837 "A4",
838 "A5",
839 "A6",
840 "A7",
843 struct pragma_description
845 struct pragma_description *next;
846 char basename[200];
847 char funcname[200];
848 unsigned short offset;
849 int numargs;
850 int args[16];
853 char * skipstr(char * line, char skipper,int direction)
855 while (line[0] == skipper) {
856 line += direction;
858 return line;
861 void free_pragma_description(struct pragma_description * pd)
863 struct pragma_description * _pd;
864 while (pd != NULL) {
865 _pd = pd -> next;
866 free(pd);
867 pd = _pd;
872 struct pragma_description * find_pragma_description(struct pragma_description * pd,
873 char * funcname)
875 while (NULL != pd) {
876 if (0 == strcmp(pd->funcname,
877 funcname))
878 return pd;
879 pd = pd->next;
881 return NULL;
884 struct pragma_description * parse_pragmas(char * filename)
886 FILE *fdi =NULL;
887 char *line;
888 struct pragma_description * base_pd = NULL;
889 fdi = fopen(filename,"r");
891 if (!fdi){
892 fprintf(stderr, "Couldn't open file %s!\n",filename);
893 return NULL;
896 while( (line = get_line(fdi))) {
897 char * substr;
898 //printf("%s\n",line);
900 * look for '#', then 'pragma'.
902 substr = skipstr(line,' ',1);
904 if (substr[0] == '#'){
905 substr++;
906 substr = skipstr(substr, ' ',1);
907 //printf("1. %s\n",substr);
908 if (0 == strncmp(substr, "pragma",6)) {
909 substr += 6;
910 substr = skipstr(substr,' ',1);
911 //printf("2. %s\n",substr);
912 if (!strncmp(substr, "amicall",7)) {
913 substr += 7;
914 substr = skipstr(substr,' ',1);
916 if (substr[0] == '(') {
917 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
918 substr += 1;
919 substr = skipstr(substr,' ',1);
920 if (NULL != pd) {
921 char * comma;
922 char * lastchar;
923 pd->next = base_pd;
924 base_pd = pd;
926 * Now read the name of the base
927 * of the library!
929 comma = strchr(substr, ',');
930 lastchar = skipstr(comma-1,' ',-1);
932 strncpy(&pd->basename[0],
933 substr,
934 lastchar-substr+1);
935 //printf("basename: %s\n",pd->basename);
938 * after the comma comes the offset in HEX!
940 pd->offset = strtol(comma+1,&lastchar,16)/6;
941 //printf("Offset : %x\n",pd->offset);
944 * Now for the next ','
946 comma = strchr(lastchar, ',');
947 comma = skipstr(comma+1,' ',1);
948 //printf("%s\n",comma);
950 if ( NULL == comma) {
951 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
952 free_pragma_description(base_pd);
953 fclose(fdi);
954 exit(-1);
958 * Now the name of the function
960 lastchar = strchr(comma+1, '(');
961 if ( NULL == lastchar) {
962 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
963 free_pragma_description(base_pd);
964 fclose(fdi);
965 exit(-1);
969 strncpy(&pd->funcname[0],
970 comma,
971 skipstr(lastchar,' ',-1)-comma);
972 //printf("funcname: %s\n",pd->funcname);
974 substr = lastchar + 1;
975 //printf("%s\n",substr);
976 lastchar = strchr(substr,')');
978 * Now read the CPU registers.
981 while (substr < lastchar) {
982 int r = 0;
983 substr = skipstr(substr, ' ',1);
985 if (substr[0] == 'a' ||
986 substr[0] == 'A') {
987 r = 8;
988 } else if (substr[0] == 'd' ||
989 substr[0] == 'D') {
990 } else {
991 fprintf(stderr, "Wrong register (letter) in pragma file!\n");
992 free_pragma_description(base_pd);
993 fclose(fdi);
994 exit(-1);
997 if (substr[1] >= '0' && substr[1] <= '8') {
998 r += substr[1] - '0';
999 } else {
1000 fprintf(stderr, "Wrong register (number) in pragma file!\n");
1001 free_pragma_description(base_pd);
1002 fclose(fdi);
1003 exit(-1);
1006 printf("r:%d\n",r);
1007 printf("parameter %d goes into %s\n",
1008 pd->numargs+1,
1009 m68k_registers[r]);
1011 pd->args[pd->numargs] = r;
1012 pd->numargs++;
1014 substr+=2;
1015 skipstr(substr, ' ', 1);
1016 substr+=1;
1022 } else if (!strncmp(substr, "libcall",7)) {
1023 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
1024 substr += 7;
1025 //substr = skipstr(substr,' ',1);
1026 if (NULL != pd) {
1027 char offset_s[10];
1028 char parameters_s[20];
1029 char hex[3]={0,0,0};
1030 int i,c;
1032 * Read in the description of the
1033 * function
1035 sscanf(substr, "%s %s %s %s",
1036 &pd->basename[0],
1037 &pd->funcname[0],
1038 offset_s,
1039 parameters_s);
1040 pd->offset = strtol(offset_s,NULL,16)/6;
1041 #if 1
1042 printf("|%s| |%s| %d %s[%zd]\t",
1043 pd->basename,
1044 pd->funcname,
1045 pd->offset,
1046 parameters_s,
1047 strlen(parameters_s));
1048 #endif
1050 * Process the parameters.
1052 i = strlen(parameters_s)-1;
1053 hex[0] = parameters_s[i-1];
1054 hex[1] = parameters_s[i];
1055 i -= 2;
1056 pd->numargs = strtol(hex,NULL,16);
1057 c = 0;
1058 hex[1] = 0;
1059 while (i >= 0) {
1060 hex[0] = parameters_s[i];
1061 pd->args[c] = strtol(hex,NULL,16);
1062 printf("%s ",m68k_registers[pd->args[c]]);
1063 i--;
1064 c++;
1066 printf("\n");
1068 pd->next = base_pd;
1069 base_pd = pd;
1071 } else if(!strncmp(substr, "usrcall",7)) {
1072 substr += 7;
1073 substr = skipstr(substr,' ',1);
1075 if (substr[0] == '(') {
1076 struct pragma_description * pd = calloc(1,sizeof(struct pragma_description));
1077 substr += 1;
1078 substr = skipstr(substr,' ',1);
1079 if (NULL != pd) {
1080 char * lastchar;
1081 pd->offset = 0xffff; // sign for user function
1082 pd->next = base_pd;
1083 base_pd = pd;
1085 * Now the name of the function
1087 printf("%s\n",substr);
1088 lastchar = strchr(substr+1, '(');
1089 if ( NULL == lastchar) {
1090 fprintf(stderr, "%d: Error parsing pragma file!\n",__LINE__);
1091 free_pragma_description(base_pd);
1092 fclose(fdi);
1093 exit(-1);
1097 strncpy(&pd->funcname[0],
1098 substr,
1099 skipstr(lastchar,' ',-1)-substr);
1100 //printf("funcname: %s\n",pd->funcname);
1102 substr = lastchar + 1;
1103 //printf("%s\n",substr);
1104 lastchar = strchr(substr,')');
1106 * Now read the CPU registers.
1109 while (substr < lastchar) {
1110 int r = 0;
1111 substr = skipstr(substr, ' ',1);
1113 if (substr[0] == 'a' ||
1114 substr[0] == 'A') {
1115 r = 8;
1116 } else if (substr[0] == 'd' ||
1117 substr[0] == 'D') {
1118 } else {
1119 fprintf(stderr, "Wrong register (letter) in pragma file!\n");
1120 free_pragma_description(base_pd);
1121 fclose(fdi);
1122 exit(-1);
1125 if (substr[1] >= '0' && substr[1] <= '8') {
1126 r += substr[1] - '0';
1127 } else {
1128 fprintf(stderr, "Wrong register (number) in pragma file!\n");
1129 free_pragma_description(base_pd);
1130 fclose(fdi);
1131 exit(-1);
1134 printf("r:%d\n",r);
1135 printf("parameter %d goes into %s\n",
1136 pd->numargs+1,
1137 m68k_registers[r]);
1139 pd->args[pd->numargs] = r;
1140 pd->numargs++;
1142 substr+=2;
1143 skipstr(substr, ' ', 1);
1144 substr+=1;
1152 free(line);
1156 fclose(fdi);
1157 return base_pd;
1161 int countchars (char * s, char c)
1163 int ctr = 0;
1164 while (s[0] != 0) {
1165 if (s[0] == c)
1166 ctr++;
1167 s++;
1169 return ctr;
1173 * Add a line to the cache. If NULL is added the old cache
1174 * is flushed to the disk.
1175 * If a line is added everything that ended with a ';' up
1176 * to that point will be written into the file and the
1177 * cache will be cut down to everything that was not written
1178 * so far.
1179 * If a 'end-of-comment' is added also everything is flushed to output.
1181 char * addtocache(char * cache, char * newline, int len, FILE * fdo)
1183 int cachelen;
1184 char * semic;
1185 char * newcache = NULL;
1186 char * endcomment;
1188 if (NULL == newline) {
1189 if (NULL != cache) {
1190 fprintf(fdo, "%s\n", cache);
1191 free(cache);
1193 return NULL;
1197 semic = strchr(newline, ';');
1198 endcomment = strstr(newline, "*/");
1200 if (NULL != semic || NULL != endcomment) {
1201 int newlinelen = strlen(newline);
1202 int i = newlinelen -1;
1203 char * tmp;
1205 * write the cache and everything up to the
1206 * last ';' in the new line to the file.
1208 if (NULL != cache) {
1209 fprintf(fdo,"%s\n",cache);
1210 //printf("1. Flush: |%s|\n",cache);
1213 if (NULL != endcomment) {
1214 i = endcomment - newline + 1;
1215 } else {
1216 while (newline[i] != ';')
1217 i--;
1221 tmp = malloc(i+2);
1222 memcpy(tmp,newline,i+1);
1223 tmp[i+1] = 0;
1224 fprintf(fdo, "%s",tmp);
1225 //printf("2. Flush: |%s|\n",tmp);
1226 free(tmp);
1228 if (i < newlinelen) {
1229 newcache = malloc(newlinelen-i+1);
1230 memcpy(newcache, &newline[i+1], newlinelen-i);
1231 newcache[newlinelen-i] = 0;
1233 free(cache);
1235 } else {
1237 * ';' could not be found. Enhance the cache.
1239 cachelen = 0;
1240 if (NULL != cache)
1241 cachelen = strlen(cache);
1243 cachelen += strlen(newline)+1+1;
1244 newcache = malloc(cachelen);
1245 if (NULL != cache)
1246 sprintf(newcache,"%s\n%s",cache,newline);
1247 else
1248 sprintf(newcache,"%s",newline);
1249 //printf("cache: %s\tnewcache: %s\n",cache,newcache);
1250 free (cache);
1253 return newcache;
1256 char * clear_cache(char * cache)
1258 free(cache);
1259 return NULL;
1263 * cut out all '\n' '\t' and ' ' at the end and
1264 * beginning of a string
1266 void strtrim(char ** s)
1268 int end = strlen(*s)-1;
1269 int start = 0;
1270 char * newstr;
1271 int end_orig = end;
1273 while ((start < end) && (
1274 '\t' == (*s)[start] ||
1275 '\n' == (*s)[start] ||
1276 ' ' == (*s)[start])) {
1277 start++;
1280 while (end > 0 && (
1281 '\t' == (*s)[end] ||
1282 '\n' == (*s)[end] ||
1283 ' ' == (*s)[end])) {
1284 end--;
1287 if ((end > start) && ((start > 0) || (end_orig != end))) {
1288 newstr = malloc(end-start+2);
1289 strncpy(newstr, (*s)+start, end-start+1);
1290 newstr[end-start+1] = 0;
1291 free(*s);
1292 *s = newstr;
1296 char * getfuncname(char * s)
1298 int i = strlen(s)-1;
1299 int c = 0;
1300 char * name;
1301 int last;
1302 while (i > 0) {
1303 if (')' == s[i])
1304 c++;
1305 else if ('(' == s[i]) {
1306 c--;
1307 if (0 == c) {
1308 i--;
1309 while (i >= 0 && ' ' == s[i])
1310 i--;
1312 if (i == 0)
1313 return NULL;
1315 last = i;
1316 while (i > 0 && ' ' != s[i] && '\n' != s[i])
1317 i--;
1319 if (last == i)
1320 return NULL;
1322 if (s[i+1] == '*')
1323 i++;
1325 name = malloc(last-i+2);
1326 strncpy(name, &s[i+1], last-i);
1327 name[last-i]=0;
1328 strtrim(&name);
1329 return name;
1333 i--;
1335 return NULL;
1338 char * get_returntype(char * pattern, char * funcname)
1340 size_t len;
1341 int c = 0;
1342 char * ret_type;
1343 len = strstr(pattern, funcname) - pattern;
1345 ret_type = malloc(len-c+1);
1346 strncpy(ret_type, pattern+c, len-c);
1347 ret_type[len-c] = 0;
1349 strtrim(&ret_type);
1351 return ret_type;
1354 void get_argument(int num, int max, char * pattern, char ** type, char ** val)
1356 int i = 0;
1357 int _num = num;
1358 while (1) {
1359 if ('(' == pattern[i++]) {
1360 char * start;
1361 int c;
1362 int depth = 0;
1363 int other = 0;
1365 while (_num > 0) {
1366 if (',' == pattern[i])
1367 _num--;
1368 i++;
1371 /* Start of nth argument. */
1372 start = &pattern[i];
1374 //printf("start: %s\n",start);
1376 i = 0;
1377 while (1) {
1378 if (',' == start[i])
1379 break;
1380 else if ('(' == start[i])
1381 depth++;
1382 else if (')' == start[i])
1383 depth--;
1385 if (-1 == depth)
1386 break;
1388 i++;
1391 i--;
1392 //printf("end at %d\n",i);
1394 * Search for the parameter value backwards
1396 c = i;
1397 while (1) {
1398 if (1 == other && (' ' == start[c] || '\t' == start[c] || '\n' == start[c] || '*' == start[c]))
1399 break;
1401 if (' ' != start[c])
1402 other = 1;
1403 c--;
1405 //c++;
1406 //printf("variable at %d\n",c);
1407 *type = malloc(c+2);
1408 strncpy(*type, start, c+1);
1409 (*type)[c+1] = 0;
1410 *val = malloc(i-c+2);
1411 strncpy(*val , start+c+1, i-c);
1412 (*val)[i-c] = 0;
1413 //printf("|%s| |%s|\n",*type,*val);
1415 strtrim(type);
1416 strtrim(val);
1417 return;
1424 * Rewrite a c function to AROS style c function
1426 int rewrite_function(FILE * fdo,
1427 char * pattern,
1428 struct pragma_description * pd,
1429 struct libconf * lc,
1430 FILE * fdefines)
1432 char output[1024];
1433 int i = 0;
1434 char * ret_type;
1435 char * argtype, * argval;
1436 memset(&output[0],0,1024);
1438 printf("must pick ???? from info in: \n%s\n",pattern);
1439 ret_type = get_returntype(pattern,pd->funcname);
1442 if (0xffff != pd->offset) {
1443 fprintf(fdo,
1444 "\nAROS_LH%d(%s, %s,\n",
1445 pd->numargs,
1446 ret_type,
1447 pd->funcname);
1450 while (i < pd->numargs) {
1451 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1452 fprintf(fdo,
1453 " AROS_LHA(%s, %s, %s),\n",
1454 argtype,
1455 argval,
1456 m68k_registers[pd->args[i]]);
1458 free(argtype);
1459 free(argval);
1460 i++;
1463 if (0 != pd->offset) {
1464 fprintf(fdo,
1465 " %s, %s, %d, %s)\n{\n",
1466 lc->libbasetypeptr,
1467 lc->libbase,
1468 pd->offset,
1469 lc->basename);
1470 } else {
1471 fprintf(fdo,
1472 " struct ExecBase *, SysBase, 0, %s)\n{\n",
1473 lc->basename);
1477 * Make the entry in the defines file. Only write
1478 * those functions with offset > 4 (not init,open,close,
1479 * expunge, null)
1481 if (pd->offset > 4) {
1482 fprintf(fdefines, "#ifndef %s\n#define %s(",
1483 pd->funcname,
1484 pd->funcname);
1486 i = 0;
1488 while (i < pd->numargs) {
1489 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1490 fprintf(fdefines,
1491 "%s",
1492 argval);
1493 if (i < pd->numargs-1) {
1494 fprintf(fdefines,",");
1496 free(argtype);
1497 free(argval);
1499 i++;
1502 fprintf(fdefines,") \\\n\tAROS_LC%d(%s,%s, \\\n",
1503 pd->numargs,
1504 ret_type,
1505 pd->funcname);
1507 i = 0;
1508 while (i < pd->numargs) {
1509 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1510 fprintf(fdefines,
1511 "\tAROS_LCA(%s,%s,%s),\\\n",
1512 argtype,
1513 argval,
1514 m68k_registers[pd->args[i]]);
1515 free(argtype);
1516 free(argval);
1518 i++;
1521 fprintf(fdefines,
1522 "\t%s, %s, %d, %s)\n#endif\n\n",
1523 lc->libbasetypeptr,
1524 lc->libbase,
1525 pd->offset,
1526 lc->basename);
1528 free(ret_type);
1530 } else {
1531 fprintf(fdo,
1532 "\nAROS_UFH%d(%s, %s",
1533 pd->numargs,
1534 ret_type,
1535 pd->funcname);
1538 while (i < pd->numargs) {
1539 get_argument(i, pd->numargs,pattern, &argtype, &argval);
1540 strtrim(&argtype);
1541 strtrim(&argval);
1543 fprintf(fdo,
1544 ",\n AROS_UFHA(%s, %s, %s)",
1545 argtype,
1546 argval,
1547 m68k_registers[pd->args[i]]);
1549 free(argtype);
1550 free(argval);
1551 i++;
1553 fprintf(fdo,")\n{\n");
1555 return 0;
1559 * Rewrite a whole c source code file according to the info provided
1560 * from a pragma file.
1562 int rewritecfile(FILE * fdi,
1563 FILE * fdo,
1564 struct pragma_description * pd,
1565 struct libconf * lc,
1566 FILE * fdefines)
1568 char * line;
1569 int depth = 0; // counting '{' and '}'
1570 char * cache = NULL;
1572 while (1) {
1573 line = get_line(fdi);
1574 if (NULL == line) {
1575 cache = addtocache(cache, NULL, 0, fdo);
1576 return 0;
1579 if (0 == depth) {
1580 depth = countchars(line,'{');
1581 if (0 != depth) {
1582 char * funcname;
1584 * A function begins in this line.
1587 cache = addtocache(cache,line,-1,fdo);
1589 //printf("\ncache where to find function: %s\n",cache);
1590 funcname = getfuncname(cache);
1591 if (funcname != NULL) {
1592 struct pragma_description * _pd;
1593 printf("funcname: %s",funcname);
1594 _pd = find_pragma_description(pd, funcname);
1595 if (_pd) {
1596 printf("-> Rewriting!\n");
1597 rewrite_function(fdo,cache,_pd,lc,fdefines);
1599 * Do not throw the cache into the
1600 * file but clear it
1602 cache = clear_cache(cache);
1603 } else
1604 printf("-> Not rewriting!\n");
1605 free(funcname);
1606 } else {
1607 //printf("ADDING 1\n");
1608 // cache = addtocache(cache,line,-1,fdo);
1611 //printf("ADDING 2\n");
1612 cache = addtocache(cache,NULL,0,fdo);
1613 } else {
1614 char * substr;
1616 * No function begins in this line.
1617 * So let's collect it unless it is
1618 * a comment ot starts with a '#'.
1620 substr = skipstr(line, ' ',1);
1622 if ('#' == substr[0] ||
1623 NULL != strstr(line,"//") ) {
1624 cache = addtocache(cache,line,-1,fdo);
1625 cache = addtocache(cache,NULL,0,fdo);
1626 //printf("cache: %p\n",cache);
1627 //fprintf(fdo,"%s\n",line);
1628 } else {
1629 cache = addtocache(cache,line,-1,fdo);
1632 depth -= countchars(line,'}');
1633 } else {
1634 depth += countchars(line,'{');
1635 depth -= countchars(line,'}');
1636 fprintf(fdo,"%s\n",line);
1638 free(line);
1641 return 0;
1644 FILE * create_definesfile(char * filename)
1646 FILE * fdo = fopen(filename, "r");
1649 * If file existed position at end.
1651 if (fdo) {
1652 fclose(fdo);
1653 fdo = fopen(filename, "a+");
1654 return fdo;
1658 * File does not exist, so start it, if possible.
1660 fdo = fopen(filename, "w");
1661 if (NULL != fdo) {
1662 fprintf(fdo, "#include <aros/libcall.h>\n"
1663 "#include <exec/types.h>\n\n");
1667 return fdo;
1671 * Generate AROS source code for a library from the description
1672 * in a pragmas file.
1674 int genarossource(int argc, char **argv)
1676 FILE *fdo =NULL;
1677 FILE *fdi =NULL;
1678 FILE *fdefines = NULL;
1679 char * filename;
1680 char * sourcefile, * destfile;
1681 char * definesfile;
1682 struct libconf *lc;
1683 struct pragma_description * pd;
1686 if (argc !=5) {
1687 fprintf(stderr,"Usage: %s <source pragma file> <source c file> <dest c file> <output defines file>\n", argv[0]);
1688 exit(-1);
1691 if(!(lc = parse_libconf(NULL)) )
1693 return(-1);
1695 filename = malloc( (strlen(argv[1])+strlen(lc->libname)+20) * sizeof(char) );
1696 sprintf( filename, "%s", argv[1]);
1698 sourcefile = argv[2];
1699 destfile = argv[3];
1700 definesfile = argv[4];
1702 pd = parse_pragmas(filename);
1704 if (NULL == pd) {
1705 fprintf(stderr, "Could not read in the pragmas!\n");
1706 exit(-1);
1710 * Now open and parse the C input file and generate an output.
1712 fdi = fopen(sourcefile, "r");
1713 fdo = fopen(destfile, "w");
1714 fdefines = create_definesfile(definesfile);
1716 if (NULL != fdi && NULL != fdo && NULL != fdefines)
1717 rewritecfile(fdi,fdo,pd,lc,fdefines);
1719 if (NULL != fdi)
1720 fclose(fdi);
1721 if (NULL != fdo)
1722 fclose(fdo);
1723 if (NULL != fdefines)
1724 fclose(fdefines);
1726 free_pragma_description(pd);
1728 free(lc);
1729 free(filename);
1730 return 0;
1734 int main(int argc, char **argv)
1736 int retval = 0;
1737 char option;
1739 if( argc < 2 )
1741 fprintf( stderr, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv[0] );
1742 fprintf( stderr, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );
1743 exit(-1);
1746 if( argv[1][0] == '-' )
1748 argc--;
1749 option = argv[1][1];
1750 argv[1] = malloc( (strlen(argv[0])+4) * sizeof(char) );
1751 sprintf( argv[1], "%s -%c", argv[0], option );
1752 switch( option )
1754 case 'R':
1755 retval = genarossource(argc, &argv[1]);
1756 break;
1757 case 't':
1758 retval = genfunctable( argc, &argv[1] );
1759 break;
1760 case 'c':
1761 retval = genlibdefs( argc, &argv[1] );
1762 break;
1763 case 'h':
1764 default:
1765 fprintf( stdout, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv[0] );
1766 fprintf( stdout, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );
1767 break;
1771 return retval;