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 ******************************************************************************/
42 const static char version_str
[]="$VER: fd2inline " VERSION
" (24.2.2002)";
44 /******************************************************************************
45 * These are general definitions including types for defining registers etc.
46 ******************************************************************************/
54 #if (defined(__GNUC__) || defined(__SASC)) && 0
55 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
60 #define REGS 16 /* d0=0,...,a7=15 */
63 /* To prevent the enum below from getting broken when building on AROS */
68 d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
, a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, illegal
71 typedef unsigned char shortcard
;
73 typedef enum { false, nodef
, real_error
} Error
;
75 enum { NEW
, OLD
, STUBS
, PROTO
, GATESTUBS
, GATEPROTO
} output_mode
=NEW
;
76 enum { IX86BE_AMITHLON
, AROS
, M68K_AMIGAOS
, M68K_POS
, PPC_POWERUP
, PPC_MORPHOS
} target
= M68K_AMIGAOS
;
79 int DirectVarargsCalls
= 0;
83 char *gateprefix
= "";
86 char BaseName
[64], BaseNamU
[64], BaseNamL
[64], BaseNamC
[64];
89 const static char *LibExcTable
[]=
91 "BattClockBase", "Node",
92 "BattMemBase", "Node",
93 "ConsoleDevice", "Device",
94 "DiskBase", "DiskResource",
95 "DOSBase", "DosLibrary",
96 "SysBase", "ExecBase",
97 "ExpansionBase", "ExpansionBase",
99 "InputBase", "Device",
100 "IntuitionBase", "IntuitionBase",
101 "LocaleBase", "LocaleBase",
102 "MathIeeeDoubBasBase", "MathIEEEBase",
103 "MathIeeeDoubTransBase","MathIEEEBase",
104 "MathIeeeSingBasBase", "MathIEEEBase",
105 "MathIeeeSingTransBase","MathIEEEBase",
108 "RamdriveDevice", "Device",
109 "RealTimeBase", "RealTimeBase",
110 "RexxSysBase", "RxsLib",
111 "TimerBase", "Device",
112 "UtilityBase", "UtilityBase"
114 const char *StdLib
; /* global lib-name ptr */
116 /*******************************************
117 * just some support functions, no checking
118 *******************************************/
121 NewString(char** new, const char* old
)
126 while (*old
&& (*old
==' ' || *old
=='\t'))
129 for (high
=old
+len
-1; high
>=old
&& (*high
==' ' || *high
=='\t'); high
--);
135 strncpy(*new, old
, len
);
139 fprintf(stderr
, "No mem for string\n");
144 illparams(const char* funcname
)
146 fprintf(stderr
, "%s: illegal Parameters\n", funcname
);
149 static INLINE
const char*
152 const static char *aosregs
[]=
154 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
155 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
182 return (target
!=M68K_POS
? aosregs
[reg
] : posregs
[reg
]);
185 static INLINE
const char*
188 const static char *aosregs
[]=
190 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
191 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
198 return (target
!=M68K_POS
? aosregs
[reg
] : RegStr(reg
));
203 /******************************************************************************
206 * searches string in from position at downwards, as long as in does not
207 * contain any character in not.
209 ******************************************************************************/
212 StrNRBrk(const char* in
, const char* not, const char* at
)
217 chcheck
=""; /* if at<in, the result will be NULL */
218 for (ready
=false; ready
==false && at
>=in
;)
220 for (chcheck
=not; *chcheck
&& *chcheck
!= *at
; chcheck
++);
226 DBP(fprintf(stderr
, "{%c}", *chcheck
));
227 return *chcheck
? at
: NULL
;
231 Our own "strupr", since it is a non-standard function.
244 MatchGlob( char* glob
, char* str
)
261 if( c
== 0 || *str
!= c
)
275 if( MatchGlob( glob
, str
) )
298 /******************************************************************************
301 * stores a file with a temporary buffer (static length, sorry), a line number,
302 * an offset (used for library offsets and an error field.
303 * When there's no error, line will contain line #lineno and offset will be
304 * the last offset set by the interpretation of the last line. If there's been
305 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
306 * It is assumed offsets are always negative.
307 ******************************************************************************/
309 #define fF_BUFSIZE 1024
311 /* all you need to know about an fdFile you parse */
313 typedef enum {FD_PRIVATE
=1, FD_SHADOW
=2} fdflags
;
317 FILE* file
; /* the file we're reading from */
318 char line
[fF_BUFSIZE
]; /* the current line */
319 unsigned long lineno
; /* current line number */
320 long offset
; /* current fd offset (-bias) */
321 Error error
; /* is everything o.k. */
322 fdflags flags
; /* for ##private, ##shadow (p.OS) */
326 fF_ctor (const char* fname
);
328 fF_dtor (fdFile
* obj
);
330 fF_SetError (fdFile
* obj
, Error error
);
332 fF_SetOffset (fdFile
* obj
, long at
);
334 fF_readln (fdFile
* obj
);
336 fF_GetError (const fdFile
* obj
);
338 fF_GetOffset (const fdFile
* obj
);
340 fF_FuncName (fdFile
* obj
); /* return name or null */
342 fF_SetFlags (fdFile
* obj
, fdflags flags
);
344 fF_GetFlags (const fdFile
* obj
);
354 fF_SetError(fdFile
* obj
, Error error
)
359 illparams("fF_SetError");
362 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
365 fF_SetOffset(fdFile
* obj
, long at
)
370 illparams("fFSetOffset");
374 fF_SetFlags(fdFile
* obj
, fdflags flags
)
379 illparams("fF_SetFlags");
383 fF_ctor(const char* fname
)
389 result
=malloc(sizeof(fdFile
));
392 result
->file
=fopen(fname
, "r");
396 fF_SetOffset(result
, -30);
397 fF_SetError(result
, false);
398 fF_SetFlags(result
, 0);
399 result
->line
[0]='\0';
411 illparams("fF_ctor");
417 fF_readln(fdFile
* obj
)
420 long glen
, /* the length we read until now */
421 len
; /* the length of the last segment */
431 if (!fgets(low
, fF_BUFSIZE
-1-glen
, obj
->file
))
433 fF_SetError(obj
, real_error
);
437 if (low
==strpbrk(low
, "*#/"))
439 DBP(fprintf(stderr
, "in# %s\n", obj
->line
));
444 while (len
&& isspace(*bpoint
))
449 if (*bpoint
==';' || *bpoint
==')')
451 DBP(fprintf(stderr
, "\nin: %s\n", obj
->line
));
456 if (glen
>=fF_BUFSIZE
-10) /* somewhat pessimistic? */
458 fF_SetError(obj
, real_error
);
459 fprintf(stderr
, "Line %lu too long.\n", obj
->lineno
);
462 DBP(fprintf(stderr
, "+"));
465 illparams("fF_readln");
470 fF_GetError(const fdFile
* obj
)
474 illparams("fF_GetError");
479 fF_GetOffset(const fdFile
* obj
)
483 illparams("fF_GetOffset");
487 /******************************************************************************
490 * checks if it can find a function-name and return it's address, or NULL
491 * if the current line does not seem to contain one. The return value will
492 * be a pointer into a malloced buffer, thus the caller will have to free().
493 ******************************************************************************/
496 fF_FuncName(fdFile
* obj
)
501 long obraces
; /* count of open braces */
502 Error ready
; /* ready with searching */
504 if (!obj
|| fF_GetError(obj
)==real_error
)
506 illparams("fF_FuncName");
511 while (*lower
&& (*lower
==' ' || *lower
=='\t'))
514 if (!*lower
|| (!isalpha(*lower
) && *lower
!='_'))
516 fF_SetError(obj
, nodef
);
522 if (!isalnum(*lower
) && !isspace(*lower
) && *lower
!='*' && *lower
!=','
523 && *lower
!='.' && *lower
!=';' && *lower
!='(' && *lower
!=')' &&
524 *lower
!='[' && *lower
!=']' && *lower
!='_' && *lower
!='\\')
526 fF_SetError(obj
, nodef
);
535 if (obj
&& fF_GetError(obj
)==false)
537 if ((upper
=strrchr(obj
->line
, ')'))!=0)
539 DBP(fprintf(stderr
, "end:%s:", upper
));
541 for (obraces
=1, ready
=false; ready
==false; upper
=lower
)
543 lower
=StrNRBrk(obj
->line
, "()", --upper
);
550 DBP(fprintf(stderr
, " )%ld%s", obraces
, lower
));
554 DBP(fprintf(stderr
, " (%ld%s", obraces
, lower
));
559 fprintf(stderr
, "Faulty StrNRBrk\n");
564 fprintf(stderr
, "'(' or ')' expected in line %lu.\n",
569 if (ready
==nodef
) /* we found the matching '(' */
576 while (upper
>=obj
->line
&& (*upper
==' ' || *upper
=='\t'))
579 lower
=StrNRBrk(obj
->line
, " \t*)", upper
);
586 for (name
=lower
; name
<=upper
; name
++)
587 if (!isalnum(*name
) && *name
!='_')
589 fF_SetError(obj
, nodef
);
593 newlen
=upper
-lower
+1;
594 buf
=malloc(newlen
+1);
598 strncpy(buf
, lower
, newlen
);
602 fprintf(stderr
, "No mem for fF_FuncName");
607 illparams("fF_FuncName");
611 static INLINE fdflags
612 fF_GetFlags(const fdFile
* obj
)
616 illparams("fF_GetFlags");
620 /*********************
622 *********************/
632 regs funcpar
; /* number of argument that has type "pointer to function" */
638 fD_dtor (fdDef
* obj
);
640 fD_NewName (fdDef
* obj
, const char* newname
);
642 fD_NewParam (fdDef
* obj
, shortcard at
, const char* newstr
);
644 fD_NewProto (fdDef
* obj
, shortcard at
, char* newstr
);
646 fD_NewReg (fdDef
* obj
, shortcard at
, regs reg
);
648 fD_NewType (fdDef
* obj
, const char* newstr
);
650 fD_SetOffset (fdDef
* obj
, long off
);
652 fD_parsefd (fdDef
* obj
, fdFile
* infile
);
654 fD_parsepr (fdDef
* obj
, fdFile
* infile
);
656 fD_GetName (const fdDef
* obj
);
658 fD_GetOffset (const fdDef
* obj
);
660 fD_GetParam (const fdDef
* obj
, shortcard at
);
662 fD_GetReg (const fdDef
* obj
, shortcard at
);
664 fD_GetRegStr (const fdDef
* obj
, shortcard at
);
666 fD_GetRegStrU (const fdDef
* obj
, shortcard at
);
668 fD_GetType (const fdDef
* obj
);
670 fD_ParamNum (const fdDef
* obj
);
672 fD_ProtoNum (const fdDef
* obj
);
674 fD_RegNum (const fdDef
* obj
);
676 fD_cmpName (const void* big
, const void* small
);
678 fD_write (FILE* outfile
, const fdDef
* obj
);
680 fD_GetFuncParNum (const fdDef
* obj
);
682 fD_SetFuncParNum (fdDef
* obj
, shortcard at
);
684 fD_adjustargnames(fdDef
*obj
);
689 char *fD_nostring
="";
697 result
=malloc(sizeof(fdDef
));
701 result
->name
=fD_nostring
;
702 result
->type
=fD_nostring
;
703 result
->funcpar
=illegal
;
705 for (count
=d0
; count
<illegal
; count
++ )
707 result
->reg
[count
]=illegal
;
708 result
->param
[count
]=fD_nostring
; /* if (!strlen) dont't free() */
709 result
->proto
[count
]=fD_nostring
;
715 /* free all resources and make the object as illegal as possible */
725 fprintf(stderr
, "fD_dtor: null name");
727 if (obj
->name
!=fD_nostring
)
731 fprintf(stderr
, "fD_dtor: null type");
733 if (obj
->type
!=fD_nostring
)
736 obj
->name
=obj
->type
=NULL
;
738 for (count
=d0
; count
<illegal
; count
++)
740 obj
->reg
[count
]=illegal
;
742 if (!obj
->param
[count
])
743 fprintf(stderr
, "fD_dtor: null param");
745 if (obj
->param
[count
]!=fD_nostring
)
746 free(obj
->param
[count
]);
748 if (!obj
->proto
[count
])
749 fprintf(stderr
, "fD_dtor: null proto");
751 if (obj
->proto
[count
]!=fD_nostring
)
752 free(obj
->proto
[count
]);
754 obj
->param
[count
]=obj
->proto
[count
]=NULL
;
760 fprintf(stderr
, "fd_dtor(NULL)\n");
764 fD_NewName(fdDef
* obj
, const char* newname
)
768 if (obj
->name
&& obj
->name
!=fD_nostring
)
770 if (!NewString(&obj
->name
, newname
))
771 obj
->name
=fD_nostring
;
774 illparams("fD_NewName");
778 fD_NewParam(fdDef
* obj
, shortcard at
, const char* newstr
)
782 if (newstr
&& obj
&& at
<illegal
)
786 if (pa
&& pa
!=fD_nostring
)
789 while (*newstr
==' ' || *newstr
=='\t')
792 if (NewString(&pa
, newstr
))
796 prefix_pa
= malloc( strlen( pa
) + 4 );
798 if( prefix_pa
== NULL
)
800 fprintf(stderr
, "No mem for string\n");
804 sprintf( prefix_pa
, "___%s", pa
);
805 obj
->param
[at
]=prefix_pa
;
810 obj
->param
[at
]=fD_nostring
;
813 illparams("fD_NewParam");
816 /* get first free *reg or illegal */
818 static INLINE shortcard
819 fD_RegNum(const fdDef
* obj
)
825 for (count
=d0
; count
<illegal
&& obj
->reg
[count
]!=illegal
; count
++);
830 illparams("fD_RegNum");
836 fD_NewReg(fdDef
* obj
, shortcard at
, regs reg
)
838 if (obj
&& at
<illegal
&& reg
>=d0
&& reg
<=illegal
)
841 illparams("fD_NewReg");
845 fD_GetReg(const fdDef
* obj
, shortcard at
)
847 if (obj
&& at
<illegal
)
851 illparams("fD_GetReg");
856 static INLINE shortcard
857 fD_GetFuncParNum(const fdDef
* obj
)
860 return (shortcard
)obj
->funcpar
;
863 illparams("fD_GetFuncParNum");
869 fD_SetFuncParNum(fdDef
* obj
, shortcard at
)
871 if (obj
&& at
<illegal
)
874 illparams("fD_SetFuncParNum");
878 fD_NewProto(fdDef
* obj
, shortcard at
, char* newstr
)
882 if (newstr
&& obj
&& at
<illegal
)
884 char *t
, arr
[200]; /* I hope 200 will be enough... */
888 if (pr
&& pr
!=fD_nostring
)
891 while (*newstr
==' ' || *newstr
=='\t')
892 newstr
++; /* Skip leading spaces */
895 while ((*t
++=*newstr
)!=0)
897 /* Copy the rest, counting number of words */
898 if ((*newstr
==' ' || *newstr
=='\t') && newstr
[1] && newstr
[1]!=' ' &&
905 while (*t
==' ' || *t
=='\t')
907 t
[1]='\0'; /* Get rid of tailing spaces */
909 if (at
!=fD_GetFuncParNum(obj
))
911 if (numwords
>1) /* One word - must be type */
914 /* '*' on the end - no parameter name used */
915 while (*t
!=' ' && *t
!='\t' && *t
!='*')
918 if (strcmp(t
, "char") && strcmp(t
, "short") && strcmp(t
, "int")
919 && strcmp(t
, "long") && strcmp(t
, "APTR"))
921 /* Not one of applicable keywords - must be parameter name.
924 while (*t
==' ' || *t
=='\t')
932 /* Parameter of type "pointer to function". */
936 while (*t
==' ' || *t
=='\t')
942 if (target
!=M68K_POS
)
944 memmove(t
+2, end
, strlen(end
)+1);
949 memmove(t
, end
, strlen(end
)+1);
952 if (NewString(&pr
, arr
))
955 while (*pr
==' ' || *pr
=='\t')
957 if (!strcasecmp(pr
, "double"))
959 /* "double" needs two data registers */
960 int count
, regs
=fD_RegNum(obj
);
961 for (count
=at
+1; count
<regs
; count
++)
962 fD_NewReg(obj
, count
, fD_GetReg(obj
, count
+1));
966 obj
->proto
[at
]=fD_nostring
;
969 illparams("fD_NewProto");
975 fD_NewType(fdDef
* obj
, const char* newtype
)
979 if (obj
->type
&& obj
->type
!=fD_nostring
)
981 if (!NewString(&obj
->type
, newtype
))
982 obj
->type
=fD_nostring
;
985 illparams("fD_NewType");
989 fD_SetOffset(fdDef
* obj
, long off
)
994 illparams("fD_SetOffset");
997 static INLINE
const char*
998 fD_GetName(const fdDef
* obj
)
1000 if (obj
&& obj
->name
)
1004 illparams("fD_GetName");
1010 fD_GetOffset(const fdDef
* obj
)
1016 illparams("fD_GetOffset");
1021 static INLINE
const char*
1022 fD_GetProto(const fdDef
* obj
, shortcard at
)
1024 if (obj
&& at
<illegal
&& obj
->proto
[at
])
1025 return obj
->proto
[at
];
1028 illparams("fD_GetProto");
1033 static INLINE
const char*
1034 fD_GetParam(const fdDef
* obj
, shortcard at
)
1036 if (obj
&& at
<illegal
&& obj
->param
[at
])
1037 return obj
->param
[at
];
1040 illparams("fD_GetParam");
1045 static INLINE
const char*
1046 fD_GetRegStr(const fdDef
* obj
, shortcard at
)
1048 if (obj
&& at
<illegal
)
1049 return RegStr(obj
->reg
[at
]);
1052 illparams("fD_GetReg");
1053 return RegStr(illegal
);
1057 static INLINE
const char*
1058 fD_GetRegStrU(const fdDef
* obj
, shortcard at
)
1060 if (obj
&& at
<illegal
)
1061 return RegStrU(obj
->reg
[at
]);
1064 illparams("fD_GetReg");
1065 return RegStrU(illegal
);
1069 static INLINE
const char*
1070 fD_GetType(const fdDef
* obj
)
1072 if (obj
&& obj
->type
)
1076 illparams("fD_GetType");
1081 /* get first free param or illegal */
1083 static INLINE shortcard
1084 fD_ParamNum(const fdDef
* obj
)
1090 for (count
=d0
; count
<illegal
&& obj
->param
[count
]!=fD_nostring
;
1096 illparams("fD_ParamNum");
1101 static INLINE shortcard
1102 fD_ProtoNum(const fdDef
* obj
)
1108 for (count
=d0
; count
<illegal
&& obj
->proto
[count
]!=fD_nostring
;
1114 illparams("fD_ProtoNum");
1119 /******************************************************************************
1122 * parse the current line. Needs to copy input, in order to insert \0's
1124 * fF_GetError(infile):
1125 * false = read a definition.
1126 * nodef = not a definition on line (so try again)
1127 * error = real error
1128 ******************************************************************************/
1131 fD_parsefd(fdDef
* obj
, fdFile
* infile
)
1133 enum parse_info
{ name
, params
, regs
, ready
} parsing
;
1134 char *buf
, *bpoint
, *bnext
;
1135 unsigned long index
;
1137 if (obj
&& infile
&& fF_GetError(infile
)==false)
1141 if (!NewString(&buf
, infile
->line
))
1143 fprintf(stderr
, "No mem for line %lu\n", infile
->lineno
);
1144 fF_SetError(infile
, real_error
);
1146 bpoint
=buf
; /* so -Wall keeps quiet */
1148 /* try to parse the line until there's an error or we are done */
1150 while (parsing
!=ready
&& fF_GetError(infile
)==false)
1158 if (strncmp("##base", buf
, 6)==0)
1161 while (*bnext
==' ' || *bnext
=='\t' || *bnext
=='_')
1163 strcpy(BaseName
, bnext
);
1164 BaseName
[strlen(BaseName
)-1]='\0';
1167 if (strncmp("##bias", buf
, 6)==0)
1169 if (!sscanf(buf
+6, "%ld", &infile
->offset
))
1171 fprintf(stderr
, "Illegal ##bias in line %lu: %s\n",
1172 infile
->lineno
, infile
->line
);
1173 fF_SetError(infile
, real_error
);
1174 break; /* avoid nodef */
1178 if (fF_GetOffset(infile
)>0)
1179 fF_SetOffset(infile
, -fF_GetOffset(infile
));
1180 DBP(fprintf(stderr
, "set offset to %ld\n",
1181 fF_GetOffset(infile
)));
1186 if (strncmp("##private", buf
, 9)==0)
1187 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1189 else if (strncmp("##public", buf
, 8)==0)
1190 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1192 else if (strncmp("##shadow", buf
, 8)==0)
1193 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1196 /* drop through for error comment */
1199 /* try again somewhere else */
1200 fF_SetError(infile
, nodef
);
1204 /* assume a regular line here */
1205 if (fF_GetFlags(infile
) & (FD_PRIVATE
| FD_SHADOW
))
1207 /* don't store names of privates */
1208 fF_SetError(infile
, nodef
);
1209 if (!(fF_GetFlags(infile
) & FD_SHADOW
))
1210 fF_SetOffset(infile
,
1211 fF_GetOffset(infile
)-FUNCTION_GAP
);
1213 /* Shadow is valid for one line only. */
1214 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1218 parsing
=name
; /* switch (parsing) */
1219 for (index
=0; buf
[index
] && buf
[index
]!='('; index
++);
1224 fprintf(stderr
, "Not an fd, line %lu: %s\n",
1225 infile
->lineno
, buf
/* infile->line */);
1226 fF_SetError(infile
, nodef
);
1227 } /* maybe next time */
1232 fD_NewName(obj
, buf
);
1233 fD_SetOffset(obj
, fF_GetOffset(infile
));
1236 parsing
=params
; /* continue the loop */
1243 char *bptmp
; /* needed for fD_NewParam */
1245 /* look for parameters now */
1247 for (bnext
= bpoint
; *bnext
&& *bnext
!=',' && *bnext
!=')';
1256 if (bnext
[1] != '(')
1258 fprintf(stderr
, "Registers expected in line %lu: %s\n",
1259 infile
->lineno
, infile
->line
);
1260 fF_SetError(infile
, nodef
);
1271 /* terminate string and advance to next item */
1274 fD_NewParam(obj
, fD_ParamNum(obj
), bptmp
);
1278 fF_SetError(infile
, nodef
);
1279 fprintf(stderr
, "Param expected in line %lu: %s\n",
1280 infile
->lineno
, infile
->line
);
1282 break; /* switch parsing */
1286 /* look for parameters now */
1288 for (bnext
=bpoint
; *bnext
&& *bnext
!='/' && *bnext
!=',' &&
1289 *bnext
!=')'; bnext
++);
1295 /* wow, we've finished */
1296 fF_SetOffset(infile
, fF_GetOffset(infile
)-FUNCTION_GAP
);
1301 bpoint
[0]=tolower(bpoint
[0]);
1303 if ((bpoint
[0]=='d' || bpoint
[0]=='a') && bpoint
[1]>='0' &&
1304 bpoint
[1]<='8' && bnext
==bpoint
+2)
1305 fD_NewReg(obj
, fD_RegNum(obj
),
1306 bpoint
[1]-'0'+(bpoint
[0]=='a'? 8 : 0));
1310 /* it is when our function is void */
1311 fprintf(stderr
, "Illegal register %s in line %ld\n",
1312 bpoint
, infile
->lineno
);
1313 fF_SetError(infile
, nodef
);
1319 fF_SetError(infile
, nodef
);
1320 fprintf(stderr
, "Reg expected in line %lu\n",
1323 break; /* switch parsing */
1326 fprintf(stderr
, "Internal error, use another compiler.\n");
1332 return fF_GetError(infile
);
1336 illparams("fD_parsefd");
1342 fD_adjustargnames(fdDef
*obj
)
1346 if (output_mode
!=NEW
)
1349 /* For #define-base output mode, we have to check if argument names are not
1350 the same as some words in type names. We check from the first argument
1351 to the last, resolving conflicts by changing argument names, if
1354 for (parnum
=0; parnum
<fD_ParamNum(obj
); parnum
++)
1356 const char *parname
=fD_GetParam(obj
, parnum
);
1361 const char *type
=fD_GetType(obj
);
1366 if ((str
=strstr(type
, parname
))!=0 && (str
==type
||
1367 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1368 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_')))
1370 char buf
[300]; /* Hope will be enough... */
1371 strcpy(buf
, parname
);
1373 fD_NewParam(obj
, parnum
, buf
);
1374 parname
=fD_GetParam(obj
, parnum
);
1378 for (num
=0; num
<fD_ParamNum(obj
); num
++)
1380 const char *name
=fD_GetParam(obj
, num
);
1381 const char *proto
=fD_GetProto(obj
, num
);
1382 if ((num
<parnum
&& strcmp(name
, parname
)==0) ||
1383 ((str
=strstr(proto
, parname
))!=0 && (str
==proto
||
1384 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1385 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_'))))
1387 char buf
[300]; /* Hope will be enough... */
1388 strcpy(buf
, parname
);
1390 fD_NewParam(obj
, parnum
, buf
);
1391 parname
=fD_GetParam(obj
, parnum
);
1396 } while (!finished
);
1401 fD_parsepr(fdDef
* obj
, fdFile
* infile
)
1403 char *buf
; /* a copy of infile->line */
1404 char *bpoint
, /* cursor in buf */
1405 *bnext
, /* looking for the end */
1406 *lowarg
; /* beginning of this argument */
1407 long obraces
; /* count of open braces */
1408 regs count
, /* count parameter number */
1409 args
; /* the number of arguments for this function */
1411 if (!(obj
&& infile
&& fF_GetError(infile
)==false))
1413 illparams("fD_parsepr");
1414 fF_SetError(infile
, real_error
);
1417 if (!NewString(&buf
, infile
->line
))
1419 fprintf(stderr
, "No mem for fD_parsepr\n");
1420 fF_SetError(infile
, real_error
);
1423 fF_SetError(infile
, false);
1425 bpoint
=strchr(buf
, '(');
1426 while (--bpoint
>=buf
&& strstr(bpoint
, fD_GetName(obj
))!=bpoint
);
1429 while (--bpoint
>= buf
&& (*bpoint
==' ' || *bpoint
=='\t'));
1432 fD_NewType(obj
, buf
);
1434 while (bpoint
&& *bpoint
++!='('); /* one beyond '(' */
1439 for (count
=0, args
=fD_RegNum(obj
); count
<args
; bpoint
=bnext
+1)
1441 while (*bpoint
&& (*bpoint
==' ' || *bpoint
=='\t')) /* ignore spaces */
1444 if (!obraces
&& target
==M68K_POS
&& strncmp(bpoint
, "_R_", 3)==0 &&
1445 isalnum(bpoint
[3]) && isalnum(bpoint
[4]) && isspace(bpoint
[5]))
1448 bnext
=strpbrk(bpoint
, "(),");
1457 if (target
==M68K_AMIGAOS
|| target
==M68K_POS
)
1459 if (fD_GetFuncParNum(obj
)!=illegal
&&
1460 fD_GetFuncParNum(obj
)!=count
&&
1462 fprintf(stderr
, "Warning: two parameters of type "
1463 "pointer to function are used.\n"
1464 "This is not supported!\n");
1467 fD_SetFuncParNum(obj
, count
);
1470 DBP(fprintf(stderr
, "< (%ld%s >", obraces
, bnext
));
1476 DBP(fprintf(stderr
, "< )%ld%s >", obraces
, bnext
));
1482 DBP(fprintf(stderr
, "< )0> [LAST PROTO=%s]", lowarg
));
1483 if (fD_NewProto(obj
, count
, lowarg
))
1484 fprintf(stderr
, "Parser confused in line %ld\n",
1490 DBP(fprintf(stderr
, "%s needs %u arguments and got %u.\n",
1491 fD_GetName(obj
), args
, count
+1));
1492 fF_SetError(infile
, nodef
);
1502 DBP(fprintf(stderr
, " [PROTO=%s] ", lowarg
));
1503 if (fD_NewProto(obj
, count
, lowarg
))
1504 fprintf(stderr
, "Parser confused in line %ld\n",
1512 fprintf(stderr
, "Faulty strpbrk in line %lu.\n",
1518 DBP(fprintf(stderr
, "Faulty argument %u in line %lu.\n", count
+1,
1520 count
=args
; /* this will effectively quit the for loop */
1521 fF_SetError(infile
, nodef
);
1524 if (fD_ProtoNum(obj
)!=fD_RegNum(obj
))
1525 fF_SetError(infile
, nodef
);
1529 fprintf(stderr
, "fD_parsepr was fooled in line %lu\n", infile
->lineno
);
1530 fprintf(stderr
, "function , definition %s.\n",
1531 /* fD_GetName(obj),*/ infile
->line
);
1532 fF_SetError(infile
, nodef
);
1537 fD_adjustargnames(obj
);
1539 return fF_GetError(infile
);
1543 fD_cmpName(const void* big
, const void* small
) /* for qsort and bsearch */
1545 return strcmp(fD_GetName(*(fdDef
**)big
), fD_GetName(*(fdDef
**)small
));
1548 const static char *TagExcTable
[]=
1550 "BuildEasyRequestArgs", "BuildEasyRequest",
1551 "DoDTMethodA", "DoDTMethod",
1552 "DoGadgetMethodA", "DoGadgetMethod",
1553 "EasyRequestArgs", "EasyRequest",
1554 "MUI_MakeObjectA", "MUI_MakeObject",
1555 "MUI_RequestA", "MUI_Request",
1556 "PrintDTObjectA", "PrintDTObject",
1557 "RefreshDTObjectA", "RefreshDTObjects",
1558 "UMSVLog", "UMSLog",
1559 "VFWritef", "FWritef",
1560 "VFPrintf", "FPrintf",
1561 "VPrintf", "Printf",
1565 getvarargsfunction(const fdDef
* obj
)
1568 const char *name
= fD_GetName(obj
);
1570 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1572 if (strcmp(name
, TagExcTable
[count
])==0)
1574 return TagExcTable
[count
+1];
1581 taggedfunction(const fdDef
* obj
)
1583 shortcard numregs
=fD_RegNum(obj
);
1586 const char *name
=fD_GetName(obj
);
1587 static char newname
[200]; /* Hope will be enough... static because used
1588 out of the function. */
1589 const char *lastarg
;
1590 const static char *TagExcTable2
[]=
1598 "PackStructureTags",
1599 "RefreshTagItemClones",
1600 "UnpackStructureTags",
1606 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1607 if (strcmp(name
, TagExcTable
[count
])==0)
1609 // lcs return TagExcTable[count+1];
1611 for (count
=0; count
<sizeof TagExcTable2
/sizeof TagExcTable2
[0]; count
++)
1612 if (strcmp(name
, TagExcTable2
[count
])==0)
1615 lastarg
=fD_GetProto(obj
, numregs
-1);
1616 if (strncmp(lastarg
, "const", 5)==0 || strncmp(lastarg
, "CONST", 5)==0)
1618 while (*lastarg
==' ' || *lastarg
=='\t')
1620 if (strncmp(lastarg
, "struct", 6))
1623 while (*lastarg
==' ' || *lastarg
=='\t')
1626 if (strncmp(lastarg
, "TagItem", 7) &&
1627 (target
!=M68K_POS
|| ((aos_tagitem
=strncmp(lastarg
, "pOS_TagItem", 11))!=0)))
1629 lastarg
+=(aos_tagitem
? 7 : 11);
1630 while (*lastarg
==' ' || *lastarg
=='\t')
1632 if (strcmp(lastarg
, "*"))
1635 strcpy(newname
, name
);
1636 if (newname
[strlen(newname
)-1]=='A')
1637 newname
[strlen(newname
)-1]='\0';
1639 if (strlen(newname
)>7 && !strcmp(newname
+strlen(newname
)-7, "TagList"))
1640 strcpy(newname
+strlen(newname
)-4, "s");
1642 strcat(newname
, "Tags");
1647 aliasfunction(const char* name
)
1649 const static char *AliasTable
[]=
1651 "AllocDosObject", "AllocDosObjectTagList",
1652 "CreateNewProc", "CreateNewProcTagList",
1653 "NewLoadSeg", "NewLoadSegTagList",
1654 "System", "SystemTagList",
1657 for (count
=0; count
<sizeof AliasTable
/sizeof AliasTable
[0]; count
++)
1658 if (strcmp(name
, AliasTable
[count
])==0)
1659 return AliasTable
[count
+(count
%2 ? -1 : 1)];
1664 fD_write(FILE* outfile
, const fdDef
* obj
)
1666 shortcard count
, numregs
;
1667 const char *chtmp
, *tagname
, *varname
, *name
, *rettype
;
1668 int vd
=0, a45
=0, d7
=0;
1670 DBP(fprintf(stderr
, "func %s\n", fD_GetName(obj
)));
1672 numregs
=fD_RegNum(obj
);
1674 if ((rettype
=fD_GetType(obj
))==fD_nostring
)
1676 fprintf(stderr
, "%s has no prototype.\n", fD_GetName(obj
));
1679 if (!strcasecmp(rettype
, "void"))
1680 vd
= 1; /* set flag */
1681 for (count
=d0
; count
<numregs
; count
++)
1683 const char *reg
=fD_GetRegStr(obj
, count
);
1684 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1686 if (strcmp(reg
, "a4")==0 || strcmp(reg
, "a5")==0)
1689 a45
=(strcmp(reg
, "a4") ? 5 : 4); /* set flag */
1690 else /* Security check */
1692 fprintf(stderr
, "Warning: both a4 and a5 are used. "
1693 "This is not supported!\n");
1696 if (strcmp(reg
, "d7")==0) /* Used only when a45!=0 */
1700 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1702 if (a45
&& d7
) /* Security check */
1704 fprintf(stderr
, "Warning: d7 and a4 or a5 are used. This is not "
1708 name
=fD_GetName(obj
);
1710 if (fD_ProtoNum(obj
)!=numregs
)
1712 fprintf(stderr
, "%s gets %d fd args and %d proto%s.\n", name
, numregs
,
1713 fD_ProtoNum(obj
), fD_ProtoNum(obj
)!= 1 ? "s" : "");
1717 if (output_mode
==NEW
)
1719 fprintf(outfile
, "#define %s(", name
);
1723 for (count
=d0
; count
<numregs
-1; count
++)
1724 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
1725 fprintf(outfile
, "%s", fD_GetParam(obj
, count
));
1728 if (target
==M68K_AMIGAOS
)
1730 fprintf(outfile
, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs
,
1731 (vd
? "NR" : ""), (a45
? (a45
==4 ? "A4" : "A5") : ""),
1732 (BaseName
[0] ? "" : "UB"),
1733 (fD_GetFuncParNum(obj
)==illegal
? "" : "FP"), -fD_GetOffset(obj
));
1735 fprintf(outfile
, "%s, ", rettype
);
1736 fprintf(outfile
, "%s, ", name
);
1738 for (count
=d0
; count
<numregs
; count
++)
1740 chtmp
=fD_GetRegStr(obj
, count
);
1741 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1743 fprintf(outfile
, "%s, %s, %s%s", (fD_GetFuncParNum(obj
)==count
?
1744 "__fpt" : fD_GetProto(obj
, count
)),
1745 fD_GetParam(obj
, count
),
1746 chtmp
, (count
==numregs
-1 && !BaseName
[0] ? "" : ", "));
1749 if (BaseName
[0]) /* was "##base" used? */
1750 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1751 if (fD_GetFuncParNum(obj
)!=illegal
)
1753 fprintf(outfile
, ", ");
1754 fprintf(outfile
, fD_GetProto(obj
, fD_GetFuncParNum(obj
)), "__fpt");
1756 fprintf(outfile
, ")\n\n");
1758 else if(target
==M68K_POS
)
1760 fprintf(outfile
, ") \\\n\t__INLINE_FUN_%d(", numregs
);
1761 fprintf(outfile
, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1762 BaseNamU
, BaseNamU
, -fD_GetOffset(obj
), rettype
, name
,
1763 (numregs
? ", \\\n\t" : ""));
1765 for (count
=d0
; count
<numregs
; count
++)
1766 fprintf(outfile
, "%s, %s, %s%s", fD_GetProto(obj
, count
),
1767 fD_GetParam(obj
, count
), fD_GetRegStr(obj
, count
),
1768 (count
==numregs
-1 ? "" : ", "));
1769 fprintf(outfile
, ")\n\n");
1771 else if (target
==PPC_POWERUP
|| target
==PPC_MORPHOS
)
1773 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1776 (BaseName
[0] ? "" : "UB"),
1777 -fD_GetOffset(obj
));
1780 fprintf(outfile
, "%s, ", rettype
);
1781 fprintf(outfile
, "%s, ", name
);
1783 for (count
=d0
; count
<numregs
; count
++)
1785 chtmp
=fD_GetRegStr(obj
, count
);
1787 if (strchr(fD_GetProto(obj
, count
),'%'))
1790 fD_GetProto(obj
, count
),
1793 fprintf(outfile
, "%s, %s, %s%s",
1795 fD_GetParam(obj
, count
),
1797 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1801 fprintf(outfile
, "%s, %s, %s%s",
1802 fD_GetProto(obj
, count
),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1803 fD_GetParam(obj
, count
),
1805 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1810 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1813 * Here it would make sense to create a database file to
1814 * integrate optimizations automaticly into every new
1815 * build. Not every function needs a complete flush. For
1816 * example functions with no parameter wouldn`t need a
1817 * PPC flush normally. Or Read(File,Addr,Size); would
1818 * only need a flush for Addr with the Size
1821 fprintf(outfile
, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1822 fprintf(outfile
, ")\n\n");
1824 else if (target
==IX86BE_AMITHLON
)
1826 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1829 (BaseName
[0] ? "" : "UB"),
1830 -fD_GetOffset(obj
));
1833 fprintf(outfile
, "%s, ", rettype
);
1834 fprintf(outfile
, "%s, ", name
);
1836 for (count
=d0
; count
<numregs
; count
++)
1838 chtmp
=fD_GetRegStr(obj
, count
);
1840 if (strchr(fD_GetProto(obj
, count
),'%'))
1843 fD_GetProto(obj
, count
),
1846 fprintf(outfile
, "%s, %s, %s%s",
1848 fD_GetParam(obj
, count
),
1850 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1854 fprintf(outfile
, "%s, %s, %s%s",
1855 fD_GetProto(obj
, count
),
1856 fD_GetParam(obj
, count
),
1858 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1863 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1865 fprintf(outfile
, ")\n\n");
1867 else if (target
==AROS
)
1869 fprintf(outfile
, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1871 (BaseName
[0] ? "" : "I"),
1872 (vd
? "void" : rettype
),
1875 for (count
=d0
; count
<numregs
; count
++)
1877 chtmp
=fD_GetRegStrU(obj
, count
);
1878 fprintf(outfile
, "\tAROS_LCA(%s, (%s), %s), \\\n",
1879 fD_GetProto(obj
, count
),
1880 fD_GetParam(obj
, count
),
1884 if (BaseName
[0]) /* was "##base" used? */
1886 fprintf(outfile
, "\tstruct %s *, %s_BASE_NAME, ", StdLib
, BaseNamU
);
1890 fprintf(outfile
, "\t/* bt */, /* bn */, ");
1893 "%ld, /* s */)\n\n",
1894 -fD_GetOffset(obj
) / 6);
1898 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
1902 else if (output_mode
==OLD
|| output_mode
==STUBS
)
1904 fprintf(outfile
, "%s__inline %s\n%s(%s",
1905 (output_mode
==STUBS
? "" : "extern "), rettype
, name
,
1906 (BaseName
[0] ? (numregs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1908 if (target
==M68K_AMIGAOS
)
1910 for (count
=d0
; count
<numregs
; count
++)
1912 chtmp
=fD_GetProto(obj
, count
);
1913 if (fD_GetFuncParNum(obj
)==count
)
1914 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1916 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1917 "" : " "), fD_GetParam(obj
, count
));
1918 if (count
<numregs
-1)
1919 fprintf(outfile
, ", ");
1922 fprintf(outfile
, ")\n{\n%s", (BaseName
[0] ? " BASE_EXT_DECL\n" : ""));
1924 fprintf(outfile
, " register %s%sres __asm(\"d0\");\n", rettype
,
1925 (*(rettype
+strlen(rettype
)-1)=='*' ? "" : " "));
1928 fprintf(outfile
, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1931 for (count
=d0
; count
<numregs
; count
++)
1933 chtmp
=fD_GetRegStr(obj
, count
);
1934 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1936 if (fD_GetFuncParNum(obj
)==count
)
1938 fprintf(outfile
, " register ");
1939 fprintf(outfile
, fD_GetProto(obj
, count
), chtmp
);
1940 fprintf(outfile
, " __asm(\"%s\") = %s;\n", chtmp
, fD_GetParam(obj
,
1945 const char *proto
=fD_GetProto(obj
, count
);
1946 fprintf(outfile
, " register %s%s%s __asm(\"%s\") = %s;\n",
1947 proto
, (*(proto
+strlen(proto
)-1)=='*' ? "" : " "), chtmp
,
1948 chtmp
, fD_GetParam(obj
, count
));
1952 fprintf(outfile
, " __asm volatile (\"exg d7,%s\\n\\t"
1953 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45
==4 ? "a4" : "a5"),
1954 -fD_GetOffset(obj
), (a45
==4 ? "a4" : "a5"));
1956 fprintf(outfile
, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1957 -fD_GetOffset(obj
));
1959 fprintf(outfile
, (vd
? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1961 fprintf(outfile
, " : ");
1963 fprintf(outfile
, "\"r\" (a6)%s", (numregs
? ", ": ""));
1965 for (count
=d0
; count
<numregs
; count
++)
1967 chtmp
=fD_GetRegStr(obj
, count
);
1968 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1970 fprintf(outfile
, "\"r\" (%s)%s", chtmp
, (count
<numregs
-1 ? ", " : ""));
1972 fprintf(outfile
, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1975 fprintf(outfile
, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1977 fprintf(outfile
, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1980 else if (target
==PPC_POWERUP
)
1982 for (count
= d0
; count
< numregs
; count
++)
1984 chtmp
= fD_GetProto(obj
, count
);
1985 if (fD_GetFuncParNum(obj
) == count
)
1986 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1988 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
1989 "" : " "), fD_GetParam(obj
, count
));
1990 if (count
< numregs
- 1)
1991 fprintf(outfile
, ", ");
1994 fprintf(outfile
, ")\t\n");
1995 fprintf(outfile
, "{\t\n");
1996 fprintf(outfile
, "struct Caos\tMyCaos;\n");
1997 fprintf(outfile
, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1998 fprintf(outfile
, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
1999 fprintf(outfile
, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2000 fprintf(outfile
, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2001 fprintf(outfile
, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2002 fprintf(outfile
, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2006 for (count
= d0
; count
< numregs
; count
++)
2008 fprintf(outfile
, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2009 fD_GetRegStr(obj
, count
),
2010 fD_GetParam(obj
, count
));
2014 fprintf(outfile
, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj
));
2016 * was "##base" used?
2019 fprintf(outfile
, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2023 fprintf(outfile
, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2027 fprintf(outfile
, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2031 else if (target
==PPC_MORPHOS
)
2033 for (count
= d0
; count
< numregs
; count
++)
2035 chtmp
= fD_GetProto(obj
, count
);
2036 if (fD_GetFuncParNum(obj
) == count
)
2037 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2039 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2040 "" : " "), fD_GetParam(obj
, count
));
2041 if (count
< numregs
- 1)
2042 fprintf(outfile
, ", ");
2045 fprintf(outfile
, ")\t\n{\t\n");
2049 for (count
= d0
; count
< numregs
; count
++)
2051 fprintf(outfile
, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2052 fD_GetRegStrU(obj
, count
), fD_GetParam(obj
, count
));
2057 * was "##base" used?
2060 fprintf(outfile
, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2064 fprintf(outfile
, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj
));
2068 fprintf(outfile
, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2069 rettype
, fD_GetOffset(obj
));
2072 else if (target
==IX86BE_AMITHLON
)
2075 for (count
= d0
; count
< numregs
; count
++)
2077 chtmp
= fD_GetProto(obj
, count
);
2078 if (fD_GetFuncParNum(obj
) == count
)
2079 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2081 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2082 "" : " "), fD_GetParam(obj
, count
));
2083 if (count
< numregs
- 1)
2084 fprintf(outfile
, ", ");
2087 fprintf(outfile
, ")\n{\n");
2088 fprintf(outfile
, "\tstruct _Regs _regs;\n");
2092 for (count
= d0
; count
< numregs
; count
++)
2094 fprintf(outfile
, "\t_regs.reg_%s = (ULONG) (%s);\n",
2095 fD_GetRegStr(obj
, count
),
2096 fD_GetParam(obj
, count
));
2102 fprintf(outfile
, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2107 fprintf(outfile
, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2108 -fD_GetOffset(obj
));
2112 fprintf(outfile
, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2113 rettype
,-fD_GetOffset(obj
));
2116 for (count
= d0
; count
< numregs
; count
++)
2118 chtmp
= fD_GetProto(obj
, count
);
2119 if (fD_GetFuncParNum(obj
) == count
)
2120 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2122 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2123 "" : " "), fD_GetParam(obj
, count
));
2124 if (count
< numregs
- 1)
2125 fprintf(outfile
, ", ");
2128 fprintf(outfile
, ")\n{\n");
2129 fprintf(outfile
, "\t%s LP%d%s%s(0x%lx, ",
2130 (vd
? "" : "return "),
2133 (BaseName
[0] ? "" : "UB"),
2134 -fD_GetOffset(obj
));
2137 fprintf(outfile
, "%s, ", rettype
);
2138 fprintf(outfile
, "%s, ", name
);
2140 for (count
=d0
; count
<numregs
; count
++)
2142 chtmp
=fD_GetRegStr(obj
, count
);
2144 if (strchr(fD_GetProto(obj
, count
),'%'))
2147 fD_GetProto(obj
, count
),
2150 fprintf(outfile
, "%s, %s, %s%s",
2152 fD_GetParam(obj
, count
),
2154 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2158 fprintf(outfile
, "%s, %s, %s%s",
2159 fD_GetProto(obj
, count
),
2160 fD_GetParam(obj
, count
),
2162 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2167 fprintf(outfile
, "\\\n\t, BASE_NAME");
2169 fprintf(outfile
, ");\n}\n\n");
2174 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2178 else if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
2180 int has_base
= (BaseName
[0] && fD_GetOffset(obj
) != 0);
2185 for (count
=d0
; count
<numregs
; count
++)
2187 if (fD_GetFuncParNum(obj
) == count
)
2189 char funcproto
[200]; /* Hope will be enough... */
2190 sprintf(funcproto
, "%s_%s_funcproto_%d",
2191 BaseNamC
, name
, count
);
2192 fprintf(outfile
, "typedef ");
2193 fprintf(outfile
, fD_GetProto(obj
, count
), funcproto
);
2194 fprintf(outfile
, ";\n");
2199 if (output_mode
==GATESTUBS
)
2201 fprintf(outfile
, "%s %s%s(",
2206 for (count
=d0
; count
<numregs
; count
++)
2208 chtmp
= fD_GetProto(obj
, count
);
2210 fprintf(outfile
, chtmp
, "");
2211 fprintf(outfile
, "%s",
2212 (count
== numregs
- 1 && !has_base
? ");\n" : ", "));
2216 fprintf(outfile
, "struct %s *);\n", StdLib
);
2219 if (target
==M68K_AMIGAOS
)
2221 fprintf(outfile
, "%s %s%s(\n",
2226 for (count
=d0
; count
<numregs
; count
++)
2228 chtmp
= fD_GetProto(obj
, count
);
2230 if (fD_GetFuncParNum(obj
) == count
)
2232 fprintf(outfile
, "\t");
2233 fprintf(outfile
, chtmp
,
2234 fD_GetParam(obj
, count
));
2235 fprintf(outfile
, " __asm(\"%s\")%s",
2236 fD_GetRegStr(obj
, count
),
2237 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2241 fprintf(outfile
, "\t%s %s __asm(\"%s\")%s",
2243 fD_GetParam(obj
, count
),
2244 fD_GetRegStr(obj
, count
),
2245 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2250 fprintf(outfile
, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib
);
2252 if (output_mode
==GATESTUBS
)
2253 fprintf(outfile
, "{\n");
2255 else if (target
==AROS
)
2257 fprintf(outfile
, "AROS_LH%d%s(%s, %s%s,\n",
2259 has_base
? "" : "I",
2264 for (count
=d0
; count
<numregs
; count
++)
2266 char funcproto
[200]; /* Hope will be enough... */
2268 if (fD_GetFuncParNum(obj
) == count
)
2270 sprintf(funcproto
, "%s_%s_funcproto_%d",
2271 BaseNamC
, name
, count
);
2274 fprintf(outfile
, "\tAROS_LHA(%s, %s, %s),\n",
2275 fD_GetFuncParNum(obj
) == count
? funcproto
: fD_GetProto(obj
, count
),
2276 fD_GetParam(obj
, count
),
2277 fD_GetRegStrU(obj
, count
));
2280 fprintf(outfile
, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2282 -fD_GetOffset(obj
) / 6,
2285 if (output_mode
==GATESTUBS
)
2286 fprintf(outfile
, "{\n");
2288 else if (target
==PPC_MORPHOS
)
2290 fprintf(outfile
, "%s %s%s(void)\n",
2295 if (output_mode
==GATESTUBS
)
2297 fprintf(outfile
, "{\n");
2299 for (count
=d0
; count
<numregs
; count
++)
2301 chtmp
= fD_GetProto(obj
, count
);
2303 if (fD_GetFuncParNum(obj
) == count
)
2305 fprintf(outfile
, "\t");
2306 fprintf(outfile
, chtmp
,
2307 fD_GetParam(obj
, count
));
2308 fprintf(outfile
, " = (");
2309 fprintf(outfile
, chtmp
, "");
2310 fprintf(outfile
, ") REG_%s;\n",
2311 fD_GetRegStrU(obj
, count
));
2315 fprintf(outfile
, "\t%s %s = (%s) REG_%s;\n",
2316 fD_GetProto(obj
, count
),
2317 fD_GetParam(obj
, count
),
2318 fD_GetProto(obj
, count
),
2319 fD_GetRegStrU(obj
, count
));
2325 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2328 fprintf(outfile
, "\n");
2331 else if (target
==IX86BE_AMITHLON
)
2333 fprintf(outfile
, "%s %s%s( struct _Regs _regs )\n",
2338 if (output_mode
==GATESTUBS
)
2340 fprintf(outfile
, "{\n");
2342 for (count
=d0
; count
<numregs
; count
++)
2344 chtmp
= fD_GetProto(obj
, count
);
2346 if (fD_GetFuncParNum(obj
) == count
)
2348 fprintf(outfile
, "\t");
2349 fprintf(outfile
, chtmp
,
2350 fD_GetParam(obj
, count
));
2351 fprintf(outfile
, " = (");
2352 fprintf(outfile
, chtmp
, "");
2353 fprintf(outfile
, ") _regs.%s;\n",
2354 fD_GetRegStr(obj
, count
));
2358 fprintf(outfile
, "\t%s %s = (%s) _regs.%s;\n",
2359 fD_GetProto(obj
, count
),
2360 fD_GetParam(obj
, count
),
2361 fD_GetProto(obj
, count
),
2362 fD_GetRegStr(obj
, count
));
2368 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2371 fprintf(outfile
, "\n");
2376 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2380 if (output_mode
==GATESTUBS
)
2382 fprintf(outfile
,"\treturn %s%s(",
2386 for (count
=d0
; count
<numregs
; count
++)
2388 fprintf(outfile
, "%s%s",
2389 fD_GetParam(obj
, count
),
2390 (count
== numregs
- 1 && !has_base
? ");" : ", "));
2394 fprintf(outfile
, "BASE_NAME);");
2396 fprintf(outfile
,"\n}\n\n");
2400 fprintf(outfile
,";\n");
2404 fprintf(outfile
, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2407 BaseNamC
,fD_GetOffset(obj
));
2410 fprintf(outfile
,"\n");
2415 fprintf(stderr
, "Internal error: Unknown output mode in fD_write().\n");
2419 if ((tagname
=aliasfunction(fD_GetName(obj
)))!=0 &&
2420 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2422 fprintf(outfile
, "#define %s(", tagname
);
2423 for (count
=d0
; count
<numregs
-1; count
++)
2424 fprintf(outfile
, "a%d, ", count
);
2425 fprintf(outfile
, "a%d) %s (", count
, name
);
2426 for (count
=d0
; count
<numregs
-1; count
++)
2427 fprintf(outfile
, "(a%d), ", count
);
2428 fprintf(outfile
, "(a%d))\n\n", count
);
2431 if ((tagname
=taggedfunction(obj
))!=0 &&
2432 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2434 if (output_mode
!=STUBS
)
2437 "#ifndef %sNO_INLINE_STDARG\n"
2439 (target
==M68K_POS
? "__" : ""),
2442 for (count
=d0
; count
<numregs
-1; count
++)
2443 fprintf(outfile
, "a%d, ", count
);
2445 fprintf(outfile
, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2448 for (count
=d0
; count
<numregs
-1; count
++)
2449 fprintf(outfile
, "(a%d), ", count
);
2451 fprintf(outfile
, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2452 fD_GetProto(obj
, fD_RegNum(obj
)-1),
2453 (target
==M68K_POS
? "__" : ""));
2458 if (target
==M68K_AMIGAOS
|| target
==IX86BE_AMITHLON
)
2460 fprintf(outfile
, "__inline %s\n%s(", rettype
, tagname
);
2462 for (count
=d0
; count
<numregs
-1; count
++)
2464 chtmp
=fD_GetProto(obj
, count
);
2465 if (count
==fD_GetFuncParNum(obj
))
2466 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2468 fprintf(outfile
, "%s%s%s", chtmp
,
2469 (*(chtmp
+strlen(chtmp
)-1)=='*' ? "" : " "),
2470 fD_GetParam(obj
, count
));
2471 fprintf(outfile
, ", ");
2474 fprintf(outfile
, "int tag, ...)\n{\n ");
2476 fprintf(outfile
, "return ");
2478 fprintf(outfile
, "%s(", name
);
2479 for (count
=d0
; count
<numregs
-1; count
++)
2480 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
2482 fprintf(outfile
, "(%s)&tag);\n}\n\n", fD_GetProto(obj
, fD_RegNum(obj
)-1));
2484 else if (target
==PPC_MORPHOS
)
2486 int n
= 9 - numregs
; /* number of regs that contain varargs */
2487 int d
= n
& 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2488 int taglist
= 8; /* offset of the start of the taglist */
2489 int local
= (taglist
+ n
* 4 + d
+ 8 + 15) & ~15; /* size of the stack frame */
2494 * 0 - 3: next frame ptr
2496 * 8 - 8+n*4+d+8-1: tag list start
2497 * ? - local-1: padding
2504 " .type %s,@function\n"
2506 " stwu 1,-%d(1) \n" /* create stack frame */
2509 tagname
, tagname
, tagname
, local
, local
+ 4);
2512 * If n is odd, one tag is split between regs and stack.
2513 * Copy its ti_Data together with the ti_Tag.
2516 fprintf(outfile
, " lwz 0,%d(1)\n", local
+ 8); /* read ti_Data */
2518 * Save the registers
2520 for (count
= numregs
; count
<= 8; count
++)
2521 fprintf(outfile
, " stw %d,%d(1)\n", count
+ 2, (count
- numregs
) * 4 + taglist
);
2524 fprintf(outfile
, " stw 0,%d(1)\n", taglist
+ n
* 4); /* write ti_Data */
2529 fprintf(outfile
, " li 11,2 \n"
2531 " stw 11,%d(1) \n" /* add TAG_MORE */
2532 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2534 taglist
+ n
* 4 + d
,
2535 taglist
+ n
* 4 + d
+ 4);
2538 if (DirectVarargsCalls
)
2541 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2543 numregs
+ 2, taglist
, name
);
2548 * Save the non-varargs registers in the EmulHandle struct.
2550 for (count
= 0; count
< numregs
- 1; count
++)
2552 int r
= fD_GetReg(obj
, count
);
2554 fprintf(outfile
, " stw %d,%d(2)\n", count
+ 3, r
* 4);
2560 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2561 " stw 0,%d(2) \n" /* REG_?? = taglist */
2563 " lwz 12,%s@l(12)\n"
2564 " li 3,%ld \n" /* r3 = lvo */
2565 " stw 12,56(2) \n" /* REG_A6 = libbase */
2566 " bctrl \n",/* EmulCallOS() */
2567 BaseName
, taglist
, 4 * fD_GetReg(obj
, numregs
- 1), BaseName
,
2571 fprintf(outfile
," lwz 0,%d(1) \n" /* clear stack frame & return */
2576 " .size\t%s,.L%se1-%s\n"
2579 tagname
, tagname
, tagname
, tagname
);
2583 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2588 else if ((varname
= getvarargsfunction(obj
)) != 0 &&
2589 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2591 if (output_mode
!= STUBS
)
2594 "#ifndef NO_INLINE_VARARGS\n"
2595 "#define %s(", varname
);
2597 for (count
= d0
; count
< numregs
- 1; count
++)
2598 fprintf(outfile
, "a%d, ", count
);
2602 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2605 for (count
= d0
; count
< numregs
- 1; count
++)
2606 fprintf(outfile
, "(a%d), ", count
);
2610 "#endif /* !NO_INLINE_VARARGS */\n\n",
2611 fD_GetProto(obj
, fD_RegNum(obj
) - 1));
2615 fprintf(stderr
, "can`t create a varargs stub function for %s\n",
2620 if (strcmp(name
, "DoPkt")==0 &&
2621 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2623 fdDef
*objnc
=(fdDef
*)obj
;
2624 char newname
[7]="DoPkt0";
2625 objnc
->name
=newname
;
2626 for (count
=2; count
<7; count
++)
2628 regs reg
=objnc
->reg
[count
];
2629 char *proto
=objnc
->proto
[count
];
2630 objnc
->reg
[count
]=illegal
;
2631 objnc
->proto
[count
]=fD_nostring
;
2632 fD_write(outfile
, objnc
);
2633 objnc
->reg
[count
]=reg
;
2634 objnc
->proto
[count
]=proto
;
2637 objnc
->name
=(char*)name
;
2642 varargsfunction(const char* proto
, const char* funcname
)
2644 const char *end
=proto
+strlen(proto
)-1;
2645 while (isspace(*end
))
2649 while (isspace(*end
))
2653 while (isspace(*end
))
2655 if (!strncmp(end
-2, "...", 3))
2657 /* Seems to be a varargs function. Check if it will be recognized
2660 char fixedname
[200]; /* Hope will be enough... */
2663 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0];
2665 if (strcmp(funcname
, TagExcTable
[count
+1])==0)
2668 if (!(tmpdef
=fD_ctor()))
2670 fprintf(stderr
, "No mem for FDs\n");
2674 strcpy(fixedname
, funcname
);
2675 if (strlen(funcname
)>4 &&
2676 !strcmp(funcname
+strlen(funcname
)-4, "Tags"))
2678 /* Might be either nothing or "TagList". */
2679 fixedname
[strlen(fixedname
)-4]='\0';
2680 fD_NewName(tmpdef
, fixedname
);
2681 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2685 strcat(fixedname
, "TagList");
2686 fD_NewName(tmpdef
, fixedname
);
2687 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2693 strcat(fixedname
, "A");
2694 fD_NewName(tmpdef
, fixedname
);
2695 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2706 ishandleddifferently(const char* proto
, const char* funcname
)
2708 /* First check if this is a vararg call? */
2709 if (varargsfunction(proto
, funcname
))
2712 /* It might be a dos.library "alias" name. */
2713 if (aliasfunction(funcname
))
2716 /* It might be one from dos.library/DoPkt() family. */
2717 if (strlen(funcname
)==6 && !strncmp(funcname
, "DoPkt", 5) &&
2718 funcname
[5]>='0' && funcname
[6]<='4')
2721 /* Finally, it can be intuition.library/ReportMouse1(). */
2722 return !strcmp(funcname
, "ReportMouse1");
2726 printusage(const char* exename
)
2729 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2732 "--mode=MODE\t\tMODE is one of the following:\n"
2733 "\tnew\t\t\tPreprocessor based (default)\n"
2734 "\told\t\t\tInline based\n"
2735 "\tstubs\t\t\tLibrary stubs\n"
2736 "\tgatestubs\t\tLibrary gate stubs\n"
2737 "\tgateproto\t\tLibrary gate prototypes\n"
2738 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2740 "--target=OS\t\tOS is one of the following: \n"
2741 "\t*-aros\t\t\tAROS (any CPU)\n"
2742 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2743 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2744 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2745 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2746 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2748 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2749 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2750 "--libprefix=PREFIX\tLocal function name prefix\n"
2751 "--local\t\t\tUse local includes\n"
2752 "--quiet\t\t\tDon't display warnings\n"
2753 "--version\t\tPrint version number and exit\n\n"
2754 "Compatibility options:\n"
2755 "--new\t\t\tSame as --mode=new\n"
2756 "--old\t\t\tSame as --mode=old\n"
2757 "--stubs\t\t\tSame as --mode=stubs\n"
2758 "--gatestubs\t\tSame as --mode=gatestubs\n"
2759 "--proto\t\t\tSame as --mode=prot\n"
2760 "--pos\t\t\tSame as --target=m68k-pos\n"
2761 "--morphos\t\tSame as --target=powerpc-morphos\n"
2762 "--powerup\t\tSame as --target=powerpc-powerup\n"
2766 void output_proto(FILE* outfile
)
2769 "/* Automatically generated header! Do not edit! */\n\n"
2770 "#ifndef PROTO_%s_H\n"
2771 "#define PROTO_%s_H\n\n",
2772 BaseNamU
, BaseNamU
);
2776 "#ifndef __NOLIBBASE__\n"
2777 "extern struct %s *\n"
2778 "#ifdef __CONSTLIBBASEDECL__\n"
2779 "__CONSTLIBBASEDECL__\n"
2780 "#endif /* __CONSTLIBBASEDECL__ */\n"
2782 "#endif /* !__NOLIBBASE__ */\n\n",
2786 "#ifdef __amigaos4__\n"
2787 "#include <interfaces/%s.h>\n"
2788 "#ifdef __USE_INLINE__\n"
2789 "#include <inline4/%s.h>\n"
2790 "#endif /* __USE_INLINE__ */\n"
2791 "#ifndef CLIB_%s_PROTOS_H\n"
2792 "#define CLIB_%s_PROTOS_H\n"
2793 "#endif /* CLIB_%s_PROTOS_H */\n"
2794 "#ifndef __NOGLOBALIFACE__\n"
2795 "extern struct %sIFace *I%s;\n"
2796 "#endif /* __NOGLOBALIFACE__ */\n"
2797 "#else /* __amigaos4__ */\n"
2798 "#include <clib/%s_protos.h>\n"
2801 "#ifndef NOLIBDEFINES\n"
2802 "#ifndef %s_NOLIBDEFINES\n"
2803 "#include <defines/%s.h>\n"
2804 "#endif /* %s_NOLIBDEFINES */\n"
2805 "#endif /* NOLIBDEFINES */\n"
2808 "#ifndef _NO_PPCINLINE\n"
2809 "#include <ppcinline/%s.h>\n"
2810 "#endif /* _NO_PPCINLINE */\n"
2812 "#ifndef _NO_INLINE\n"
2813 "#include <inline/%s.h>\n"
2814 "#endif /* _NO_INLINE */\n"
2815 "#endif /* __PPC__ */\n"
2816 "#endif /* __AROS__ */\n"
2818 "#include <pragmas/%s_pragmas.h>\n"
2819 "#endif /* __GNUC__ */\n"
2820 "#endif /* __amigaos4__ */\n\n"
2821 "#endif /* !PROTO_%s_H */\n",
2822 BaseNamL
, BaseNamL
, BaseNamU
, BaseNamU
, BaseNamU
, BaseNamC
, BaseNamC
,
2824 BaseNamU
, BaseNamL
, BaseNamU
,
2825 BaseNamL
, BaseNamL
, BaseNamL
,
2829 /******************************************************************************/
2832 main(int argc
, char** argv
)
2834 fdDef
*tmpdef
, /* a dummy to contain the name to look for */
2835 *founddef
; /* the fdDef for which we found a prototype */
2840 char *fdfilename
=0, *clibfilename
=0, *outfilename
=0;
2845 for (count
=1; count
<argc
; count
++)
2847 char *option
=argv
[count
];
2851 if (strcmp(option
, "o")==0)
2853 if (count
==argc
-1 || outfilename
)
2855 printusage(argv
[0]);
2856 return EXIT_FAILURE
;
2858 if (strcmp(argv
[++count
], "-"))
2859 outfilename
=argv
[count
];
2863 if (*option
=='-') /* Accept GNU-style '--' options */
2865 if (strncmp(option
, "mode=", 5)==0)
2867 if (strcmp(option
+5, "new")==0)
2869 else if (strcmp(option
+5, "old")==0)
2871 else if (strcmp(option
+5, "stubs")==0)
2873 else if (strcmp(option
+5, "gatestubs")==0)
2874 output_mode
=GATESTUBS
;
2875 else if (strcmp(option
+5, "gateproto")==0)
2876 output_mode
=GATEPROTO
;
2877 else if (strcmp(option
+5, "proto")==0)
2880 else if (strncmp(option
, "target=", 7)==0)
2882 if (MatchGlob("*-aros",option
+7))
2884 else if (MatchGlob("i?86be*-amithlon",option
+7))
2885 target
=IX86BE_AMITHLON
;
2886 else if (MatchGlob("m68k*-amigaos",option
+7))
2887 target
=M68K_AMIGAOS
;
2888 else if (MatchGlob("m68k*-pos",option
+7))
2890 else if (MatchGlob("powerpc*-powerup",option
+7))
2892 else if (MatchGlob("powerpc*-morphos",option
+7))
2896 printusage(argv
[0]);
2897 return EXIT_FAILURE
;
2900 else if (strcmp(option
, "direct-varargs-calls") == 0)
2901 DirectVarargsCalls
= 1;
2902 else if (strncmp(option
, "gateprefix=", 11)==0)
2903 gateprefix
= option
+11;
2904 else if (strncmp(option
, "libprefix=", 10)==0)
2905 libprefix
= option
+10;
2906 else if (strcmp(option
, "quiet") == 0)
2908 else if (strcmp(option
, "version")==0)
2910 fprintf(stderr
, "fd2inline version " VERSION
"\n");
2911 return EXIT_SUCCESS
;
2913 /* Compatibility options */
2914 else if (strcmp(option
, "new")==0)
2916 else if (strcmp(option
, "old")==0)
2918 else if (strcmp(option
, "stubs")==0)
2920 else if (strcmp(option
, "gatestubs")==0)
2921 output_mode
=GATESTUBS
;
2922 else if (strcmp(option
, "proto")==0)
2924 else if (strcmp(option
, "pos")==0)
2926 else if (strcmp(option
, "powerup")==0)
2928 else if (strcmp(option
, "morphos")==0)
2930 /* Unknown option */
2933 printusage(argv
[0]);
2934 return EXIT_FAILURE
;
2940 /* One of the filenames */
2943 else if (!clibfilename
)
2944 clibfilename
=option
;
2945 else if (!outfilename
)
2949 printusage(argv
[0]);
2950 return EXIT_FAILURE
;
2955 if (!fdfilename
|| (!clibfilename
&& output_mode
!=PROTO
))
2957 printusage(argv
[0]);
2958 return EXIT_FAILURE
;
2961 if (target
==M68K_POS
&& output_mode
!=NEW
)
2963 fprintf(stderr
, "Target is not compatible with the mode.\n");
2964 return EXIT_FAILURE
;
2967 if (!(arrdefs
=malloc(FDS
*sizeof(fdDef
*))))
2969 fprintf(stderr
, "No mem for FDs\n");
2970 return EXIT_FAILURE
;
2972 for (count
=0; count
<FDS
; count
++)
2973 arrdefs
[count
]=NULL
;
2975 if (!(myfile
=fF_ctor(fdfilename
)))
2977 fprintf(stderr
, "Couldn't open file '%s'.\n", fdfilename
);
2978 return EXIT_FAILURE
;
2983 for (count
=0; count
<FDS
&& lerror
==false; count
++)
2985 if (!(arrdefs
[count
]=fD_ctor()))
2987 fprintf(stderr
, "No mem for FDs\n" );
2988 return EXIT_FAILURE
;
2992 if ((lerror
=fF_readln(myfile
))==false)
2994 fF_SetError(myfile
, false);
2995 lerror
=fD_parsefd(arrdefs
[count
], myfile
);
2998 while (lerror
==nodef
);
3003 fD_dtor(arrdefs
[count
]);
3004 arrdefs
[count
]=NULL
;
3008 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpName
);
3010 if (output_mode
!=NEW
|| target
==AROS
)
3012 unsigned int count2
;
3015 for (count2
=0; count2
<sizeof LibExcTable
/sizeof LibExcTable
[0]; count2
+=2)
3016 if (strcmp(BaseName
, LibExcTable
[count2
])==0)
3018 StdLib
=LibExcTable
[count2
+1];
3025 if (output_mode
!=PROTO
)
3027 if (!(myfile
=fF_ctor(clibfilename
)))
3029 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3030 return EXIT_FAILURE
;
3033 if (!(tmpdef
=fD_ctor()))
3035 fprintf(stderr
, "No mem for FDs\n");
3036 return EXIT_FAILURE
;
3039 for (lerror
=false; lerror
==false || lerror
==nodef
;)
3040 if ((lerror
=fF_readln(myfile
))==false)
3042 fF_SetError(myfile
, false); /* continue even on errors */
3043 tmpstr
=fF_FuncName(myfile
);
3048 fD_NewName(tmpdef
, tmpstr
);
3049 res
=(fdDef
**)bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
3055 DBP(fprintf(stderr
, "found (%s).\n", fD_GetName(founddef
)));
3056 fF_SetError(myfile
, false);
3057 lerror
=fD_parsepr(founddef
, myfile
);
3060 if (!ishandleddifferently(myfile
->line
, tmpstr
))
3062 fprintf(stderr
, "Don't know what to do with <%s> in line %lu.\n",
3063 tmpstr
, myfile
->lineno
);
3073 if (strlen(fdfilename
)>7 &&
3074 !strcmp(fdfilename
+strlen(fdfilename
)-7, "_lib.fd"))
3076 char *str
=fdfilename
+strlen(fdfilename
)-8;
3077 while (str
!=fdfilename
&& str
[-1]!='/' && str
[-1]!=':')
3079 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3080 strncpy(BaseNamU
, str
, strlen(str
)-7);
3081 BaseNamU
[strlen(str
)-7]='\0';
3082 strcpy(BaseNamL
, BaseNamU
);
3083 strcpy(BaseNamC
, BaseNamU
);
3087 strcpy(BaseNamU
, BaseName
);
3088 if (strlen(BaseNamU
)>4 && strcmp(BaseNamU
+strlen(BaseNamU
)-4, "Base")==0)
3089 BaseNamU
[strlen(BaseNamU
)-4]='\0';
3090 if (target
==M68K_POS
&& strncmp(BaseNamU
, "gb_", 3)==0)
3091 memmove(BaseNamU
, &BaseNamU
[3], strlen(&BaseNamU
[3])+1);
3092 strcpy(BaseNamL
, BaseNamU
);
3093 strcpy(BaseNamC
, BaseNamU
);
3096 BaseNamC
[0]=toupper(BaseNamC
[0]);
3100 if (!(outfile
=fopen(outfilename
, "w")))
3102 fprintf(stderr
, "Couldn't open output file.\n");
3103 return EXIT_FAILURE
;
3113 if (output_mode
==PROTO
)
3114 output_proto(outfile
);
3117 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
||
3118 output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3120 if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3123 "/* Automatically generated stubs! Do not edit! */\n\n");
3128 "/* Automatically generated header! Do not edit! */\n\n"
3129 "#ifndef %sINLINE_%s_H\n"
3130 "#define %sINLINE_%s_H\n\n",
3131 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3133 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3137 if (output_mode
==NEW
)
3139 if(target
==M68K_POS
)
3142 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3143 "#include <pInline/macros.h>\n"
3144 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3146 else if(target
==AROS
)
3149 "#ifndef AROS_LIBCALL_H\n"
3150 "#include <aros/libcall.h>\n"
3151 "#endif /* !AROS_LIBCALL_H */\n\n");
3156 "#ifndef __INLINE_MACROS_H\n"
3157 "#include <inline/macros.h>\n"
3158 "#endif /* !__INLINE_MACROS_H */\n\n");
3166 "#ifndef __INLINE_STUB_H\n"
3167 "#include <inline/stubs.h>\n"
3168 "#endif /* !__INLINE_STUB_H */\n\n");
3170 fprintf(outfile
, "#ifdef __CLIB_TYPES__\n" );
3172 clib
= fopen( clibfilename
, "r" );
3176 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3180 char* buffer
= malloc( 1024 );
3182 if( buffer
== NULL
)
3184 fprintf(stderr
, "No memory for line buffer.\n " );
3188 while( fgets( buffer
, 1023, clib
) != NULL
)
3190 if( buffer
[ 0 ] == '#' /* Pre-processor instruction */ ||
3191 strncmp( buffer
, "typedef", 7 ) == 0 )
3193 fputs(buffer
, outfile
);
3203 fprintf(outfile
, "#endif /* __CLIB_TYPES__ */\n\n" );
3208 "#include <aros/libcall.h>\n\n" );
3210 else if(target
==IX86BE_AMITHLON
)
3213 "#ifndef __INLINE_MACROS_H\n"
3214 "#include <inline/macros.h>\n"
3215 "#endif /* __INLINE_MACROS_H */\n\n");
3217 else if (target
== PPC_MORPHOS
)
3220 "#include <emul/emulregs.h>\n\n" );
3226 fprintf(stderr
, "Internal error: Unknown output mode in main().\n");
3233 return EXIT_FAILURE
;
3238 if (output_mode
==NEW
)
3241 "#ifndef %s%s_BASE_NAME\n"
3242 "#define %s%s_BASE_NAME %s\n"
3243 "#endif /* !%s%s_BASE_NAME */\n\n",
3244 (target
==M68K_POS
? "__" : ""), BaseNamU
,
3245 (target
==M68K_POS
? "__" : ""), BaseNamU
, BaseName
,
3246 (target
==M68K_POS
? "__" : ""), BaseNamU
);
3247 if (target
==M68K_POS
)
3249 "#ifndef __%s_LIB_NAME\n"
3250 "#define __%s_LIB_NAME %s\n"
3251 "#endif /* !__%s_LIB_NAME */\n\n",
3253 (strcmp(BaseName
, "gb_ExecBase") ? BaseName
: "gb_ExecLib"),
3258 "#ifndef BASE_EXT_DECL\n"
3259 "#define BASE_EXT_DECL\n"
3260 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3261 "#endif /* !BASE_EXT_DECL */\n"
3262 "#ifndef BASE_PAR_DECL\n"
3263 "#define BASE_PAR_DECL\n"
3264 "#define BASE_PAR_DECL0 void\n"
3265 "#endif /* !BASE_PAR_DECL */\n"
3266 "#ifndef BASE_NAME\n"
3267 "#define BASE_NAME %s\n"
3268 "#endif /* !BASE_NAME */\n\n"
3269 "BASE_EXT_DECL0\n\n", StdLib
, BaseName
, BaseName
);
3272 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3274 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3276 fD_write(outfile
, arrdefs
[count
]);
3277 fD_dtor(arrdefs
[count
]);
3278 arrdefs
[count
]=NULL
;
3281 if (output_mode
!=NEW
)
3284 "#undef BASE_EXT_DECL\n"
3285 "#undef BASE_EXT_DECL0\n"
3286 "#undef BASE_PAR_DECL\n"
3287 "#undef BASE_PAR_DECL0\n"
3288 "#undef BASE_NAME\n\n");
3290 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
)
3292 fprintf(outfile
, "#endif /* !%sINLINE_%s_H */\n",
3293 (target
==M68K_POS
? "__INC_POS_P" : "_"), BaseNamU
);
3304 return EXIT_SUCCESS
;