2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
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 !
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
);
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
)
65 count
= fread(&buffer
,1,1,fd
);
67 } while(count
!=0 && buffer
!='\n');
68 if(len
==0 && count
==0)
70 fseek( fd
, -len
, SEEK_CUR
);
71 line
= malloc( (len
+1) * sizeof(char) );
72 fread (line
,1,len
,fd
);
75 while(isspace(line
[len
])&& len
>=0)
84 char *keyword(char *line
)
92 while(line
[len
] && !isspace(line
[len
]))
94 key
= malloc( len
* sizeof(char) );
95 strncpy( key
, &line
[1], len
-1 );
104 int get_words(char *line
, char ***outarray
)
112 fprintf( stderr
, "Passed invalid NULL pointer to get_words()!\n" );
130 while( *word
&& isspace(*word
) )
133 while( word
[len
] && !isspace(word
[len
]) )
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;
153 void strlower(char *string
)
157 *string
= tolower(*string
);
162 int filesdiffer( char *file1
, char *file2
)
166 char buffer1
[1], buffer2
[1];
169 fd1
= fopen(file1
,"rb");
172 fd2
= fopen(file2
,"rb");
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
)
189 void moveifchanged(char *old
, char *new)
191 struct stat
*statold
, *statnew
;
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 */
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 );
208 bakname
= malloc( (strlen(old
)+5) * sizeof(char) );
209 sprintf( bakname
, "%s.bak", old
);
210 if(statold
->st_size
!= statnew
->st_size
)
215 else if( filesdiffer(old
,new) )
253 char *libbasetypeptr
;
254 int version
, revision
;
262 struct libconf
* parse_libconf(char *file
)
268 struct libconf
* lc
= calloc (1, sizeof (struct libconf
));
270 fd
= fopen((file
?file
:"lib.conf"),"rb");
273 fprintf( stderr
, "Couldn't open %s!\n", (file
?file
:"lib.conf") );
276 while( (line
= get_line(fd
)) )
278 num
= get_words(line
,&words
);
281 if( strcmp(words
[0],"name")==0 )
284 len
= strlen(words
[1]);
285 lc
->libname
= strdup(words
[1]);
287 else if( strcmp(words
[0],"libname")==0 )
290 lc
->libname
= strdup(words
[1]);
292 else if( strcmp(words
[0],"basename")==0 )
294 len
= strlen(words
[1]);
296 lc
->basename
= strdup(words
[1]);
298 else if( strcmp(words
[0],"libbase")==0 )
300 len
= strlen(words
[1]);
302 lc
->libbase
= strdup(words
[1]);
304 else if( strcmp(words
[0],"libbasetype")==0 )
307 for( i
=1 ; i
<num
; i
++ )
308 len
+= strlen(words
[i
]);
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 )
322 for( i
=1 ; i
<num
; i
++ )
323 len
+= strlen(words
[i
]);
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 )
337 while( words
[1][i
] && words
[1][i
]!='.' )
339 lc
->revision
= (words
[1][i
]==0?0:atoi(&words
[1][i
+1]));
347 lc
->version
= atoi(words
[1]);
350 else if( strcmp(words
[0],"copyright")==0 )
353 while( *word
&& isspace(*word
) )
356 lc
->copyright
= strdup(word
);
358 else if( strcmp(words
[0],"define")==0 )
361 lc
->define
= strdup(words
[1]);
363 else if( strcmp(words
[0],"type")==0 )
365 if( strcmp(words
[1],"device")==0 )
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 )
373 else if( strcmp(words
[1],"gadget")==0 )
375 else if( strcmp(words
[1],"image")==0 )
377 else if( strcmp(words
[1],"class")==0 )
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 )
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
;
404 if( lc
->libname
== NULL
)
406 fprintf( stderr
, "Missing field \"name\" in lib.conf!\n" );
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" );
433 lc
->type
= t_library
;
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:
448 # libbasetype XxxBase
449 # libbasetypeptr XxxBase *
451 # Variables will only be changed if they have not yet been
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
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
483 # rom - For ROM based libraries. Implies noexpunge and
485 # unique - Generate unique names for all external
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
496 int genlibdefs(int argc
, char **argv
)
500 char *date
, *filename
, *conffile
;
505 filename
= "libdefs.h";
506 conffile
= "lib.conf";
507 for (i
=2; i
<=argc
; i
++)
509 if (strcmp(argv
[i
-1],"-o")==0)
515 conffile
= argv
[i
-1];
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");
524 fprintf( stderr
, "Couldn't open file %s!\n", "libdefs.h.new" );
527 if(!(lc
= parse_libconf(conffile
)) )
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
);
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
);
620 void emit(FILE *out
, struct libconf
*lc
, char **names
, int number
)
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,1) (void);\n" );
643 fprintf( out
, "extern void AROS_SLIB_ENTRY(close,BASENAME,2) (void);\n" );
644 fprintf( out
, "extern void AROS_SLIB_ENTRY(expunge,BASENAME,3) (void);\n" );
645 fprintf( out
, "extern void AROS_SLIB_ENTRY(null,BASENAME,0) (void);\n" );
649 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader,1) (void);\n" );
650 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader,2) (void);\n" );
651 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader,3) (void);\n" );
652 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader,4) (void);\n" );
654 for( i
= 0 ; i
< number
-4 ; i
++ )
657 fprintf( out
, "extern void AROS_SLIB_ENTRY(%s,BASENAME,%d) (void);\n", names
[i
], i
+5 );
659 fprintf( out
, "\nvoid *const LIBFUNCTABLE[]=\n{\n" );
660 if(lc
->option
& o_nolibheader
)
662 fprintf( out
, " AROS_SLIB_ENTRY(open, BASENAME, 1),\n" );
663 fprintf( out
, " AROS_SLIB_ENTRY(close, BASENAME, 2),\n" );
664 fprintf( out
, " AROS_SLIB_ENTRY(expunge, BASENAME, 3),\n" );
665 fprintf( out
, " AROS_SLIB_ENTRY(null, BASENAME, 0),\n" );
669 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader,1),\n" );
670 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader,2),\n" );
671 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader,3),\n" );
672 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader,4),\n" );
674 for( i
= 0 ; i
< number
-4 ; i
++ )
677 fprintf( out
, " AROS_SLIB_ENTRY(%s,BASENAME,%d), /* %d */\n", names
[i
], i
+5, i
+5 );
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
;
689 char *word
, **words
= NULL
;
690 int in_archive
, in_header
, in_function
, in_autodoc
, in_code
;
692 char *funcname
= NULL
, **funcnames
= NULL
;
694 /* Well, there are already 4 functions (open,close,expunge,null) */
700 /* First check if we have a HIDD which does not have an archive */
701 if(!(lc
=parse_libconf(NULL
)))
704 if (lc
->type
== t_hidd
|| lc
->type
== t_gadget
|| lc
->type
== t_class
|| lc
->type
== t_usbclass
)
711 fd
= fopen(argv
[1],"rb");
714 fprintf( stderr
, "Couldn't open file %s!\n", argv
[1] );
724 fprintf( stderr
, "Usage: %s <archfile>\n", argv
[0] );
728 fdo
= fopen("functable.c.new","w");
731 fprintf( stderr
, "Couldn't open file %s!\n", "functable.c.new" );
742 while( (line
= get_line(fd
)) )
744 word
= keyword(line
);
747 if( strcmp(word
,"Archive")==0 && !in_archive
)
749 else if( strcmp(word
,"/Archive")==0 && in_archive
&& ! in_function
)
751 else if( strcmp(word
,"AutoDoc")==0 && in_function
&& !in_autodoc
&& !in_code
)
753 else if( strcmp(word
,"/AutoDoc")==0 && in_autodoc
)
755 else if( strcmp(word
,"Code")==0 && in_function
&& !in_code
&& !in_autodoc
)
757 else if( strcmp(word
,"/Code")==0 && in_code
)
759 else if( strcmp(word
,"Header")==0 && in_archive
&& !in_function
)
761 else if( strcmp(word
,"/Header")==0 && in_header
)
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]);
769 else if( strcmp(word
,"/Function")==0 && in_function
&& !in_autodoc
&& !in_code
)
771 else if( strcmp(word
,"LibOffset")==0 && in_function
&& !in_autodoc
&& !in_code
)
773 get_words(line
,&words
);
774 num
= atoi(words
[1]);
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
;
790 emit(fdo
,lc
,funcnames
,numfuncs
);
796 moveifchanged("functable.c","functable.c.new");
803 const char * m68k_registers
[] = {
822 struct pragma_description
824 struct pragma_description
*next
;
827 unsigned short offset
;
832 char * skipstr(char * line
, char skipper
,int direction
)
834 while (line
[0] == skipper
) {
840 void free_pragma_description(struct pragma_description
* pd
)
842 struct pragma_description
* _pd
;
851 struct pragma_description
* find_pragma_description(struct pragma_description
* pd
,
855 if (0 == strcmp(pd
->funcname
,
863 struct pragma_description
* parse_pragmas(char * filename
)
867 struct pragma_description
* base_pd
= NULL
;
868 fdi
= fopen(filename
,"r");
871 fprintf(stderr
, "Couldn't open file %s!\n",filename
);
875 while( (line
= get_line(fdi
))) {
877 //printf("%s\n",line);
879 * look for '#', then 'pragma'.
881 substr
= skipstr(line
,' ',1);
883 if (substr
[0] == '#'){
885 substr
= skipstr(substr
, ' ',1);
886 //printf("1. %s\n",substr);
887 if (0 == strncmp(substr
, "pragma",6)) {
889 substr
= skipstr(substr
,' ',1);
890 //printf("2. %s\n",substr);
891 if (!strncmp(substr
, "amicall",7)) {
893 substr
= skipstr(substr
,' ',1);
895 if (substr
[0] == '(') {
896 struct pragma_description
* pd
= calloc(1,sizeof(struct pragma_description
));
898 substr
= skipstr(substr
,' ',1);
905 * Now read the name of the base
908 comma
= strchr(substr
, ',');
909 lastchar
= skipstr(comma
-1,' ',-1);
911 strncpy(&pd
->basename
[0],
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
);
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
);
948 strncpy(&pd
->funcname
[0],
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
) {
962 substr
= skipstr(substr
, ' ',1);
964 if (substr
[0] == 'a' ||
967 } else if (substr
[0] == 'd' ||
970 fprintf(stderr
, "Wrong register (letter) in pragma file!\n");
971 free_pragma_description(base_pd
);
976 if (substr
[1] >= '0' && substr
[1] <= '8') {
977 r
+= substr
[1] - '0';
979 fprintf(stderr
, "Wrong register (number) in pragma file!\n");
980 free_pragma_description(base_pd
);
986 printf("parameter %d goes into %s\n",
990 pd
->args
[pd
->numargs
] = r
;
994 skipstr(substr
, ' ', 1);
1001 } else if (!strncmp(substr
, "libcall",7)) {
1002 struct pragma_description
* pd
= calloc(1,sizeof(struct pragma_description
));
1004 //substr = skipstr(substr,' ',1);
1007 char parameters_s
[20];
1008 char hex
[3]={0,0,0};
1011 * Read in the description of the
1014 sscanf(substr
, "%s %s %s %s",
1019 pd
->offset
= strtol(offset_s
,NULL
,16)/6;
1021 printf("|%s| |%s| %d %s[%zd]\t",
1026 strlen(parameters_s
));
1029 * Process the parameters.
1031 i
= strlen(parameters_s
)-1;
1032 hex
[0] = parameters_s
[i
-1];
1033 hex
[1] = parameters_s
[i
];
1035 pd
->numargs
= strtol(hex
,NULL
,16);
1039 hex
[0] = parameters_s
[i
];
1040 pd
->args
[c
] = strtol(hex
,NULL
,16);
1041 printf("%s ",m68k_registers
[pd
->args
[c
]]);
1050 } else if(!strncmp(substr
, "usrcall",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
1058 substr
= skipstr(substr
,' ',1);
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
);
1076 strncpy(&pd
->funcname
[0],
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
) {
1090 substr
= skipstr(substr
, ' ',1);
1092 if (substr
[0] == 'a' ||
1095 } else if (substr
[0] == 'd' ||
1098 fprintf(stderr
, "Wrong register (letter) in pragma file!\n");
1099 free_pragma_description(base_pd
);
1104 if (substr
[1] >= '0' && substr
[1] <= '8') {
1105 r
+= substr
[1] - '0';
1107 fprintf(stderr
, "Wrong register (number) in pragma file!\n");
1108 free_pragma_description(base_pd
);
1114 printf("parameter %d goes into %s\n",
1118 pd
->args
[pd
->numargs
] = r
;
1122 skipstr(substr
, ' ', 1);
1140 int countchars (char * s
, char c
)
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
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
)
1164 char * newcache
= NULL
;
1167 if (NULL
== newline
) {
1168 if (NULL
!= cache
) {
1169 fprintf(fdo
, "%s\n", cache
);
1176 semic
= strchr(newline
, ';');
1177 endcomment
= strstr(newline
, "*/");
1179 if (NULL
!= semic
|| NULL
!= endcomment
) {
1180 int newlinelen
= strlen(newline
);
1181 int i
= newlinelen
-1;
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;
1195 while (newline
[i
] != ';')
1201 memcpy(tmp
,newline
,i
+1);
1203 fprintf(fdo
, "%s",tmp
);
1204 //printf("2. Flush: |%s|\n",tmp);
1207 if (i
< newlinelen
) {
1208 newcache
= malloc(newlinelen
-i
+1);
1209 memcpy(newcache
, &newline
[i
+1], newlinelen
-i
);
1210 newcache
[newlinelen
-i
] = 0;
1216 * ';' could not be found. Enhance the cache.
1220 cachelen
= strlen(cache
);
1222 cachelen
+= strlen(newline
)+1+1;
1223 newcache
= malloc(cachelen
);
1225 sprintf(newcache
,"%s\n%s",cache
,newline
);
1227 sprintf(newcache
,"%s",newline
);
1228 //printf("cache: %s\tnewcache: %s\n",cache,newcache);
1235 char * clear_cache(char * cache
)
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;
1252 while ((start
< end
) && (
1253 '\t' == (*s
)[start
] ||
1254 '\n' == (*s
)[start
] ||
1255 ' ' == (*s
)[start
])) {
1260 '\t' == (*s
)[end
] ||
1261 '\n' == (*s
)[end
] ||
1262 ' ' == (*s
)[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;
1275 char * getfuncname(char * s
)
1277 int i
= strlen(s
)-1;
1284 else if ('(' == s
[i
]) {
1288 while (i
>= 0 && ' ' == s
[i
])
1295 while (i
> 0 && ' ' != s
[i
] && '\n' != s
[i
])
1304 name
= malloc(last
-i
+2);
1305 strncpy(name
, &s
[i
+1], last
-i
);
1317 char * get_returntype(char * pattern
, char * funcname
)
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;
1333 void get_argument(int num
, int max
, char * pattern
, char ** type
, char ** val
)
1338 if ('(' == pattern
[i
++]) {
1345 if (',' == pattern
[i
])
1350 /* Start of nth argument. */
1351 start
= &pattern
[i
];
1353 //printf("start: %s\n",start);
1357 if (',' == start
[i
])
1359 else if ('(' == start
[i
])
1361 else if (')' == start
[i
])
1371 //printf("end at %d\n",i);
1373 * Search for the parameter value backwards
1377 if (1 == other
&& (' ' == start
[c
] || '\t' == start
[c
] || '\n' == start
[c
] || '*' == start
[c
]))
1380 if (' ' != start
[c
])
1385 //printf("variable at %d\n",c);
1386 *type
= malloc(c
+2);
1387 strncpy(*type
, start
, c
+1);
1389 *val
= malloc(i
-c
+2);
1390 strncpy(*val
, start
+c
+1, i
-c
);
1392 //printf("|%s| |%s|\n",*type,*val);
1403 * Rewrite a c function to AROS style c function
1405 int rewrite_function(FILE * fdo
,
1407 struct pragma_description
* pd
,
1408 struct libconf
* lc
,
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
) {
1423 "\nAROS_LH%d(%s, %s,\n",
1429 while (i
< pd
->numargs
) {
1430 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1432 " AROS_LHA(%s, %s, %s),\n",
1435 m68k_registers
[pd
->args
[i
]]);
1442 if (0 != pd
->offset
) {
1444 " %s, %s, %d, %s)\n{\n",
1451 " struct ExecBase *, SysBase, 0, %s)\n{\n",
1456 * Make the entry in the defines file. Only write
1457 * those functions with offset > 4 (not init,open,close,
1460 if (pd
->offset
> 4) {
1461 fprintf(fdefines
, "#ifndef %s\n#define %s(",
1467 while (i
< pd
->numargs
) {
1468 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1472 if (i
< pd
->numargs
-1) {
1473 fprintf(fdefines
,",");
1481 fprintf(fdefines
,") \\\n\tAROS_LC%d(%s,%s, \\\n",
1487 while (i
< pd
->numargs
) {
1488 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1490 "\tAROS_LCA(%s,%s,%s),\\\n",
1493 m68k_registers
[pd
->args
[i
]]);
1501 "\t%s, %s, %d, %s)\n#endif\n\n",
1511 "\nAROS_UFH%d(%s, %s",
1517 while (i
< pd
->numargs
) {
1518 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1523 ",\n AROS_UFHA(%s, %s, %s)",
1526 m68k_registers
[pd
->args
[i
]]);
1532 fprintf(fdo
,")\n{\n");
1538 * Rewrite a whole c source code file according to the info provided
1539 * from a pragma file.
1541 int rewritecfile(FILE * fdi
,
1543 struct pragma_description
* pd
,
1544 struct libconf
* lc
,
1548 int depth
= 0; // counting '{' and '}'
1549 char * cache
= NULL
;
1552 line
= get_line(fdi
);
1554 cache
= addtocache(cache
, NULL
, 0, fdo
);
1559 depth
= countchars(line
,'{');
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
);
1575 printf("-> Rewriting!\n");
1576 rewrite_function(fdo
,cache
,_pd
,lc
,fdefines
);
1578 * Do not throw the cache into the
1581 cache
= clear_cache(cache
);
1583 printf("-> Not rewriting!\n");
1586 //printf("ADDING 1\n");
1587 // cache = addtocache(cache,line,-1,fdo);
1590 //printf("ADDING 2\n");
1591 cache
= addtocache(cache
,NULL
,0,fdo
);
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);
1608 cache
= addtocache(cache
,line
,-1,fdo
);
1611 depth
-= countchars(line
,'}');
1613 depth
+= countchars(line
,'{');
1614 depth
-= countchars(line
,'}');
1615 fprintf(fdo
,"%s\n",line
);
1623 FILE * create_definesfile(char * filename
)
1625 FILE * fdo
= fopen(filename
, "r");
1628 * If file existed position at end.
1632 fdo
= fopen(filename
, "a+");
1637 * File does not exist, so start it, if possible.
1639 fdo
= fopen(filename
, "w");
1641 fprintf(fdo
, "#include <aros/libcall.h>\n"
1642 "#include <exec/types.h>\n\n");
1650 * Generate AROS source code for a library from the description
1651 * in a pragmas file.
1653 int genarossource(int argc
, char **argv
)
1657 FILE *fdefines
= NULL
;
1659 char * sourcefile
, * destfile
;
1662 struct pragma_description
* pd
;
1666 fprintf(stderr
,"Usage: %s <source pragma file> <source c file> <dest c file> <output defines file>\n", argv
[0]);
1670 if(!(lc
= parse_libconf(NULL
)) )
1674 filename
= malloc( (strlen(argv
[1])+strlen(lc
->libname
)+20) * sizeof(char) );
1675 sprintf( filename
, "%s", argv
[1]);
1677 sourcefile
= argv
[2];
1679 definesfile
= argv
[4];
1681 pd
= parse_pragmas(filename
);
1684 fprintf(stderr
, "Could not read in the pragmas!\n");
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
);
1702 if (NULL
!= fdefines
)
1705 free_pragma_description(pd
);
1713 int main(int argc
, char **argv
)
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" );
1725 if( argv
[1][0] == '-' )
1728 option
= argv
[1][1];
1729 argv
[1] = malloc( (strlen(argv
[0])+4) * sizeof(char) );
1730 sprintf( argv
[1], "%s -%c", argv
[0], option
);
1734 retval
= genarossource(argc
, &argv
[1]);
1737 retval
= genfunctable( argc
, &argv
[1] );
1740 retval
= genlibdefs( argc
, &argv
[1] );
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" );