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 *****************************************************************************/
32 /******************************************************************************
33 * The program has a few sort of class definitions, which are the result of
34 * object oriented thinking, to be imlemented in plain C. I just haven't
35 * had the time to learn C++ or install the compiler. The design does however
36 * improve robustness, which allows the source to be used over and over again.
37 * if you use this code, please leave a little origin note.
38 ******************************************************************************/
40 const static char version_str
[]="$VER: fd2inline " VERSION
" (24.2.2002)";
42 /******************************************************************************
43 * These are general definitions including types for defining registers etc.
44 ******************************************************************************/
52 #if (defined(__GNUC__) || defined(__SASC)) && 0
53 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
58 #define REGS 16 /* d0=0,...,a7=15 */
63 d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
, a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, illegal
66 typedef unsigned char shortcard
;
68 typedef enum { false, nodef
, real_error
} Error
;
70 enum { NEW
, OLD
, STUBS
, PROTO
, GATESTUBS
, GATEPROTO
} output_mode
=NEW
;
71 enum { IX86BE_AMITHLON
, AROS
, M68K_AMIGAOS
, M68K_POS
, PPC_POWERUP
, PPC_MORPHOS
} target
= M68K_AMIGAOS
;
74 int DirectVarargsCalls
= 0;
78 char *gateprefix
= "";
81 char BaseName
[64], BaseNamU
[64], BaseNamL
[64], BaseNamC
[64];
84 const static char *LibExcTable
[]=
86 "BattClockBase", "Node",
87 "BattMemBase", "Node",
88 "ConsoleDevice", "Device",
89 "DiskBase", "DiskResource",
90 "DOSBase", "DosLibrary",
91 "SysBase", "ExecBase",
92 "ExpansionBase", "ExpansionBase",
94 "InputBase", "Device",
95 "IntuitionBase", "IntuitionBase",
96 "LocaleBase", "LocaleBase",
97 "MathIeeeDoubBasBase", "MathIEEEBase",
98 "MathIeeeDoubTransBase","MathIEEEBase",
99 "MathIeeeSingBasBase", "MathIEEEBase",
100 "MathIeeeSingTransBase","MathIEEEBase",
103 "RamdriveDevice", "Device",
104 "RealTimeBase", "RealTimeBase",
105 "RexxSysBase", "RxsLib",
106 "TimerBase", "Device",
107 "UtilityBase", "UtilityBase"
109 const char *StdLib
; /* global lib-name ptr */
111 /*******************************************
112 * just some support functions, no checking
113 *******************************************/
116 NewString(char** new, const char* old
)
121 while (*old
&& (*old
==' ' || *old
=='\t'))
124 for (high
=old
+len
-1; high
>=old
&& (*high
==' ' || *high
=='\t'); high
--);
130 strncpy(*new, old
, len
);
134 fprintf(stderr
, "No mem for string\n");
139 illparams(const char* funcname
)
141 fprintf(stderr
, "%s: illegal Parameters\n", funcname
);
144 static INLINE
const char*
147 const static char *aosregs
[]=
149 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
150 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
177 return (target
!=M68K_POS
? aosregs
[reg
] : posregs
[reg
]);
180 static INLINE
const char*
183 const static char *aosregs
[]=
185 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
186 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
193 return (target
!=M68K_POS
? aosregs
[reg
] : RegStr(reg
));
198 /******************************************************************************
201 * searches string in from position at downwards, as long as in does not
202 * contain any character in not.
204 ******************************************************************************/
207 StrNRBrk(const char* in
, const char* not, const char* at
)
212 chcheck
=""; /* if at<in, the result will be NULL */
213 for (ready
=false; ready
==false && at
>=in
;)
215 for (chcheck
=not; *chcheck
&& *chcheck
!= *at
; chcheck
++);
221 DBP(fprintf(stderr
, "{%c}", *chcheck
));
222 return *chcheck
? at
: NULL
;
226 Our own "strupr", since it is a non-standard function.
239 MatchGlob( char* glob
, char* str
)
256 if( c
== 0 || *str
!= c
)
270 if( MatchGlob( glob
, str
) )
293 /******************************************************************************
296 * stores a file with a temporary buffer (static length, sorry), a line number,
297 * an offset (used for library offsets and an error field.
298 * When there's no error, line will contain line #lineno and offset will be
299 * the last offset set by the interpretation of the last line. If there's been
300 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
301 * It is assumed offsets are always negative.
302 ******************************************************************************/
304 #define fF_BUFSIZE 1024
306 /* all you need to know about an fdFile you parse */
308 typedef enum {FD_PRIVATE
=1, FD_SHADOW
=2} fdflags
;
312 FILE* file
; /* the file we're reading from */
313 char line
[fF_BUFSIZE
]; /* the current line */
314 unsigned long lineno
; /* current line number */
315 long offset
; /* current fd offset (-bias) */
316 Error error
; /* is everything o.k. */
317 fdflags flags
; /* for ##private, ##shadow (p.OS) */
321 fF_ctor (const char* fname
);
323 fF_dtor (fdFile
* obj
);
325 fF_SetError (fdFile
* obj
, Error error
);
327 fF_SetOffset (fdFile
* obj
, long at
);
329 fF_readln (fdFile
* obj
);
331 fF_GetError (const fdFile
* obj
);
333 fF_GetOffset (const fdFile
* obj
);
335 fF_FuncName (fdFile
* obj
); /* return name or null */
337 fF_SetFlags (fdFile
* obj
, fdflags flags
);
339 fF_GetFlags (const fdFile
* obj
);
349 fF_SetError(fdFile
* obj
, Error error
)
354 illparams("fF_SetError");
357 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
360 fF_SetOffset(fdFile
* obj
, long at
)
365 illparams("fFSetOffset");
369 fF_SetFlags(fdFile
* obj
, fdflags flags
)
374 illparams("fF_SetFlags");
378 fF_ctor(const char* fname
)
384 result
=malloc(sizeof(fdFile
));
387 result
->file
=fopen(fname
, "r");
391 fF_SetOffset(result
, -30);
392 fF_SetError(result
, false);
393 fF_SetFlags(result
, 0);
394 result
->line
[0]='\0';
406 illparams("fF_ctor");
412 fF_readln(fdFile
* obj
)
415 long glen
, /* the length we read until now */
416 len
; /* the length of the last segment */
426 if (!fgets(low
, fF_BUFSIZE
-1-glen
, obj
->file
))
428 fF_SetError(obj
, real_error
);
432 if (low
==strpbrk(low
, "*#/"))
434 DBP(fprintf(stderr
, "in# %s\n", obj
->line
));
439 while (len
&& isspace(*bpoint
))
444 if (*bpoint
==';' || *bpoint
==')')
446 DBP(fprintf(stderr
, "\nin: %s\n", obj
->line
));
451 if (glen
>=fF_BUFSIZE
-10) /* somewhat pessimistic? */
453 fF_SetError(obj
, real_error
);
454 fprintf(stderr
, "Line %lu too long.\n", obj
->lineno
);
457 DBP(fprintf(stderr
, "+"));
460 illparams("fF_readln");
465 fF_GetError(const fdFile
* obj
)
469 illparams("fF_GetError");
474 fF_GetOffset(const fdFile
* obj
)
478 illparams("fF_GetOffset");
482 /******************************************************************************
485 * checks if it can find a function-name and return it's address, or NULL
486 * if the current line does not seem to contain one. The return value will
487 * be a pointer into a malloced buffer, thus the caller will have to free().
488 ******************************************************************************/
491 fF_FuncName(fdFile
* obj
)
496 long obraces
; /* count of open braces */
497 Error ready
; /* ready with searching */
499 if (!obj
|| fF_GetError(obj
)==real_error
)
501 illparams("fF_FuncName");
506 while (*lower
&& (*lower
==' ' || *lower
=='\t'))
509 if (!*lower
|| (!isalpha(*lower
) && *lower
!='_'))
511 fF_SetError(obj
, nodef
);
517 if (!isalnum(*lower
) && !isspace(*lower
) && *lower
!='*' && *lower
!=','
518 && *lower
!='.' && *lower
!=';' && *lower
!='(' && *lower
!=')' &&
519 *lower
!='[' && *lower
!=']' && *lower
!='_' && *lower
!='\\')
521 fF_SetError(obj
, nodef
);
530 if (obj
&& fF_GetError(obj
)==false)
532 if ((upper
=strrchr(obj
->line
, ')'))!=0)
534 DBP(fprintf(stderr
, "end:%s:", upper
));
536 for (obraces
=1, ready
=false; ready
==false; upper
=lower
)
538 lower
=StrNRBrk(obj
->line
, "()", --upper
);
545 DBP(fprintf(stderr
, " )%ld%s", obraces
, lower
));
549 DBP(fprintf(stderr
, " (%ld%s", obraces
, lower
));
554 fprintf(stderr
, "Faulty StrNRBrk\n");
559 fprintf(stderr
, "'(' or ')' expected in line %lu.\n",
564 if (ready
==nodef
) /* we found the matching '(' */
571 while (upper
>=obj
->line
&& (*upper
==' ' || *upper
=='\t'))
574 lower
=StrNRBrk(obj
->line
, " \t*)", upper
);
581 for (name
=lower
; name
<=upper
; name
++)
582 if (!isalnum(*name
) && *name
!='_')
584 fF_SetError(obj
, nodef
);
588 newlen
=upper
-lower
+1;
589 buf
=malloc(newlen
+1);
593 strncpy(buf
, lower
, newlen
);
597 fprintf(stderr
, "No mem for fF_FuncName");
602 illparams("fF_FuncName");
606 static INLINE fdflags
607 fF_GetFlags(const fdFile
* obj
)
611 illparams("fF_GetFlags");
615 /*********************
617 *********************/
627 regs funcpar
; /* number of argument that has type "pointer to function" */
633 fD_dtor (fdDef
* obj
);
635 fD_NewName (fdDef
* obj
, const char* newname
);
637 fD_NewParam (fdDef
* obj
, shortcard at
, const char* newstr
);
639 fD_NewProto (fdDef
* obj
, shortcard at
, char* newstr
);
641 fD_NewReg (fdDef
* obj
, shortcard at
, regs reg
);
643 fD_NewType (fdDef
* obj
, const char* newstr
);
645 fD_SetOffset (fdDef
* obj
, long off
);
647 fD_parsefd (fdDef
* obj
, fdFile
* infile
);
649 fD_parsepr (fdDef
* obj
, fdFile
* infile
);
651 fD_GetName (const fdDef
* obj
);
653 fD_GetOffset (const fdDef
* obj
);
655 fD_GetParam (const fdDef
* obj
, shortcard at
);
657 fD_GetReg (const fdDef
* obj
, shortcard at
);
659 fD_GetRegStr (const fdDef
* obj
, shortcard at
);
661 fD_GetRegStrU (const fdDef
* obj
, shortcard at
);
663 fD_GetType (const fdDef
* obj
);
665 fD_ParamNum (const fdDef
* obj
);
667 fD_ProtoNum (const fdDef
* obj
);
669 fD_RegNum (const fdDef
* obj
);
671 fD_cmpName (const void* big
, const void* small
);
673 fD_write (FILE* outfile
, const fdDef
* obj
);
675 fD_GetFuncParNum (const fdDef
* obj
);
677 fD_SetFuncParNum (fdDef
* obj
, shortcard at
);
679 fD_adjustargnames(fdDef
*obj
);
684 char *fD_nostring
="";
692 result
=malloc(sizeof(fdDef
));
696 result
->name
=fD_nostring
;
697 result
->type
=fD_nostring
;
698 result
->funcpar
=illegal
;
700 for (count
=d0
; count
<illegal
; count
++ )
702 result
->reg
[count
]=illegal
;
703 result
->param
[count
]=fD_nostring
; /* if (!strlen) dont't free() */
704 result
->proto
[count
]=fD_nostring
;
710 /* free all resources and make the object as illegal as possible */
720 fprintf(stderr
, "fD_dtor: null name");
722 if (obj
->name
!=fD_nostring
)
726 fprintf(stderr
, "fD_dtor: null type");
728 if (obj
->type
!=fD_nostring
)
731 obj
->name
=obj
->type
=NULL
;
733 for (count
=d0
; count
<illegal
; count
++)
735 obj
->reg
[count
]=illegal
;
737 if (!obj
->param
[count
])
738 fprintf(stderr
, "fD_dtor: null param");
740 if (obj
->param
[count
]!=fD_nostring
)
741 free(obj
->param
[count
]);
743 if (!obj
->proto
[count
])
744 fprintf(stderr
, "fD_dtor: null proto");
746 if (obj
->proto
[count
]!=fD_nostring
)
747 free(obj
->proto
[count
]);
749 obj
->param
[count
]=obj
->proto
[count
]=NULL
;
755 fprintf(stderr
, "fd_dtor(NULL)\n");
759 fD_NewName(fdDef
* obj
, const char* newname
)
763 if (obj
->name
&& obj
->name
!=fD_nostring
)
765 if (!NewString(&obj
->name
, newname
))
766 obj
->name
=fD_nostring
;
769 illparams("fD_NewName");
773 fD_NewParam(fdDef
* obj
, shortcard at
, const char* newstr
)
777 if (newstr
&& obj
&& at
<illegal
)
781 if (pa
&& pa
!=fD_nostring
)
784 while (*newstr
==' ' || *newstr
=='\t')
787 if (NewString(&pa
, newstr
))
791 prefix_pa
= malloc( strlen( pa
) + 4 );
793 if( prefix_pa
== NULL
)
795 fprintf(stderr
, "No mem for string\n");
799 sprintf( prefix_pa
, "___%s", pa
);
800 obj
->param
[at
]=prefix_pa
;
805 obj
->param
[at
]=fD_nostring
;
808 illparams("fD_NewParam");
811 /* get first free *reg or illegal */
813 static INLINE shortcard
814 fD_RegNum(const fdDef
* obj
)
820 for (count
=d0
; count
<illegal
&& obj
->reg
[count
]!=illegal
; count
++);
825 illparams("fD_RegNum");
831 fD_NewReg(fdDef
* obj
, shortcard at
, regs reg
)
833 if (obj
&& at
<illegal
&& reg
>=d0
&& reg
<=illegal
)
836 illparams("fD_NewReg");
840 fD_GetReg(const fdDef
* obj
, shortcard at
)
842 if (obj
&& at
<illegal
)
846 illparams("fD_GetReg");
851 static INLINE shortcard
852 fD_GetFuncParNum(const fdDef
* obj
)
855 return (shortcard
)obj
->funcpar
;
858 illparams("fD_GetFuncParNum");
864 fD_SetFuncParNum(fdDef
* obj
, shortcard at
)
866 if (obj
&& at
<illegal
)
869 illparams("fD_SetFuncParNum");
873 fD_NewProto(fdDef
* obj
, shortcard at
, char* newstr
)
877 if (newstr
&& obj
&& at
<illegal
)
879 char *t
, arr
[200]; /* I hope 200 will be enough... */
883 if (pr
&& pr
!=fD_nostring
)
886 while (*newstr
==' ' || *newstr
=='\t')
887 newstr
++; /* Skip leading spaces */
890 while ((*t
++=*newstr
)!=0)
892 /* Copy the rest, counting number of words */
893 if ((*newstr
==' ' || *newstr
=='\t') && newstr
[1] && newstr
[1]!=' ' &&
900 while (*t
==' ' || *t
=='\t')
902 t
[1]='\0'; /* Get rid of tailing spaces */
904 if (at
!=fD_GetFuncParNum(obj
))
906 if (numwords
>1) /* One word - must be type */
909 /* '*' on the end - no parameter name used */
910 while (*t
!=' ' && *t
!='\t' && *t
!='*')
913 if (strcmp(t
, "char") && strcmp(t
, "short") && strcmp(t
, "int")
914 && strcmp(t
, "long") && strcmp(t
, "APTR"))
916 /* Not one of applicable keywords - must be parameter name.
919 while (*t
==' ' || *t
=='\t')
927 /* Parameter of type "pointer to function". */
931 while (*t
==' ' || *t
=='\t')
937 if (target
!=M68K_POS
)
939 memmove(t
+2, end
, strlen(end
)+1);
944 memmove(t
, end
, strlen(end
)+1);
947 if (NewString(&pr
, arr
))
950 while (*pr
==' ' || *pr
=='\t')
952 if (!strcasecmp(pr
, "double"))
954 /* "double" needs two data registers */
955 int count
, regs
=fD_RegNum(obj
);
956 for (count
=at
+1; count
<regs
; count
++)
957 fD_NewReg(obj
, count
, fD_GetReg(obj
, count
+1));
961 obj
->proto
[at
]=fD_nostring
;
964 illparams("fD_NewProto");
970 fD_NewType(fdDef
* obj
, const char* newtype
)
974 if (obj
->type
&& obj
->type
!=fD_nostring
)
976 if (!NewString(&obj
->type
, newtype
))
977 obj
->type
=fD_nostring
;
980 illparams("fD_NewType");
984 fD_SetOffset(fdDef
* obj
, long off
)
989 illparams("fD_SetOffset");
992 static INLINE
const char*
993 fD_GetName(const fdDef
* obj
)
995 if (obj
&& obj
->name
)
999 illparams("fD_GetName");
1005 fD_GetOffset(const fdDef
* obj
)
1011 illparams("fD_GetOffset");
1016 static INLINE
const char*
1017 fD_GetProto(const fdDef
* obj
, shortcard at
)
1019 if (obj
&& at
<illegal
&& obj
->proto
[at
])
1020 return obj
->proto
[at
];
1023 illparams("fD_GetProto");
1028 static INLINE
const char*
1029 fD_GetParam(const fdDef
* obj
, shortcard at
)
1031 if (obj
&& at
<illegal
&& obj
->param
[at
])
1032 return obj
->param
[at
];
1035 illparams("fD_GetParam");
1040 static INLINE
const char*
1041 fD_GetRegStr(const fdDef
* obj
, shortcard at
)
1043 if (obj
&& at
<illegal
)
1044 return RegStr(obj
->reg
[at
]);
1047 illparams("fD_GetReg");
1048 return RegStr(illegal
);
1052 static INLINE
const char*
1053 fD_GetRegStrU(const fdDef
* obj
, shortcard at
)
1055 if (obj
&& at
<illegal
)
1056 return RegStrU(obj
->reg
[at
]);
1059 illparams("fD_GetReg");
1060 return RegStrU(illegal
);
1064 static INLINE
const char*
1065 fD_GetType(const fdDef
* obj
)
1067 if (obj
&& obj
->type
)
1071 illparams("fD_GetType");
1076 /* get first free param or illegal */
1078 static INLINE shortcard
1079 fD_ParamNum(const fdDef
* obj
)
1085 for (count
=d0
; count
<illegal
&& obj
->param
[count
]!=fD_nostring
;
1091 illparams("fD_ParamNum");
1096 static INLINE shortcard
1097 fD_ProtoNum(const fdDef
* obj
)
1103 for (count
=d0
; count
<illegal
&& obj
->proto
[count
]!=fD_nostring
;
1109 illparams("fD_ProtoNum");
1114 /******************************************************************************
1117 * parse the current line. Needs to copy input, in order to insert \0's
1119 * fF_GetError(infile):
1120 * false = read a definition.
1121 * nodef = not a definition on line (so try again)
1122 * error = real error
1123 ******************************************************************************/
1126 fD_parsefd(fdDef
* obj
, fdFile
* infile
)
1128 enum parse_info
{ name
, params
, regs
, ready
} parsing
;
1129 char *buf
, *bpoint
, *bnext
;
1130 unsigned long index
;
1132 if (obj
&& infile
&& fF_GetError(infile
)==false)
1136 if (!NewString(&buf
, infile
->line
))
1138 fprintf(stderr
, "No mem for line %lu\n", infile
->lineno
);
1139 fF_SetError(infile
, real_error
);
1141 bpoint
=buf
; /* so -Wall keeps quiet */
1143 /* try to parse the line until there's an error or we are done */
1145 while (parsing
!=ready
&& fF_GetError(infile
)==false)
1153 if (strncmp("##base", buf
, 6)==0)
1156 while (*bnext
==' ' || *bnext
=='\t' || *bnext
=='_')
1158 strcpy(BaseName
, bnext
);
1159 BaseName
[strlen(BaseName
)-1]='\0';
1162 if (strncmp("##bias", buf
, 6)==0)
1164 if (!sscanf(buf
+6, "%ld", &infile
->offset
))
1166 fprintf(stderr
, "Illegal ##bias in line %lu: %s\n",
1167 infile
->lineno
, infile
->line
);
1168 fF_SetError(infile
, real_error
);
1169 break; /* avoid nodef */
1173 if (fF_GetOffset(infile
)>0)
1174 fF_SetOffset(infile
, -fF_GetOffset(infile
));
1175 DBP(fprintf(stderr
, "set offset to %ld\n",
1176 fF_GetOffset(infile
)));
1181 if (strncmp("##private", buf
, 9)==0)
1182 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1184 else if (strncmp("##public", buf
, 8)==0)
1185 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1187 else if (strncmp("##shadow", buf
, 8)==0)
1188 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1191 /* drop through for error comment */
1194 /* try again somewhere else */
1195 fF_SetError(infile
, nodef
);
1199 /* assume a regular line here */
1200 if (fF_GetFlags(infile
) & (FD_PRIVATE
| FD_SHADOW
))
1202 /* don't store names of privates */
1203 fF_SetError(infile
, nodef
);
1204 if (!(fF_GetFlags(infile
) & FD_SHADOW
))
1205 fF_SetOffset(infile
,
1206 fF_GetOffset(infile
)-FUNCTION_GAP
);
1208 /* Shadow is valid for one line only. */
1209 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1213 parsing
=name
; /* switch (parsing) */
1214 for (index
=0; buf
[index
] && buf
[index
]!='('; index
++);
1219 fprintf(stderr
, "Not an fd, line %lu: %s\n",
1220 infile
->lineno
, buf
/* infile->line */);
1221 fF_SetError(infile
, nodef
);
1222 } /* maybe next time */
1227 fD_NewName(obj
, buf
);
1228 fD_SetOffset(obj
, fF_GetOffset(infile
));
1231 parsing
=params
; /* continue the loop */
1238 char *bptmp
; /* needed for fD_NewParam */
1240 /* look for parameters now */
1242 for (bnext
= bpoint
; *bnext
&& *bnext
!=',' && *bnext
!=')';
1251 if (bnext
[1] != '(')
1253 fprintf(stderr
, "Registers expected in line %lu: %s\n",
1254 infile
->lineno
, infile
->line
);
1255 fF_SetError(infile
, nodef
);
1266 /* terminate string and advance to next item */
1269 fD_NewParam(obj
, fD_ParamNum(obj
), bptmp
);
1273 fF_SetError(infile
, nodef
);
1274 fprintf(stderr
, "Param expected in line %lu: %s\n",
1275 infile
->lineno
, infile
->line
);
1277 break; /* switch parsing */
1281 /* look for parameters now */
1283 for (bnext
=bpoint
; *bnext
&& *bnext
!='/' && *bnext
!=',' &&
1284 *bnext
!=')'; bnext
++);
1290 /* wow, we've finished */
1291 fF_SetOffset(infile
, fF_GetOffset(infile
)-FUNCTION_GAP
);
1296 bpoint
[0]=tolower(bpoint
[0]);
1298 if ((bpoint
[0]=='d' || bpoint
[0]=='a') && bpoint
[1]>='0' &&
1299 bpoint
[1]<='8' && bnext
==bpoint
+2)
1300 fD_NewReg(obj
, fD_RegNum(obj
),
1301 bpoint
[1]-'0'+(bpoint
[0]=='a'? 8 : 0));
1305 /* it is when our function is void */
1306 fprintf(stderr
, "Illegal register %s in line %ld\n",
1307 bpoint
, infile
->lineno
);
1308 fF_SetError(infile
, nodef
);
1314 fF_SetError(infile
, nodef
);
1315 fprintf(stderr
, "Reg expected in line %lu\n",
1318 break; /* switch parsing */
1321 fprintf(stderr
, "Internal error, use another compiler.\n");
1327 return fF_GetError(infile
);
1331 illparams("fD_parsefd");
1337 fD_adjustargnames(fdDef
*obj
)
1341 if (output_mode
!=NEW
)
1344 /* For #define-base output mode, we have to check if argument names are not
1345 the same as some words in type names. We check from the first argument
1346 to the last, resolving conflicts by changing argument names, if
1349 for (parnum
=0; parnum
<fD_ParamNum(obj
); parnum
++)
1351 const char *parname
=fD_GetParam(obj
, parnum
);
1356 const char *type
=fD_GetType(obj
);
1361 if ((str
=strstr(type
, parname
))!=0 && (str
==type
||
1362 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1363 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_')))
1365 char buf
[300]; /* Hope will be enough... */
1366 strcpy(buf
, parname
);
1368 fD_NewParam(obj
, parnum
, buf
);
1369 parname
=fD_GetParam(obj
, parnum
);
1373 for (num
=0; num
<fD_ParamNum(obj
); num
++)
1375 const char *name
=fD_GetParam(obj
, num
);
1376 const char *proto
=fD_GetProto(obj
, num
);
1377 if ((num
<parnum
&& strcmp(name
, parname
)==0) ||
1378 ((str
=strstr(proto
, parname
))!=0 && (str
==proto
||
1379 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1380 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_'))))
1382 char buf
[300]; /* Hope will be enough... */
1383 strcpy(buf
, parname
);
1385 fD_NewParam(obj
, parnum
, buf
);
1386 parname
=fD_GetParam(obj
, parnum
);
1391 } while (!finished
);
1396 fD_parsepr(fdDef
* obj
, fdFile
* infile
)
1398 char *buf
; /* a copy of infile->line */
1399 char *bpoint
, /* cursor in buf */
1400 *bnext
, /* looking for the end */
1401 *lowarg
; /* beginning of this argument */
1402 long obraces
; /* count of open braces */
1403 regs count
, /* count parameter number */
1404 args
; /* the number of arguments for this function */
1406 if (!(obj
&& infile
&& fF_GetError(infile
)==false))
1408 illparams("fD_parsepr");
1409 fF_SetError(infile
, real_error
);
1412 if (!NewString(&buf
, infile
->line
))
1414 fprintf(stderr
, "No mem for fD_parsepr\n");
1415 fF_SetError(infile
, real_error
);
1418 fF_SetError(infile
, false);
1420 bpoint
=strchr(buf
, '(');
1421 while (--bpoint
>=buf
&& strstr(bpoint
, fD_GetName(obj
))!=bpoint
);
1424 while (--bpoint
>= buf
&& (*bpoint
==' ' || *bpoint
=='\t'));
1427 fD_NewType(obj
, buf
);
1429 while (bpoint
&& *bpoint
++!='('); /* one beyond '(' */
1434 for (count
=0, args
=fD_RegNum(obj
); count
<args
; bpoint
=bnext
+1)
1436 while (*bpoint
&& (*bpoint
==' ' || *bpoint
=='\t')) /* ignore spaces */
1439 if (!obraces
&& target
==M68K_POS
&& strncmp(bpoint
, "_R_", 3)==0 &&
1440 isalnum(bpoint
[3]) && isalnum(bpoint
[4]) && isspace(bpoint
[5]))
1443 bnext
=strpbrk(bpoint
, "(),");
1452 if (target
==M68K_AMIGAOS
|| target
==M68K_POS
)
1454 if (fD_GetFuncParNum(obj
)!=illegal
&&
1455 fD_GetFuncParNum(obj
)!=count
&&
1457 fprintf(stderr
, "Warning: two parameters of type "
1458 "pointer to function are used.\n"
1459 "This is not supported!\n");
1462 fD_SetFuncParNum(obj
, count
);
1465 DBP(fprintf(stderr
, "< (%ld%s >", obraces
, bnext
));
1471 DBP(fprintf(stderr
, "< )%ld%s >", obraces
, bnext
));
1477 DBP(fprintf(stderr
, "< )0> [LAST PROTO=%s]", lowarg
));
1478 if (fD_NewProto(obj
, count
, lowarg
))
1479 fprintf(stderr
, "Parser confused in line %ld\n",
1485 DBP(fprintf(stderr
, "%s needs %u arguments and got %u.\n",
1486 fD_GetName(obj
), args
, count
+1));
1487 fF_SetError(infile
, nodef
);
1497 DBP(fprintf(stderr
, " [PROTO=%s] ", lowarg
));
1498 if (fD_NewProto(obj
, count
, lowarg
))
1499 fprintf(stderr
, "Parser confused in line %ld\n",
1507 fprintf(stderr
, "Faulty strpbrk in line %lu.\n",
1513 DBP(fprintf(stderr
, "Faulty argument %u in line %lu.\n", count
+1,
1515 count
=args
; /* this will effectively quit the for loop */
1516 fF_SetError(infile
, nodef
);
1519 if (fD_ProtoNum(obj
)!=fD_RegNum(obj
))
1520 fF_SetError(infile
, nodef
);
1524 fprintf(stderr
, "fD_parsepr was fooled in line %lu\n", infile
->lineno
);
1525 fprintf(stderr
, "function , definition %s.\n",
1526 /* fD_GetName(obj),*/ infile
->line
);
1527 fF_SetError(infile
, nodef
);
1532 fD_adjustargnames(obj
);
1534 return fF_GetError(infile
);
1538 fD_cmpName(const void* big
, const void* small
) /* for qsort and bsearch */
1540 return strcmp(fD_GetName(*(fdDef
**)big
), fD_GetName(*(fdDef
**)small
));
1543 const static char *TagExcTable
[]=
1545 "BuildEasyRequestArgs", "BuildEasyRequest",
1546 "DoDTMethodA", "DoDTMethod",
1547 "DoGadgetMethodA", "DoGadgetMethod",
1548 "EasyRequestArgs", "EasyRequest",
1549 "MUI_MakeObjectA", "MUI_MakeObject",
1550 "MUI_RequestA", "MUI_Request",
1551 "PrintDTObjectA", "PrintDTObject",
1552 "RefreshDTObjectA", "RefreshDTObjects",
1553 "UMSVLog", "UMSLog",
1554 "VFWritef", "FWritef",
1555 "VFPrintf", "FPrintf",
1556 "VPrintf", "Printf",
1560 getvarargsfunction(const fdDef
* obj
)
1563 const char *name
= fD_GetName(obj
);
1565 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1567 if (strcmp(name
, TagExcTable
[count
])==0)
1569 return TagExcTable
[count
+1];
1576 taggedfunction(const fdDef
* obj
)
1578 shortcard numregs
=fD_RegNum(obj
);
1581 const char *name
=fD_GetName(obj
);
1582 static char newname
[200]; /* Hope will be enough... static because used
1583 out of the function. */
1584 const char *lastarg
;
1585 const static char *TagExcTable2
[]=
1593 "PackStructureTags",
1594 "RefreshTagItemClones",
1595 "UnpackStructureTags",
1601 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1602 if (strcmp(name
, TagExcTable
[count
])==0)
1604 // lcs return TagExcTable[count+1];
1606 for (count
=0; count
<sizeof TagExcTable2
/sizeof TagExcTable2
[0]; count
++)
1607 if (strcmp(name
, TagExcTable2
[count
])==0)
1610 lastarg
=fD_GetProto(obj
, numregs
-1);
1611 if (strncmp(lastarg
, "const", 5)==0 || strncmp(lastarg
, "CONST", 5)==0)
1613 while (*lastarg
==' ' || *lastarg
=='\t')
1615 if (strncmp(lastarg
, "struct", 6))
1618 while (*lastarg
==' ' || *lastarg
=='\t')
1621 if (strncmp(lastarg
, "TagItem", 7) &&
1622 (target
!=M68K_POS
|| ((aos_tagitem
=strncmp(lastarg
, "pOS_TagItem", 11))!=0)))
1624 lastarg
+=(aos_tagitem
? 7 : 11);
1625 while (*lastarg
==' ' || *lastarg
=='\t')
1627 if (strcmp(lastarg
, "*"))
1630 strcpy(newname
, name
);
1631 if (newname
[strlen(newname
)-1]=='A')
1632 newname
[strlen(newname
)-1]='\0';
1634 if (strlen(newname
)>7 && !strcmp(newname
+strlen(newname
)-7, "TagList"))
1635 strcpy(newname
+strlen(newname
)-4, "s");
1637 strcat(newname
, "Tags");
1642 aliasfunction(const char* name
)
1644 const static char *AliasTable
[]=
1646 "AllocDosObject", "AllocDosObjectTagList",
1647 "CreateNewProc", "CreateNewProcTagList",
1648 "NewLoadSeg", "NewLoadSegTagList",
1649 "System", "SystemTagList",
1652 for (count
=0; count
<sizeof AliasTable
/sizeof AliasTable
[0]; count
++)
1653 if (strcmp(name
, AliasTable
[count
])==0)
1654 return AliasTable
[count
+(count
%2 ? -1 : 1)];
1659 fD_write(FILE* outfile
, const fdDef
* obj
)
1661 shortcard count
, numregs
;
1662 const char *chtmp
, *tagname
, *varname
, *name
, *rettype
;
1663 int vd
=0, a45
=0, d7
=0;
1665 DBP(fprintf(stderr
, "func %s\n", fD_GetName(obj
)));
1667 numregs
=fD_RegNum(obj
);
1669 if ((rettype
=fD_GetType(obj
))==fD_nostring
)
1671 fprintf(stderr
, "%s has no prototype.\n", fD_GetName(obj
));
1674 if (!strcasecmp(rettype
, "void"))
1675 vd
= 1; /* set flag */
1676 for (count
=d0
; count
<numregs
; count
++)
1678 const char *reg
=fD_GetRegStr(obj
, count
);
1679 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1681 if (strcmp(reg
, "a4")==0 || strcmp(reg
, "a5")==0)
1684 a45
=(strcmp(reg
, "a4") ? 5 : 4); /* set flag */
1685 else /* Security check */
1687 fprintf(stderr
, "Warning: both a4 and a5 are used. "
1688 "This is not supported!\n");
1691 if (strcmp(reg
, "d7")==0) /* Used only when a45!=0 */
1695 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1697 if (a45
&& d7
) /* Security check */
1699 fprintf(stderr
, "Warning: d7 and a4 or a5 are used. This is not "
1703 name
=fD_GetName(obj
);
1705 if (fD_ProtoNum(obj
)!=numregs
)
1707 fprintf(stderr
, "%s gets %d fd args and %d proto%s.\n", name
, numregs
,
1708 fD_ProtoNum(obj
), fD_ProtoNum(obj
)!= 1 ? "s" : "");
1712 if (output_mode
==NEW
)
1714 fprintf(outfile
, "#define %s(", name
);
1718 for (count
=d0
; count
<numregs
-1; count
++)
1719 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
1720 fprintf(outfile
, "%s", fD_GetParam(obj
, count
));
1723 if (target
==M68K_AMIGAOS
)
1725 fprintf(outfile
, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs
,
1726 (vd
? "NR" : ""), (a45
? (a45
==4 ? "A4" : "A5") : ""),
1727 (BaseName
[0] ? "" : "UB"),
1728 (fD_GetFuncParNum(obj
)==illegal
? "" : "FP"), -fD_GetOffset(obj
));
1730 fprintf(outfile
, "%s, ", rettype
);
1731 fprintf(outfile
, "%s, ", name
);
1733 for (count
=d0
; count
<numregs
; count
++)
1735 chtmp
=fD_GetRegStr(obj
, count
);
1736 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1738 fprintf(outfile
, "%s, %s, %s%s", (fD_GetFuncParNum(obj
)==count
?
1739 "__fpt" : fD_GetProto(obj
, count
)),
1740 fD_GetParam(obj
, count
),
1741 chtmp
, (count
==numregs
-1 && !BaseName
[0] ? "" : ", "));
1744 if (BaseName
[0]) /* was "##base" used? */
1745 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1746 if (fD_GetFuncParNum(obj
)!=illegal
)
1748 fprintf(outfile
, ", ");
1749 fprintf(outfile
, fD_GetProto(obj
, fD_GetFuncParNum(obj
)), "__fpt");
1751 fprintf(outfile
, ")\n\n");
1753 else if(target
==M68K_POS
)
1755 fprintf(outfile
, ") \\\n\t__INLINE_FUN_%d(", numregs
);
1756 fprintf(outfile
, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1757 BaseNamU
, BaseNamU
, -fD_GetOffset(obj
), rettype
, name
,
1758 (numregs
? ", \\\n\t" : ""));
1760 for (count
=d0
; count
<numregs
; count
++)
1761 fprintf(outfile
, "%s, %s, %s%s", fD_GetProto(obj
, count
),
1762 fD_GetParam(obj
, count
), fD_GetRegStr(obj
, count
),
1763 (count
==numregs
-1 ? "" : ", "));
1764 fprintf(outfile
, ")\n\n");
1766 else if (target
==PPC_POWERUP
|| target
==PPC_MORPHOS
)
1768 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1771 (BaseName
[0] ? "" : "UB"),
1772 -fD_GetOffset(obj
));
1775 fprintf(outfile
, "%s, ", rettype
);
1776 fprintf(outfile
, "%s, ", name
);
1778 for (count
=d0
; count
<numregs
; count
++)
1780 chtmp
=fD_GetRegStr(obj
, count
);
1782 if (strchr(fD_GetProto(obj
, count
),'%'))
1785 fD_GetProto(obj
, count
),
1788 fprintf(outfile
, "%s, %s, %s%s",
1790 fD_GetParam(obj
, count
),
1792 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1796 fprintf(outfile
, "%s, %s, %s%s",
1797 fD_GetProto(obj
, count
),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1798 fD_GetParam(obj
, count
),
1800 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1805 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1808 * Here it would make sense to create a database file to
1809 * integrate optimizations automaticly into every new
1810 * build. Not every function needs a complete flush. For
1811 * example functions with no parameter wouldn`t need a
1812 * PPC flush normally. Or Read(File,Addr,Size); would
1813 * only need a flush for Addr with the Size
1816 fprintf(outfile
, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1817 fprintf(outfile
, ")\n\n");
1819 else if (target
==IX86BE_AMITHLON
)
1821 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1824 (BaseName
[0] ? "" : "UB"),
1825 -fD_GetOffset(obj
));
1828 fprintf(outfile
, "%s, ", rettype
);
1829 fprintf(outfile
, "%s, ", name
);
1831 for (count
=d0
; count
<numregs
; count
++)
1833 chtmp
=fD_GetRegStr(obj
, count
);
1835 if (strchr(fD_GetProto(obj
, count
),'%'))
1838 fD_GetProto(obj
, count
),
1841 fprintf(outfile
, "%s, %s, %s%s",
1843 fD_GetParam(obj
, count
),
1845 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1849 fprintf(outfile
, "%s, %s, %s%s",
1850 fD_GetProto(obj
, count
),
1851 fD_GetParam(obj
, count
),
1853 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1858 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1860 fprintf(outfile
, ")\n\n");
1862 else if (target
==AROS
)
1864 fprintf(outfile
, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1866 (BaseName
[0] ? "" : "I"),
1867 (vd
? "void" : rettype
),
1870 for (count
=d0
; count
<numregs
; count
++)
1872 chtmp
=fD_GetRegStrU(obj
, count
);
1873 fprintf(outfile
, "\tAROS_LCA(%s, (%s), %s), \\\n",
1874 fD_GetProto(obj
, count
),
1875 fD_GetParam(obj
, count
),
1879 if (BaseName
[0]) /* was "##base" used? */
1881 fprintf(outfile
, "\tstruct %s *, %s_BASE_NAME, ", StdLib
, BaseNamU
);
1885 fprintf(outfile
, "\t/* bt */, /* bn */, ");
1888 "%ld, /* s */)\n\n",
1889 -fD_GetOffset(obj
) / 6);
1893 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
1897 else if (output_mode
==OLD
|| output_mode
==STUBS
)
1899 fprintf(outfile
, "%s__inline %s\n%s(%s",
1900 (output_mode
==STUBS
? "" : "extern "), rettype
, name
,
1901 (BaseName
[0] ? (numregs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1903 if (target
==M68K_AMIGAOS
)
1905 for (count
=d0
; count
<numregs
; count
++)
1907 chtmp
=fD_GetProto(obj
, count
);
1908 if (fD_GetFuncParNum(obj
)==count
)
1909 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1911 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1912 "" : " "), fD_GetParam(obj
, count
));
1913 if (count
<numregs
-1)
1914 fprintf(outfile
, ", ");
1917 fprintf(outfile
, ")\n{\n%s", (BaseName
[0] ? " BASE_EXT_DECL\n" : ""));
1919 fprintf(outfile
, " register %s%sres __asm(\"d0\");\n", rettype
,
1920 (*(rettype
+strlen(rettype
)-1)=='*' ? "" : " "));
1923 fprintf(outfile
, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1926 for (count
=d0
; count
<numregs
; count
++)
1928 chtmp
=fD_GetRegStr(obj
, count
);
1929 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1931 if (fD_GetFuncParNum(obj
)==count
)
1933 fprintf(outfile
, " register ");
1934 fprintf(outfile
, fD_GetProto(obj
, count
), chtmp
);
1935 fprintf(outfile
, " __asm(\"%s\") = %s;\n", chtmp
, fD_GetParam(obj
,
1940 const char *proto
=fD_GetProto(obj
, count
);
1941 fprintf(outfile
, " register %s%s%s __asm(\"%s\") = %s;\n",
1942 proto
, (*(proto
+strlen(proto
)-1)=='*' ? "" : " "), chtmp
,
1943 chtmp
, fD_GetParam(obj
, count
));
1947 fprintf(outfile
, " __asm volatile (\"exg d7,%s\\n\\t"
1948 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45
==4 ? "a4" : "a5"),
1949 -fD_GetOffset(obj
), (a45
==4 ? "a4" : "a5"));
1951 fprintf(outfile
, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1952 -fD_GetOffset(obj
));
1954 fprintf(outfile
, (vd
? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1956 fprintf(outfile
, " : ");
1958 fprintf(outfile
, "\"r\" (a6)%s", (numregs
? ", ": ""));
1960 for (count
=d0
; count
<numregs
; count
++)
1962 chtmp
=fD_GetRegStr(obj
, count
);
1963 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1965 fprintf(outfile
, "\"r\" (%s)%s", chtmp
, (count
<numregs
-1 ? ", " : ""));
1967 fprintf(outfile
, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1970 fprintf(outfile
, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1972 fprintf(outfile
, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1975 else if (target
==PPC_POWERUP
)
1977 for (count
= d0
; count
< numregs
; count
++)
1979 chtmp
= fD_GetProto(obj
, count
);
1980 if (fD_GetFuncParNum(obj
) == count
)
1981 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1983 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
1984 "" : " "), fD_GetParam(obj
, count
));
1985 if (count
< numregs
- 1)
1986 fprintf(outfile
, ", ");
1989 fprintf(outfile
, ")\t\n");
1990 fprintf(outfile
, "{\t\n");
1991 fprintf(outfile
, "struct Caos\tMyCaos;\n");
1992 fprintf(outfile
, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1993 fprintf(outfile
, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
1994 fprintf(outfile
, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
1995 fprintf(outfile
, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1996 fprintf(outfile
, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
1997 fprintf(outfile
, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2001 for (count
= d0
; count
< numregs
; count
++)
2003 fprintf(outfile
, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2004 fD_GetRegStr(obj
, count
),
2005 fD_GetParam(obj
, count
));
2009 fprintf(outfile
, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj
));
2011 * was "##base" used?
2014 fprintf(outfile
, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2018 fprintf(outfile
, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2022 fprintf(outfile
, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2026 else if (target
==PPC_MORPHOS
)
2028 for (count
= d0
; count
< numregs
; count
++)
2030 chtmp
= fD_GetProto(obj
, count
);
2031 if (fD_GetFuncParNum(obj
) == count
)
2032 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2034 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2035 "" : " "), fD_GetParam(obj
, count
));
2036 if (count
< numregs
- 1)
2037 fprintf(outfile
, ", ");
2040 fprintf(outfile
, ")\t\n{\t\n");
2044 for (count
= d0
; count
< numregs
; count
++)
2046 fprintf(outfile
, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2047 fD_GetRegStrU(obj
, count
), fD_GetParam(obj
, count
));
2052 * was "##base" used?
2055 fprintf(outfile
, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2059 fprintf(outfile
, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj
));
2063 fprintf(outfile
, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2064 rettype
, fD_GetOffset(obj
));
2067 else if (target
==IX86BE_AMITHLON
)
2070 for (count
= d0
; count
< numregs
; count
++)
2072 chtmp
= fD_GetProto(obj
, count
);
2073 if (fD_GetFuncParNum(obj
) == count
)
2074 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2076 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2077 "" : " "), fD_GetParam(obj
, count
));
2078 if (count
< numregs
- 1)
2079 fprintf(outfile
, ", ");
2082 fprintf(outfile
, ")\n{\n");
2083 fprintf(outfile
, "\tstruct _Regs _regs;\n");
2087 for (count
= d0
; count
< numregs
; count
++)
2089 fprintf(outfile
, "\t_regs.reg_%s = (ULONG) (%s);\n",
2090 fD_GetRegStr(obj
, count
),
2091 fD_GetParam(obj
, count
));
2097 fprintf(outfile
, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2102 fprintf(outfile
, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2103 -fD_GetOffset(obj
));
2107 fprintf(outfile
, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2108 rettype
,-fD_GetOffset(obj
));
2111 for (count
= d0
; count
< numregs
; count
++)
2113 chtmp
= fD_GetProto(obj
, count
);
2114 if (fD_GetFuncParNum(obj
) == count
)
2115 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2117 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2118 "" : " "), fD_GetParam(obj
, count
));
2119 if (count
< numregs
- 1)
2120 fprintf(outfile
, ", ");
2123 fprintf(outfile
, ")\n{\n");
2124 fprintf(outfile
, "\t%s LP%d%s%s(0x%lx, ",
2125 (vd
? "" : "return "),
2128 (BaseName
[0] ? "" : "UB"),
2129 -fD_GetOffset(obj
));
2132 fprintf(outfile
, "%s, ", rettype
);
2133 fprintf(outfile
, "%s, ", name
);
2135 for (count
=d0
; count
<numregs
; count
++)
2137 chtmp
=fD_GetRegStr(obj
, count
);
2139 if (strchr(fD_GetProto(obj
, count
),'%'))
2142 fD_GetProto(obj
, count
),
2145 fprintf(outfile
, "%s, %s, %s%s",
2147 fD_GetParam(obj
, count
),
2149 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2153 fprintf(outfile
, "%s, %s, %s%s",
2154 fD_GetProto(obj
, count
),
2155 fD_GetParam(obj
, count
),
2157 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2162 fprintf(outfile
, "\\\n\t, BASE_NAME");
2164 fprintf(outfile
, ");\n}\n\n");
2169 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2173 else if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
2175 int has_base
= (BaseName
[0] && fD_GetOffset(obj
) != 0);
2180 for (count
=d0
; count
<numregs
; count
++)
2182 if (fD_GetFuncParNum(obj
) == count
)
2184 char funcproto
[200]; /* Hope will be enough... */
2185 sprintf(funcproto
, "%s_%s_funcproto_%d",
2186 BaseNamC
, name
, count
);
2187 fprintf(outfile
, "typedef ");
2188 fprintf(outfile
, fD_GetProto(obj
, count
), funcproto
);
2189 fprintf(outfile
, ";\n");
2194 if (output_mode
==GATESTUBS
)
2196 fprintf(outfile
, "%s %s%s(",
2201 for (count
=d0
; count
<numregs
; count
++)
2203 chtmp
= fD_GetProto(obj
, count
);
2205 fprintf(outfile
, chtmp
, "");
2206 fprintf(outfile
, "%s",
2207 (count
== numregs
- 1 && !has_base
? ");\n" : ", "));
2211 fprintf(outfile
, "struct %s *);\n", StdLib
);
2214 if (target
==M68K_AMIGAOS
)
2216 fprintf(outfile
, "%s %s%s(\n",
2221 for (count
=d0
; count
<numregs
; count
++)
2223 chtmp
= fD_GetProto(obj
, count
);
2225 if (fD_GetFuncParNum(obj
) == count
)
2227 fprintf(outfile
, "\t");
2228 fprintf(outfile
, chtmp
,
2229 fD_GetParam(obj
, count
));
2230 fprintf(outfile
, " __asm(\"%s\")%s",
2231 fD_GetRegStr(obj
, count
),
2232 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2236 fprintf(outfile
, "\t%s %s __asm(\"%s\")%s",
2238 fD_GetParam(obj
, count
),
2239 fD_GetRegStr(obj
, count
),
2240 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2245 fprintf(outfile
, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib
);
2247 if (output_mode
==GATESTUBS
)
2248 fprintf(outfile
, "{\n");
2250 else if (target
==AROS
)
2252 fprintf(outfile
, "AROS_LH%d%s(%s, %s%s,\n",
2254 has_base
? "" : "I",
2259 for (count
=d0
; count
<numregs
; count
++)
2261 char funcproto
[200]; /* Hope will be enough... */
2263 if (fD_GetFuncParNum(obj
) == count
)
2265 sprintf(funcproto
, "%s_%s_funcproto_%d",
2266 BaseNamC
, name
, count
);
2269 fprintf(outfile
, "\tAROS_LHA(%s, %s, %s),\n",
2270 fD_GetFuncParNum(obj
) == count
? funcproto
: fD_GetProto(obj
, count
),
2271 fD_GetParam(obj
, count
),
2272 fD_GetRegStrU(obj
, count
));
2275 fprintf(outfile
, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2277 -fD_GetOffset(obj
) / 6,
2280 if (output_mode
==GATESTUBS
)
2281 fprintf(outfile
, "{\n");
2283 else if (target
==PPC_MORPHOS
)
2285 fprintf(outfile
, "%s %s%s(void)\n",
2290 if (output_mode
==GATESTUBS
)
2292 fprintf(outfile
, "{\n");
2294 for (count
=d0
; count
<numregs
; count
++)
2296 chtmp
= fD_GetProto(obj
, count
);
2298 if (fD_GetFuncParNum(obj
) == count
)
2300 fprintf(outfile
, "\t");
2301 fprintf(outfile
, chtmp
,
2302 fD_GetParam(obj
, count
));
2303 fprintf(outfile
, " = (");
2304 fprintf(outfile
, chtmp
, "");
2305 fprintf(outfile
, ") REG_%s;\n",
2306 fD_GetRegStrU(obj
, count
));
2310 fprintf(outfile
, "\t%s %s = (%s) REG_%s;\n",
2311 fD_GetProto(obj
, count
),
2312 fD_GetParam(obj
, count
),
2313 fD_GetProto(obj
, count
),
2314 fD_GetRegStrU(obj
, count
));
2320 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2323 fprintf(outfile
, "\n");
2326 else if (target
==IX86BE_AMITHLON
)
2328 fprintf(outfile
, "%s %s%s( struct _Regs _regs )\n",
2333 if (output_mode
==GATESTUBS
)
2335 fprintf(outfile
, "{\n");
2337 for (count
=d0
; count
<numregs
; count
++)
2339 chtmp
= fD_GetProto(obj
, count
);
2341 if (fD_GetFuncParNum(obj
) == count
)
2343 fprintf(outfile
, "\t");
2344 fprintf(outfile
, chtmp
,
2345 fD_GetParam(obj
, count
));
2346 fprintf(outfile
, " = (");
2347 fprintf(outfile
, chtmp
, "");
2348 fprintf(outfile
, ") _regs.%s;\n",
2349 fD_GetRegStr(obj
, count
));
2353 fprintf(outfile
, "\t%s %s = (%s) _regs.%s;\n",
2354 fD_GetProto(obj
, count
),
2355 fD_GetParam(obj
, count
),
2356 fD_GetProto(obj
, count
),
2357 fD_GetRegStr(obj
, count
));
2363 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2366 fprintf(outfile
, "\n");
2371 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2375 if (output_mode
==GATESTUBS
)
2377 fprintf(outfile
,"\treturn %s%s(",
2381 for (count
=d0
; count
<numregs
; count
++)
2383 fprintf(outfile
, "%s%s",
2384 fD_GetParam(obj
, count
),
2385 (count
== numregs
- 1 && !has_base
? ");" : ", "));
2389 fprintf(outfile
, "BASE_NAME);");
2391 fprintf(outfile
,"\n}\n\n");
2395 fprintf(outfile
,";\n");
2399 fprintf(outfile
, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s)\n",
2405 fprintf(outfile
,"\n");
2410 fprintf(stderr
, "Internal error: Unknown output mode in fD_write().\n");
2414 if ((tagname
=aliasfunction(fD_GetName(obj
)))!=0 &&
2415 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2417 fprintf(outfile
, "#define %s(", tagname
);
2418 for (count
=d0
; count
<numregs
-1; count
++)
2419 fprintf(outfile
, "a%d, ", count
);
2420 fprintf(outfile
, "a%d) %s (", count
, name
);
2421 for (count
=d0
; count
<numregs
-1; count
++)
2422 fprintf(outfile
, "(a%d), ", count
);
2423 fprintf(outfile
, "(a%d))\n\n", count
);
2426 if ((tagname
=taggedfunction(obj
))!=0 &&
2427 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2429 if (output_mode
!=STUBS
)
2432 "#ifndef %sNO_INLINE_STDARG\n"
2434 (target
==M68K_POS
? "__" : ""),
2437 for (count
=d0
; count
<numregs
-1; count
++)
2438 fprintf(outfile
, "a%d, ", count
);
2440 fprintf(outfile
, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2443 for (count
=d0
; count
<numregs
-1; count
++)
2444 fprintf(outfile
, "(a%d), ", count
);
2446 fprintf(outfile
, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2447 fD_GetProto(obj
, fD_RegNum(obj
)-1),
2448 (target
==M68K_POS
? "__" : ""));
2453 if (target
==M68K_AMIGAOS
|| target
==IX86BE_AMITHLON
)
2455 fprintf(outfile
, "__inline %s\n%s(", rettype
, tagname
);
2457 for (count
=d0
; count
<numregs
-1; count
++)
2459 chtmp
=fD_GetProto(obj
, count
);
2460 if (count
==fD_GetFuncParNum(obj
))
2461 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2463 fprintf(outfile
, "%s%s%s", chtmp
,
2464 (*(chtmp
+strlen(chtmp
)-1)=='*' ? "" : " "),
2465 fD_GetParam(obj
, count
));
2466 fprintf(outfile
, ", ");
2469 fprintf(outfile
, "int tag, ...)\n{\n ");
2471 fprintf(outfile
, "return ");
2473 fprintf(outfile
, "%s(", name
);
2474 for (count
=d0
; count
<numregs
-1; count
++)
2475 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
2477 fprintf(outfile
, "(%s)&tag);\n}\n\n", fD_GetProto(obj
, fD_RegNum(obj
)-1));
2479 else if (target
==PPC_MORPHOS
)
2481 int n
= 9 - numregs
; /* number of regs that contain varargs */
2482 int d
= n
& 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2483 int taglist
= 8; /* offset of the start of the taglist */
2484 int local
= (taglist
+ n
* 4 + d
+ 8 + 15) & ~15; /* size of the stack frame */
2489 * 0 - 3: next frame ptr
2491 * 8 - 8+n*4+d+8-1: tag list start
2492 * ? - local-1: padding
2499 " .type %s,@function\n"
2501 " stwu 1,-%d(1) \n" /* create stack frame */
2504 tagname
, tagname
, tagname
, local
, local
+ 4);
2507 * If n is odd, one tag is split between regs and stack.
2508 * Copy its ti_Data together with the ti_Tag.
2511 fprintf(outfile
, " lwz 0,%d(1)\n", local
+ 8); /* read ti_Data */
2513 * Save the registers
2515 for (count
= numregs
; count
<= 8; count
++)
2516 fprintf(outfile
, " stw %d,%d(1)\n", count
+ 2, (count
- numregs
) * 4 + taglist
);
2519 fprintf(outfile
, " stw 0,%d(1)\n", taglist
+ n
* 4); /* write ti_Data */
2524 fprintf(outfile
, " li 11,2 \n"
2526 " stw 11,%d(1) \n" /* add TAG_MORE */
2527 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2529 taglist
+ n
* 4 + d
,
2530 taglist
+ n
* 4 + d
+ 4);
2533 if (DirectVarargsCalls
)
2536 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2538 numregs
+ 2, taglist
, name
);
2543 * Save the non-varargs registers in the EmulHandle struct.
2545 for (count
= 0; count
< numregs
- 1; count
++)
2547 int r
= fD_GetReg(obj
, count
);
2549 fprintf(outfile
, " stw %d,%d(2)\n", count
+ 3, r
* 4);
2555 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2556 " stw 0,%d(2) \n" /* REG_?? = taglist */
2558 " lwz 12,%s@l(12)\n"
2559 " li 3,%ld \n" /* r3 = lvo */
2560 " stw 12,56(2) \n" /* REG_A6 = libbase */
2561 " bctrl \n",/* EmulCallOS() */
2562 BaseName
, taglist
, 4 * fD_GetReg(obj
, numregs
- 1), BaseName
,
2566 fprintf(outfile
," lwz 0,%d(1) \n" /* clear stack frame & return */
2571 " .size\t%s,.L%se1-%s\n"
2574 tagname
, tagname
, tagname
, tagname
);
2578 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2583 else if ((varname
= getvarargsfunction(obj
)) != 0 &&
2584 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2586 if (output_mode
!= STUBS
)
2589 "#ifndef NO_INLINE_VARARGS\n"
2590 "#define %s(", varname
);
2592 for (count
= d0
; count
< numregs
- 1; count
++)
2593 fprintf(outfile
, "a%d, ", count
);
2597 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2600 for (count
= d0
; count
< numregs
- 1; count
++)
2601 fprintf(outfile
, "(a%d), ", count
);
2605 "#endif /* !NO_INLINE_VARARGS */\n\n",
2606 fD_GetProto(obj
, fD_RegNum(obj
) - 1));
2610 fprintf(stderr
, "can`t create a varargs stub function for %s\n",
2615 if (strcmp(name
, "DoPkt")==0 &&
2616 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2618 fdDef
*objnc
=(fdDef
*)obj
;
2619 char newname
[7]="DoPkt0";
2620 objnc
->name
=newname
;
2621 for (count
=2; count
<7; count
++)
2623 regs reg
=objnc
->reg
[count
];
2624 char *proto
=objnc
->proto
[count
];
2625 objnc
->reg
[count
]=illegal
;
2626 objnc
->proto
[count
]=fD_nostring
;
2627 fD_write(outfile
, objnc
);
2628 objnc
->reg
[count
]=reg
;
2629 objnc
->proto
[count
]=proto
;
2632 objnc
->name
=(char*)name
;
2637 varargsfunction(const char* proto
, const char* funcname
)
2639 const char *end
=proto
+strlen(proto
)-1;
2640 while (isspace(*end
))
2644 while (isspace(*end
))
2648 while (isspace(*end
))
2650 if (!strncmp(end
-2, "...", 3))
2652 /* Seems to be a varargs function. Check if it will be recognized
2655 char fixedname
[200]; /* Hope will be enough... */
2658 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0];
2660 if (strcmp(funcname
, TagExcTable
[count
+1])==0)
2663 if (!(tmpdef
=fD_ctor()))
2665 fprintf(stderr
, "No mem for FDs\n");
2669 strcpy(fixedname
, funcname
);
2670 if (strlen(funcname
)>4 &&
2671 !strcmp(funcname
+strlen(funcname
)-4, "Tags"))
2673 /* Might be either nothing or "TagList". */
2674 fixedname
[strlen(fixedname
)-4]='\0';
2675 fD_NewName(tmpdef
, fixedname
);
2676 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2680 strcat(fixedname
, "TagList");
2681 fD_NewName(tmpdef
, fixedname
);
2682 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2688 strcat(fixedname
, "A");
2689 fD_NewName(tmpdef
, fixedname
);
2690 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2701 ishandleddifferently(const char* proto
, const char* funcname
)
2703 /* First check if this is a vararg call? */
2704 if (varargsfunction(proto
, funcname
))
2707 /* It might be a dos.library "alias" name. */
2708 if (aliasfunction(funcname
))
2711 /* It might be one from dos.library/DoPkt() family. */
2712 if (strlen(funcname
)==6 && !strncmp(funcname
, "DoPkt", 5) &&
2713 funcname
[5]>='0' && funcname
[6]<='4')
2716 /* Finally, it can be intuition.library/ReportMouse1(). */
2717 return !strcmp(funcname
, "ReportMouse1");
2721 printusage(const char* exename
)
2724 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2727 "--mode=MODE\t\tMODE is one of the following:\n"
2728 "\tnew\t\t\tPreprocessor based (default)\n"
2729 "\told\t\t\tInline based\n"
2730 "\tstubs\t\t\tLibrary stubs\n"
2731 "\tgatestubs\t\tLibrary gate stubs\n"
2732 "\tgateproto\t\tLibrary gate prototypes\n"
2733 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2735 "--target=OS\t\tOS is one of the following: \n"
2736 "\t*-aros\t\t\tAROS (any CPU)\n"
2737 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2738 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2739 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2740 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2741 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2743 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2744 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2745 "--libprefix=PREFIX\tLocal function name prefix\n"
2746 "--local\t\t\tUse local includes\n"
2747 "--quiet\t\t\tDon't display warnings\n"
2748 "--version\t\tPrint version number and exit\n\n"
2749 "Compatibility options:\n"
2750 "--new\t\t\tSame as --mode=new\n"
2751 "--old\t\t\tSame as --mode=old\n"
2752 "--stubs\t\t\tSame as --mode=stubs\n"
2753 "--gatestubs\t\tSame as --mode=gatestubs\n"
2754 "--proto\t\t\tSame as --mode=prot\n"
2755 "--pos\t\t\tSame as --target=m68k-pos\n"
2756 "--morphos\t\tSame as --target=powerpc-morphos\n"
2757 "--powerup\t\tSame as --target=powerpc-powerup\n"
2761 void output_proto(FILE* outfile
)
2764 "/* Automatically generated header! Do not edit! */\n\n"
2765 "#ifndef PROTO_%s_H\n"
2766 "#define PROTO_%s_H\n\n"
2767 "#include <clib/%s_protos.h>\n\n"
2768 "#ifndef _NO_INLINE\n"
2770 "#include <inline/%s.h>\n"
2771 "#endif /* __GNUC__ */\n"
2772 "#endif /* !_NO_INLINE */\n\n",
2773 BaseNamU
, BaseNamU
, BaseNamL
, BaseNamL
);
2777 "#ifndef __NOLIBBASE__\n"
2778 "extern struct %s *\n"
2779 "#ifdef __CONSTLIBBASEDECL__\n"
2780 "__CONSTLIBBASEDECL__\n"
2781 "#endif /* __CONSTLIBBASEDECL__ */\n"
2783 "#endif /* !__NOLIBBASE__ */\n\n",
2787 "#endif /* !PROTO_%s_H */\n", BaseNamU
);
2790 /******************************************************************************/
2793 main(int argc
, char** argv
)
2795 fdDef
*tmpdef
, /* a dummy to contain the name to look for */
2796 *founddef
; /* the fdDef for which we found a prototype */
2801 char *fdfilename
=0, *clibfilename
=0, *outfilename
=0;
2806 for (count
=1; count
<argc
; count
++)
2808 char *option
=argv
[count
];
2812 if (strcmp(option
, "o")==0)
2814 if (count
==argc
-1 || outfilename
)
2816 printusage(argv
[0]);
2817 return EXIT_FAILURE
;
2819 if (strcmp(argv
[++count
], "-"))
2820 outfilename
=argv
[count
];
2824 if (*option
=='-') /* Accept GNU-style '--' options */
2826 if (strncmp(option
, "mode=", 5)==0)
2828 if (strcmp(option
+5, "new")==0)
2830 else if (strcmp(option
+5, "old")==0)
2832 else if (strcmp(option
+5, "stubs")==0)
2834 else if (strcmp(option
+5, "gatestubs")==0)
2835 output_mode
=GATESTUBS
;
2836 else if (strcmp(option
+5, "gateproto")==0)
2837 output_mode
=GATEPROTO
;
2838 else if (strcmp(option
+5, "proto")==0)
2841 else if (strncmp(option
, "target=", 7)==0)
2843 if (MatchGlob("*-aros",option
+7))
2845 else if (MatchGlob("i?86be*-amithlon",option
+7))
2846 target
=IX86BE_AMITHLON
;
2847 else if (MatchGlob("m68k*-amigaos",option
+7))
2848 target
=M68K_AMIGAOS
;
2849 else if (MatchGlob("m68k*-pos",option
+7))
2851 else if (MatchGlob("powerpc*-powerup",option
+7))
2853 else if (MatchGlob("powerpc*-morphos",option
+7))
2857 printusage(argv
[0]);
2858 return EXIT_FAILURE
;
2861 else if (strcmp(option
, "direct-varargs-calls") == 0)
2862 DirectVarargsCalls
= 1;
2863 else if (strncmp(option
, "gateprefix=", 11)==0)
2864 gateprefix
= option
+11;
2865 else if (strncmp(option
, "libprefix=", 10)==0)
2866 libprefix
= option
+10;
2867 else if (strcmp(option
, "quiet") == 0)
2869 else if (strcmp(option
, "version")==0)
2871 fprintf(stderr
, "fd2inline version " VERSION
"\n");
2872 return EXIT_SUCCESS
;
2874 /* Compatibility options */
2875 else if (strcmp(option
, "new")==0)
2877 else if (strcmp(option
, "old")==0)
2879 else if (strcmp(option
, "stubs")==0)
2881 else if (strcmp(option
, "gatestubs")==0)
2882 output_mode
=GATESTUBS
;
2883 else if (strcmp(option
, "proto")==0)
2885 else if (strcmp(option
, "pos")==0)
2887 else if (strcmp(option
, "powerup")==0)
2889 else if (strcmp(option
, "morphos")==0)
2891 /* Unknown option */
2894 printusage(argv
[0]);
2895 return EXIT_FAILURE
;
2901 /* One of the filenames */
2904 else if (!clibfilename
)
2905 clibfilename
=option
;
2906 else if (!outfilename
)
2910 printusage(argv
[0]);
2911 return EXIT_FAILURE
;
2916 if (!fdfilename
|| (!clibfilename
&& output_mode
!=PROTO
))
2918 printusage(argv
[0]);
2919 return EXIT_FAILURE
;
2922 if (target
==M68K_POS
&& output_mode
!=NEW
)
2924 fprintf(stderr
, "Target is not compatible with the mode.\n");
2925 return EXIT_FAILURE
;
2928 if (!(arrdefs
=malloc(FDS
*sizeof(fdDef
*))))
2930 fprintf(stderr
, "No mem for FDs\n");
2931 return EXIT_FAILURE
;
2933 for (count
=0; count
<FDS
; count
++)
2934 arrdefs
[count
]=NULL
;
2936 if (!(myfile
=fF_ctor(fdfilename
)))
2938 fprintf(stderr
, "Couldn't open file '%s'.\n", fdfilename
);
2939 return EXIT_FAILURE
;
2944 for (count
=0; count
<FDS
&& lerror
==false; count
++)
2946 if (!(arrdefs
[count
]=fD_ctor()))
2948 fprintf(stderr
, "No mem for FDs\n" );
2949 return EXIT_FAILURE
;
2953 if ((lerror
=fF_readln(myfile
))==false)
2955 fF_SetError(myfile
, false);
2956 lerror
=fD_parsefd(arrdefs
[count
], myfile
);
2959 while (lerror
==nodef
);
2964 fD_dtor(arrdefs
[count
]);
2965 arrdefs
[count
]=NULL
;
2969 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpName
);
2971 if (output_mode
!=NEW
|| target
==AROS
)
2973 unsigned int count2
;
2976 for (count2
=0; count2
<sizeof LibExcTable
/sizeof LibExcTable
[0]; count2
+=2)
2977 if (strcmp(BaseName
, LibExcTable
[count2
])==0)
2979 StdLib
=LibExcTable
[count2
+1];
2986 if (output_mode
!=PROTO
)
2988 if (!(myfile
=fF_ctor(clibfilename
)))
2990 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
2991 return EXIT_FAILURE
;
2994 if (!(tmpdef
=fD_ctor()))
2996 fprintf(stderr
, "No mem for FDs\n");
2997 return EXIT_FAILURE
;
3000 for (lerror
=false; lerror
==false || lerror
==nodef
;)
3001 if ((lerror
=fF_readln(myfile
))==false)
3003 fF_SetError(myfile
, false); /* continue even on errors */
3004 tmpstr
=fF_FuncName(myfile
);
3009 fD_NewName(tmpdef
, tmpstr
);
3010 res
=(fdDef
**)bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
3016 DBP(fprintf(stderr
, "found (%s).\n", fD_GetName(founddef
)));
3017 fF_SetError(myfile
, false);
3018 lerror
=fD_parsepr(founddef
, myfile
);
3021 if (!ishandleddifferently(myfile
->line
, tmpstr
))
3023 fprintf(stderr
, "Don't know what to do with <%s> in line %lu.\n",
3024 tmpstr
, myfile
->lineno
);
3034 if (strlen(fdfilename
)>7 &&
3035 !strcmp(fdfilename
+strlen(fdfilename
)-7, "_lib.fd"))
3037 char *str
=fdfilename
+strlen(fdfilename
)-8;
3038 while (str
!=fdfilename
&& str
[-1]!='/' && str
[-1]!=':')
3040 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3041 strncpy(BaseNamU
, str
, strlen(str
)-7);
3042 BaseNamU
[strlen(str
)-7]='\0';
3043 strcpy(BaseNamL
, BaseNamU
);
3044 strcpy(BaseNamC
, BaseNamU
);
3048 strcpy(BaseNamU
, BaseName
);
3049 if (strlen(BaseNamU
)>4 && strcmp(BaseNamU
+strlen(BaseNamU
)-4, "Base")==0)
3050 BaseNamU
[strlen(BaseNamU
)-4]='\0';
3051 if (target
==M68K_POS
&& strncmp(BaseNamU
, "gb_", 3)==0)
3052 memmove(BaseNamU
, &BaseNamU
[3], strlen(&BaseNamU
[3])+1);
3053 strcpy(BaseNamL
, BaseNamU
);
3054 strcpy(BaseNamC
, BaseNamU
);
3057 BaseNamC
[0]=toupper(BaseNamC
[0]);
3061 if (!(outfile
=fopen(outfilename
, "w")))
3063 fprintf(stderr
, "Couldn't open output file.\n");
3064 return EXIT_FAILURE
;
3074 if (output_mode
==PROTO
)
3075 output_proto(outfile
);
3078 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
||
3079 output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3081 if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3084 "/* Automatically generated stubs! Do not edit! */\n\n");
3089 "/* Automatically generated header! Do not edit! */\n\n"
3090 "#ifndef %sINLINE_%s_H\n"
3091 "#define %sINLINE_%s_H\n\n",
3092 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3094 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3098 if (output_mode
==NEW
)
3100 if(target
==M68K_POS
)
3103 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3104 "#include <pInline/macros.h>\n"
3105 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3107 else if(target
==AROS
)
3110 "#ifndef AROS_LIBCALL_H\n"
3111 "#include <aros/libcall.h>\n"
3112 "#endif /* !AROS_LIBCALL_H */\n\n");
3117 "#ifndef __INLINE_MACROS_H\n"
3118 "#include <inline/macros.h>\n"
3119 "#endif /* !__INLINE_MACROS_H */\n\n");
3127 "#ifndef __INLINE_STUB_H\n"
3128 "#include <inline/stubs.h>\n"
3129 "#endif /* !__INLINE_STUB_H */\n\n");
3131 fprintf(outfile
, "#ifdef __CLIB_TYPES__\n" );
3133 clib
= fopen( clibfilename
, "r" );
3137 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3141 char* buffer
= malloc( 1024 );
3143 if( buffer
== NULL
)
3145 fprintf(stderr
, "No memory for line buffer.\n " );
3149 while( fgets( buffer
, 1023, clib
) != NULL
)
3151 if( buffer
[ 0 ] == '#' /* Pre-processor instruction */ ||
3152 strncmp( buffer
, "typedef", 7 ) == 0 )
3154 fprintf(outfile
, buffer
);
3164 fprintf(outfile
, "#endif /* __CLIB_TYPES__ */\n\n" );
3169 "#include <aros/libcall.h>\n\n" );
3171 else if(target
==IX86BE_AMITHLON
)
3174 "#ifndef __INLINE_MACROS_H\n"
3175 "#include <inline/macros.h>\n"
3176 "#endif /* __INLINE_MACROS_H */\n\n");
3178 else if (target
== PPC_MORPHOS
)
3181 "#include <emul/emulregs.h>\n\n" );
3187 fprintf(stderr
, "Internal error: Unknown output mode in main().\n");
3194 return EXIT_FAILURE
;
3199 if (output_mode
==NEW
)
3202 "#ifndef %s%s_BASE_NAME\n"
3203 "#define %s%s_BASE_NAME %s\n"
3204 "#endif /* !%s%s_BASE_NAME */\n\n",
3205 (target
==M68K_POS
? "__" : ""), BaseNamU
,
3206 (target
==M68K_POS
? "__" : ""), BaseNamU
, BaseName
,
3207 (target
==M68K_POS
? "__" : ""), BaseNamU
);
3208 if (target
==M68K_POS
)
3210 "#ifndef __%s_LIB_NAME\n"
3211 "#define __%s_LIB_NAME %s\n"
3212 "#endif /* !__%s_LIB_NAME */\n\n",
3214 (strcmp(BaseName
, "gb_ExecBase") ? BaseName
: "gb_ExecLib"),
3219 "#ifndef BASE_EXT_DECL\n"
3220 "#define BASE_EXT_DECL\n"
3221 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3222 "#endif /* !BASE_EXT_DECL */\n"
3223 "#ifndef BASE_PAR_DECL\n"
3224 "#define BASE_PAR_DECL\n"
3225 "#define BASE_PAR_DECL0 void\n"
3226 "#endif /* !BASE_PAR_DECL */\n"
3227 "#ifndef BASE_NAME\n"
3228 "#define BASE_NAME %s\n"
3229 "#endif /* !BASE_NAME */\n\n"
3230 "BASE_EXT_DECL0\n\n", StdLib
, BaseName
, BaseName
);
3233 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3235 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3237 fD_write(outfile
, arrdefs
[count
]);
3238 fD_dtor(arrdefs
[count
]);
3239 arrdefs
[count
]=NULL
;
3242 if (output_mode
!=NEW
)
3245 "#undef BASE_EXT_DECL\n"
3246 "#undef BASE_EXT_DECL0\n"
3247 "#undef BASE_PAR_DECL\n"
3248 "#undef BASE_PAR_DECL0\n"
3249 "#undef BASE_NAME\n\n");
3251 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
)
3253 fprintf(outfile
, "#endif /* !%sINLINE_%s_H */\n",
3254 (target
==M68K_POS
? "__INC_POS_P" : "_"), BaseNamU
);
3265 return EXIT_SUCCESS
;