1 /******************************************************************************
5 * Should be able to parse CBM fd files and generate vanilla inline calls
6 * for gcc. Works as a filter.
8 * by Wolfgang Baron, all rights reserved.
10 * improved, updated, simply made workable by Rainer F. Trunz 1/95
12 * Completely reworked Version, cleaned up and removed a whole lot of bugs
13 * found by Kamil Iskra.
15 * Expect miracles now (hopefully...). Ok, I am just kidding :)
17 * Version 0.99a by Rainer F. Trunz 6/95
19 * Version 0.99b and later by Kamil Iskra.
21 * Version 1.3x by Martin Blom
22 * See fd2inline.guide/fd2inline.info for details.
24 * version 1.38 by AROS development team
26 *****************************************************************************/
34 /******************************************************************************
35 * The program has a few sort of class definitions, which are the result of
36 * object oriented thinking, to be imlemented in plain C. I just haven't
37 * had the time to learn C++ or install the compiler. The design does however
38 * improve robustness, which allows the source to be used over and over again.
39 * if you use this code, please leave a little origin note.
40 ******************************************************************************/
43 const static char version_str
[]="$VER: fd2inline " VERSION
" (24.2.2002)";
46 /******************************************************************************
47 * These are general definitions including types for defining registers etc.
48 ******************************************************************************/
56 #if (defined(__GNUC__) || defined(__SASC)) && 0
57 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
62 #define REGS 16 /* d0=0,...,a7=15 */
65 /* To prevent the enum below from getting broken when building on AROS */
70 d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
, a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, illegal
73 typedef unsigned char shortcard
;
75 typedef enum { false, nodef
, real_error
} Error
;
77 enum { NEW
, OLD
, STUBS
, PROTO
, GATESTUBS
, GATEPROTO
, GENMODULE
} output_mode
=NEW
;
78 enum { IX86BE_AMITHLON
, AROS
, M68K_AMIGAOS
, M68K_POS
, PPC_POWERUP
, PPC_MORPHOS
} target
= M68K_AMIGAOS
;
81 int DirectVarargsCalls
= 0;
85 char *gateprefix
= "";
88 char BaseName
[64], BaseNamU
[64], BaseNamL
[64], BaseNamC
[64];
91 const static char *LibExcTable
[]=
93 "BattClockBase", "Node",
94 "BattMemBase", "Node",
95 "ConsoleDevice", "Device",
96 "DiskBase", "DiskResource",
97 "DOSBase", "DosLibrary",
98 "SysBase", "ExecBase",
99 "ExpansionBase", "ExpansionBase",
100 "GfxBase", "GfxBase",
101 "InputBase", "Device",
102 "IntuitionBase", "IntuitionBase",
103 "LocaleBase", "LocaleBase",
104 "MathIeeeDoubBasBase", "MathIEEEBase",
105 "MathIeeeDoubTransBase","MathIEEEBase",
106 "MathIeeeSingBasBase", "MathIEEEBase",
107 "MathIeeeSingTransBase","MathIEEEBase",
110 "RamdriveDevice", "Device",
111 "RealTimeBase", "RealTimeBase",
112 "RexxSysBase", "RxsLib",
113 "TimerBase", "Device",
114 "UtilityBase", "UtilityBase"
116 const char *StdLib
; /* global lib-name ptr */
118 /*******************************************
119 * just some support functions, no checking
120 *******************************************/
123 NewString(char** new, const char* old
)
128 while (*old
&& (*old
==' ' || *old
=='\t'))
131 for (high
=old
+len
-1; high
>=old
&& (*high
==' ' || *high
=='\t'); high
--);
137 strncpy(*new, old
, len
);
141 fprintf(stderr
, "No mem for string\n");
146 illparams(const char* funcname
)
148 fprintf(stderr
, "%s: illegal Parameters\n", funcname
);
151 static INLINE
const char*
154 const static char *aosregs
[]=
156 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
157 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
184 return (target
!=M68K_POS
? aosregs
[reg
] : posregs
[reg
]);
187 static INLINE
const char*
190 const static char *aosregs
[]=
192 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
193 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
200 return (target
!=M68K_POS
? aosregs
[reg
] : RegStr(reg
));
205 /******************************************************************************
208 * searches string in from position at downwards, as long as in does not
209 * contain any character in not.
211 ******************************************************************************/
214 StrNRBrk(const char* in
, const char* not, const char* at
)
219 chcheck
=""; /* if at<in, the result will be NULL */
220 for (ready
=false; ready
==false && at
>=in
;)
222 for (chcheck
=not; *chcheck
&& *chcheck
!= *at
; chcheck
++);
228 DBP(fprintf(stderr
, "{%c}", *chcheck
));
229 return *chcheck
? at
: NULL
;
233 Our own "strupr", since it is a non-standard function.
246 MatchGlob( char* glob
, char* str
)
263 if( c
== 0 || *str
!= c
)
277 if( MatchGlob( glob
, str
) )
300 /******************************************************************************
303 * stores a file with a temporary buffer (static length, sorry), a line number,
304 * an offset (used for library offsets and an error field.
305 * When there's no error, line will contain line #lineno and offset will be
306 * the last offset set by the interpretation of the last line. If there's been
307 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
308 * It is assumed offsets are always negative.
309 ******************************************************************************/
311 #define fF_BUFSIZE 1024
313 /* all you need to know about an fdFile you parse */
315 typedef enum {FD_PRIVATE
=1, FD_SHADOW
=2} fdflags
;
319 FILE* file
; /* the file we're reading from */
320 char line
[fF_BUFSIZE
]; /* the current line */
321 unsigned long lineno
; /* current line number */
322 long offset
; /* current fd offset (-bias) */
323 Error error
; /* is everything o.k. */
324 fdflags flags
; /* for ##private, ##shadow (p.OS) */
328 fF_ctor (const char* fname
);
330 fF_dtor (fdFile
* obj
);
332 fF_SetError (fdFile
* obj
, Error error
);
334 fF_SetOffset (fdFile
* obj
, long at
);
336 fF_readln (fdFile
* obj
);
338 fF_GetError (const fdFile
* obj
);
340 fF_GetOffset (const fdFile
* obj
);
342 fF_FuncName (fdFile
* obj
); /* return name or null */
344 fF_SetFlags (fdFile
* obj
, fdflags flags
);
346 fF_GetFlags (const fdFile
* obj
);
356 fF_SetError(fdFile
* obj
, Error error
)
361 illparams("fF_SetError");
364 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
367 fF_SetOffset(fdFile
* obj
, long at
)
372 illparams("fFSetOffset");
376 fF_SetFlags(fdFile
* obj
, fdflags flags
)
381 illparams("fF_SetFlags");
385 fF_ctor(const char* fname
)
391 result
=malloc(sizeof(fdFile
));
394 result
->file
=fopen(fname
, "r");
398 fF_SetOffset(result
, -30);
399 fF_SetError(result
, false);
400 fF_SetFlags(result
, 0);
401 result
->line
[0]='\0';
413 illparams("fF_ctor");
419 fF_readln(fdFile
* obj
)
422 long glen
, /* the length we read until now */
423 len
; /* the length of the last segment */
433 if (!fgets(low
, fF_BUFSIZE
-1-glen
, obj
->file
))
435 fF_SetError(obj
, real_error
);
439 if (*low
== ' ' && *(low
+1) == '*')
441 if (low
==strpbrk(low
, "*#/"))
443 DBP(fprintf(stderr
, "in# %s\n", obj
->line
));
448 while (len
&& isspace(*bpoint
))
453 if (*bpoint
==';' || *bpoint
==')')
455 DBP(fprintf(stderr
, "\nin: %s\n", obj
->line
));
460 if (glen
>=fF_BUFSIZE
-10) /* somewhat pessimistic? */
462 fF_SetError(obj
, real_error
);
463 fprintf(stderr
, "Line %lu too long.\n", obj
->lineno
);
466 DBP(fprintf(stderr
, "+"));
469 illparams("fF_readln");
474 fF_GetError(const fdFile
* obj
)
478 illparams("fF_GetError");
483 fF_GetOffset(const fdFile
* obj
)
487 illparams("fF_GetOffset");
491 /******************************************************************************
494 * checks if it can find a function-name and return it's address, or NULL
495 * if the current line does not seem to contain one. The return value will
496 * be a pointer into a malloced buffer, thus the caller will have to free().
497 ******************************************************************************/
500 fF_FuncName(fdFile
* obj
)
505 long obraces
; /* count of open braces */
506 Error ready
; /* ready with searching */
508 if (!obj
|| fF_GetError(obj
)==real_error
)
510 illparams("fF_FuncName");
515 while (*lower
&& (*lower
==' ' || *lower
=='\t'))
518 if (!*lower
|| (!isalpha(*lower
) && *lower
!='_'))
520 fF_SetError(obj
, nodef
);
526 if (!isalnum(*lower
) && !isspace(*lower
) && *lower
!='*' && *lower
!=','
527 && *lower
!='.' && *lower
!=';' && *lower
!='(' && *lower
!=')' &&
528 *lower
!='[' && *lower
!=']' && *lower
!='_' && *lower
!='\\')
530 fF_SetError(obj
, nodef
);
539 if (obj
&& fF_GetError(obj
)==false)
541 if ((upper
=strrchr(obj
->line
, ')'))!=0)
543 DBP(fprintf(stderr
, "end:%s:", upper
));
545 for (obraces
=1, ready
=false; ready
==false; upper
=lower
)
547 lower
=StrNRBrk(obj
->line
, "()", --upper
);
554 DBP(fprintf(stderr
, " )%ld%s", obraces
, lower
));
558 DBP(fprintf(stderr
, " (%ld%s", obraces
, lower
));
563 fprintf(stderr
, "Faulty StrNRBrk\n");
568 fprintf(stderr
, "'(' or ')' expected in line %lu.\n",
573 if (ready
==nodef
) /* we found the matching '(' */
580 while (upper
>=obj
->line
&& (*upper
==' ' || *upper
=='\t'))
583 lower
=StrNRBrk(obj
->line
, " \t*)", upper
);
590 for (name
=lower
; name
<=upper
; name
++)
591 if (!isalnum(*name
) && *name
!='_')
593 fF_SetError(obj
, nodef
);
597 newlen
=upper
-lower
+1;
598 buf
=malloc(newlen
+1);
602 strncpy(buf
, lower
, newlen
);
606 fprintf(stderr
, "No mem for fF_FuncName");
611 illparams("fF_FuncName");
615 static INLINE fdflags
616 fF_GetFlags(const fdFile
* obj
)
620 illparams("fF_GetFlags");
624 /*********************
626 *********************/
636 regs funcpar
; /* number of argument that has type "pointer to function" */
642 fD_dtor (fdDef
* obj
);
644 fD_NewName (fdDef
* obj
, const char* newname
);
646 fD_NewParam (fdDef
* obj
, shortcard at
, const char* newstr
);
648 fD_NewProto (fdDef
* obj
, shortcard at
, char* newstr
);
650 fD_NewReg (fdDef
* obj
, shortcard at
, regs reg
);
652 fD_NewType (fdDef
* obj
, const char* newstr
);
654 fD_SetOffset (fdDef
* obj
, long off
);
656 fD_parsefd (fdDef
* obj
, fdFile
* infile
);
658 fD_parsepr (fdDef
* obj
, fdFile
* infile
);
660 fD_GetName (const fdDef
* obj
);
662 fD_GetOffset (const fdDef
* obj
);
664 fD_GetParam (const fdDef
* obj
, shortcard at
);
666 fD_GetReg (const fdDef
* obj
, shortcard at
);
668 fD_GetRegStr (const fdDef
* obj
, shortcard at
);
670 fD_GetRegStrU (const fdDef
* obj
, shortcard at
);
672 fD_GetType (const fdDef
* obj
);
674 fD_ParamNum (const fdDef
* obj
);
676 fD_ProtoNum (const fdDef
* obj
);
678 fD_RegNum (const fdDef
* obj
);
680 fD_cmpName (const void* big
, const void* small
);
682 fD_cmpOffset (const void* big
, const void* small
);
684 fD_write (FILE* outfile
, const fdDef
* obj
);
686 fD_GetFuncParNum (const fdDef
* obj
);
688 fD_SetFuncParNum (fdDef
* obj
, shortcard at
);
690 fD_adjustargnames(fdDef
*obj
);
695 char *fD_nostring
="";
703 result
=malloc(sizeof(fdDef
));
707 result
->name
=fD_nostring
;
708 result
->type
=fD_nostring
;
709 result
->funcpar
=illegal
;
711 for (count
=d0
; count
<illegal
; count
++ )
713 result
->reg
[count
]=illegal
;
714 result
->param
[count
]=fD_nostring
; /* if (!strlen) dont't free() */
715 result
->proto
[count
]=fD_nostring
;
721 /* free all resources and make the object as illegal as possible */
731 fprintf(stderr
, "fD_dtor: null name");
733 if (obj
->name
!=fD_nostring
)
737 fprintf(stderr
, "fD_dtor: null type");
739 if (obj
->type
!=fD_nostring
)
742 obj
->name
=obj
->type
=NULL
;
744 for (count
=d0
; count
<illegal
; count
++)
746 obj
->reg
[count
]=illegal
;
748 if (!obj
->param
[count
])
749 fprintf(stderr
, "fD_dtor: null param");
751 if (obj
->param
[count
]!=fD_nostring
)
752 free(obj
->param
[count
]);
754 if (!obj
->proto
[count
])
755 fprintf(stderr
, "fD_dtor: null proto");
757 if (obj
->proto
[count
]!=fD_nostring
)
758 free(obj
->proto
[count
]);
760 obj
->param
[count
]=obj
->proto
[count
]=NULL
;
766 fprintf(stderr
, "fd_dtor(NULL)\n");
770 fD_NewName(fdDef
* obj
, const char* newname
)
774 if (obj
->name
&& obj
->name
!=fD_nostring
)
776 if (!NewString(&obj
->name
, newname
))
777 obj
->name
=fD_nostring
;
780 illparams("fD_NewName");
784 fD_NewParam(fdDef
* obj
, shortcard at
, const char* newstr
)
788 if (newstr
&& obj
&& at
<illegal
)
792 if (pa
&& pa
!=fD_nostring
)
795 while (*newstr
==' ' || *newstr
=='\t')
798 if (NewString(&pa
, newstr
))
802 prefix_pa
= malloc( strlen( pa
) + 4 );
804 if( prefix_pa
== NULL
)
806 fprintf(stderr
, "No mem for string\n");
810 sprintf( prefix_pa
, "___%s", pa
);
811 obj
->param
[at
]=prefix_pa
;
816 obj
->param
[at
]=fD_nostring
;
819 illparams("fD_NewParam");
822 /* get first free *reg or illegal */
824 static INLINE shortcard
825 fD_RegNum(const fdDef
* obj
)
831 for (count
=d0
; count
<illegal
&& obj
->reg
[count
]!=illegal
; count
++);
836 illparams("fD_RegNum");
842 fD_NewReg(fdDef
* obj
, shortcard at
, regs reg
)
844 if (obj
&& at
<illegal
&& reg
>=d0
&& reg
<=illegal
)
847 illparams("fD_NewReg");
851 fD_GetReg(const fdDef
* obj
, shortcard at
)
853 if (obj
&& at
<illegal
)
857 illparams("fD_GetReg");
862 static INLINE shortcard
863 fD_GetFuncParNum(const fdDef
* obj
)
866 return (shortcard
)obj
->funcpar
;
869 illparams("fD_GetFuncParNum");
875 fD_SetFuncParNum(fdDef
* obj
, shortcard at
)
877 if (obj
&& at
<illegal
)
880 illparams("fD_SetFuncParNum");
884 fD_NewProto(fdDef
* obj
, shortcard at
, char* newstr
)
888 if (newstr
&& obj
&& at
<illegal
)
890 char *t
, arr
[200]; /* I hope 200 will be enough... */
894 if (pr
&& pr
!=fD_nostring
)
897 while (*newstr
==' ' || *newstr
=='\t')
898 newstr
++; /* Skip leading spaces */
901 while ((*t
++=*newstr
)!=0)
903 /* Copy the rest, counting number of words */
904 if ((*newstr
==' ' || *newstr
=='\t') && newstr
[1] && newstr
[1]!=' ' &&
911 while (*t
==' ' || *t
=='\t')
913 t
[1]='\0'; /* Get rid of tailing spaces */
915 if (at
!=fD_GetFuncParNum(obj
))
917 if (numwords
>1) /* One word - must be type */
920 /* '*' on the end - no parameter name used */
921 while (*t
!=' ' && *t
!='\t' && *t
!='*')
924 if (strcmp(t
, "char") && strcmp(t
, "short") && strcmp(t
, "int")
925 && strcmp(t
, "long") && strcmp(t
, "APTR"))
927 /* Not one of applicable keywords - must be parameter name.
930 while (*t
==' ' || *t
=='\t')
938 /* Parameter of type "pointer to function". */
942 while (*t
==' ' || *t
=='\t')
948 if (target
!=M68K_POS
)
950 memmove(t
+2, end
, strlen(end
)+1);
955 memmove(t
, end
, strlen(end
)+1);
958 if (NewString(&pr
, arr
))
961 while (*pr
==' ' || *pr
=='\t')
963 if (!strcasecmp(pr
, "double"))
965 /* "double" needs two data registers */
966 int count
, regs
=fD_RegNum(obj
);
967 for (count
=at
+1; count
<regs
; count
++)
968 fD_NewReg(obj
, count
, fD_GetReg(obj
, count
+1));
972 obj
->proto
[at
]=fD_nostring
;
975 illparams("fD_NewProto");
981 fD_NewType(fdDef
* obj
, const char* newtype
)
985 if (obj
->type
&& obj
->type
!=fD_nostring
)
987 if (!NewString(&obj
->type
, newtype
))
988 obj
->type
=fD_nostring
;
991 illparams("fD_NewType");
995 fD_SetOffset(fdDef
* obj
, long off
)
1000 illparams("fD_SetOffset");
1003 static INLINE
const char*
1004 fD_GetName(const fdDef
* obj
)
1006 if (obj
&& obj
->name
)
1010 illparams("fD_GetName");
1016 fD_GetOffset(const fdDef
* obj
)
1022 illparams("fD_GetOffset");
1027 static INLINE
const char*
1028 fD_GetProto(const fdDef
* obj
, shortcard at
)
1030 if (obj
&& at
<illegal
&& obj
->proto
[at
])
1031 return obj
->proto
[at
];
1034 illparams("fD_GetProto");
1039 static INLINE
const char*
1040 fD_GetParam(const fdDef
* obj
, shortcard at
)
1042 if (obj
&& at
<illegal
&& obj
->param
[at
])
1043 return obj
->param
[at
];
1046 illparams("fD_GetParam");
1051 static INLINE
const char*
1052 fD_GetRegStr(const fdDef
* obj
, shortcard at
)
1054 if (obj
&& at
<illegal
)
1055 return RegStr(obj
->reg
[at
]);
1058 illparams("fD_GetReg");
1059 return RegStr(illegal
);
1063 static INLINE
const char*
1064 fD_GetRegStrU(const fdDef
* obj
, shortcard at
)
1066 if (obj
&& at
<illegal
)
1067 return RegStrU(obj
->reg
[at
]);
1070 illparams("fD_GetReg");
1071 return RegStrU(illegal
);
1075 static INLINE
const char*
1076 fD_GetType(const fdDef
* obj
)
1078 if (obj
&& obj
->type
)
1082 illparams("fD_GetType");
1087 /* get first free param or illegal */
1089 static INLINE shortcard
1090 fD_ParamNum(const fdDef
* obj
)
1096 for (count
=d0
; count
<illegal
&& obj
->param
[count
]!=fD_nostring
;
1102 illparams("fD_ParamNum");
1107 static INLINE shortcard
1108 fD_ProtoNum(const fdDef
* obj
)
1114 for (count
=d0
; count
<illegal
&& obj
->proto
[count
]!=fD_nostring
;
1120 illparams("fD_ProtoNum");
1125 /******************************************************************************
1128 * parse the current line. Needs to copy input, in order to insert \0's
1130 * fF_GetError(infile):
1131 * false = read a definition.
1132 * nodef = not a definition on line (so try again)
1133 * error = real error
1134 ******************************************************************************/
1137 fD_parsefd(fdDef
* obj
, fdFile
* infile
)
1139 enum parse_info
{ name
, params
, regs
, ready
} parsing
;
1140 char *buf
, *bpoint
, *bnext
;
1141 unsigned long index
;
1143 if (obj
&& infile
&& fF_GetError(infile
)==false)
1147 if (!NewString(&buf
, infile
->line
))
1149 fprintf(stderr
, "No mem for line %lu\n", infile
->lineno
);
1150 fF_SetError(infile
, real_error
);
1152 bpoint
=buf
; /* so -Wall keeps quiet */
1154 /* try to parse the line until there's an error or we are done */
1156 while (parsing
!=ready
&& fF_GetError(infile
)==false)
1164 if (strncmp("##base", buf
, 6)==0)
1167 while (*bnext
==' ' || *bnext
=='\t' || *bnext
=='_')
1169 strcpy(BaseName
, bnext
);
1170 BaseName
[strlen(BaseName
)-1]='\0';
1173 if (strncmp("##bias", buf
, 6)==0)
1175 if (!sscanf(buf
+6, "%ld", &infile
->offset
))
1177 fprintf(stderr
, "Illegal ##bias in line %lu: %s\n",
1178 infile
->lineno
, infile
->line
);
1179 fF_SetError(infile
, real_error
);
1180 break; /* avoid nodef */
1184 if (fF_GetOffset(infile
)>0)
1185 fF_SetOffset(infile
, -fF_GetOffset(infile
));
1186 DBP(fprintf(stderr
, "set offset to %ld\n",
1187 fF_GetOffset(infile
)));
1192 if (strncmp("##private", buf
, 9)==0)
1193 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1195 else if (strncmp("##public", buf
, 8)==0)
1196 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1198 else if (strncmp("##shadow", buf
, 8)==0)
1199 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1202 /* drop through for error comment */
1205 /* try again somewhere else */
1206 fF_SetError(infile
, nodef
);
1210 /* assume a regular line here */
1211 if (fF_GetFlags(infile
) & (FD_PRIVATE
| FD_SHADOW
))
1213 /* don't store names of privates */
1214 fF_SetError(infile
, nodef
);
1215 if (!(fF_GetFlags(infile
) & FD_SHADOW
))
1216 fF_SetOffset(infile
,
1217 fF_GetOffset(infile
)-FUNCTION_GAP
);
1219 /* Shadow is valid for one line only. */
1220 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1224 parsing
=name
; /* switch (parsing) */
1225 for (index
=0; buf
[index
] && buf
[index
]!='('; index
++);
1230 fprintf(stderr
, "Not an fd, line %lu: %s\n",
1231 infile
->lineno
, buf
/* infile->line */);
1232 fF_SetError(infile
, nodef
);
1233 } /* maybe next time */
1238 fD_NewName(obj
, buf
);
1239 fD_SetOffset(obj
, fF_GetOffset(infile
));
1242 parsing
=params
; /* continue the loop */
1249 char *bptmp
; /* needed for fD_NewParam */
1251 /* look for parameters now */
1253 for (bnext
= bpoint
; *bnext
&& *bnext
!=',' && *bnext
!=')';
1262 if (bnext
[1] != '(')
1264 fprintf(stderr
, "Registers expected in line %lu: %s\n",
1265 infile
->lineno
, infile
->line
);
1266 fF_SetError(infile
, nodef
);
1277 /* terminate string and advance to next item */
1280 fD_NewParam(obj
, fD_ParamNum(obj
), bptmp
);
1284 fF_SetError(infile
, nodef
);
1285 fprintf(stderr
, "Param expected in line %lu: %s\n",
1286 infile
->lineno
, infile
->line
);
1288 break; /* switch parsing */
1292 /* look for parameters now */
1294 for (bnext
=bpoint
; *bnext
&& *bnext
!='/' && *bnext
!=',' &&
1295 *bnext
!=')'; bnext
++);
1301 /* wow, we've finished */
1302 fF_SetOffset(infile
, fF_GetOffset(infile
)-FUNCTION_GAP
);
1307 bpoint
[0]=tolower(bpoint
[0]);
1309 if ((bpoint
[0]=='d' || bpoint
[0]=='a') && bpoint
[1]>='0' &&
1310 bpoint
[1]<='8' && bnext
==bpoint
+2)
1311 fD_NewReg(obj
, fD_RegNum(obj
),
1312 bpoint
[1]-'0'+(bpoint
[0]=='a'? 8 : 0));
1316 /* it is when our function is void */
1317 fprintf(stderr
, "Illegal register %s in line %ld\n",
1318 bpoint
, infile
->lineno
);
1319 fF_SetError(infile
, nodef
);
1325 fF_SetError(infile
, nodef
);
1326 fprintf(stderr
, "Reg expected in line %lu\n",
1329 break; /* switch parsing */
1332 fprintf(stderr
, "Internal error, use another compiler.\n");
1338 return fF_GetError(infile
);
1342 illparams("fD_parsefd");
1348 fD_adjustargnames(fdDef
*obj
)
1352 if (output_mode
!=NEW
&& output_mode
!=GENMODULE
)
1355 /* For #define-base output mode, we have to check if argument names are not
1356 the same as some words in type names. We check from the first argument
1357 to the last, resolving conflicts by changing argument names, if
1360 for (parnum
=0; parnum
<fD_ParamNum(obj
); parnum
++)
1362 const char *parname
=fD_GetParam(obj
, parnum
);
1367 const char *type
=fD_GetType(obj
);
1372 if ((str
=strstr(type
, parname
))!=0 && (str
==type
||
1373 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1374 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_')))
1376 char buf
[300]; /* Hope will be enough... */
1377 strcpy(buf
, parname
);
1379 fD_NewParam(obj
, parnum
, buf
);
1380 parname
=fD_GetParam(obj
, parnum
);
1384 for (num
=0; num
<fD_ParamNum(obj
); num
++)
1386 const char *name
=fD_GetParam(obj
, num
);
1387 const char *proto
=fD_GetProto(obj
, num
);
1388 if ((num
<parnum
&& strcmp(name
, parname
)==0) ||
1389 ((str
=strstr(proto
, parname
))!=0 && (str
==proto
||
1390 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1391 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_'))))
1393 char buf
[300]; /* Hope will be enough... */
1394 strcpy(buf
, parname
);
1396 fD_NewParam(obj
, parnum
, buf
);
1397 parname
=fD_GetParam(obj
, parnum
);
1402 } while (!finished
);
1407 fD_parsepr(fdDef
* obj
, fdFile
* infile
)
1409 char *buf
; /* a copy of infile->line */
1410 char *bpoint
, /* cursor in buf */
1411 *bnext
, /* looking for the end */
1412 *lowarg
; /* beginning of this argument */
1413 long obraces
; /* count of open braces */
1414 regs count
, /* count parameter number */
1415 args
; /* the number of arguments for this function */
1417 if (!(obj
&& infile
&& fF_GetError(infile
)==false))
1419 illparams("fD_parsepr");
1420 fF_SetError(infile
, real_error
);
1423 if (!NewString(&buf
, infile
->line
))
1425 fprintf(stderr
, "No mem for fD_parsepr\n");
1426 fF_SetError(infile
, real_error
);
1429 fF_SetError(infile
, false);
1431 bpoint
=strchr(buf
, '(');
1432 while (--bpoint
>=buf
&& strstr(bpoint
, fD_GetName(obj
))!=bpoint
);
1435 while (--bpoint
>= buf
&& (*bpoint
==' ' || *bpoint
=='\t'));
1438 fD_NewType(obj
, buf
);
1440 while (bpoint
&& *bpoint
++!='('); /* one beyond '(' */
1445 for (count
=0, args
=fD_RegNum(obj
); count
<args
; bpoint
=bnext
+1)
1447 while (*bpoint
&& (*bpoint
==' ' || *bpoint
=='\t')) /* ignore spaces */
1450 if (!obraces
&& target
==M68K_POS
&& strncmp(bpoint
, "_R_", 3)==0 &&
1451 isalnum(bpoint
[3]) && isalnum(bpoint
[4]) && isspace(bpoint
[5]))
1454 bnext
=strpbrk(bpoint
, "(),");
1463 if (target
==M68K_AMIGAOS
|| target
==M68K_POS
)
1465 if (fD_GetFuncParNum(obj
)!=illegal
&&
1466 fD_GetFuncParNum(obj
)!=count
&&
1468 fprintf(stderr
, "Warning: two parameters of type "
1469 "pointer to function are used.\n"
1470 "This is not supported!\n");
1473 fD_SetFuncParNum(obj
, count
);
1476 DBP(fprintf(stderr
, "< (%ld%s >", obraces
, bnext
));
1482 DBP(fprintf(stderr
, "< )%ld%s >", obraces
, bnext
));
1488 DBP(fprintf(stderr
, "< )0> [LAST PROTO=%s]", lowarg
));
1489 if (fD_NewProto(obj
, count
, lowarg
))
1490 fprintf(stderr
, "Parser confused in line %ld\n",
1496 DBP(fprintf(stderr
, "%s needs %u arguments and got %u.\n",
1497 fD_GetName(obj
), args
, count
+1));
1498 fF_SetError(infile
, nodef
);
1508 DBP(fprintf(stderr
, " [PROTO=%s] ", lowarg
));
1509 if (fD_NewProto(obj
, count
, lowarg
))
1510 fprintf(stderr
, "Parser confused in line %ld\n",
1518 fprintf(stderr
, "Faulty strpbrk in line %lu.\n",
1524 DBP(fprintf(stderr
, "Faulty argument %u in line %lu.\n", count
+1,
1526 count
=args
; /* this will effectively quit the for loop */
1527 fF_SetError(infile
, nodef
);
1530 if (fD_ProtoNum(obj
)!=fD_RegNum(obj
))
1531 fF_SetError(infile
, nodef
);
1535 fprintf(stderr
, "fD_parsepr was fooled in line %lu\n", infile
->lineno
);
1536 fprintf(stderr
, "function , definition %s.\n",
1537 /* fD_GetName(obj),*/ infile
->line
);
1538 fF_SetError(infile
, nodef
);
1543 fD_adjustargnames(obj
);
1545 return fF_GetError(infile
);
1549 fD_cmpName(const void* big
, const void* small
) /* for qsort and bsearch */
1551 return strcmp(fD_GetName(*(fdDef
**)big
), fD_GetName(*(fdDef
**)small
));
1555 fD_cmpOffset(const void* big
, const void* small
) /* for qsort and bsearch */
1557 return fD_GetOffset(*(fdDef
**)small
) - fD_GetOffset(*(fdDef
**)big
);
1560 const static char *TagExcTable
[]=
1562 "BuildEasyRequestArgs", "BuildEasyRequest",
1563 "DoDTMethodA", "DoDTMethod",
1564 "DoGadgetMethodA", "DoGadgetMethod",
1565 "EasyRequestArgs", "EasyRequest",
1566 "MUI_MakeObjectA", "MUI_MakeObject",
1567 "MUI_RequestA", "MUI_Request",
1568 "PrintDTObjectA", "PrintDTObject",
1569 "RefreshDTObjectA", "RefreshDTObjects",
1570 "UMSVLog", "UMSLog",
1571 "VFWritef", "FWritef",
1572 "VFPrintf", "FPrintf",
1573 "VPrintf", "Printf",
1577 getvarargsfunction(const fdDef
* obj
)
1580 const char *name
= fD_GetName(obj
);
1582 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1584 if (strcmp(name
, TagExcTable
[count
])==0)
1586 return TagExcTable
[count
+1];
1593 taggedfunction(const fdDef
* obj
)
1595 shortcard numregs
=fD_RegNum(obj
);
1598 const char *name
=fD_GetName(obj
);
1599 static char newname
[200]; /* Hope will be enough... static because used
1600 out of the function. */
1601 const char *lastarg
;
1602 const static char *TagExcTable2
[]=
1610 "PackStructureTags",
1611 "RefreshTagItemClones",
1612 "UnpackStructureTags",
1618 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1619 if (strcmp(name
, TagExcTable
[count
])==0)
1621 // lcs return TagExcTable[count+1];
1623 for (count
=0; count
<sizeof TagExcTable2
/sizeof TagExcTable2
[0]; count
++)
1624 if (strcmp(name
, TagExcTable2
[count
])==0)
1627 lastarg
=fD_GetProto(obj
, numregs
-1);
1628 if (strncmp(lastarg
, "const", 5)==0 || strncmp(lastarg
, "CONST", 5)==0)
1630 while (*lastarg
==' ' || *lastarg
=='\t')
1632 if (strncmp(lastarg
, "struct", 6))
1635 while (*lastarg
==' ' || *lastarg
=='\t')
1638 if (strncmp(lastarg
, "TagItem", 7) &&
1639 (target
!=M68K_POS
|| ((aos_tagitem
=strncmp(lastarg
, "pOS_TagItem", 11))!=0)))
1641 lastarg
+=(aos_tagitem
? 7 : 11);
1642 while (*lastarg
==' ' || *lastarg
=='\t')
1644 if (strcmp(lastarg
, "*"))
1647 strcpy(newname
, name
);
1648 if (newname
[strlen(newname
)-1]=='A')
1649 newname
[strlen(newname
)-1]='\0';
1651 if (strlen(newname
)>7 && !strcmp(newname
+strlen(newname
)-7, "TagList"))
1652 strcpy(newname
+strlen(newname
)-4, "s");
1654 strcat(newname
, "Tags");
1659 aliasfunction(const char* name
)
1661 const static char *AliasTable
[]=
1663 "AllocDosObject", "AllocDosObjectTagList",
1664 "CreateNewProc", "CreateNewProcTagList",
1665 "NewLoadSeg", "NewLoadSegTagList",
1666 "System", "SystemTagList",
1669 for (count
=0; count
<sizeof AliasTable
/sizeof AliasTable
[0]; count
++)
1670 if (strcmp(name
, AliasTable
[count
])==0)
1671 return AliasTable
[count
+(count
%2 ? -1 : 1)];
1676 fD_write(FILE* outfile
, const fdDef
* obj
)
1678 shortcard count
, numregs
;
1679 const char *chtmp
, *tagname
, *varname
, *name
, *rettype
;
1680 int vd
=0, a45
=0, d7
=0;
1682 DBP(fprintf(stderr
, "func %s\n", fD_GetName(obj
)));
1684 numregs
=fD_RegNum(obj
);
1686 if ((rettype
=fD_GetType(obj
))==fD_nostring
)
1688 fprintf(stderr
, "%s has no prototype.\n", fD_GetName(obj
));
1691 if (!strcasecmp(rettype
, "void"))
1692 vd
= 1; /* set flag */
1693 for (count
=d0
; count
<numregs
; count
++)
1695 const char *reg
=fD_GetRegStr(obj
, count
);
1696 if (!((output_mode
== NEW
|| output_mode
== GENMODULE
) && (target
== PPC_POWERUP
)))
1698 if (strcmp(reg
, "a4")==0 || strcmp(reg
, "a5")==0)
1701 a45
=(strcmp(reg
, "a4") ? 5 : 4); /* set flag */
1702 else /* Security check */
1704 fprintf(stderr
, "Warning: both a4 and a5 are used. "
1705 "This is not supported!\n");
1708 if (strcmp(reg
, "d7")==0) /* Used only when a45!=0 */
1712 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1714 if (a45
&& d7
) /* Security check */
1716 fprintf(stderr
, "Warning: d7 and a4 or a5 are used. This is not "
1720 name
=fD_GetName(obj
);
1722 if (fD_ProtoNum(obj
)!=numregs
)
1724 fprintf(stderr
, "%s gets %d fd args and %d proto%s.\n", name
, numregs
,
1725 fD_ProtoNum(obj
), fD_ProtoNum(obj
)!= 1 ? "s" : "");
1729 if (output_mode
==GENMODULE
)
1731 fprintf(outfile
, "%s %s(", rettype
, name
);
1732 for (count
=d0
; count
<numregs
; count
++)
1734 chtmp
=fD_GetProto(obj
, count
);
1735 if (fD_GetFuncParNum(obj
)==count
)
1736 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1738 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1739 "" : " "), fD_GetParam(obj
, count
));
1740 if (count
<numregs
-1)
1741 fprintf(outfile
, ", ");
1744 fprintf(outfile
,") (");
1745 for (count
=d0
; count
<numregs
; count
++)
1747 chtmp
=fD_GetRegStr(obj
, count
);
1748 /* AROS wants the registers in UPPERCASE */
1750 fprintf(outfile
, "%c", toupper(*(chtmp
++)));
1751 if (count
<numregs
-1)
1752 fprintf(outfile
, ", ");
1754 fprintf(outfile
, ")\n");
1756 else if (output_mode
==NEW
)
1758 fprintf(outfile
, "#define %s(", name
);
1762 for (count
=d0
; count
<numregs
-1; count
++)
1763 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
1764 fprintf(outfile
, "%s", fD_GetParam(obj
, count
));
1767 if (target
==M68K_AMIGAOS
)
1769 fprintf(outfile
, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs
,
1770 (vd
? "NR" : ""), (a45
? (a45
==4 ? "A4" : "A5") : ""),
1771 (BaseName
[0] ? "" : "UB"),
1772 (fD_GetFuncParNum(obj
)==illegal
? "" : "FP"), -fD_GetOffset(obj
));
1774 fprintf(outfile
, "%s, ", rettype
);
1775 fprintf(outfile
, "%s, ", name
);
1777 for (count
=d0
; count
<numregs
; count
++)
1779 chtmp
=fD_GetRegStr(obj
, count
);
1780 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1782 fprintf(outfile
, "%s, %s, %s%s", (fD_GetFuncParNum(obj
)==count
?
1783 "__fpt" : fD_GetProto(obj
, count
)),
1784 fD_GetParam(obj
, count
),
1785 chtmp
, (count
==numregs
-1 && !BaseName
[0] ? "" : ", "));
1788 if (BaseName
[0]) /* was "##base" used? */
1789 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1790 if (fD_GetFuncParNum(obj
)!=illegal
)
1792 fprintf(outfile
, ", ");
1793 fprintf(outfile
, fD_GetProto(obj
, fD_GetFuncParNum(obj
)), "__fpt");
1795 fprintf(outfile
, ")\n\n");
1797 else if(target
==M68K_POS
)
1799 fprintf(outfile
, ") \\\n\t__INLINE_FUN_%d(", numregs
);
1800 fprintf(outfile
, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1801 BaseNamU
, BaseNamU
, -fD_GetOffset(obj
), rettype
, name
,
1802 (numregs
? ", \\\n\t" : ""));
1804 for (count
=d0
; count
<numregs
; count
++)
1805 fprintf(outfile
, "%s, %s, %s%s", fD_GetProto(obj
, count
),
1806 fD_GetParam(obj
, count
), fD_GetRegStr(obj
, count
),
1807 (count
==numregs
-1 ? "" : ", "));
1808 fprintf(outfile
, ")\n\n");
1810 else if (target
==PPC_POWERUP
|| target
==PPC_MORPHOS
)
1812 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1815 (BaseName
[0] ? "" : "UB"),
1816 -fD_GetOffset(obj
));
1819 fprintf(outfile
, "%s, ", rettype
);
1820 fprintf(outfile
, "%s, ", name
);
1822 for (count
=d0
; count
<numregs
; count
++)
1824 chtmp
=fD_GetRegStr(obj
, count
);
1826 if (strchr(fD_GetProto(obj
, count
),'%'))
1829 fD_GetProto(obj
, count
),
1832 fprintf(outfile
, "%s, %s, %s%s",
1834 fD_GetParam(obj
, count
),
1836 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1840 fprintf(outfile
, "%s, %s, %s%s",
1841 fD_GetProto(obj
, count
),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1842 fD_GetParam(obj
, count
),
1844 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1849 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1852 * Here it would make sense to create a database file to
1853 * integrate optimizations automaticly into every new
1854 * build. Not every function needs a complete flush. For
1855 * example functions with no parameter wouldn`t need a
1856 * PPC flush normally. Or Read(File,Addr,Size); would
1857 * only need a flush for Addr with the Size
1860 fprintf(outfile
, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1861 fprintf(outfile
, ")\n\n");
1863 else if (target
==IX86BE_AMITHLON
)
1865 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1868 (BaseName
[0] ? "" : "UB"),
1869 -fD_GetOffset(obj
));
1872 fprintf(outfile
, "%s, ", rettype
);
1873 fprintf(outfile
, "%s, ", name
);
1875 for (count
=d0
; count
<numregs
; count
++)
1877 chtmp
=fD_GetRegStr(obj
, count
);
1879 if (strchr(fD_GetProto(obj
, count
),'%'))
1882 fD_GetProto(obj
, count
),
1885 fprintf(outfile
, "%s, %s, %s%s",
1887 fD_GetParam(obj
, count
),
1889 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1893 fprintf(outfile
, "%s, %s, %s%s",
1894 fD_GetProto(obj
, count
),
1895 fD_GetParam(obj
, count
),
1897 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1902 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1904 fprintf(outfile
, ")\n\n");
1906 else if (target
==AROS
)
1908 fprintf(outfile
, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1910 (BaseName
[0] ? "" : "I"),
1911 (vd
? "void" : rettype
),
1914 for (count
=d0
; count
<numregs
; count
++)
1916 chtmp
=fD_GetRegStrU(obj
, count
);
1917 fprintf(outfile
, "\tAROS_LCA(%s, (%s), %s), \\\n",
1918 fD_GetProto(obj
, count
),
1919 fD_GetParam(obj
, count
),
1923 if (BaseName
[0]) /* was "##base" used? */
1925 fprintf(outfile
, "\tstruct %s *, %s_BASE_NAME, ", StdLib
, BaseNamU
);
1929 fprintf(outfile
, "\t/* bt */, /* bn */, ");
1932 "%ld, /* s */)\n\n",
1933 -fD_GetOffset(obj
) / 6);
1937 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
1941 else if (output_mode
==OLD
|| output_mode
==STUBS
)
1943 fprintf(outfile
, "%s__inline %s\n%s(%s",
1944 (output_mode
==STUBS
? "" : "extern "), rettype
, name
,
1945 (BaseName
[0] ? (numregs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1947 if (target
==M68K_AMIGAOS
)
1949 for (count
=d0
; count
<numregs
; count
++)
1951 chtmp
=fD_GetProto(obj
, count
);
1952 if (fD_GetFuncParNum(obj
)==count
)
1953 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1955 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1956 "" : " "), fD_GetParam(obj
, count
));
1957 if (count
<numregs
-1)
1958 fprintf(outfile
, ", ");
1961 fprintf(outfile
, ")\n{\n%s", (BaseName
[0] ? " BASE_EXT_DECL\n" : ""));
1963 fprintf(outfile
, " register %s%sres __asm(\"d0\");\n", rettype
,
1964 (*(rettype
+strlen(rettype
)-1)=='*' ? "" : " "));
1967 fprintf(outfile
, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1970 for (count
=d0
; count
<numregs
; count
++)
1972 chtmp
=fD_GetRegStr(obj
, count
);
1973 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1975 if (fD_GetFuncParNum(obj
)==count
)
1977 fprintf(outfile
, " register ");
1978 fprintf(outfile
, fD_GetProto(obj
, count
), chtmp
);
1979 fprintf(outfile
, " __asm(\"%s\") = %s;\n", chtmp
, fD_GetParam(obj
,
1984 const char *proto
=fD_GetProto(obj
, count
);
1985 fprintf(outfile
, " register %s%s%s __asm(\"%s\") = %s;\n",
1986 proto
, (*(proto
+strlen(proto
)-1)=='*' ? "" : " "), chtmp
,
1987 chtmp
, fD_GetParam(obj
, count
));
1991 fprintf(outfile
, " __asm volatile (\"exg d7,%s\\n\\t"
1992 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45
==4 ? "a4" : "a5"),
1993 -fD_GetOffset(obj
), (a45
==4 ? "a4" : "a5"));
1995 fprintf(outfile
, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1996 -fD_GetOffset(obj
));
1998 fprintf(outfile
, (vd
? " : /* No Output */\n" : " : \"=r\" (res)\n"));
2000 fprintf(outfile
, " : ");
2002 fprintf(outfile
, "\"r\" (a6)%s", (numregs
? ", ": ""));
2004 for (count
=d0
; count
<numregs
; count
++)
2006 chtmp
=fD_GetRegStr(obj
, count
);
2007 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
2009 fprintf(outfile
, "\"r\" (%s)%s", chtmp
, (count
<numregs
-1 ? ", " : ""));
2011 fprintf(outfile
, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
2014 fprintf(outfile
, ", \"cc\", \"memory\");\n}\n\n"); /* { */
2016 fprintf(outfile
, ", \"cc\", \"memory\");\n return res;\n}\n\n");
2019 else if (target
==PPC_POWERUP
)
2021 for (count
= d0
; count
< numregs
; count
++)
2023 chtmp
= fD_GetProto(obj
, count
);
2024 if (fD_GetFuncParNum(obj
) == count
)
2025 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2027 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2028 "" : " "), fD_GetParam(obj
, count
));
2029 if (count
< numregs
- 1)
2030 fprintf(outfile
, ", ");
2033 fprintf(outfile
, ")\t\n");
2034 fprintf(outfile
, "{\t\n");
2035 fprintf(outfile
, "struct Caos\tMyCaos;\n");
2036 fprintf(outfile
, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2037 fprintf(outfile
, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
2038 fprintf(outfile
, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2039 fprintf(outfile
, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2040 fprintf(outfile
, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2041 fprintf(outfile
, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2045 for (count
= d0
; count
< numregs
; count
++)
2047 fprintf(outfile
, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2048 fD_GetRegStr(obj
, count
),
2049 fD_GetParam(obj
, count
));
2053 fprintf(outfile
, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj
));
2055 * was "##base" used?
2058 fprintf(outfile
, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2062 fprintf(outfile
, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2066 fprintf(outfile
, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2070 else if (target
==PPC_MORPHOS
)
2072 for (count
= d0
; count
< numregs
; count
++)
2074 chtmp
= fD_GetProto(obj
, count
);
2075 if (fD_GetFuncParNum(obj
) == count
)
2076 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2078 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2079 "" : " "), fD_GetParam(obj
, count
));
2080 if (count
< numregs
- 1)
2081 fprintf(outfile
, ", ");
2084 fprintf(outfile
, ")\t\n{\t\n");
2088 for (count
= d0
; count
< numregs
; count
++)
2090 fprintf(outfile
, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2091 fD_GetRegStrU(obj
, count
), fD_GetParam(obj
, count
));
2096 * was "##base" used?
2099 fprintf(outfile
, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2103 fprintf(outfile
, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj
));
2107 fprintf(outfile
, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2108 rettype
, fD_GetOffset(obj
));
2111 else if (target
==IX86BE_AMITHLON
)
2114 for (count
= d0
; count
< numregs
; count
++)
2116 chtmp
= fD_GetProto(obj
, count
);
2117 if (fD_GetFuncParNum(obj
) == count
)
2118 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2120 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2121 "" : " "), fD_GetParam(obj
, count
));
2122 if (count
< numregs
- 1)
2123 fprintf(outfile
, ", ");
2126 fprintf(outfile
, ")\n{\n");
2127 fprintf(outfile
, "\tstruct _Regs _regs;\n");
2131 for (count
= d0
; count
< numregs
; count
++)
2133 fprintf(outfile
, "\t_regs.reg_%s = (ULONG) (%s);\n",
2134 fD_GetRegStr(obj
, count
),
2135 fD_GetParam(obj
, count
));
2141 fprintf(outfile
, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2146 fprintf(outfile
, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2147 -fD_GetOffset(obj
));
2151 fprintf(outfile
, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2152 rettype
,-fD_GetOffset(obj
));
2155 for (count
= d0
; count
< numregs
; count
++)
2157 chtmp
= fD_GetProto(obj
, count
);
2158 if (fD_GetFuncParNum(obj
) == count
)
2159 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2161 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2162 "" : " "), fD_GetParam(obj
, count
));
2163 if (count
< numregs
- 1)
2164 fprintf(outfile
, ", ");
2167 fprintf(outfile
, ")\n{\n");
2168 fprintf(outfile
, "\t%s LP%d%s%s(0x%lx, ",
2169 (vd
? "" : "return "),
2172 (BaseName
[0] ? "" : "UB"),
2173 -fD_GetOffset(obj
));
2176 fprintf(outfile
, "%s, ", rettype
);
2177 fprintf(outfile
, "%s, ", name
);
2179 for (count
=d0
; count
<numregs
; count
++)
2181 chtmp
=fD_GetRegStr(obj
, count
);
2183 if (strchr(fD_GetProto(obj
, count
),'%'))
2186 fD_GetProto(obj
, count
),
2189 fprintf(outfile
, "%s, %s, %s%s",
2191 fD_GetParam(obj
, count
),
2193 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2197 fprintf(outfile
, "%s, %s, %s%s",
2198 fD_GetProto(obj
, count
),
2199 fD_GetParam(obj
, count
),
2201 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2206 fprintf(outfile
, "\\\n\t, BASE_NAME");
2208 fprintf(outfile
, ");\n}\n\n");
2213 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2217 else if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
2219 int has_base
= (BaseName
[0] && fD_GetOffset(obj
) != 0);
2224 for (count
=d0
; count
<numregs
; count
++)
2226 if (fD_GetFuncParNum(obj
) == count
)
2228 char funcproto
[200]; /* Hope will be enough... */
2229 sprintf(funcproto
, "%s_%s_funcproto_%d",
2230 BaseNamC
, name
, count
);
2231 fprintf(outfile
, "typedef ");
2232 fprintf(outfile
, fD_GetProto(obj
, count
), funcproto
);
2233 fprintf(outfile
, ";\n");
2238 if (output_mode
==GATESTUBS
)
2240 fprintf(outfile
, "%s %s%s(",
2245 for (count
=d0
; count
<numregs
; count
++)
2247 chtmp
= fD_GetProto(obj
, count
);
2249 fprintf(outfile
, chtmp
, "");
2250 fprintf(outfile
, "%s",
2251 (count
== numregs
- 1 && !has_base
? ");\n" : ", "));
2255 fprintf(outfile
, "struct %s *);\n", StdLib
);
2258 if (target
==M68K_AMIGAOS
)
2260 fprintf(outfile
, "%s %s%s(\n",
2265 for (count
=d0
; count
<numregs
; count
++)
2267 chtmp
= fD_GetProto(obj
, count
);
2269 if (fD_GetFuncParNum(obj
) == count
)
2271 fprintf(outfile
, "\t");
2272 fprintf(outfile
, chtmp
,
2273 fD_GetParam(obj
, count
));
2274 fprintf(outfile
, " __asm(\"%s\")%s",
2275 fD_GetRegStr(obj
, count
),
2276 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2280 fprintf(outfile
, "\t%s %s __asm(\"%s\")%s",
2282 fD_GetParam(obj
, count
),
2283 fD_GetRegStr(obj
, count
),
2284 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2289 fprintf(outfile
, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib
);
2291 if (output_mode
==GATESTUBS
)
2292 fprintf(outfile
, "{\n");
2294 else if (target
==AROS
)
2296 fprintf(outfile
, "AROS_LH%d%s(%s, %s%s,\n",
2298 has_base
? "" : "I",
2303 for (count
=d0
; count
<numregs
; count
++)
2305 char funcproto
[200]; /* Hope will be enough... */
2307 if (fD_GetFuncParNum(obj
) == count
)
2309 sprintf(funcproto
, "%s_%s_funcproto_%d",
2310 BaseNamC
, name
, count
);
2313 fprintf(outfile
, "\tAROS_LHA(%s, %s, %s),\n",
2314 fD_GetFuncParNum(obj
) == count
? funcproto
: fD_GetProto(obj
, count
),
2315 fD_GetParam(obj
, count
),
2316 fD_GetRegStrU(obj
, count
));
2319 fprintf(outfile
, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2321 -fD_GetOffset(obj
) / 6,
2324 if (output_mode
==GATESTUBS
)
2325 fprintf(outfile
, "{\n");
2327 else if (target
==PPC_MORPHOS
)
2329 fprintf(outfile
, "%s %s%s(void)\n",
2334 if (output_mode
==GATESTUBS
)
2336 fprintf(outfile
, "{\n");
2338 for (count
=d0
; count
<numregs
; count
++)
2340 chtmp
= fD_GetProto(obj
, count
);
2342 if (fD_GetFuncParNum(obj
) == count
)
2344 fprintf(outfile
, "\t");
2345 fprintf(outfile
, chtmp
,
2346 fD_GetParam(obj
, count
));
2347 fprintf(outfile
, " = (");
2348 fprintf(outfile
, chtmp
, "");
2349 fprintf(outfile
, ") REG_%s;\n",
2350 fD_GetRegStrU(obj
, count
));
2354 fprintf(outfile
, "\t%s %s = (%s) REG_%s;\n",
2355 fD_GetProto(obj
, count
),
2356 fD_GetParam(obj
, count
),
2357 fD_GetProto(obj
, count
),
2358 fD_GetRegStrU(obj
, count
));
2364 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2367 fprintf(outfile
, "\n");
2370 else if (target
==IX86BE_AMITHLON
)
2372 fprintf(outfile
, "%s %s%s( struct _Regs _regs )\n",
2377 if (output_mode
==GATESTUBS
)
2379 fprintf(outfile
, "{\n");
2381 for (count
=d0
; count
<numregs
; count
++)
2383 chtmp
= fD_GetProto(obj
, count
);
2385 if (fD_GetFuncParNum(obj
) == count
)
2387 fprintf(outfile
, "\t");
2388 fprintf(outfile
, chtmp
,
2389 fD_GetParam(obj
, count
));
2390 fprintf(outfile
, " = (");
2391 fprintf(outfile
, chtmp
, "");
2392 fprintf(outfile
, ") _regs.%s;\n",
2393 fD_GetRegStr(obj
, count
));
2397 fprintf(outfile
, "\t%s %s = (%s) _regs.%s;\n",
2398 fD_GetProto(obj
, count
),
2399 fD_GetParam(obj
, count
),
2400 fD_GetProto(obj
, count
),
2401 fD_GetRegStr(obj
, count
));
2407 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2410 fprintf(outfile
, "\n");
2415 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2419 if (output_mode
==GATESTUBS
)
2421 fprintf(outfile
,"\treturn %s%s(",
2425 for (count
=d0
; count
<numregs
; count
++)
2427 fprintf(outfile
, "%s%s",
2428 fD_GetParam(obj
, count
),
2429 (count
== numregs
- 1 && !has_base
? ");" : ", "));
2433 fprintf(outfile
, "BASE_NAME);");
2435 fprintf(outfile
,"\n}\n\n");
2439 fprintf(outfile
,";\n");
2443 fprintf(outfile
, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2446 BaseNamC
,fD_GetOffset(obj
));
2449 fprintf(outfile
,"\n");
2454 fprintf(stderr
, "Internal error: Unknown output mode in fD_write().\n");
2458 if ((tagname
=aliasfunction(fD_GetName(obj
)))!=0 &&
2459 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2461 fprintf(outfile
, "#define %s(", tagname
);
2462 for (count
=d0
; count
<numregs
-1; count
++)
2463 fprintf(outfile
, "a%d, ", count
);
2464 fprintf(outfile
, "a%d) %s (", count
, name
);
2465 for (count
=d0
; count
<numregs
-1; count
++)
2466 fprintf(outfile
, "(a%d), ", count
);
2467 fprintf(outfile
, "(a%d))\n\n", count
);
2470 if ((tagname
=taggedfunction(obj
))!=0 &&
2471 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2473 if (output_mode
==GENMODULE
)
2477 else if (output_mode
!=STUBS
)
2480 "#ifndef %sNO_INLINE_STDARG\n"
2482 (target
==M68K_POS
? "__" : ""),
2485 for (count
=d0
; count
<numregs
-1; count
++)
2486 fprintf(outfile
, "a%d, ", count
);
2488 fprintf(outfile
, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2491 for (count
=d0
; count
<numregs
-1; count
++)
2492 fprintf(outfile
, "(a%d), ", count
);
2494 fprintf(outfile
, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2495 fD_GetProto(obj
, fD_RegNum(obj
)-1),
2496 (target
==M68K_POS
? "__" : ""));
2501 if (target
==M68K_AMIGAOS
|| target
==IX86BE_AMITHLON
)
2503 fprintf(outfile
, "__inline %s\n%s(", rettype
, tagname
);
2505 for (count
=d0
; count
<numregs
-1; count
++)
2507 chtmp
=fD_GetProto(obj
, count
);
2508 if (count
==fD_GetFuncParNum(obj
))
2509 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2511 fprintf(outfile
, "%s%s%s", chtmp
,
2512 (*(chtmp
+strlen(chtmp
)-1)=='*' ? "" : " "),
2513 fD_GetParam(obj
, count
));
2514 fprintf(outfile
, ", ");
2517 fprintf(outfile
, "int tag, ...)\n{\n ");
2519 fprintf(outfile
, "return ");
2521 fprintf(outfile
, "%s(", name
);
2522 for (count
=d0
; count
<numregs
-1; count
++)
2523 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
2525 fprintf(outfile
, "(%s)&tag);\n}\n\n", fD_GetProto(obj
, fD_RegNum(obj
)-1));
2527 else if (target
==PPC_MORPHOS
)
2529 int n
= 9 - numregs
; /* number of regs that contain varargs */
2530 int d
= n
& 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2531 int taglist
= 8; /* offset of the start of the taglist */
2532 int local
= (taglist
+ n
* 4 + d
+ 8 + 15) & ~15; /* size of the stack frame */
2537 * 0 - 3: next frame ptr
2539 * 8 - 8+n*4+d+8-1: tag list start
2540 * ? - local-1: padding
2547 " .type %s,@function\n"
2549 " stwu 1,-%d(1) \n" /* create stack frame */
2552 tagname
, tagname
, tagname
, local
, local
+ 4);
2555 * If n is odd, one tag is split between regs and stack.
2556 * Copy its ti_Data together with the ti_Tag.
2559 fprintf(outfile
, " lwz 0,%d(1)\n", local
+ 8); /* read ti_Data */
2561 * Save the registers
2563 for (count
= numregs
; count
<= 8; count
++)
2564 fprintf(outfile
, " stw %d,%d(1)\n", count
+ 2, (count
- numregs
) * 4 + taglist
);
2567 fprintf(outfile
, " stw 0,%d(1)\n", taglist
+ n
* 4); /* write ti_Data */
2572 fprintf(outfile
, " li 11,2 \n"
2574 " stw 11,%d(1) \n" /* add TAG_MORE */
2575 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2577 taglist
+ n
* 4 + d
,
2578 taglist
+ n
* 4 + d
+ 4);
2581 if (DirectVarargsCalls
)
2584 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2586 numregs
+ 2, taglist
, name
);
2591 * Save the non-varargs registers in the EmulHandle struct.
2593 for (count
= 0; count
< numregs
- 1; count
++)
2595 int r
= fD_GetReg(obj
, count
);
2597 fprintf(outfile
, " stw %d,%d(2)\n", count
+ 3, r
* 4);
2603 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2604 " stw 0,%d(2) \n" /* REG_?? = taglist */
2606 " lwz 12,%s@l(12)\n"
2607 " li 3,%ld \n" /* r3 = lvo */
2608 " stw 12,56(2) \n" /* REG_A6 = libbase */
2609 " bctrl \n",/* EmulCallOS() */
2610 BaseName
, taglist
, 4 * fD_GetReg(obj
, numregs
- 1), BaseName
,
2614 fprintf(outfile
," lwz 0,%d(1) \n" /* clear stack frame & return */
2619 " .size\t%s,.L%se1-%s\n"
2622 tagname
, tagname
, tagname
, tagname
);
2626 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2631 else if ((varname
= getvarargsfunction(obj
)) != 0 &&
2632 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2634 if (output_mode
!= STUBS
)
2637 "#ifndef NO_INLINE_VARARGS\n"
2638 "#define %s(", varname
);
2640 for (count
= d0
; count
< numregs
- 1; count
++)
2641 fprintf(outfile
, "a%d, ", count
);
2645 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2648 for (count
= d0
; count
< numregs
- 1; count
++)
2649 fprintf(outfile
, "(a%d), ", count
);
2653 "#endif /* !NO_INLINE_VARARGS */\n\n",
2654 fD_GetProto(obj
, fD_RegNum(obj
) - 1));
2658 fprintf(stderr
, "can`t create a varargs stub function for %s\n",
2663 if (strcmp(name
, "DoPkt")==0 &&
2664 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2666 fdDef
*objnc
=(fdDef
*)obj
;
2667 char newname
[7]="DoPkt0";
2668 objnc
->name
=newname
;
2669 for (count
=2; count
<7; count
++)
2671 regs reg
=objnc
->reg
[count
];
2672 char *proto
=objnc
->proto
[count
];
2673 objnc
->reg
[count
]=illegal
;
2674 objnc
->proto
[count
]=fD_nostring
;
2675 fD_write(outfile
, objnc
);
2676 objnc
->reg
[count
]=reg
;
2677 objnc
->proto
[count
]=proto
;
2680 objnc
->name
=(char*)name
;
2685 varargsfunction(const char* proto
, const char* funcname
)
2687 const char *end
=proto
+strlen(proto
)-1;
2688 while (isspace(*end
))
2692 while (isspace(*end
))
2696 while (isspace(*end
))
2698 if (!strncmp(end
-2, "...", 3))
2700 /* Seems to be a varargs function. Check if it will be recognized
2703 char fixedname
[200]; /* Hope will be enough... */
2706 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0];
2708 if (strcmp(funcname
, TagExcTable
[count
+1])==0)
2711 if (!(tmpdef
=fD_ctor()))
2713 fprintf(stderr
, "No mem for FDs\n");
2717 strcpy(fixedname
, funcname
);
2718 if (strlen(funcname
)>4 &&
2719 !strcmp(funcname
+strlen(funcname
)-4, "Tags"))
2721 /* Might be either nothing or "TagList". */
2722 fixedname
[strlen(fixedname
)-4]='\0';
2723 fD_NewName(tmpdef
, fixedname
);
2724 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2728 strcat(fixedname
, "TagList");
2729 fD_NewName(tmpdef
, fixedname
);
2730 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2736 strcat(fixedname
, "A");
2737 fD_NewName(tmpdef
, fixedname
);
2738 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2749 ishandleddifferently(const char* proto
, const char* funcname
)
2751 /* First check if this is a vararg call? */
2752 if (varargsfunction(proto
, funcname
))
2755 /* It might be a dos.library "alias" name. */
2756 if (aliasfunction(funcname
))
2759 /* It might be one from dos.library/DoPkt() family. */
2760 if (strlen(funcname
)==6 && !strncmp(funcname
, "DoPkt", 5) &&
2761 funcname
[5]>='0' && funcname
[6]<='4')
2764 /* Finally, it can be intuition.library/ReportMouse1(). */
2765 return !strcmp(funcname
, "ReportMouse1");
2769 printusage(const char* exename
)
2772 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2775 "--mode=MODE\t\tMODE is one of the following:\n"
2776 "\tnew\t\t\tPreprocessor based (default)\n"
2777 "\told\t\t\tInline based\n"
2778 "\tstubs\t\t\tLibrary stubs\n"
2779 "\tgatestubs\t\tLibrary gate stubs\n"
2780 "\tgateproto\t\tLibrary gate prototypes\n"
2781 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2782 "\tgenmodule\t\t\tBuild genmodule .conf file\n"
2784 "--target=OS\t\tOS is one of the following: \n"
2785 "\t*-aros\t\t\tAROS (any CPU)\n"
2786 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2787 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2788 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2789 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2790 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2792 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2793 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2794 "--libprefix=PREFIX\tLocal function name prefix\n"
2795 "--local\t\t\tUse local includes\n"
2796 "--quiet\t\t\tDon't display warnings\n"
2797 "--version\t\tPrint version number and exit\n\n"
2798 "Compatibility options:\n"
2799 "--new\t\t\tSame as --mode=new\n"
2800 "--old\t\t\tSame as --mode=old\n"
2801 "--stubs\t\t\tSame as --mode=stubs\n"
2802 "--gatestubs\t\tSame as --mode=gatestubs\n"
2803 "--proto\t\t\tSame as --mode=prot\n"
2804 "--pos\t\t\tSame as --target=m68k-pos\n"
2805 "--morphos\t\tSame as --target=powerpc-morphos\n"
2806 "--powerup\t\tSame as --target=powerpc-powerup\n"
2810 void output_proto(FILE* outfile
)
2813 "/* Automatically generated header! Do not edit! */\n\n"
2814 "#ifndef PROTO_%s_H\n"
2815 "#define PROTO_%s_H\n\n",
2816 BaseNamU
, BaseNamU
);
2820 "#ifndef __NOLIBBASE__\n"
2821 "extern struct %s *\n"
2822 "#ifdef __CONSTLIBBASEDECL__\n"
2823 "__CONSTLIBBASEDECL__\n"
2824 "#endif /* __CONSTLIBBASEDECL__ */\n"
2826 "#endif /* !__NOLIBBASE__ */\n\n",
2830 "#ifdef __amigaos4__\n"
2831 "#include <interfaces/%s.h>\n"
2832 "#ifdef __USE_INLINE__\n"
2833 "#include <inline4/%s.h>\n"
2834 "#endif /* __USE_INLINE__ */\n"
2835 "#ifndef CLIB_%s_PROTOS_H\n"
2836 "#define CLIB_%s_PROTOS_H\n"
2837 "#endif /* CLIB_%s_PROTOS_H */\n"
2838 "#ifndef __NOGLOBALIFACE__\n"
2839 "extern struct %sIFace *I%s;\n"
2840 "#endif /* __NOGLOBALIFACE__ */\n"
2841 "#else /* __amigaos4__ */\n"
2842 "#include <clib/%s_protos.h>\n"
2845 "#ifndef NOLIBDEFINES\n"
2846 "#ifndef %s_NOLIBDEFINES\n"
2847 "#include <defines/%s.h>\n"
2848 "#endif /* %s_NOLIBDEFINES */\n"
2849 "#endif /* NOLIBDEFINES */\n"
2852 "#ifndef _NO_PPCINLINE\n"
2853 "#include <ppcinline/%s.h>\n"
2854 "#endif /* _NO_PPCINLINE */\n"
2856 "#ifndef _NO_INLINE\n"
2857 "#include <inline/%s.h>\n"
2858 "#endif /* _NO_INLINE */\n"
2859 "#endif /* __PPC__ */\n"
2860 "#endif /* __AROS__ */\n"
2862 "#include <pragmas/%s_pragmas.h>\n"
2863 "#endif /* __GNUC__ */\n"
2864 "#endif /* __amigaos4__ */\n\n"
2865 "#endif /* !PROTO_%s_H */\n",
2866 BaseNamL
, BaseNamL
, BaseNamU
, BaseNamU
, BaseNamU
, BaseNamC
, BaseNamC
,
2868 BaseNamU
, BaseNamL
, BaseNamU
,
2869 BaseNamL
, BaseNamL
, BaseNamL
,
2873 /******************************************************************************/
2876 main(int argc
, char** argv
)
2878 fdDef
*tmpdef
, /* a dummy to contain the name to look for */
2879 *founddef
; /* the fdDef for which we found a prototype */
2884 char *fdfilename
=0, *clibfilename
=0, *outfilename
=0;
2889 for (count
=1; count
<argc
; count
++)
2891 char *option
=argv
[count
];
2895 if (strcmp(option
, "o")==0)
2897 if (count
==argc
-1 || outfilename
)
2899 printusage(argv
[0]);
2900 return EXIT_FAILURE
;
2902 if (strcmp(argv
[++count
], "-"))
2903 outfilename
=argv
[count
];
2907 if (*option
=='-') /* Accept GNU-style '--' options */
2909 if (strncmp(option
, "mode=", 5)==0)
2911 if (strcmp(option
+5, "new")==0)
2913 else if (strcmp(option
+5, "old")==0)
2915 else if (strcmp(option
+5, "stubs")==0)
2917 else if (strcmp(option
+5, "gatestubs")==0)
2918 output_mode
=GATESTUBS
;
2919 else if (strcmp(option
+5, "gateproto")==0)
2920 output_mode
=GATEPROTO
;
2921 else if (strcmp(option
+5, "proto")==0)
2923 else if (strcmp(option
+5, "genmodule")==0)
2924 output_mode
=GENMODULE
;
2926 else if (strncmp(option
, "target=", 7)==0)
2928 if (MatchGlob("*-aros",option
+7))
2930 else if (MatchGlob("i?86be*-amithlon",option
+7))
2931 target
=IX86BE_AMITHLON
;
2932 else if (MatchGlob("m68k*-amigaos",option
+7))
2933 target
=M68K_AMIGAOS
;
2934 else if (MatchGlob("m68k*-pos",option
+7))
2936 else if (MatchGlob("powerpc*-powerup",option
+7))
2938 else if (MatchGlob("powerpc*-morphos",option
+7))
2942 printusage(argv
[0]);
2943 return EXIT_FAILURE
;
2946 else if (strcmp(option
, "direct-varargs-calls") == 0)
2947 DirectVarargsCalls
= 1;
2948 else if (strncmp(option
, "gateprefix=", 11)==0)
2949 gateprefix
= option
+11;
2950 else if (strncmp(option
, "libprefix=", 10)==0)
2951 libprefix
= option
+10;
2952 else if (strcmp(option
, "quiet") == 0)
2954 else if (strcmp(option
, "version")==0)
2956 fprintf(stderr
, "fd2inline version " VERSION
"\n");
2957 return EXIT_SUCCESS
;
2959 /* Compatibility options */
2960 else if (strcmp(option
, "new")==0)
2962 else if (strcmp(option
, "old")==0)
2964 else if (strcmp(option
, "stubs")==0)
2966 else if (strcmp(option
, "gatestubs")==0)
2967 output_mode
=GATESTUBS
;
2968 else if (strcmp(option
, "proto")==0)
2970 else if (strcmp(option
, "pos")==0)
2972 else if (strcmp(option
, "powerup")==0)
2974 else if (strcmp(option
, "morphos")==0)
2976 /* Unknown option */
2979 printusage(argv
[0]);
2980 return EXIT_FAILURE
;
2986 /* One of the filenames */
2989 else if (!clibfilename
)
2990 clibfilename
=option
;
2991 else if (!outfilename
)
2995 printusage(argv
[0]);
2996 return EXIT_FAILURE
;
3001 if (!fdfilename
|| (!clibfilename
&& output_mode
!=PROTO
))
3003 printusage(argv
[0]);
3004 return EXIT_FAILURE
;
3007 if (target
==M68K_POS
&& output_mode
!=NEW
&& output_mode
!=GENMODULE
)
3009 fprintf(stderr
, "Target is not compatible with the mode.\n");
3010 return EXIT_FAILURE
;
3013 if (!(arrdefs
=malloc(FDS
*sizeof(fdDef
*))))
3015 fprintf(stderr
, "No mem for FDs\n");
3016 return EXIT_FAILURE
;
3018 for (count
=0; count
<FDS
; count
++)
3019 arrdefs
[count
]=NULL
;
3021 if (!(myfile
=fF_ctor(fdfilename
)))
3023 fprintf(stderr
, "Couldn't open file '%s'.\n", fdfilename
);
3024 return EXIT_FAILURE
;
3029 for (count
=0; count
<FDS
&& lerror
==false; count
++)
3031 if (!(arrdefs
[count
]=fD_ctor()))
3033 fprintf(stderr
, "No mem for FDs\n" );
3034 return EXIT_FAILURE
;
3038 if ((lerror
=fF_readln(myfile
))==false)
3040 fF_SetError(myfile
, false);
3041 lerror
=fD_parsefd(arrdefs
[count
], myfile
);
3044 while (lerror
==nodef
);
3049 fD_dtor(arrdefs
[count
]);
3050 arrdefs
[count
]=NULL
;
3054 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpName
);
3056 if (output_mode
!=NEW
|| target
==AROS
)
3058 unsigned int count2
;
3061 for (count2
=0; count2
<sizeof LibExcTable
/sizeof LibExcTable
[0]; count2
+=2)
3062 if (strcmp(BaseName
, LibExcTable
[count2
])==0)
3064 StdLib
=LibExcTable
[count2
+1];
3071 if (output_mode
!=PROTO
)
3073 if (!(myfile
=fF_ctor(clibfilename
)))
3075 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3076 return EXIT_FAILURE
;
3079 if (!(tmpdef
=fD_ctor()))
3081 fprintf(stderr
, "No mem for FDs\n");
3082 return EXIT_FAILURE
;
3085 for (lerror
=false; lerror
==false || lerror
==nodef
;)
3086 if ((lerror
=fF_readln(myfile
))==false)
3088 fF_SetError(myfile
, false); /* continue even on errors */
3089 tmpstr
=fF_FuncName(myfile
);
3094 fD_NewName(tmpdef
, tmpstr
);
3095 res
=(fdDef
**)bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
3101 DBP(fprintf(stderr
, "found (%s).\n", fD_GetName(founddef
)));
3102 fF_SetError(myfile
, false);
3103 lerror
=fD_parsepr(founddef
, myfile
);
3106 if (!ishandleddifferently(myfile
->line
, tmpstr
))
3108 fprintf(stderr
, "Don't know what to do with <%s> in line %lu.\n",
3109 tmpstr
, myfile
->lineno
);
3119 if (strlen(fdfilename
)>7 &&
3120 !strcmp(fdfilename
+strlen(fdfilename
)-7, "_lib.fd"))
3122 char *str
=fdfilename
+strlen(fdfilename
)-8;
3123 while (str
!=fdfilename
&& str
[-1]!='/' && str
[-1]!=':')
3125 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3126 strncpy(BaseNamU
, str
, strlen(str
)-7);
3127 BaseNamU
[strlen(str
)-7]='\0';
3128 strcpy(BaseNamL
, BaseNamU
);
3129 strcpy(BaseNamC
, BaseNamU
);
3133 strcpy(BaseNamU
, BaseName
);
3134 if (strlen(BaseNamU
)>4 && strcmp(BaseNamU
+strlen(BaseNamU
)-4, "Base")==0)
3135 BaseNamU
[strlen(BaseNamU
)-4]='\0';
3136 if (target
==M68K_POS
&& strncmp(BaseNamU
, "gb_", 3)==0)
3137 memmove(BaseNamU
, &BaseNamU
[3], strlen(&BaseNamU
[3])+1);
3138 strcpy(BaseNamL
, BaseNamU
);
3139 strcpy(BaseNamC
, BaseNamU
);
3142 BaseNamC
[0]=toupper(BaseNamC
[0]);
3146 if (!(outfile
=fopen(outfilename
, "w")))
3148 fprintf(stderr
, "Couldn't open output file.\n");
3149 return EXIT_FAILURE
;
3159 if (output_mode
==PROTO
)
3160 output_proto(outfile
);
3161 else if (output_mode
==GENMODULE
)
3164 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpOffset
);
3166 fprintf(outfile
,"##begin config\n"
3174 "##begin functionlist\n"
3175 , BaseName
, BaseName
);
3178 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3180 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3181 long off
= fD_GetOffset(arrdefs
[count
]);
3183 int skip
= (offset
- off
) / 6;
3184 fprintf(outfile
, ".skip %d\n", skip
);
3187 fD_write(outfile
, arrdefs
[count
]);
3188 fD_dtor(arrdefs
[count
]);
3189 arrdefs
[count
]=NULL
;
3192 fprintf(outfile
, "##end functionlist\n");
3196 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
||
3197 output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3199 if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3202 "/* Automatically generated stubs! Do not edit! */\n\n");
3207 "/* Automatically generated header! Do not edit! */\n\n"
3208 "#ifndef %sINLINE_%s_H\n"
3209 "#define %sINLINE_%s_H\n\n",
3210 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3212 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3216 if (output_mode
==NEW
)
3218 if(target
==M68K_POS
)
3221 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3222 "#include <pInline/macros.h>\n"
3223 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3225 else if(target
==AROS
)
3228 "#ifndef AROS_LIBCALL_H\n"
3229 "#include <aros/libcall.h>\n"
3230 "#endif /* !AROS_LIBCALL_H */\n\n");
3235 "#ifndef __INLINE_MACROS_H\n"
3236 "#include <inline/macros.h>\n"
3237 "#endif /* !__INLINE_MACROS_H */\n\n");
3245 "#ifndef __INLINE_STUB_H\n"
3246 "#include <inline/stubs.h>\n"
3247 "#endif /* !__INLINE_STUB_H */\n\n");
3249 fprintf(outfile
, "#ifdef __CLIB_TYPES__\n" );
3251 clib
= fopen( clibfilename
, "r" );
3255 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3259 char* buffer
= malloc( 1024 );
3261 if( buffer
== NULL
)
3263 fprintf(stderr
, "No memory for line buffer.\n " );
3267 while( fgets( buffer
, 1023, clib
) != NULL
)
3269 if( buffer
[ 0 ] == '#' /* Pre-processor instruction */ ||
3270 strncmp( buffer
, "typedef", 7 ) == 0 )
3272 fputs(buffer
, outfile
);
3282 fprintf(outfile
, "#endif /* __CLIB_TYPES__ */\n\n" );
3287 "#include <aros/libcall.h>\n\n" );
3289 else if(target
==IX86BE_AMITHLON
)
3292 "#ifndef __INLINE_MACROS_H\n"
3293 "#include <inline/macros.h>\n"
3294 "#endif /* __INLINE_MACROS_H */\n\n");
3296 else if (target
== PPC_MORPHOS
)
3299 "#include <emul/emulregs.h>\n\n" );
3305 fprintf(stderr
, "Internal error: Unknown output mode in main().\n");
3312 return EXIT_FAILURE
;
3317 if (output_mode
==NEW
)
3320 "#ifndef %s%s_BASE_NAME\n"
3321 "#define %s%s_BASE_NAME %s\n"
3322 "#endif /* !%s%s_BASE_NAME */\n\n",
3323 (target
==M68K_POS
? "__" : ""), BaseNamU
,
3324 (target
==M68K_POS
? "__" : ""), BaseNamU
, BaseName
,
3325 (target
==M68K_POS
? "__" : ""), BaseNamU
);
3326 if (target
==M68K_POS
)
3328 "#ifndef __%s_LIB_NAME\n"
3329 "#define __%s_LIB_NAME %s\n"
3330 "#endif /* !__%s_LIB_NAME */\n\n",
3332 (strcmp(BaseName
, "gb_ExecBase") ? BaseName
: "gb_ExecLib"),
3337 "#ifndef BASE_EXT_DECL\n"
3338 "#define BASE_EXT_DECL\n"
3339 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3340 "#endif /* !BASE_EXT_DECL */\n"
3341 "#ifndef BASE_PAR_DECL\n"
3342 "#define BASE_PAR_DECL\n"
3343 "#define BASE_PAR_DECL0 void\n"
3344 "#endif /* !BASE_PAR_DECL */\n"
3345 "#ifndef BASE_NAME\n"
3346 "#define BASE_NAME %s\n"
3347 "#endif /* !BASE_NAME */\n\n"
3348 "BASE_EXT_DECL0\n\n", StdLib
, BaseName
, BaseName
);
3351 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3353 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3355 fD_write(outfile
, arrdefs
[count
]);
3356 fD_dtor(arrdefs
[count
]);
3357 arrdefs
[count
]=NULL
;
3360 if (output_mode
!=NEW
)
3363 "#undef BASE_EXT_DECL\n"
3364 "#undef BASE_EXT_DECL0\n"
3365 "#undef BASE_PAR_DECL\n"
3366 "#undef BASE_PAR_DECL0\n"
3367 "#undef BASE_NAME\n\n");
3369 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
)
3371 fprintf(outfile
, "#endif /* !%sINLINE_%s_H */\n",
3372 (target
==M68K_POS
? "__INC_POS_P" : "_"), BaseNamU
);
3383 return EXIT_SUCCESS
;