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) )
252 char *libbasetypeptr
;
253 int version
, revision
;
261 struct libconf
* parse_libconf(char *file
)
267 struct libconf
* lc
= calloc (1, sizeof (struct libconf
));
269 fd
= fopen((file
?file
:"lib.conf"),"rb");
272 fprintf( stderr
, "Couldn't open %s!\n", (file
?file
:"lib.conf") );
275 while( (line
= get_line(fd
)) )
277 num
= get_words(line
,&words
);
280 if( strcmp(words
[0],"name")==0 )
283 len
= strlen(words
[1]);
284 lc
->libname
= strdup(words
[1]);
286 else if( strcmp(words
[0],"libname")==0 )
289 lc
->libname
= strdup(words
[1]);
291 else if( strcmp(words
[0],"basename")==0 )
293 len
= strlen(words
[1]);
295 lc
->basename
= strdup(words
[1]);
297 else if( strcmp(words
[0],"libbase")==0 )
299 len
= strlen(words
[1]);
301 lc
->libbase
= strdup(words
[1]);
303 else if( strcmp(words
[0],"libbasetype")==0 )
306 for( i
=1 ; i
<num
; i
++ )
307 len
+= strlen(words
[i
]);
309 free(lc
->libbasetype
);
310 lc
->libbasetype
= malloc( len
* sizeof(char) );
311 strcpy(lc
->libbasetype
, words
[1] );
312 for( i
=2 ; i
<num
; i
++ )
314 strcat( lc
->libbasetype
, " " );
315 strcat( lc
->libbasetype
, words
[i
] );
318 else if( strcmp(words
[0],"libbasetypeptr")==0 )
321 for( i
=1 ; i
<num
; i
++ )
322 len
+= strlen(words
[i
]);
324 free(lc
->libbasetypeptr
);
325 lc
->libbasetypeptr
= malloc( len
* sizeof(char) );
326 strcpy(lc
->libbasetypeptr
, words
[1]);
327 for( i
=2 ; i
<num
; i
++ )
329 strcat( lc
->libbasetypeptr
, " " );
330 strcat( lc
->libbasetypeptr
, words
[i
] );
333 else if( strcmp(words
[0],"version")==0 )
336 while( words
[1][i
] && words
[1][i
]!='.' )
338 lc
->revision
= (words
[1][i
]==0?0:atoi(&words
[1][i
+1]));
346 lc
->version
= atoi(words
[1]);
349 else if( strcmp(words
[0],"copyright")==0 )
352 while( *word
&& isspace(*word
) )
355 lc
->copyright
= strdup(word
);
357 else if( strcmp(words
[0],"define")==0 )
360 lc
->define
= strdup(words
[1]);
362 else if( strcmp(words
[0],"type")==0 )
364 if( strcmp(words
[1],"device")==0 )
366 else if( strcmp(words
[1],"library")==0 )
367 lc
->type
= t_library
;
368 else if( strcmp(words
[1],"resource")==0 )
369 lc
->type
= t_resource
;
370 else if( strcmp(words
[1],"hidd")==0 )
372 else if( strcmp(words
[1],"gadget")==0 )
374 else if( strcmp(words
[1],"image")==0 )
376 else if( strcmp(words
[1],"class")==0 )
378 else if( strcmp(words
[1],"datatype")==0 )
379 lc
->type
= t_datatype
;
381 else if( strcmp(words
[0],"options")==0 || strcmp(words
[0],"option")==0 )
383 for( i
=1 ; i
<num
; i
++ )
385 if( strcmp(words
[i
],"noexpunge")==0 )
386 lc
->option
|= o_noexpunge
;
387 else if( strcmp(words
[i
],"rom")==0 )
389 else if( strcmp(words
[i
],"unique")==0 )
390 lc
->option
|= o_unique
;
391 else if( strcmp(words
[i
],"nolibheader")==0 )
392 lc
->option
|= o_nolibheader
;
393 else if( strcmp(words
[i
],"hasrt")==0 )
394 lc
->option
|= o_hasrt
;
401 if( lc
->libname
== NULL
)
403 fprintf( stderr
, "Missing field \"name\" in lib.conf!\n" );
406 if( lc
->basename
== NULL
)
408 lc
->basename
= strdup(lc
->libname
);
409 lc
->basename
[0] = toupper(lc
->basename
[0]);
411 if( lc
->libbase
== NULL
)
413 lc
->libbase
= malloc( (strlen(lc
->basename
)+5) * sizeof(char) );
414 sprintf( lc
->libbase
, "%sBase", lc
->basename
);
416 if( lc
->libbasetype
== NULL
)
418 lc
->libbasetype
= malloc( (strlen(lc
->libbase
)+8) * sizeof(char) );
419 sprintf( lc
->libbasetype
, "struct %s", lc
->libbase
);
421 if( lc
->libbasetypeptr
== NULL
)
423 lc
->libbasetypeptr
= malloc( (strlen(lc
->libbasetype
)+3) * sizeof(char) );
424 sprintf( lc
->libbasetypeptr
, "%s *", lc
->libbasetype
);
427 if( lc
->define
== NULL
)
428 lc
->define
= strdup( "_LIBDEFS_H" );
430 lc
->type
= t_library
;
437 # Create libdefs.h from a file lib.conf. lib.conf may contain these options:
439 # name <string> - Init the various fields with reasonable defaults. If
440 # <string> is XXX, then this is the result:
445 # libbasetype XxxBase
446 # libbasetypeptr XxxBase *
448 # Variables will only be changed if they have not yet been
451 # libname <string> - Set libname to <string>. This is the name of the
452 # library (ie. you can open it with <string>.library).
453 # It will show up in the version string, too.
454 # basename <string> - Set basename to <string>. The basename is used in
455 # the AROS-LHx macros in the location part (last parameter)
456 # and to specify defaults for libbase and libbasetype
457 # in case they have no value yet. If <string> is xXx, then
458 # libbase will become xXxBase and libbasetype will become
460 # libbase <string> - Defines the name of the library base (ie. SysBase,
461 # DOSBase, IconBase, etc). If libbasetype is not set, then
462 # it is set to <string>, too.
463 # libbasetype <string> - The type of libbase (with struct), ie.
464 # struct ExecBase, struct DosLibrary, struct IconBase, etc).
465 # libbasetypeptr <string> - Type of a pointer to the libbase. (eg.
466 # struct ExecBase *).
467 # version <version>.<revision> - Specifies the version and revision of the
468 # library. 41.0103 means version 41 and revision 103.
469 # copyright <string> - Copyright string.
470 # define <string> - The define to use to protect the resulting file
471 # against double inclusion (ie. #ifndef <string>...)
472 # The default is _LIBDEFS_H.
473 # type <string> - What kind of library is this ? Valid values
474 # for <string> are: device, library, resource and hidd.
475 # option <string>... - Specify an option. Valid values for <string> are:
477 # noexpunge - Once the lib/dev is loaded, it can't be
478 # removed from memory. Be careful with this
480 # rom - For ROM based libraries. Implies noexpunge and
482 # unique - Generate unique names for all external
484 # nolibheader - We don't want to use the LibHeader prefixed
485 # functions in the function table.
486 # hasrt - This library has resource tracking.
488 # You can specify more than one option in a config file and
489 # more than one option per option line. Separate options by
493 int genlibdefs(int argc
, char **argv
)
497 char *date
, *filename
, *conffile
;
502 filename
= "libdefs.h";
503 conffile
= "lib.conf";
504 for (i
=2; i
<=argc
; i
++)
506 if (strcmp(argv
[i
-1],"-o")==0)
512 conffile
= argv
[i
-1];
516 date
= malloc( 11 * sizeof(char) );
517 sprintf( date
, "%02d.%02d.%4d", tm
->tm_mday
, tm
->tm_mon
+1, tm
->tm_year
+1900 );
518 fd
= fopen(filename
,"w");
521 fprintf( stderr
, "Couldn't open file %s!\n", "libdefs.h.new" );
524 if(!(lc
= parse_libconf(conffile
)) )
526 if( lc
->copyright
== NULL
)
528 lc
->copyright
= strdup("");
530 fprintf( fd
, "/* *** Automatic generated file. Do not edit *** */\n\n");
531 fprintf( fd
, "#ifndef %s\n#define %s\n", lc
->define
, lc
->define
);
533 if (lc
->type
== t_library
)
535 fprintf( fd
, "#define NAME_STRING \"%s.library\"\n", lc
->libname
);
536 fprintf( fd
, "#define NT_TYPE NT_LIBRARY\n" );
538 else if (lc
->type
== t_device
)
540 fprintf( fd
, "#define NAME_STRING \"%s.device\"\n", lc
->libname
);
541 fprintf( fd
, "#define NT_TYPE NT_DEVICE\n" );
543 else if (lc
->type
== t_resource
)
545 fprintf( fd
, "#define NAME_STRING \"%s.resource\"\n", lc
->libname
);
546 fprintf( fd
, "#define NT_TYPE NT_RESOURCE\n" );
548 else if (lc
->type
== t_hidd
)
550 fprintf( fd
, "#define NAME_STRING \"%s.hidd\"\n", lc
->libname
);
551 fprintf( fd
, "#define NT_TYPE NT_HIDD\n" );
553 else if (lc
->type
== t_gadget
)
555 fprintf( fd
, "#define NAME_STRING \"%s.gadget\"\n", lc
->libname
);
556 fprintf( fd
, "#define NT_TYPE NT_LIBRARY\n" );
558 else if (lc
->type
== t_image
)
560 fprintf( fd
, "#define NAME_STRING \"%s.image\"\n", lc
->libname
);
561 fprintf( fd
, "#define NT_TYPE NT_LIBRARY\n" );
563 else if (lc
->type
== t_class
)
565 fprintf( fd
, "#define NAME_STRING \"%s.class\"\n", lc
->libname
);
566 fprintf( fd
, "#define NT_TYPE NT_LIBRARY\n" );
568 else if (lc
->type
== t_datatype
)
570 fprintf( fd
, "#define NAME_STRING \"%s.datatype\"\n", lc
->libname
);
571 fprintf( fd
, "#define NT_TYPE NT_LIBRARY\n" );
574 if (lc
->option
& o_rom
)
575 lc
->option
|= o_noexpunge
;
577 if (lc
->option
& o_noexpunge
)
578 fprintf( fd
, "#define NOEXPUNGE\n" );
579 if (lc
->option
& o_rom
)
580 fprintf( fd
, "#define ROMBASED\n" );
581 if (lc
->option
& o_nolibheader
)
582 fprintf( fd
, "#define NOLIBHEADER\n" );
584 if (lc
->option
& o_rom
|| lc
->option
& o_unique
)
586 fprintf( fd
, "#define LC_UNIQUE_PREFIX %s\n", lc
->basename
);
587 fprintf( fd
, "#define LC_BUILDNAME(n) %s ## n\n", lc
->basename
);
591 fprintf( fd
, "#define LC_BUILDNAME(n) n\n" );
594 fprintf( fd
, "#define LIBBASE %s\n", lc
->libbase
);
595 fprintf( fd
, "#define LIBBASETYPE %s\n", lc
->libbasetype
);
596 fprintf( fd
, "#define LIBBASETYPEPTR %s\n", lc
->libbasetypeptr
);
597 fprintf( fd
, "#define VERSION_NUMBER %d\n", lc
->version
);
598 fprintf( fd
, "#define REVISION_NUMBER %d\n", lc
->revision
);
599 fprintf( fd
, "#define BASENAME %s\n", lc
->basename
);
600 fprintf( fd
, "#define BASENAME_STRING \"%s\"\n", lc
->basename
);
601 fprintf( fd
, "#define VERSION_STRING \"$VER: %s %d.%d (%s)\\r\\n\"\n", lc
->libname
, lc
->version
, lc
->revision
, date
);
602 fprintf( fd
, "#define LIBEND %s_end\n", lc
->basename
);
603 fprintf( fd
, "#define LIBFUNCTABLE %s_functable\n", lc
->basename
);
604 fprintf( fd
, "#define COPYRIGHT_STRING \"%s\"\n", lc
->copyright
);
605 fprintf( fd
, "#endif /* %s */\n", lc
->define
);
612 void emit(FILE *out
, struct libconf
*lc
, char **names
, int number
)
616 fprintf( out
, "/*\n" );
617 fprintf( out
, " Copyright © 1995-1998, The AROS Development Team. All rights reserved.\n" );
618 fprintf( out
, " *** Automatic generated file. Do not edit ***\n" );
619 fprintf( out
, " Desc: Function table for %s\n", lc
->basename
);
620 fprintf( out
, " Lang: english\n" );
621 fprintf( out
, "*/\n" );
622 fprintf( out
, "#ifndef LIBCORE_COMPILER_H\n" );
623 fprintf( out
, "# include <libcore/compiler.h>\n" );
624 fprintf( out
, "#endif\n" );
625 fprintf( out
, "#ifndef NULL\n" );
626 fprintf( out
, "#define NULL ((void *)0)\n" );
627 fprintf( out
, "#endif\n\n" );
628 fprintf( out
, "#ifndef LC_LIBDEFS_FILE\n" );
629 fprintf( out
, "#define LC_LIBDEFS_FILE \"libdefs.h\"\n" );
630 fprintf( out
, "#endif\n" );
631 fprintf( out
, "#include LC_LIBDEFS_FILE\n" );
632 if(lc
->option
& o_nolibheader
)
634 fprintf( out
, "extern void AROS_SLIB_ENTRY(open,BASENAME) (void);\n" );
635 fprintf( out
, "extern void AROS_SLIB_ENTRY(close,BASENAME) (void);\n" );
636 fprintf( out
, "extern void AROS_SLIB_ENTRY(expunge,BASENAME) (void);\n" );
637 fprintf( out
, "extern void AROS_SLIB_ENTRY(null,BASENAME) (void);\n" );
641 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader) (void);\n" );
642 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader) (void);\n" );
643 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader) (void);\n" );
644 fprintf( out
, "extern void AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader) (void);\n" );
646 for( i
= 0 ; i
< number
-4 ; i
++ )
649 fprintf( out
, "extern void AROS_SLIB_ENTRY(%s,BASENAME) (void);\n", names
[i
] );
651 fprintf( out
, "\nvoid *const LIBFUNCTABLE[]=\n{\n" );
652 if(lc
->option
& o_nolibheader
)
654 fprintf( out
, " AROS_SLIB_ENTRY(open, BASENAME),\n" );
655 fprintf( out
, " AROS_SLIB_ENTRY(close, BASENAME),\n" );
656 fprintf( out
, " AROS_SLIB_ENTRY(expunge, BASENAME),\n" );
657 fprintf( out
, " AROS_SLIB_ENTRY(null, BASENAME),\n" );
661 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(OpenLib),LibHeader),\n" );
662 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(CloseLib),LibHeader),\n" );
663 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExpungeLib),LibHeader),\n" );
664 fprintf( out
, " AROS_SLIB_ENTRY(LC_BUILDNAME(ExtFuncLib),LibHeader),\n" );
666 for( i
= 0 ; i
< number
-4 ; i
++ )
669 fprintf( out
, " AROS_SLIB_ENTRY(%s,BASENAME), /* %d */\n", names
[i
], i
+5 );
671 fprintf( out
, " NULL, /* %d */\n", i
+5 );
673 fprintf( out
, " (void *)-1L\n};\n" );
676 int genfunctable(int argc
, char **argv
)
678 FILE *fd
= NULL
, *fdo
;
681 char *word
, **words
= NULL
;
682 int in_archive
, in_header
, in_function
, in_autodoc
, in_code
;
684 char *funcname
= NULL
, **funcnames
= NULL
;
686 /* Well, there are already 4 functions (open,close,expunge,null) */
692 /* First check if we have a HIDD which does not have an archive */
693 if(!(lc
=parse_libconf(NULL
)))
696 if (lc
->type
== t_hidd
|| lc
->type
== t_gadget
|| lc
->type
== t_class
)
703 fd
= fopen(argv
[1],"rb");
706 fprintf( stderr
, "Couldn't open file %s!\n", argv
[1] );
716 fprintf( stderr
, "Usage: %s <archfile>\n", argv
[0] );
720 fdo
= fopen("functable.c.new","w");
723 fprintf( stderr
, "Couldn't open file %s!\n", "functable.c.new" );
734 while( (line
= get_line(fd
)) )
736 word
= keyword(line
);
739 if( strcmp(word
,"Archive")==0 && !in_archive
)
741 else if( strcmp(word
,"/Archive")==0 && in_archive
&& ! in_function
)
743 else if( strcmp(word
,"AutoDoc")==0 && in_function
&& !in_autodoc
&& !in_code
)
745 else if( strcmp(word
,"/AutoDoc")==0 && in_autodoc
)
747 else if( strcmp(word
,"Code")==0 && in_function
&& !in_code
&& !in_autodoc
)
749 else if( strcmp(word
,"/Code")==0 && in_code
)
751 else if( strcmp(word
,"Header")==0 && in_archive
&& !in_function
)
753 else if( strcmp(word
,"/Header")==0 && in_header
)
755 else if( strcmp(word
,"Function")==0 && in_archive
&& !in_function
&& !in_header
)
757 num
= get_words(line
,&words
);
758 funcname
= strdup(words
[num
-1]);
761 else if( strcmp(word
,"/Function")==0 && in_function
&& !in_autodoc
&& !in_code
)
763 else if( strcmp(word
,"LibOffset")==0 && in_function
&& !in_autodoc
&& !in_code
)
765 get_words(line
,&words
);
766 num
= atoi(words
[1]);
769 funcnames
= realloc( funcnames
, (num
-4) * sizeof(char *));
770 /* initialize new memory */
771 for( ;numfuncs
<num
; numfuncs
++)
772 funcnames
[numfuncs
-4] = NULL
;
774 funcnames
[num
-5] = funcname
;
782 emit(fdo
,lc
,funcnames
,numfuncs
);
788 moveifchanged("functable.c","functable.c.new");
795 const char * m68k_registers
[] = {
814 struct pragma_description
816 struct pragma_description
*next
;
819 unsigned short offset
;
824 char * skipstr(char * line
, char skipper
,int direction
)
826 while (line
[0] == skipper
) {
832 void free_pragma_description(struct pragma_description
* pd
)
834 struct pragma_description
* _pd
;
843 struct pragma_description
* find_pragma_description(struct pragma_description
* pd
,
847 if (0 == strcmp(pd
->funcname
,
855 struct pragma_description
* parse_pragmas(char * filename
)
859 struct pragma_description
* base_pd
= NULL
;
860 fdi
= fopen(filename
,"r");
863 fprintf(stderr
, "Couldn't open file %s!\n",filename
);
867 while( (line
= get_line(fdi
))) {
869 //printf("%s\n",line);
871 * look for '#', then 'pragma'.
873 substr
= skipstr(line
,' ',1);
875 if (substr
[0] == '#'){
877 substr
= skipstr(substr
, ' ',1);
878 //printf("1. %s\n",substr);
879 if (0 == strncmp(substr
, "pragma",6)) {
881 substr
= skipstr(substr
,' ',1);
882 //printf("2. %s\n",substr);
883 if (!strncmp(substr
, "amicall",7)) {
885 substr
= skipstr(substr
,' ',1);
887 if (substr
[0] == '(') {
888 struct pragma_description
* pd
= calloc(1,sizeof(struct pragma_description
));
890 substr
= skipstr(substr
,' ',1);
897 * Now read the name of the base
900 comma
= strchr(substr
, ',');
901 lastchar
= skipstr(comma
-1,' ',-1);
903 strncpy(&pd
->basename
[0],
906 //printf("basename: %s\n",pd->basename);
909 * after the comma comes the offset in HEX!
911 pd
->offset
= strtol(comma
+1,&lastchar
,16)/6;
912 //printf("Offset : %x\n",pd->offset);
915 * Now for the next ','
917 comma
= strchr(lastchar
, ',');
918 comma
= skipstr(comma
+1,' ',1);
919 //printf("%s\n",comma);
921 if ( NULL
== comma
) {
922 fprintf(stderr
, "%d: Error parsing pragma file!\n",__LINE__
);
923 free_pragma_description(base_pd
);
929 * Now the name of the function
931 lastchar
= strchr(comma
+1, '(');
932 if ( NULL
== lastchar
) {
933 fprintf(stderr
, "%d: Error parsing pragma file!\n",__LINE__
);
934 free_pragma_description(base_pd
);
940 strncpy(&pd
->funcname
[0],
942 skipstr(lastchar
,' ',-1)-comma
);
943 //printf("funcname: %s\n",pd->funcname);
945 substr
= lastchar
+ 1;
946 //printf("%s\n",substr);
947 lastchar
= strchr(substr
,')');
949 * Now read the CPU registers.
952 while (substr
< lastchar
) {
954 substr
= skipstr(substr
, ' ',1);
956 if (substr
[0] == 'a' ||
959 } else if (substr
[0] == 'd' ||
962 fprintf(stderr
, "Wrong register (letter) in pragma file!\n");
963 free_pragma_description(base_pd
);
968 if (substr
[1] >= '0' && substr
[1] <= '8') {
969 r
+= substr
[1] - '0';
971 fprintf(stderr
, "Wrong register (number) in pragma file!\n");
972 free_pragma_description(base_pd
);
978 printf("parameter %d goes into %s\n",
982 pd
->args
[pd
->numargs
] = r
;
986 skipstr(substr
, ' ', 1);
993 } else if (!strncmp(substr
, "libcall",7)) {
994 struct pragma_description
* pd
= calloc(1,sizeof(struct pragma_description
));
996 //substr = skipstr(substr,' ',1);
999 char parameters_s
[20];
1000 char hex
[3]={0,0,0};
1003 * Read in the description of the
1006 sscanf(substr
, "%s %s %s %s",
1011 pd
->offset
= strtol(offset_s
,NULL
,16)/6;
1013 printf("|%s| |%s| %d %s[%d]\t",
1018 strlen(parameters_s
));
1021 * Process the parameters.
1023 i
= strlen(parameters_s
)-1;
1024 hex
[0] = parameters_s
[i
-1];
1025 hex
[1] = parameters_s
[i
];
1027 pd
->numargs
= strtol(hex
,NULL
,16);
1031 hex
[0] = parameters_s
[i
];
1032 pd
->args
[c
] = strtol(hex
,NULL
,16);
1033 printf("%s ",m68k_registers
[pd
->args
[c
]]);
1042 } else if(!strncmp(substr
, "usrcall",7)) {
1044 substr
= skipstr(substr
,' ',1);
1046 if (substr
[0] == '(') {
1047 struct pragma_description
* pd
= calloc(1,sizeof(struct pragma_description
));
1048 pd
->offset
= 0xffff; // sign for user function
1050 substr
= skipstr(substr
,' ',1);
1056 * Now the name of the function
1058 printf("%s\n",substr
);
1059 lastchar
= strchr(substr
+1, '(');
1060 if ( NULL
== lastchar
) {
1061 fprintf(stderr
, "%d: Error parsing pragma file!\n",__LINE__
);
1062 free_pragma_description(base_pd
);
1068 strncpy(&pd
->funcname
[0],
1070 skipstr(lastchar
,' ',-1)-substr
);
1071 //printf("funcname: %s\n",pd->funcname);
1073 substr
= lastchar
+ 1;
1074 //printf("%s\n",substr);
1075 lastchar
= strchr(substr
,')');
1077 * Now read the CPU registers.
1080 while (substr
< lastchar
) {
1082 substr
= skipstr(substr
, ' ',1);
1084 if (substr
[0] == 'a' ||
1087 } else if (substr
[0] == 'd' ||
1090 fprintf(stderr
, "Wrong register (letter) in pragma file!\n");
1091 free_pragma_description(base_pd
);
1096 if (substr
[1] >= '0' && substr
[1] <= '8') {
1097 r
+= substr
[1] - '0';
1099 fprintf(stderr
, "Wrong register (number) in pragma file!\n");
1100 free_pragma_description(base_pd
);
1106 printf("parameter %d goes into %s\n",
1110 pd
->args
[pd
->numargs
] = r
;
1114 skipstr(substr
, ' ', 1);
1132 int countchars (char * s
, char c
)
1144 * Add a line to the cache. If NULL is added the old cache
1145 * is flushed to the disk.
1146 * If a line is added everything that ended with a ';' up
1147 * to that point will be written into the file and the
1148 * cache will be cut down to everything that was not written
1150 * If a 'end-of-comment' is added also everything is flushed to output.
1152 char * addtocache(char * cache
, char * newline
, int len
, FILE * fdo
)
1156 char * newcache
= NULL
;
1159 if (NULL
== newline
) {
1160 if (NULL
!= cache
) {
1161 fprintf(fdo
, "%s\n", cache
);
1168 semic
= strchr(newline
, ';');
1169 endcomment
= strstr(newline
, "*/");
1171 if (NULL
!= semic
|| NULL
!= endcomment
) {
1172 int newlinelen
= strlen(newline
);
1173 int i
= newlinelen
-1;
1176 * write the cache and everything up to the
1177 * last ';' in the new line to the file.
1179 if (NULL
!= cache
) {
1180 fprintf(fdo
,"%s\n",cache
);
1181 //printf("1. Flush: |%s|\n",cache);
1184 if (NULL
!= endcomment
) {
1185 i
= endcomment
- newline
+ 1;
1187 while (newline
[i
] != ';')
1193 memcpy(tmp
,newline
,i
+1);
1195 fprintf(fdo
, "%s",tmp
);
1196 //printf("2. Flush: |%s|\n",tmp);
1199 if (i
< newlinelen
) {
1200 newcache
= malloc(newlinelen
-i
+1);
1201 memcpy(newcache
, &newline
[i
+1], newlinelen
-i
);
1202 newcache
[newlinelen
-i
] = 0;
1208 * ';' could not be found. Enhance the cache.
1212 cachelen
= strlen(cache
);
1214 cachelen
+= strlen(newline
)+1+1;
1215 newcache
= malloc(cachelen
);
1217 sprintf(newcache
,"%s\n%s",cache
,newline
);
1219 sprintf(newcache
,"%s",newline
);
1220 //printf("cache: %s\tnewcache: %s\n",cache,newcache);
1227 char * clear_cache(char * cache
)
1234 * cut out all '\n' '\t' and ' ' at the end and
1235 * beginning of a string
1237 void strtrim(char ** s
)
1239 int end
= strlen(*s
)-1;
1244 while ((start
< end
) && (
1245 '\t' == (*s
)[start
] ||
1246 '\n' == (*s
)[start
] ||
1247 ' ' == (*s
)[start
])) {
1252 '\t' == (*s
)[end
] ||
1253 '\n' == (*s
)[end
] ||
1254 ' ' == (*s
)[end
])) {
1258 if ((end
> start
) && ((start
> 0) || (end_orig
!= end
))) {
1259 newstr
= malloc(end
-start
+2);
1260 strncpy(newstr
, (*s
)+start
, end
-start
+1);
1261 newstr
[end
-start
+1] = 0;
1267 char * getfuncname(char * s
)
1269 int i
= strlen(s
)-1;
1276 else if ('(' == s
[i
]) {
1280 while (i
>= 0 && ' ' == s
[i
])
1287 while (i
> 0 && ' ' != s
[i
] && '\n' != s
[i
])
1296 name
= malloc(last
-i
+2);
1297 strncpy(name
, &s
[i
+1], last
-i
);
1309 char * get_returntype(char * pattern
, char * funcname
)
1314 len
= (int)strstr(pattern
, funcname
) - (int)pattern
;
1316 ret_type
= malloc(len
-c
+1);
1317 strncpy(ret_type
, pattern
+c
, len
-c
);
1318 ret_type
[len
-c
] = 0;
1325 void get_argument(int num
, int max
, char * pattern
, char ** type
, char ** val
)
1330 if ('(' == pattern
[i
++]) {
1337 if (',' == pattern
[i
])
1342 /* Start of nth argument. */
1343 start
= &pattern
[i
];
1345 //printf("start: %s\n",start);
1349 if (',' == start
[i
])
1351 else if ('(' == start
[i
])
1353 else if (')' == start
[i
])
1363 //printf("end at %d\n",i);
1365 * Search for the parameter value backwards
1369 if (1 == other
&& (' ' == start
[c
] || '\t' == start
[c
] || '\n' == start
[c
] || '*' == start
[c
]))
1372 if (' ' != start
[c
])
1377 //printf("variable at %d\n",c);
1378 *type
= malloc(c
+2);
1379 strncpy(*type
, start
, c
+1);
1381 *val
= malloc(i
-c
+2);
1382 strncpy(*val
, start
+c
+1, i
-c
);
1384 //printf("|%s| |%s|\n",*type,*val);
1395 * Rewrite a c function to AROS style c function
1397 int rewrite_function(FILE * fdo
,
1399 struct pragma_description
* pd
,
1400 struct libconf
* lc
,
1406 char * argtype
, * argval
;
1407 memset(&output
[0],0,1024);
1409 printf("must pick ???? from info in: \n%s\n",pattern
);
1410 ret_type
= get_returntype(pattern
,pd
->funcname
);
1413 if (0xffff != pd
->offset
) {
1415 "\nAROS_LH%d(%s, %s,\n",
1421 while (i
< pd
->numargs
) {
1422 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1424 " AROS_LHA(%s, %s, %s),\n",
1427 m68k_registers
[pd
->args
[i
]]);
1434 if (0 != pd
->offset
) {
1436 " %s, %s, %d, %s)\n{\n",
1443 " struct ExecBase *, SysBase, 0, %s)\n{\n",
1448 * Make the entry in the defines file. Only write
1449 * those functions with offset > 4 (not init,open,close,
1452 if (pd
->offset
> 4) {
1453 fprintf(fdefines
, "#ifndef %s\n#define %s(",
1459 while (i
< pd
->numargs
) {
1460 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1464 if (i
< pd
->numargs
-1) {
1465 fprintf(fdefines
,",");
1473 fprintf(fdefines
,") \\\n\tAROS_LC%d(%s,%s, \\\n",
1479 while (i
< pd
->numargs
) {
1480 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1482 "\tAROS_LCA(%s,%s,%s),\\\n",
1485 m68k_registers
[pd
->args
[i
]]);
1493 "\t%s, %s, %d, %s)\n#endif\n\n",
1503 "\nAROS_UFH%d(%s, %s",
1509 while (i
< pd
->numargs
) {
1510 get_argument(i
, pd
->numargs
,pattern
, &argtype
, &argval
);
1515 ",\n AROS_UFHA(%s, %s, %s)",
1518 m68k_registers
[pd
->args
[i
]]);
1524 fprintf(fdo
,")\n{\n");
1530 * Rewrite a whole c source code file according to the info provided
1531 * from a pragma file.
1533 int rewritecfile(FILE * fdi
,
1535 struct pragma_description
* pd
,
1536 struct libconf
* lc
,
1540 int depth
= 0; // counting '{' and '}'
1541 char * cache
= NULL
;
1544 line
= get_line(fdi
);
1546 cache
= addtocache(cache
, NULL
, 0, fdo
);
1551 depth
= countchars(line
,'{');
1555 * A function begins in this line.
1558 cache
= addtocache(cache
,line
,-1,fdo
);
1560 //printf("\ncache where to find function: %s\n",cache);
1561 funcname
= getfuncname(cache
);
1562 if (funcname
!= NULL
) {
1563 struct pragma_description
* _pd
;
1564 printf("funcname: %s",funcname
);
1565 _pd
= find_pragma_description(pd
, funcname
);
1567 printf("-> Rewriting!\n");
1568 rewrite_function(fdo
,cache
,_pd
,lc
,fdefines
);
1570 * Do not throw the cache into the
1573 cache
= clear_cache(cache
);
1575 printf("-> Not rewriting!\n");
1578 //printf("ADDING 1\n");
1579 // cache = addtocache(cache,line,-1,fdo);
1582 //printf("ADDING 2\n");
1583 cache
= addtocache(cache
,NULL
,0,fdo
);
1587 * No function begins in this line.
1588 * So let's collect it unless it is
1589 * a comment ot starts with a '#'.
1591 substr
= skipstr(line
, ' ',1);
1593 if ('#' == substr
[0] ||
1594 NULL
!= strstr(line
,"//") ) {
1595 cache
= addtocache(cache
,line
,-1,fdo
);
1596 cache
= addtocache(cache
,NULL
,0,fdo
);
1597 //printf("cache: %p\n",cache);
1598 //fprintf(fdo,"%s\n",line);
1600 cache
= addtocache(cache
,line
,-1,fdo
);
1603 depth
-= countchars(line
,'}');
1605 depth
+= countchars(line
,'{');
1606 depth
-= countchars(line
,'}');
1607 fprintf(fdo
,"%s\n",line
);
1615 FILE * create_definesfile(char * filename
)
1617 FILE * fdo
= fopen(filename
, "r");
1620 * If file existed position at end.
1624 fdo
= fopen(filename
, "a+");
1629 * File does not exist, so start it, if possible.
1631 fdo
= fopen(filename
, "w");
1633 fprintf(fdo
, "#include <aros/libcall.h>\n"
1634 "#include <exec/types.h>\n\n");
1642 * Generate AROS source code for a library from the description
1643 * in a pragmas file.
1645 int genarossource(int argc
, char **argv
)
1649 FILE *fdefines
= NULL
;
1651 char * sourcefile
, * destfile
;
1654 struct pragma_description
* pd
;
1658 fprintf(stderr
,"Usage: %s <source pragma file> <source c file> <dest c file> <output defines file>\n", argv
[0]);
1662 if(!(lc
= parse_libconf(NULL
)) )
1666 filename
= malloc( (strlen(argv
[1])+strlen(lc
->libname
)+20) * sizeof(char) );
1667 sprintf( filename
, "%s", argv
[1]);
1669 sourcefile
= argv
[2];
1671 definesfile
= argv
[4];
1673 pd
= parse_pragmas(filename
);
1676 fprintf(stderr
, "Could not read in the pragmas!\n");
1681 * Now open and parse the C input file and generate an output.
1683 fdi
= fopen(sourcefile
, "r");
1684 fdo
= fopen(destfile
, "w");
1685 fdefines
= create_definesfile(definesfile
);
1687 if (NULL
!= fdi
&& NULL
!= fdo
&& NULL
!= fdefines
)
1688 rewritecfile(fdi
,fdo
,pd
,lc
,fdefines
);
1694 if (NULL
!= fdefines
)
1697 free_pragma_description(pd
);
1705 int main(int argc
, char **argv
)
1712 fprintf( stderr
, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv
[0] );
1713 fprintf( stderr
, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );
1717 if( argv
[1][0] == '-' )
1720 option
= argv
[1][1];
1721 argv
[1] = malloc( (strlen(argv
[0])+4) * sizeof(char) );
1722 sprintf( argv
[1], "%s -%c", argv
[0], option
);
1726 retval
= genarossource(argc
, &argv
[1]);
1729 retval
= genfunctable( argc
, &argv
[1] );
1732 retval
= genlibdefs( argc
, &argv
[1] );
1736 fprintf( stdout
, "Usage: %s [-h|-t|-c|-R] <parameter>\n", argv
[0] );
1737 fprintf( stdout
, " -h help\n -t genfunctable\n -c genlibdefs\n -R genarossource\n" );