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 */
61 /* To prevent the enum below from getting broken when building on AROS */
66 d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
, a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, illegal
69 typedef unsigned char shortcard
;
71 typedef enum { false, nodef
, real_error
} Error
;
73 enum { NEW
, OLD
, STUBS
, PROTO
, GATESTUBS
, GATEPROTO
} output_mode
=NEW
;
74 enum { IX86BE_AMITHLON
, AROS
, M68K_AMIGAOS
, M68K_POS
, PPC_POWERUP
, PPC_MORPHOS
} target
= M68K_AMIGAOS
;
77 int DirectVarargsCalls
= 0;
81 char *gateprefix
= "";
84 char BaseName
[64], BaseNamU
[64], BaseNamL
[64], BaseNamC
[64];
87 const static char *LibExcTable
[]=
89 "BattClockBase", "Node",
90 "BattMemBase", "Node",
91 "ConsoleDevice", "Device",
92 "DiskBase", "DiskResource",
93 "DOSBase", "DosLibrary",
94 "SysBase", "ExecBase",
95 "ExpansionBase", "ExpansionBase",
97 "InputBase", "Device",
98 "IntuitionBase", "IntuitionBase",
99 "LocaleBase", "LocaleBase",
100 "MathIeeeDoubBasBase", "MathIEEEBase",
101 "MathIeeeDoubTransBase","MathIEEEBase",
102 "MathIeeeSingBasBase", "MathIEEEBase",
103 "MathIeeeSingTransBase","MathIEEEBase",
106 "RamdriveDevice", "Device",
107 "RealTimeBase", "RealTimeBase",
108 "RexxSysBase", "RxsLib",
109 "TimerBase", "Device",
110 "UtilityBase", "UtilityBase"
112 const char *StdLib
; /* global lib-name ptr */
114 /*******************************************
115 * just some support functions, no checking
116 *******************************************/
119 NewString(char** new, const char* old
)
124 while (*old
&& (*old
==' ' || *old
=='\t'))
127 for (high
=old
+len
-1; high
>=old
&& (*high
==' ' || *high
=='\t'); high
--);
133 strncpy(*new, old
, len
);
137 fprintf(stderr
, "No mem for string\n");
142 illparams(const char* funcname
)
144 fprintf(stderr
, "%s: illegal Parameters\n", funcname
);
147 static INLINE
const char*
150 const static char *aosregs
[]=
152 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
153 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
180 return (target
!=M68K_POS
? aosregs
[reg
] : posregs
[reg
]);
183 static INLINE
const char*
186 const static char *aosregs
[]=
188 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
189 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
196 return (target
!=M68K_POS
? aosregs
[reg
] : RegStr(reg
));
201 /******************************************************************************
204 * searches string in from position at downwards, as long as in does not
205 * contain any character in not.
207 ******************************************************************************/
210 StrNRBrk(const char* in
, const char* not, const char* at
)
215 chcheck
=""; /* if at<in, the result will be NULL */
216 for (ready
=false; ready
==false && at
>=in
;)
218 for (chcheck
=not; *chcheck
&& *chcheck
!= *at
; chcheck
++);
224 DBP(fprintf(stderr
, "{%c}", *chcheck
));
225 return *chcheck
? at
: NULL
;
229 Our own "strupr", since it is a non-standard function.
242 MatchGlob( char* glob
, char* str
)
259 if( c
== 0 || *str
!= c
)
273 if( MatchGlob( glob
, str
) )
296 /******************************************************************************
299 * stores a file with a temporary buffer (static length, sorry), a line number,
300 * an offset (used for library offsets and an error field.
301 * When there's no error, line will contain line #lineno and offset will be
302 * the last offset set by the interpretation of the last line. If there's been
303 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
304 * It is assumed offsets are always negative.
305 ******************************************************************************/
307 #define fF_BUFSIZE 1024
309 /* all you need to know about an fdFile you parse */
311 typedef enum {FD_PRIVATE
=1, FD_SHADOW
=2} fdflags
;
315 FILE* file
; /* the file we're reading from */
316 char line
[fF_BUFSIZE
]; /* the current line */
317 unsigned long lineno
; /* current line number */
318 long offset
; /* current fd offset (-bias) */
319 Error error
; /* is everything o.k. */
320 fdflags flags
; /* for ##private, ##shadow (p.OS) */
324 fF_ctor (const char* fname
);
326 fF_dtor (fdFile
* obj
);
328 fF_SetError (fdFile
* obj
, Error error
);
330 fF_SetOffset (fdFile
* obj
, long at
);
332 fF_readln (fdFile
* obj
);
334 fF_GetError (const fdFile
* obj
);
336 fF_GetOffset (const fdFile
* obj
);
338 fF_FuncName (fdFile
* obj
); /* return name or null */
340 fF_SetFlags (fdFile
* obj
, fdflags flags
);
342 fF_GetFlags (const fdFile
* obj
);
352 fF_SetError(fdFile
* obj
, Error error
)
357 illparams("fF_SetError");
360 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
363 fF_SetOffset(fdFile
* obj
, long at
)
368 illparams("fFSetOffset");
372 fF_SetFlags(fdFile
* obj
, fdflags flags
)
377 illparams("fF_SetFlags");
381 fF_ctor(const char* fname
)
387 result
=malloc(sizeof(fdFile
));
390 result
->file
=fopen(fname
, "r");
394 fF_SetOffset(result
, -30);
395 fF_SetError(result
, false);
396 fF_SetFlags(result
, 0);
397 result
->line
[0]='\0';
409 illparams("fF_ctor");
415 fF_readln(fdFile
* obj
)
418 long glen
, /* the length we read until now */
419 len
; /* the length of the last segment */
429 if (!fgets(low
, fF_BUFSIZE
-1-glen
, obj
->file
))
431 fF_SetError(obj
, real_error
);
435 if (low
==strpbrk(low
, "*#/"))
437 DBP(fprintf(stderr
, "in# %s\n", obj
->line
));
442 while (len
&& isspace(*bpoint
))
447 if (*bpoint
==';' || *bpoint
==')')
449 DBP(fprintf(stderr
, "\nin: %s\n", obj
->line
));
454 if (glen
>=fF_BUFSIZE
-10) /* somewhat pessimistic? */
456 fF_SetError(obj
, real_error
);
457 fprintf(stderr
, "Line %lu too long.\n", obj
->lineno
);
460 DBP(fprintf(stderr
, "+"));
463 illparams("fF_readln");
468 fF_GetError(const fdFile
* obj
)
472 illparams("fF_GetError");
477 fF_GetOffset(const fdFile
* obj
)
481 illparams("fF_GetOffset");
485 /******************************************************************************
488 * checks if it can find a function-name and return it's address, or NULL
489 * if the current line does not seem to contain one. The return value will
490 * be a pointer into a malloced buffer, thus the caller will have to free().
491 ******************************************************************************/
494 fF_FuncName(fdFile
* obj
)
499 long obraces
; /* count of open braces */
500 Error ready
; /* ready with searching */
502 if (!obj
|| fF_GetError(obj
)==real_error
)
504 illparams("fF_FuncName");
509 while (*lower
&& (*lower
==' ' || *lower
=='\t'))
512 if (!*lower
|| (!isalpha(*lower
) && *lower
!='_'))
514 fF_SetError(obj
, nodef
);
520 if (!isalnum(*lower
) && !isspace(*lower
) && *lower
!='*' && *lower
!=','
521 && *lower
!='.' && *lower
!=';' && *lower
!='(' && *lower
!=')' &&
522 *lower
!='[' && *lower
!=']' && *lower
!='_' && *lower
!='\\')
524 fF_SetError(obj
, nodef
);
533 if (obj
&& fF_GetError(obj
)==false)
535 if ((upper
=strrchr(obj
->line
, ')'))!=0)
537 DBP(fprintf(stderr
, "end:%s:", upper
));
539 for (obraces
=1, ready
=false; ready
==false; upper
=lower
)
541 lower
=StrNRBrk(obj
->line
, "()", --upper
);
548 DBP(fprintf(stderr
, " )%ld%s", obraces
, lower
));
552 DBP(fprintf(stderr
, " (%ld%s", obraces
, lower
));
557 fprintf(stderr
, "Faulty StrNRBrk\n");
562 fprintf(stderr
, "'(' or ')' expected in line %lu.\n",
567 if (ready
==nodef
) /* we found the matching '(' */
574 while (upper
>=obj
->line
&& (*upper
==' ' || *upper
=='\t'))
577 lower
=StrNRBrk(obj
->line
, " \t*)", upper
);
584 for (name
=lower
; name
<=upper
; name
++)
585 if (!isalnum(*name
) && *name
!='_')
587 fF_SetError(obj
, nodef
);
591 newlen
=upper
-lower
+1;
592 buf
=malloc(newlen
+1);
596 strncpy(buf
, lower
, newlen
);
600 fprintf(stderr
, "No mem for fF_FuncName");
605 illparams("fF_FuncName");
609 static INLINE fdflags
610 fF_GetFlags(const fdFile
* obj
)
614 illparams("fF_GetFlags");
618 /*********************
620 *********************/
630 regs funcpar
; /* number of argument that has type "pointer to function" */
636 fD_dtor (fdDef
* obj
);
638 fD_NewName (fdDef
* obj
, const char* newname
);
640 fD_NewParam (fdDef
* obj
, shortcard at
, const char* newstr
);
642 fD_NewProto (fdDef
* obj
, shortcard at
, char* newstr
);
644 fD_NewReg (fdDef
* obj
, shortcard at
, regs reg
);
646 fD_NewType (fdDef
* obj
, const char* newstr
);
648 fD_SetOffset (fdDef
* obj
, long off
);
650 fD_parsefd (fdDef
* obj
, fdFile
* infile
);
652 fD_parsepr (fdDef
* obj
, fdFile
* infile
);
654 fD_GetName (const fdDef
* obj
);
656 fD_GetOffset (const fdDef
* obj
);
658 fD_GetParam (const fdDef
* obj
, shortcard at
);
660 fD_GetReg (const fdDef
* obj
, shortcard at
);
662 fD_GetRegStr (const fdDef
* obj
, shortcard at
);
664 fD_GetRegStrU (const fdDef
* obj
, shortcard at
);
666 fD_GetType (const fdDef
* obj
);
668 fD_ParamNum (const fdDef
* obj
);
670 fD_ProtoNum (const fdDef
* obj
);
672 fD_RegNum (const fdDef
* obj
);
674 fD_cmpName (const void* big
, const void* small
);
676 fD_write (FILE* outfile
, const fdDef
* obj
);
678 fD_GetFuncParNum (const fdDef
* obj
);
680 fD_SetFuncParNum (fdDef
* obj
, shortcard at
);
682 fD_adjustargnames(fdDef
*obj
);
687 char *fD_nostring
="";
695 result
=malloc(sizeof(fdDef
));
699 result
->name
=fD_nostring
;
700 result
->type
=fD_nostring
;
701 result
->funcpar
=illegal
;
703 for (count
=d0
; count
<illegal
; count
++ )
705 result
->reg
[count
]=illegal
;
706 result
->param
[count
]=fD_nostring
; /* if (!strlen) dont't free() */
707 result
->proto
[count
]=fD_nostring
;
713 /* free all resources and make the object as illegal as possible */
723 fprintf(stderr
, "fD_dtor: null name");
725 if (obj
->name
!=fD_nostring
)
729 fprintf(stderr
, "fD_dtor: null type");
731 if (obj
->type
!=fD_nostring
)
734 obj
->name
=obj
->type
=NULL
;
736 for (count
=d0
; count
<illegal
; count
++)
738 obj
->reg
[count
]=illegal
;
740 if (!obj
->param
[count
])
741 fprintf(stderr
, "fD_dtor: null param");
743 if (obj
->param
[count
]!=fD_nostring
)
744 free(obj
->param
[count
]);
746 if (!obj
->proto
[count
])
747 fprintf(stderr
, "fD_dtor: null proto");
749 if (obj
->proto
[count
]!=fD_nostring
)
750 free(obj
->proto
[count
]);
752 obj
->param
[count
]=obj
->proto
[count
]=NULL
;
758 fprintf(stderr
, "fd_dtor(NULL)\n");
762 fD_NewName(fdDef
* obj
, const char* newname
)
766 if (obj
->name
&& obj
->name
!=fD_nostring
)
768 if (!NewString(&obj
->name
, newname
))
769 obj
->name
=fD_nostring
;
772 illparams("fD_NewName");
776 fD_NewParam(fdDef
* obj
, shortcard at
, const char* newstr
)
780 if (newstr
&& obj
&& at
<illegal
)
784 if (pa
&& pa
!=fD_nostring
)
787 while (*newstr
==' ' || *newstr
=='\t')
790 if (NewString(&pa
, newstr
))
794 prefix_pa
= malloc( strlen( pa
) + 4 );
796 if( prefix_pa
== NULL
)
798 fprintf(stderr
, "No mem for string\n");
802 sprintf( prefix_pa
, "___%s", pa
);
803 obj
->param
[at
]=prefix_pa
;
808 obj
->param
[at
]=fD_nostring
;
811 illparams("fD_NewParam");
814 /* get first free *reg or illegal */
816 static INLINE shortcard
817 fD_RegNum(const fdDef
* obj
)
823 for (count
=d0
; count
<illegal
&& obj
->reg
[count
]!=illegal
; count
++);
828 illparams("fD_RegNum");
834 fD_NewReg(fdDef
* obj
, shortcard at
, regs reg
)
836 if (obj
&& at
<illegal
&& reg
>=d0
&& reg
<=illegal
)
839 illparams("fD_NewReg");
843 fD_GetReg(const fdDef
* obj
, shortcard at
)
845 if (obj
&& at
<illegal
)
849 illparams("fD_GetReg");
854 static INLINE shortcard
855 fD_GetFuncParNum(const fdDef
* obj
)
858 return (shortcard
)obj
->funcpar
;
861 illparams("fD_GetFuncParNum");
867 fD_SetFuncParNum(fdDef
* obj
, shortcard at
)
869 if (obj
&& at
<illegal
)
872 illparams("fD_SetFuncParNum");
876 fD_NewProto(fdDef
* obj
, shortcard at
, char* newstr
)
880 if (newstr
&& obj
&& at
<illegal
)
882 char *t
, arr
[200]; /* I hope 200 will be enough... */
886 if (pr
&& pr
!=fD_nostring
)
889 while (*newstr
==' ' || *newstr
=='\t')
890 newstr
++; /* Skip leading spaces */
893 while ((*t
++=*newstr
)!=0)
895 /* Copy the rest, counting number of words */
896 if ((*newstr
==' ' || *newstr
=='\t') && newstr
[1] && newstr
[1]!=' ' &&
903 while (*t
==' ' || *t
=='\t')
905 t
[1]='\0'; /* Get rid of tailing spaces */
907 if (at
!=fD_GetFuncParNum(obj
))
909 if (numwords
>1) /* One word - must be type */
912 /* '*' on the end - no parameter name used */
913 while (*t
!=' ' && *t
!='\t' && *t
!='*')
916 if (strcmp(t
, "char") && strcmp(t
, "short") && strcmp(t
, "int")
917 && strcmp(t
, "long") && strcmp(t
, "APTR"))
919 /* Not one of applicable keywords - must be parameter name.
922 while (*t
==' ' || *t
=='\t')
930 /* Parameter of type "pointer to function". */
934 while (*t
==' ' || *t
=='\t')
940 if (target
!=M68K_POS
)
942 memmove(t
+2, end
, strlen(end
)+1);
947 memmove(t
, end
, strlen(end
)+1);
950 if (NewString(&pr
, arr
))
953 while (*pr
==' ' || *pr
=='\t')
955 if (!strcasecmp(pr
, "double"))
957 /* "double" needs two data registers */
958 int count
, regs
=fD_RegNum(obj
);
959 for (count
=at
+1; count
<regs
; count
++)
960 fD_NewReg(obj
, count
, fD_GetReg(obj
, count
+1));
964 obj
->proto
[at
]=fD_nostring
;
967 illparams("fD_NewProto");
973 fD_NewType(fdDef
* obj
, const char* newtype
)
977 if (obj
->type
&& obj
->type
!=fD_nostring
)
979 if (!NewString(&obj
->type
, newtype
))
980 obj
->type
=fD_nostring
;
983 illparams("fD_NewType");
987 fD_SetOffset(fdDef
* obj
, long off
)
992 illparams("fD_SetOffset");
995 static INLINE
const char*
996 fD_GetName(const fdDef
* obj
)
998 if (obj
&& obj
->name
)
1002 illparams("fD_GetName");
1008 fD_GetOffset(const fdDef
* obj
)
1014 illparams("fD_GetOffset");
1019 static INLINE
const char*
1020 fD_GetProto(const fdDef
* obj
, shortcard at
)
1022 if (obj
&& at
<illegal
&& obj
->proto
[at
])
1023 return obj
->proto
[at
];
1026 illparams("fD_GetProto");
1031 static INLINE
const char*
1032 fD_GetParam(const fdDef
* obj
, shortcard at
)
1034 if (obj
&& at
<illegal
&& obj
->param
[at
])
1035 return obj
->param
[at
];
1038 illparams("fD_GetParam");
1043 static INLINE
const char*
1044 fD_GetRegStr(const fdDef
* obj
, shortcard at
)
1046 if (obj
&& at
<illegal
)
1047 return RegStr(obj
->reg
[at
]);
1050 illparams("fD_GetReg");
1051 return RegStr(illegal
);
1055 static INLINE
const char*
1056 fD_GetRegStrU(const fdDef
* obj
, shortcard at
)
1058 if (obj
&& at
<illegal
)
1059 return RegStrU(obj
->reg
[at
]);
1062 illparams("fD_GetReg");
1063 return RegStrU(illegal
);
1067 static INLINE
const char*
1068 fD_GetType(const fdDef
* obj
)
1070 if (obj
&& obj
->type
)
1074 illparams("fD_GetType");
1079 /* get first free param or illegal */
1081 static INLINE shortcard
1082 fD_ParamNum(const fdDef
* obj
)
1088 for (count
=d0
; count
<illegal
&& obj
->param
[count
]!=fD_nostring
;
1094 illparams("fD_ParamNum");
1099 static INLINE shortcard
1100 fD_ProtoNum(const fdDef
* obj
)
1106 for (count
=d0
; count
<illegal
&& obj
->proto
[count
]!=fD_nostring
;
1112 illparams("fD_ProtoNum");
1117 /******************************************************************************
1120 * parse the current line. Needs to copy input, in order to insert \0's
1122 * fF_GetError(infile):
1123 * false = read a definition.
1124 * nodef = not a definition on line (so try again)
1125 * error = real error
1126 ******************************************************************************/
1129 fD_parsefd(fdDef
* obj
, fdFile
* infile
)
1131 enum parse_info
{ name
, params
, regs
, ready
} parsing
;
1132 char *buf
, *bpoint
, *bnext
;
1133 unsigned long index
;
1135 if (obj
&& infile
&& fF_GetError(infile
)==false)
1139 if (!NewString(&buf
, infile
->line
))
1141 fprintf(stderr
, "No mem for line %lu\n", infile
->lineno
);
1142 fF_SetError(infile
, real_error
);
1144 bpoint
=buf
; /* so -Wall keeps quiet */
1146 /* try to parse the line until there's an error or we are done */
1148 while (parsing
!=ready
&& fF_GetError(infile
)==false)
1156 if (strncmp("##base", buf
, 6)==0)
1159 while (*bnext
==' ' || *bnext
=='\t' || *bnext
=='_')
1161 strcpy(BaseName
, bnext
);
1162 BaseName
[strlen(BaseName
)-1]='\0';
1165 if (strncmp("##bias", buf
, 6)==0)
1167 if (!sscanf(buf
+6, "%ld", &infile
->offset
))
1169 fprintf(stderr
, "Illegal ##bias in line %lu: %s\n",
1170 infile
->lineno
, infile
->line
);
1171 fF_SetError(infile
, real_error
);
1172 break; /* avoid nodef */
1176 if (fF_GetOffset(infile
)>0)
1177 fF_SetOffset(infile
, -fF_GetOffset(infile
));
1178 DBP(fprintf(stderr
, "set offset to %ld\n",
1179 fF_GetOffset(infile
)));
1184 if (strncmp("##private", buf
, 9)==0)
1185 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1187 else if (strncmp("##public", buf
, 8)==0)
1188 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1190 else if (strncmp("##shadow", buf
, 8)==0)
1191 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1194 /* drop through for error comment */
1197 /* try again somewhere else */
1198 fF_SetError(infile
, nodef
);
1202 /* assume a regular line here */
1203 if (fF_GetFlags(infile
) & (FD_PRIVATE
| FD_SHADOW
))
1205 /* don't store names of privates */
1206 fF_SetError(infile
, nodef
);
1207 if (!(fF_GetFlags(infile
) & FD_SHADOW
))
1208 fF_SetOffset(infile
,
1209 fF_GetOffset(infile
)-FUNCTION_GAP
);
1211 /* Shadow is valid for one line only. */
1212 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1216 parsing
=name
; /* switch (parsing) */
1217 for (index
=0; buf
[index
] && buf
[index
]!='('; index
++);
1222 fprintf(stderr
, "Not an fd, line %lu: %s\n",
1223 infile
->lineno
, buf
/* infile->line */);
1224 fF_SetError(infile
, nodef
);
1225 } /* maybe next time */
1230 fD_NewName(obj
, buf
);
1231 fD_SetOffset(obj
, fF_GetOffset(infile
));
1234 parsing
=params
; /* continue the loop */
1241 char *bptmp
; /* needed for fD_NewParam */
1243 /* look for parameters now */
1245 for (bnext
= bpoint
; *bnext
&& *bnext
!=',' && *bnext
!=')';
1254 if (bnext
[1] != '(')
1256 fprintf(stderr
, "Registers expected in line %lu: %s\n",
1257 infile
->lineno
, infile
->line
);
1258 fF_SetError(infile
, nodef
);
1269 /* terminate string and advance to next item */
1272 fD_NewParam(obj
, fD_ParamNum(obj
), bptmp
);
1276 fF_SetError(infile
, nodef
);
1277 fprintf(stderr
, "Param expected in line %lu: %s\n",
1278 infile
->lineno
, infile
->line
);
1280 break; /* switch parsing */
1284 /* look for parameters now */
1286 for (bnext
=bpoint
; *bnext
&& *bnext
!='/' && *bnext
!=',' &&
1287 *bnext
!=')'; bnext
++);
1293 /* wow, we've finished */
1294 fF_SetOffset(infile
, fF_GetOffset(infile
)-FUNCTION_GAP
);
1299 bpoint
[0]=tolower(bpoint
[0]);
1301 if ((bpoint
[0]=='d' || bpoint
[0]=='a') && bpoint
[1]>='0' &&
1302 bpoint
[1]<='8' && bnext
==bpoint
+2)
1303 fD_NewReg(obj
, fD_RegNum(obj
),
1304 bpoint
[1]-'0'+(bpoint
[0]=='a'? 8 : 0));
1308 /* it is when our function is void */
1309 fprintf(stderr
, "Illegal register %s in line %ld\n",
1310 bpoint
, infile
->lineno
);
1311 fF_SetError(infile
, nodef
);
1317 fF_SetError(infile
, nodef
);
1318 fprintf(stderr
, "Reg expected in line %lu\n",
1321 break; /* switch parsing */
1324 fprintf(stderr
, "Internal error, use another compiler.\n");
1330 return fF_GetError(infile
);
1334 illparams("fD_parsefd");
1340 fD_adjustargnames(fdDef
*obj
)
1344 if (output_mode
!=NEW
)
1347 /* For #define-base output mode, we have to check if argument names are not
1348 the same as some words in type names. We check from the first argument
1349 to the last, resolving conflicts by changing argument names, if
1352 for (parnum
=0; parnum
<fD_ParamNum(obj
); parnum
++)
1354 const char *parname
=fD_GetParam(obj
, parnum
);
1359 const char *type
=fD_GetType(obj
);
1364 if ((str
=strstr(type
, parname
))!=0 && (str
==type
||
1365 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1366 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_')))
1368 char buf
[300]; /* Hope will be enough... */
1369 strcpy(buf
, parname
);
1371 fD_NewParam(obj
, parnum
, buf
);
1372 parname
=fD_GetParam(obj
, parnum
);
1376 for (num
=0; num
<fD_ParamNum(obj
); num
++)
1378 const char *name
=fD_GetParam(obj
, num
);
1379 const char *proto
=fD_GetProto(obj
, num
);
1380 if ((num
<parnum
&& strcmp(name
, parname
)==0) ||
1381 ((str
=strstr(proto
, parname
))!=0 && (str
==proto
||
1382 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1383 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_'))))
1385 char buf
[300]; /* Hope will be enough... */
1386 strcpy(buf
, parname
);
1388 fD_NewParam(obj
, parnum
, buf
);
1389 parname
=fD_GetParam(obj
, parnum
);
1394 } while (!finished
);
1399 fD_parsepr(fdDef
* obj
, fdFile
* infile
)
1401 char *buf
; /* a copy of infile->line */
1402 char *bpoint
, /* cursor in buf */
1403 *bnext
, /* looking for the end */
1404 *lowarg
; /* beginning of this argument */
1405 long obraces
; /* count of open braces */
1406 regs count
, /* count parameter number */
1407 args
; /* the number of arguments for this function */
1409 if (!(obj
&& infile
&& fF_GetError(infile
)==false))
1411 illparams("fD_parsepr");
1412 fF_SetError(infile
, real_error
);
1415 if (!NewString(&buf
, infile
->line
))
1417 fprintf(stderr
, "No mem for fD_parsepr\n");
1418 fF_SetError(infile
, real_error
);
1421 fF_SetError(infile
, false);
1423 bpoint
=strchr(buf
, '(');
1424 while (--bpoint
>=buf
&& strstr(bpoint
, fD_GetName(obj
))!=bpoint
);
1427 while (--bpoint
>= buf
&& (*bpoint
==' ' || *bpoint
=='\t'));
1430 fD_NewType(obj
, buf
);
1432 while (bpoint
&& *bpoint
++!='('); /* one beyond '(' */
1437 for (count
=0, args
=fD_RegNum(obj
); count
<args
; bpoint
=bnext
+1)
1439 while (*bpoint
&& (*bpoint
==' ' || *bpoint
=='\t')) /* ignore spaces */
1442 if (!obraces
&& target
==M68K_POS
&& strncmp(bpoint
, "_R_", 3)==0 &&
1443 isalnum(bpoint
[3]) && isalnum(bpoint
[4]) && isspace(bpoint
[5]))
1446 bnext
=strpbrk(bpoint
, "(),");
1455 if (target
==M68K_AMIGAOS
|| target
==M68K_POS
)
1457 if (fD_GetFuncParNum(obj
)!=illegal
&&
1458 fD_GetFuncParNum(obj
)!=count
&&
1460 fprintf(stderr
, "Warning: two parameters of type "
1461 "pointer to function are used.\n"
1462 "This is not supported!\n");
1465 fD_SetFuncParNum(obj
, count
);
1468 DBP(fprintf(stderr
, "< (%ld%s >", obraces
, bnext
));
1474 DBP(fprintf(stderr
, "< )%ld%s >", obraces
, bnext
));
1480 DBP(fprintf(stderr
, "< )0> [LAST PROTO=%s]", lowarg
));
1481 if (fD_NewProto(obj
, count
, lowarg
))
1482 fprintf(stderr
, "Parser confused in line %ld\n",
1488 DBP(fprintf(stderr
, "%s needs %u arguments and got %u.\n",
1489 fD_GetName(obj
), args
, count
+1));
1490 fF_SetError(infile
, nodef
);
1500 DBP(fprintf(stderr
, " [PROTO=%s] ", lowarg
));
1501 if (fD_NewProto(obj
, count
, lowarg
))
1502 fprintf(stderr
, "Parser confused in line %ld\n",
1510 fprintf(stderr
, "Faulty strpbrk in line %lu.\n",
1516 DBP(fprintf(stderr
, "Faulty argument %u in line %lu.\n", count
+1,
1518 count
=args
; /* this will effectively quit the for loop */
1519 fF_SetError(infile
, nodef
);
1522 if (fD_ProtoNum(obj
)!=fD_RegNum(obj
))
1523 fF_SetError(infile
, nodef
);
1527 fprintf(stderr
, "fD_parsepr was fooled in line %lu\n", infile
->lineno
);
1528 fprintf(stderr
, "function , definition %s.\n",
1529 /* fD_GetName(obj),*/ infile
->line
);
1530 fF_SetError(infile
, nodef
);
1535 fD_adjustargnames(obj
);
1537 return fF_GetError(infile
);
1541 fD_cmpName(const void* big
, const void* small
) /* for qsort and bsearch */
1543 return strcmp(fD_GetName(*(fdDef
**)big
), fD_GetName(*(fdDef
**)small
));
1546 const static char *TagExcTable
[]=
1548 "BuildEasyRequestArgs", "BuildEasyRequest",
1549 "DoDTMethodA", "DoDTMethod",
1550 "DoGadgetMethodA", "DoGadgetMethod",
1551 "EasyRequestArgs", "EasyRequest",
1552 "MUI_MakeObjectA", "MUI_MakeObject",
1553 "MUI_RequestA", "MUI_Request",
1554 "PrintDTObjectA", "PrintDTObject",
1555 "RefreshDTObjectA", "RefreshDTObjects",
1556 "UMSVLog", "UMSLog",
1557 "VFWritef", "FWritef",
1558 "VFPrintf", "FPrintf",
1559 "VPrintf", "Printf",
1563 getvarargsfunction(const fdDef
* obj
)
1566 const char *name
= fD_GetName(obj
);
1568 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1570 if (strcmp(name
, TagExcTable
[count
])==0)
1572 return TagExcTable
[count
+1];
1579 taggedfunction(const fdDef
* obj
)
1581 shortcard numregs
=fD_RegNum(obj
);
1584 const char *name
=fD_GetName(obj
);
1585 static char newname
[200]; /* Hope will be enough... static because used
1586 out of the function. */
1587 const char *lastarg
;
1588 const static char *TagExcTable2
[]=
1596 "PackStructureTags",
1597 "RefreshTagItemClones",
1598 "UnpackStructureTags",
1604 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1605 if (strcmp(name
, TagExcTable
[count
])==0)
1607 // lcs return TagExcTable[count+1];
1609 for (count
=0; count
<sizeof TagExcTable2
/sizeof TagExcTable2
[0]; count
++)
1610 if (strcmp(name
, TagExcTable2
[count
])==0)
1613 lastarg
=fD_GetProto(obj
, numregs
-1);
1614 if (strncmp(lastarg
, "const", 5)==0 || strncmp(lastarg
, "CONST", 5)==0)
1616 while (*lastarg
==' ' || *lastarg
=='\t')
1618 if (strncmp(lastarg
, "struct", 6))
1621 while (*lastarg
==' ' || *lastarg
=='\t')
1624 if (strncmp(lastarg
, "TagItem", 7) &&
1625 (target
!=M68K_POS
|| ((aos_tagitem
=strncmp(lastarg
, "pOS_TagItem", 11))!=0)))
1627 lastarg
+=(aos_tagitem
? 7 : 11);
1628 while (*lastarg
==' ' || *lastarg
=='\t')
1630 if (strcmp(lastarg
, "*"))
1633 strcpy(newname
, name
);
1634 if (newname
[strlen(newname
)-1]=='A')
1635 newname
[strlen(newname
)-1]='\0';
1637 if (strlen(newname
)>7 && !strcmp(newname
+strlen(newname
)-7, "TagList"))
1638 strcpy(newname
+strlen(newname
)-4, "s");
1640 strcat(newname
, "Tags");
1645 aliasfunction(const char* name
)
1647 const static char *AliasTable
[]=
1649 "AllocDosObject", "AllocDosObjectTagList",
1650 "CreateNewProc", "CreateNewProcTagList",
1651 "NewLoadSeg", "NewLoadSegTagList",
1652 "System", "SystemTagList",
1655 for (count
=0; count
<sizeof AliasTable
/sizeof AliasTable
[0]; count
++)
1656 if (strcmp(name
, AliasTable
[count
])==0)
1657 return AliasTable
[count
+(count
%2 ? -1 : 1)];
1662 fD_write(FILE* outfile
, const fdDef
* obj
)
1664 shortcard count
, numregs
;
1665 const char *chtmp
, *tagname
, *varname
, *name
, *rettype
;
1666 int vd
=0, a45
=0, d7
=0;
1668 DBP(fprintf(stderr
, "func %s\n", fD_GetName(obj
)));
1670 numregs
=fD_RegNum(obj
);
1672 if ((rettype
=fD_GetType(obj
))==fD_nostring
)
1674 fprintf(stderr
, "%s has no prototype.\n", fD_GetName(obj
));
1677 if (!strcasecmp(rettype
, "void"))
1678 vd
= 1; /* set flag */
1679 for (count
=d0
; count
<numregs
; count
++)
1681 const char *reg
=fD_GetRegStr(obj
, count
);
1682 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1684 if (strcmp(reg
, "a4")==0 || strcmp(reg
, "a5")==0)
1687 a45
=(strcmp(reg
, "a4") ? 5 : 4); /* set flag */
1688 else /* Security check */
1690 fprintf(stderr
, "Warning: both a4 and a5 are used. "
1691 "This is not supported!\n");
1694 if (strcmp(reg
, "d7")==0) /* Used only when a45!=0 */
1698 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1700 if (a45
&& d7
) /* Security check */
1702 fprintf(stderr
, "Warning: d7 and a4 or a5 are used. This is not "
1706 name
=fD_GetName(obj
);
1708 if (fD_ProtoNum(obj
)!=numregs
)
1710 fprintf(stderr
, "%s gets %d fd args and %d proto%s.\n", name
, numregs
,
1711 fD_ProtoNum(obj
), fD_ProtoNum(obj
)!= 1 ? "s" : "");
1715 if (output_mode
==NEW
)
1717 fprintf(outfile
, "#define %s(", name
);
1721 for (count
=d0
; count
<numregs
-1; count
++)
1722 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
1723 fprintf(outfile
, "%s", fD_GetParam(obj
, count
));
1726 if (target
==M68K_AMIGAOS
)
1728 fprintf(outfile
, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs
,
1729 (vd
? "NR" : ""), (a45
? (a45
==4 ? "A4" : "A5") : ""),
1730 (BaseName
[0] ? "" : "UB"),
1731 (fD_GetFuncParNum(obj
)==illegal
? "" : "FP"), -fD_GetOffset(obj
));
1733 fprintf(outfile
, "%s, ", rettype
);
1734 fprintf(outfile
, "%s, ", name
);
1736 for (count
=d0
; count
<numregs
; count
++)
1738 chtmp
=fD_GetRegStr(obj
, count
);
1739 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1741 fprintf(outfile
, "%s, %s, %s%s", (fD_GetFuncParNum(obj
)==count
?
1742 "__fpt" : fD_GetProto(obj
, count
)),
1743 fD_GetParam(obj
, count
),
1744 chtmp
, (count
==numregs
-1 && !BaseName
[0] ? "" : ", "));
1747 if (BaseName
[0]) /* was "##base" used? */
1748 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1749 if (fD_GetFuncParNum(obj
)!=illegal
)
1751 fprintf(outfile
, ", ");
1752 fprintf(outfile
, fD_GetProto(obj
, fD_GetFuncParNum(obj
)), "__fpt");
1754 fprintf(outfile
, ")\n\n");
1756 else if(target
==M68K_POS
)
1758 fprintf(outfile
, ") \\\n\t__INLINE_FUN_%d(", numregs
);
1759 fprintf(outfile
, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1760 BaseNamU
, BaseNamU
, -fD_GetOffset(obj
), rettype
, name
,
1761 (numregs
? ", \\\n\t" : ""));
1763 for (count
=d0
; count
<numregs
; count
++)
1764 fprintf(outfile
, "%s, %s, %s%s", fD_GetProto(obj
, count
),
1765 fD_GetParam(obj
, count
), fD_GetRegStr(obj
, count
),
1766 (count
==numregs
-1 ? "" : ", "));
1767 fprintf(outfile
, ")\n\n");
1769 else if (target
==PPC_POWERUP
|| target
==PPC_MORPHOS
)
1771 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1774 (BaseName
[0] ? "" : "UB"),
1775 -fD_GetOffset(obj
));
1778 fprintf(outfile
, "%s, ", rettype
);
1779 fprintf(outfile
, "%s, ", name
);
1781 for (count
=d0
; count
<numregs
; count
++)
1783 chtmp
=fD_GetRegStr(obj
, count
);
1785 if (strchr(fD_GetProto(obj
, count
),'%'))
1788 fD_GetProto(obj
, count
),
1791 fprintf(outfile
, "%s, %s, %s%s",
1793 fD_GetParam(obj
, count
),
1795 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1799 fprintf(outfile
, "%s, %s, %s%s",
1800 fD_GetProto(obj
, count
),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1801 fD_GetParam(obj
, count
),
1803 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1808 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1811 * Here it would make sense to create a database file to
1812 * integrate optimizations automaticly into every new
1813 * build. Not every function needs a complete flush. For
1814 * example functions with no parameter wouldn`t need a
1815 * PPC flush normally. Or Read(File,Addr,Size); would
1816 * only need a flush for Addr with the Size
1819 fprintf(outfile
, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1820 fprintf(outfile
, ")\n\n");
1822 else if (target
==IX86BE_AMITHLON
)
1824 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1827 (BaseName
[0] ? "" : "UB"),
1828 -fD_GetOffset(obj
));
1831 fprintf(outfile
, "%s, ", rettype
);
1832 fprintf(outfile
, "%s, ", name
);
1834 for (count
=d0
; count
<numregs
; count
++)
1836 chtmp
=fD_GetRegStr(obj
, count
);
1838 if (strchr(fD_GetProto(obj
, count
),'%'))
1841 fD_GetProto(obj
, count
),
1844 fprintf(outfile
, "%s, %s, %s%s",
1846 fD_GetParam(obj
, count
),
1848 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1852 fprintf(outfile
, "%s, %s, %s%s",
1853 fD_GetProto(obj
, count
),
1854 fD_GetParam(obj
, count
),
1856 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1861 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1863 fprintf(outfile
, ")\n\n");
1865 else if (target
==AROS
)
1867 fprintf(outfile
, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1869 (BaseName
[0] ? "" : "I"),
1870 (vd
? "void" : rettype
),
1873 for (count
=d0
; count
<numregs
; count
++)
1875 chtmp
=fD_GetRegStrU(obj
, count
);
1876 fprintf(outfile
, "\tAROS_LCA(%s, (%s), %s), \\\n",
1877 fD_GetProto(obj
, count
),
1878 fD_GetParam(obj
, count
),
1882 if (BaseName
[0]) /* was "##base" used? */
1884 fprintf(outfile
, "\tstruct %s *, %s_BASE_NAME, ", StdLib
, BaseNamU
);
1888 fprintf(outfile
, "\t/* bt */, /* bn */, ");
1891 "%ld, /* s */)\n\n",
1892 -fD_GetOffset(obj
) / 6);
1896 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
1900 else if (output_mode
==OLD
|| output_mode
==STUBS
)
1902 fprintf(outfile
, "%s__inline %s\n%s(%s",
1903 (output_mode
==STUBS
? "" : "extern "), rettype
, name
,
1904 (BaseName
[0] ? (numregs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1906 if (target
==M68K_AMIGAOS
)
1908 for (count
=d0
; count
<numregs
; count
++)
1910 chtmp
=fD_GetProto(obj
, count
);
1911 if (fD_GetFuncParNum(obj
)==count
)
1912 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1914 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1915 "" : " "), fD_GetParam(obj
, count
));
1916 if (count
<numregs
-1)
1917 fprintf(outfile
, ", ");
1920 fprintf(outfile
, ")\n{\n%s", (BaseName
[0] ? " BASE_EXT_DECL\n" : ""));
1922 fprintf(outfile
, " register %s%sres __asm(\"d0\");\n", rettype
,
1923 (*(rettype
+strlen(rettype
)-1)=='*' ? "" : " "));
1926 fprintf(outfile
, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1929 for (count
=d0
; count
<numregs
; count
++)
1931 chtmp
=fD_GetRegStr(obj
, count
);
1932 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1934 if (fD_GetFuncParNum(obj
)==count
)
1936 fprintf(outfile
, " register ");
1937 fprintf(outfile
, fD_GetProto(obj
, count
), chtmp
);
1938 fprintf(outfile
, " __asm(\"%s\") = %s;\n", chtmp
, fD_GetParam(obj
,
1943 const char *proto
=fD_GetProto(obj
, count
);
1944 fprintf(outfile
, " register %s%s%s __asm(\"%s\") = %s;\n",
1945 proto
, (*(proto
+strlen(proto
)-1)=='*' ? "" : " "), chtmp
,
1946 chtmp
, fD_GetParam(obj
, count
));
1950 fprintf(outfile
, " __asm volatile (\"exg d7,%s\\n\\t"
1951 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45
==4 ? "a4" : "a5"),
1952 -fD_GetOffset(obj
), (a45
==4 ? "a4" : "a5"));
1954 fprintf(outfile
, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1955 -fD_GetOffset(obj
));
1957 fprintf(outfile
, (vd
? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1959 fprintf(outfile
, " : ");
1961 fprintf(outfile
, "\"r\" (a6)%s", (numregs
? ", ": ""));
1963 for (count
=d0
; count
<numregs
; count
++)
1965 chtmp
=fD_GetRegStr(obj
, count
);
1966 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1968 fprintf(outfile
, "\"r\" (%s)%s", chtmp
, (count
<numregs
-1 ? ", " : ""));
1970 fprintf(outfile
, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1973 fprintf(outfile
, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1975 fprintf(outfile
, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1978 else if (target
==PPC_POWERUP
)
1980 for (count
= d0
; count
< numregs
; count
++)
1982 chtmp
= fD_GetProto(obj
, count
);
1983 if (fD_GetFuncParNum(obj
) == count
)
1984 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1986 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
1987 "" : " "), fD_GetParam(obj
, count
));
1988 if (count
< numregs
- 1)
1989 fprintf(outfile
, ", ");
1992 fprintf(outfile
, ")\t\n");
1993 fprintf(outfile
, "{\t\n");
1994 fprintf(outfile
, "struct Caos\tMyCaos;\n");
1995 fprintf(outfile
, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1996 fprintf(outfile
, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
1997 fprintf(outfile
, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
1998 fprintf(outfile
, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1999 fprintf(outfile
, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2000 fprintf(outfile
, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2004 for (count
= d0
; count
< numregs
; count
++)
2006 fprintf(outfile
, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2007 fD_GetRegStr(obj
, count
),
2008 fD_GetParam(obj
, count
));
2012 fprintf(outfile
, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj
));
2014 * was "##base" used?
2017 fprintf(outfile
, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2021 fprintf(outfile
, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2025 fprintf(outfile
, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2029 else if (target
==PPC_MORPHOS
)
2031 for (count
= d0
; count
< numregs
; count
++)
2033 chtmp
= fD_GetProto(obj
, count
);
2034 if (fD_GetFuncParNum(obj
) == count
)
2035 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2037 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2038 "" : " "), fD_GetParam(obj
, count
));
2039 if (count
< numregs
- 1)
2040 fprintf(outfile
, ", ");
2043 fprintf(outfile
, ")\t\n{\t\n");
2047 for (count
= d0
; count
< numregs
; count
++)
2049 fprintf(outfile
, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2050 fD_GetRegStrU(obj
, count
), fD_GetParam(obj
, count
));
2055 * was "##base" used?
2058 fprintf(outfile
, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2062 fprintf(outfile
, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj
));
2066 fprintf(outfile
, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2067 rettype
, fD_GetOffset(obj
));
2070 else if (target
==IX86BE_AMITHLON
)
2073 for (count
= d0
; count
< numregs
; count
++)
2075 chtmp
= fD_GetProto(obj
, count
);
2076 if (fD_GetFuncParNum(obj
) == count
)
2077 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2079 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2080 "" : " "), fD_GetParam(obj
, count
));
2081 if (count
< numregs
- 1)
2082 fprintf(outfile
, ", ");
2085 fprintf(outfile
, ")\n{\n");
2086 fprintf(outfile
, "\tstruct _Regs _regs;\n");
2090 for (count
= d0
; count
< numregs
; count
++)
2092 fprintf(outfile
, "\t_regs.reg_%s = (ULONG) (%s);\n",
2093 fD_GetRegStr(obj
, count
),
2094 fD_GetParam(obj
, count
));
2100 fprintf(outfile
, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2105 fprintf(outfile
, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2106 -fD_GetOffset(obj
));
2110 fprintf(outfile
, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2111 rettype
,-fD_GetOffset(obj
));
2114 for (count
= d0
; count
< numregs
; count
++)
2116 chtmp
= fD_GetProto(obj
, count
);
2117 if (fD_GetFuncParNum(obj
) == count
)
2118 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2120 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2121 "" : " "), fD_GetParam(obj
, count
));
2122 if (count
< numregs
- 1)
2123 fprintf(outfile
, ", ");
2126 fprintf(outfile
, ")\n{\n");
2127 fprintf(outfile
, "\t%s LP%d%s%s(0x%lx, ",
2128 (vd
? "" : "return "),
2131 (BaseName
[0] ? "" : "UB"),
2132 -fD_GetOffset(obj
));
2135 fprintf(outfile
, "%s, ", rettype
);
2136 fprintf(outfile
, "%s, ", name
);
2138 for (count
=d0
; count
<numregs
; count
++)
2140 chtmp
=fD_GetRegStr(obj
, count
);
2142 if (strchr(fD_GetProto(obj
, count
),'%'))
2145 fD_GetProto(obj
, count
),
2148 fprintf(outfile
, "%s, %s, %s%s",
2150 fD_GetParam(obj
, count
),
2152 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2156 fprintf(outfile
, "%s, %s, %s%s",
2157 fD_GetProto(obj
, count
),
2158 fD_GetParam(obj
, count
),
2160 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2165 fprintf(outfile
, "\\\n\t, BASE_NAME");
2167 fprintf(outfile
, ");\n}\n\n");
2172 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2176 else if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
2178 int has_base
= (BaseName
[0] && fD_GetOffset(obj
) != 0);
2183 for (count
=d0
; count
<numregs
; count
++)
2185 if (fD_GetFuncParNum(obj
) == count
)
2187 char funcproto
[200]; /* Hope will be enough... */
2188 sprintf(funcproto
, "%s_%s_funcproto_%d",
2189 BaseNamC
, name
, count
);
2190 fprintf(outfile
, "typedef ");
2191 fprintf(outfile
, fD_GetProto(obj
, count
), funcproto
);
2192 fprintf(outfile
, ";\n");
2197 if (output_mode
==GATESTUBS
)
2199 fprintf(outfile
, "%s %s%s(",
2204 for (count
=d0
; count
<numregs
; count
++)
2206 chtmp
= fD_GetProto(obj
, count
);
2208 fprintf(outfile
, chtmp
, "");
2209 fprintf(outfile
, "%s",
2210 (count
== numregs
- 1 && !has_base
? ");\n" : ", "));
2214 fprintf(outfile
, "struct %s *);\n", StdLib
);
2217 if (target
==M68K_AMIGAOS
)
2219 fprintf(outfile
, "%s %s%s(\n",
2224 for (count
=d0
; count
<numregs
; count
++)
2226 chtmp
= fD_GetProto(obj
, count
);
2228 if (fD_GetFuncParNum(obj
) == count
)
2230 fprintf(outfile
, "\t");
2231 fprintf(outfile
, chtmp
,
2232 fD_GetParam(obj
, count
));
2233 fprintf(outfile
, " __asm(\"%s\")%s",
2234 fD_GetRegStr(obj
, count
),
2235 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2239 fprintf(outfile
, "\t%s %s __asm(\"%s\")%s",
2241 fD_GetParam(obj
, count
),
2242 fD_GetRegStr(obj
, count
),
2243 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2248 fprintf(outfile
, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib
);
2250 if (output_mode
==GATESTUBS
)
2251 fprintf(outfile
, "{\n");
2253 else if (target
==AROS
)
2255 fprintf(outfile
, "AROS_LH%d%s(%s, %s%s,\n",
2257 has_base
? "" : "I",
2262 for (count
=d0
; count
<numregs
; count
++)
2264 char funcproto
[200]; /* Hope will be enough... */
2266 if (fD_GetFuncParNum(obj
) == count
)
2268 sprintf(funcproto
, "%s_%s_funcproto_%d",
2269 BaseNamC
, name
, count
);
2272 fprintf(outfile
, "\tAROS_LHA(%s, %s, %s),\n",
2273 fD_GetFuncParNum(obj
) == count
? funcproto
: fD_GetProto(obj
, count
),
2274 fD_GetParam(obj
, count
),
2275 fD_GetRegStrU(obj
, count
));
2278 fprintf(outfile
, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2280 -fD_GetOffset(obj
) / 6,
2283 if (output_mode
==GATESTUBS
)
2284 fprintf(outfile
, "{\n");
2286 else if (target
==PPC_MORPHOS
)
2288 fprintf(outfile
, "%s %s%s(void)\n",
2293 if (output_mode
==GATESTUBS
)
2295 fprintf(outfile
, "{\n");
2297 for (count
=d0
; count
<numregs
; count
++)
2299 chtmp
= fD_GetProto(obj
, count
);
2301 if (fD_GetFuncParNum(obj
) == count
)
2303 fprintf(outfile
, "\t");
2304 fprintf(outfile
, chtmp
,
2305 fD_GetParam(obj
, count
));
2306 fprintf(outfile
, " = (");
2307 fprintf(outfile
, chtmp
, "");
2308 fprintf(outfile
, ") REG_%s;\n",
2309 fD_GetRegStrU(obj
, count
));
2313 fprintf(outfile
, "\t%s %s = (%s) REG_%s;\n",
2314 fD_GetProto(obj
, count
),
2315 fD_GetParam(obj
, count
),
2316 fD_GetProto(obj
, count
),
2317 fD_GetRegStrU(obj
, count
));
2323 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2326 fprintf(outfile
, "\n");
2329 else if (target
==IX86BE_AMITHLON
)
2331 fprintf(outfile
, "%s %s%s( struct _Regs _regs )\n",
2336 if (output_mode
==GATESTUBS
)
2338 fprintf(outfile
, "{\n");
2340 for (count
=d0
; count
<numregs
; count
++)
2342 chtmp
= fD_GetProto(obj
, count
);
2344 if (fD_GetFuncParNum(obj
) == count
)
2346 fprintf(outfile
, "\t");
2347 fprintf(outfile
, chtmp
,
2348 fD_GetParam(obj
, count
));
2349 fprintf(outfile
, " = (");
2350 fprintf(outfile
, chtmp
, "");
2351 fprintf(outfile
, ") _regs.%s;\n",
2352 fD_GetRegStr(obj
, count
));
2356 fprintf(outfile
, "\t%s %s = (%s) _regs.%s;\n",
2357 fD_GetProto(obj
, count
),
2358 fD_GetParam(obj
, count
),
2359 fD_GetProto(obj
, count
),
2360 fD_GetRegStr(obj
, count
));
2366 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2369 fprintf(outfile
, "\n");
2374 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2378 if (output_mode
==GATESTUBS
)
2380 fprintf(outfile
,"\treturn %s%s(",
2384 for (count
=d0
; count
<numregs
; count
++)
2386 fprintf(outfile
, "%s%s",
2387 fD_GetParam(obj
, count
),
2388 (count
== numregs
- 1 && !has_base
? ");" : ", "));
2392 fprintf(outfile
, "BASE_NAME);");
2394 fprintf(outfile
,"\n}\n\n");
2398 fprintf(outfile
,";\n");
2402 fprintf(outfile
, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s)\n",
2408 fprintf(outfile
,"\n");
2413 fprintf(stderr
, "Internal error: Unknown output mode in fD_write().\n");
2417 if ((tagname
=aliasfunction(fD_GetName(obj
)))!=0 &&
2418 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2420 fprintf(outfile
, "#define %s(", tagname
);
2421 for (count
=d0
; count
<numregs
-1; count
++)
2422 fprintf(outfile
, "a%d, ", count
);
2423 fprintf(outfile
, "a%d) %s (", count
, name
);
2424 for (count
=d0
; count
<numregs
-1; count
++)
2425 fprintf(outfile
, "(a%d), ", count
);
2426 fprintf(outfile
, "(a%d))\n\n", count
);
2429 if ((tagname
=taggedfunction(obj
))!=0 &&
2430 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2432 if (output_mode
!=STUBS
)
2435 "#ifndef %sNO_INLINE_STDARG\n"
2437 (target
==M68K_POS
? "__" : ""),
2440 for (count
=d0
; count
<numregs
-1; count
++)
2441 fprintf(outfile
, "a%d, ", count
);
2443 fprintf(outfile
, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2446 for (count
=d0
; count
<numregs
-1; count
++)
2447 fprintf(outfile
, "(a%d), ", count
);
2449 fprintf(outfile
, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2450 fD_GetProto(obj
, fD_RegNum(obj
)-1),
2451 (target
==M68K_POS
? "__" : ""));
2456 if (target
==M68K_AMIGAOS
|| target
==IX86BE_AMITHLON
)
2458 fprintf(outfile
, "__inline %s\n%s(", rettype
, tagname
);
2460 for (count
=d0
; count
<numregs
-1; count
++)
2462 chtmp
=fD_GetProto(obj
, count
);
2463 if (count
==fD_GetFuncParNum(obj
))
2464 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2466 fprintf(outfile
, "%s%s%s", chtmp
,
2467 (*(chtmp
+strlen(chtmp
)-1)=='*' ? "" : " "),
2468 fD_GetParam(obj
, count
));
2469 fprintf(outfile
, ", ");
2472 fprintf(outfile
, "int tag, ...)\n{\n ");
2474 fprintf(outfile
, "return ");
2476 fprintf(outfile
, "%s(", name
);
2477 for (count
=d0
; count
<numregs
-1; count
++)
2478 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
2480 fprintf(outfile
, "(%s)&tag);\n}\n\n", fD_GetProto(obj
, fD_RegNum(obj
)-1));
2482 else if (target
==PPC_MORPHOS
)
2484 int n
= 9 - numregs
; /* number of regs that contain varargs */
2485 int d
= n
& 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2486 int taglist
= 8; /* offset of the start of the taglist */
2487 int local
= (taglist
+ n
* 4 + d
+ 8 + 15) & ~15; /* size of the stack frame */
2492 * 0 - 3: next frame ptr
2494 * 8 - 8+n*4+d+8-1: tag list start
2495 * ? - local-1: padding
2502 " .type %s,@function\n"
2504 " stwu 1,-%d(1) \n" /* create stack frame */
2507 tagname
, tagname
, tagname
, local
, local
+ 4);
2510 * If n is odd, one tag is split between regs and stack.
2511 * Copy its ti_Data together with the ti_Tag.
2514 fprintf(outfile
, " lwz 0,%d(1)\n", local
+ 8); /* read ti_Data */
2516 * Save the registers
2518 for (count
= numregs
; count
<= 8; count
++)
2519 fprintf(outfile
, " stw %d,%d(1)\n", count
+ 2, (count
- numregs
) * 4 + taglist
);
2522 fprintf(outfile
, " stw 0,%d(1)\n", taglist
+ n
* 4); /* write ti_Data */
2527 fprintf(outfile
, " li 11,2 \n"
2529 " stw 11,%d(1) \n" /* add TAG_MORE */
2530 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2532 taglist
+ n
* 4 + d
,
2533 taglist
+ n
* 4 + d
+ 4);
2536 if (DirectVarargsCalls
)
2539 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2541 numregs
+ 2, taglist
, name
);
2546 * Save the non-varargs registers in the EmulHandle struct.
2548 for (count
= 0; count
< numregs
- 1; count
++)
2550 int r
= fD_GetReg(obj
, count
);
2552 fprintf(outfile
, " stw %d,%d(2)\n", count
+ 3, r
* 4);
2558 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2559 " stw 0,%d(2) \n" /* REG_?? = taglist */
2561 " lwz 12,%s@l(12)\n"
2562 " li 3,%ld \n" /* r3 = lvo */
2563 " stw 12,56(2) \n" /* REG_A6 = libbase */
2564 " bctrl \n",/* EmulCallOS() */
2565 BaseName
, taglist
, 4 * fD_GetReg(obj
, numregs
- 1), BaseName
,
2569 fprintf(outfile
," lwz 0,%d(1) \n" /* clear stack frame & return */
2574 " .size\t%s,.L%se1-%s\n"
2577 tagname
, tagname
, tagname
, tagname
);
2581 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2586 else if ((varname
= getvarargsfunction(obj
)) != 0 &&
2587 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2589 if (output_mode
!= STUBS
)
2592 "#ifndef NO_INLINE_VARARGS\n"
2593 "#define %s(", varname
);
2595 for (count
= d0
; count
< numregs
- 1; count
++)
2596 fprintf(outfile
, "a%d, ", count
);
2600 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2603 for (count
= d0
; count
< numregs
- 1; count
++)
2604 fprintf(outfile
, "(a%d), ", count
);
2608 "#endif /* !NO_INLINE_VARARGS */\n\n",
2609 fD_GetProto(obj
, fD_RegNum(obj
) - 1));
2613 fprintf(stderr
, "can`t create a varargs stub function for %s\n",
2618 if (strcmp(name
, "DoPkt")==0 &&
2619 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2621 fdDef
*objnc
=(fdDef
*)obj
;
2622 char newname
[7]="DoPkt0";
2623 objnc
->name
=newname
;
2624 for (count
=2; count
<7; count
++)
2626 regs reg
=objnc
->reg
[count
];
2627 char *proto
=objnc
->proto
[count
];
2628 objnc
->reg
[count
]=illegal
;
2629 objnc
->proto
[count
]=fD_nostring
;
2630 fD_write(outfile
, objnc
);
2631 objnc
->reg
[count
]=reg
;
2632 objnc
->proto
[count
]=proto
;
2635 objnc
->name
=(char*)name
;
2640 varargsfunction(const char* proto
, const char* funcname
)
2642 const char *end
=proto
+strlen(proto
)-1;
2643 while (isspace(*end
))
2647 while (isspace(*end
))
2651 while (isspace(*end
))
2653 if (!strncmp(end
-2, "...", 3))
2655 /* Seems to be a varargs function. Check if it will be recognized
2658 char fixedname
[200]; /* Hope will be enough... */
2661 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0];
2663 if (strcmp(funcname
, TagExcTable
[count
+1])==0)
2666 if (!(tmpdef
=fD_ctor()))
2668 fprintf(stderr
, "No mem for FDs\n");
2672 strcpy(fixedname
, funcname
);
2673 if (strlen(funcname
)>4 &&
2674 !strcmp(funcname
+strlen(funcname
)-4, "Tags"))
2676 /* Might be either nothing or "TagList". */
2677 fixedname
[strlen(fixedname
)-4]='\0';
2678 fD_NewName(tmpdef
, fixedname
);
2679 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2683 strcat(fixedname
, "TagList");
2684 fD_NewName(tmpdef
, fixedname
);
2685 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2691 strcat(fixedname
, "A");
2692 fD_NewName(tmpdef
, fixedname
);
2693 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2704 ishandleddifferently(const char* proto
, const char* funcname
)
2706 /* First check if this is a vararg call? */
2707 if (varargsfunction(proto
, funcname
))
2710 /* It might be a dos.library "alias" name. */
2711 if (aliasfunction(funcname
))
2714 /* It might be one from dos.library/DoPkt() family. */
2715 if (strlen(funcname
)==6 && !strncmp(funcname
, "DoPkt", 5) &&
2716 funcname
[5]>='0' && funcname
[6]<='4')
2719 /* Finally, it can be intuition.library/ReportMouse1(). */
2720 return !strcmp(funcname
, "ReportMouse1");
2724 printusage(const char* exename
)
2727 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2730 "--mode=MODE\t\tMODE is one of the following:\n"
2731 "\tnew\t\t\tPreprocessor based (default)\n"
2732 "\told\t\t\tInline based\n"
2733 "\tstubs\t\t\tLibrary stubs\n"
2734 "\tgatestubs\t\tLibrary gate stubs\n"
2735 "\tgateproto\t\tLibrary gate prototypes\n"
2736 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2738 "--target=OS\t\tOS is one of the following: \n"
2739 "\t*-aros\t\t\tAROS (any CPU)\n"
2740 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2741 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2742 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2743 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2744 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2746 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2747 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2748 "--libprefix=PREFIX\tLocal function name prefix\n"
2749 "--local\t\t\tUse local includes\n"
2750 "--quiet\t\t\tDon't display warnings\n"
2751 "--version\t\tPrint version number and exit\n\n"
2752 "Compatibility options:\n"
2753 "--new\t\t\tSame as --mode=new\n"
2754 "--old\t\t\tSame as --mode=old\n"
2755 "--stubs\t\t\tSame as --mode=stubs\n"
2756 "--gatestubs\t\tSame as --mode=gatestubs\n"
2757 "--proto\t\t\tSame as --mode=prot\n"
2758 "--pos\t\t\tSame as --target=m68k-pos\n"
2759 "--morphos\t\tSame as --target=powerpc-morphos\n"
2760 "--powerup\t\tSame as --target=powerpc-powerup\n"
2764 void output_proto(FILE* outfile
)
2767 "/* Automatically generated header! Do not edit! */\n\n"
2768 "#ifndef PROTO_%s_H\n"
2769 "#define PROTO_%s_H\n\n"
2770 "#include <clib/%s_protos.h>\n\n"
2771 "#ifndef _NO_INLINE\n"
2773 "#include <inline/%s.h>\n"
2774 "#endif /* __GNUC__ */\n"
2775 "#endif /* !_NO_INLINE */\n\n",
2776 BaseNamU
, BaseNamU
, BaseNamL
, BaseNamL
);
2780 "#ifndef __NOLIBBASE__\n"
2781 "extern struct %s *\n"
2782 "#ifdef __CONSTLIBBASEDECL__\n"
2783 "__CONSTLIBBASEDECL__\n"
2784 "#endif /* __CONSTLIBBASEDECL__ */\n"
2786 "#endif /* !__NOLIBBASE__ */\n\n",
2790 "#endif /* !PROTO_%s_H */\n", BaseNamU
);
2793 /******************************************************************************/
2796 main(int argc
, char** argv
)
2798 fdDef
*tmpdef
, /* a dummy to contain the name to look for */
2799 *founddef
; /* the fdDef for which we found a prototype */
2804 char *fdfilename
=0, *clibfilename
=0, *outfilename
=0;
2809 for (count
=1; count
<argc
; count
++)
2811 char *option
=argv
[count
];
2815 if (strcmp(option
, "o")==0)
2817 if (count
==argc
-1 || outfilename
)
2819 printusage(argv
[0]);
2820 return EXIT_FAILURE
;
2822 if (strcmp(argv
[++count
], "-"))
2823 outfilename
=argv
[count
];
2827 if (*option
=='-') /* Accept GNU-style '--' options */
2829 if (strncmp(option
, "mode=", 5)==0)
2831 if (strcmp(option
+5, "new")==0)
2833 else if (strcmp(option
+5, "old")==0)
2835 else if (strcmp(option
+5, "stubs")==0)
2837 else if (strcmp(option
+5, "gatestubs")==0)
2838 output_mode
=GATESTUBS
;
2839 else if (strcmp(option
+5, "gateproto")==0)
2840 output_mode
=GATEPROTO
;
2841 else if (strcmp(option
+5, "proto")==0)
2844 else if (strncmp(option
, "target=", 7)==0)
2846 if (MatchGlob("*-aros",option
+7))
2848 else if (MatchGlob("i?86be*-amithlon",option
+7))
2849 target
=IX86BE_AMITHLON
;
2850 else if (MatchGlob("m68k*-amigaos",option
+7))
2851 target
=M68K_AMIGAOS
;
2852 else if (MatchGlob("m68k*-pos",option
+7))
2854 else if (MatchGlob("powerpc*-powerup",option
+7))
2856 else if (MatchGlob("powerpc*-morphos",option
+7))
2860 printusage(argv
[0]);
2861 return EXIT_FAILURE
;
2864 else if (strcmp(option
, "direct-varargs-calls") == 0)
2865 DirectVarargsCalls
= 1;
2866 else if (strncmp(option
, "gateprefix=", 11)==0)
2867 gateprefix
= option
+11;
2868 else if (strncmp(option
, "libprefix=", 10)==0)
2869 libprefix
= option
+10;
2870 else if (strcmp(option
, "quiet") == 0)
2872 else if (strcmp(option
, "version")==0)
2874 fprintf(stderr
, "fd2inline version " VERSION
"\n");
2875 return EXIT_SUCCESS
;
2877 /* Compatibility options */
2878 else if (strcmp(option
, "new")==0)
2880 else if (strcmp(option
, "old")==0)
2882 else if (strcmp(option
, "stubs")==0)
2884 else if (strcmp(option
, "gatestubs")==0)
2885 output_mode
=GATESTUBS
;
2886 else if (strcmp(option
, "proto")==0)
2888 else if (strcmp(option
, "pos")==0)
2890 else if (strcmp(option
, "powerup")==0)
2892 else if (strcmp(option
, "morphos")==0)
2894 /* Unknown option */
2897 printusage(argv
[0]);
2898 return EXIT_FAILURE
;
2904 /* One of the filenames */
2907 else if (!clibfilename
)
2908 clibfilename
=option
;
2909 else if (!outfilename
)
2913 printusage(argv
[0]);
2914 return EXIT_FAILURE
;
2919 if (!fdfilename
|| (!clibfilename
&& output_mode
!=PROTO
))
2921 printusage(argv
[0]);
2922 return EXIT_FAILURE
;
2925 if (target
==M68K_POS
&& output_mode
!=NEW
)
2927 fprintf(stderr
, "Target is not compatible with the mode.\n");
2928 return EXIT_FAILURE
;
2931 if (!(arrdefs
=malloc(FDS
*sizeof(fdDef
*))))
2933 fprintf(stderr
, "No mem for FDs\n");
2934 return EXIT_FAILURE
;
2936 for (count
=0; count
<FDS
; count
++)
2937 arrdefs
[count
]=NULL
;
2939 if (!(myfile
=fF_ctor(fdfilename
)))
2941 fprintf(stderr
, "Couldn't open file '%s'.\n", fdfilename
);
2942 return EXIT_FAILURE
;
2947 for (count
=0; count
<FDS
&& lerror
==false; count
++)
2949 if (!(arrdefs
[count
]=fD_ctor()))
2951 fprintf(stderr
, "No mem for FDs\n" );
2952 return EXIT_FAILURE
;
2956 if ((lerror
=fF_readln(myfile
))==false)
2958 fF_SetError(myfile
, false);
2959 lerror
=fD_parsefd(arrdefs
[count
], myfile
);
2962 while (lerror
==nodef
);
2967 fD_dtor(arrdefs
[count
]);
2968 arrdefs
[count
]=NULL
;
2972 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpName
);
2974 if (output_mode
!=NEW
|| target
==AROS
)
2976 unsigned int count2
;
2979 for (count2
=0; count2
<sizeof LibExcTable
/sizeof LibExcTable
[0]; count2
+=2)
2980 if (strcmp(BaseName
, LibExcTable
[count2
])==0)
2982 StdLib
=LibExcTable
[count2
+1];
2989 if (output_mode
!=PROTO
)
2991 if (!(myfile
=fF_ctor(clibfilename
)))
2993 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
2994 return EXIT_FAILURE
;
2997 if (!(tmpdef
=fD_ctor()))
2999 fprintf(stderr
, "No mem for FDs\n");
3000 return EXIT_FAILURE
;
3003 for (lerror
=false; lerror
==false || lerror
==nodef
;)
3004 if ((lerror
=fF_readln(myfile
))==false)
3006 fF_SetError(myfile
, false); /* continue even on errors */
3007 tmpstr
=fF_FuncName(myfile
);
3012 fD_NewName(tmpdef
, tmpstr
);
3013 res
=(fdDef
**)bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
3019 DBP(fprintf(stderr
, "found (%s).\n", fD_GetName(founddef
)));
3020 fF_SetError(myfile
, false);
3021 lerror
=fD_parsepr(founddef
, myfile
);
3024 if (!ishandleddifferently(myfile
->line
, tmpstr
))
3026 fprintf(stderr
, "Don't know what to do with <%s> in line %lu.\n",
3027 tmpstr
, myfile
->lineno
);
3037 if (strlen(fdfilename
)>7 &&
3038 !strcmp(fdfilename
+strlen(fdfilename
)-7, "_lib.fd"))
3040 char *str
=fdfilename
+strlen(fdfilename
)-8;
3041 while (str
!=fdfilename
&& str
[-1]!='/' && str
[-1]!=':')
3043 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3044 strncpy(BaseNamU
, str
, strlen(str
)-7);
3045 BaseNamU
[strlen(str
)-7]='\0';
3046 strcpy(BaseNamL
, BaseNamU
);
3047 strcpy(BaseNamC
, BaseNamU
);
3051 strcpy(BaseNamU
, BaseName
);
3052 if (strlen(BaseNamU
)>4 && strcmp(BaseNamU
+strlen(BaseNamU
)-4, "Base")==0)
3053 BaseNamU
[strlen(BaseNamU
)-4]='\0';
3054 if (target
==M68K_POS
&& strncmp(BaseNamU
, "gb_", 3)==0)
3055 memmove(BaseNamU
, &BaseNamU
[3], strlen(&BaseNamU
[3])+1);
3056 strcpy(BaseNamL
, BaseNamU
);
3057 strcpy(BaseNamC
, BaseNamU
);
3060 BaseNamC
[0]=toupper(BaseNamC
[0]);
3064 if (!(outfile
=fopen(outfilename
, "w")))
3066 fprintf(stderr
, "Couldn't open output file.\n");
3067 return EXIT_FAILURE
;
3077 if (output_mode
==PROTO
)
3078 output_proto(outfile
);
3081 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
||
3082 output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3084 if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3087 "/* Automatically generated stubs! Do not edit! */\n\n");
3092 "/* Automatically generated header! Do not edit! */\n\n"
3093 "#ifndef %sINLINE_%s_H\n"
3094 "#define %sINLINE_%s_H\n\n",
3095 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3097 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3101 if (output_mode
==NEW
)
3103 if(target
==M68K_POS
)
3106 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3107 "#include <pInline/macros.h>\n"
3108 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3110 else if(target
==AROS
)
3113 "#ifndef AROS_LIBCALL_H\n"
3114 "#include <aros/libcall.h>\n"
3115 "#endif /* !AROS_LIBCALL_H */\n\n");
3120 "#ifndef __INLINE_MACROS_H\n"
3121 "#include <inline/macros.h>\n"
3122 "#endif /* !__INLINE_MACROS_H */\n\n");
3130 "#ifndef __INLINE_STUB_H\n"
3131 "#include <inline/stubs.h>\n"
3132 "#endif /* !__INLINE_STUB_H */\n\n");
3134 fprintf(outfile
, "#ifdef __CLIB_TYPES__\n" );
3136 clib
= fopen( clibfilename
, "r" );
3140 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3144 char* buffer
= malloc( 1024 );
3146 if( buffer
== NULL
)
3148 fprintf(stderr
, "No memory for line buffer.\n " );
3152 while( fgets( buffer
, 1023, clib
) != NULL
)
3154 if( buffer
[ 0 ] == '#' /* Pre-processor instruction */ ||
3155 strncmp( buffer
, "typedef", 7 ) == 0 )
3157 fprintf(outfile
, buffer
);
3167 fprintf(outfile
, "#endif /* __CLIB_TYPES__ */\n\n" );
3172 "#include <aros/libcall.h>\n\n" );
3174 else if(target
==IX86BE_AMITHLON
)
3177 "#ifndef __INLINE_MACROS_H\n"
3178 "#include <inline/macros.h>\n"
3179 "#endif /* __INLINE_MACROS_H */\n\n");
3181 else if (target
== PPC_MORPHOS
)
3184 "#include <emul/emulregs.h>\n\n" );
3190 fprintf(stderr
, "Internal error: Unknown output mode in main().\n");
3197 return EXIT_FAILURE
;
3202 if (output_mode
==NEW
)
3205 "#ifndef %s%s_BASE_NAME\n"
3206 "#define %s%s_BASE_NAME %s\n"
3207 "#endif /* !%s%s_BASE_NAME */\n\n",
3208 (target
==M68K_POS
? "__" : ""), BaseNamU
,
3209 (target
==M68K_POS
? "__" : ""), BaseNamU
, BaseName
,
3210 (target
==M68K_POS
? "__" : ""), BaseNamU
);
3211 if (target
==M68K_POS
)
3213 "#ifndef __%s_LIB_NAME\n"
3214 "#define __%s_LIB_NAME %s\n"
3215 "#endif /* !__%s_LIB_NAME */\n\n",
3217 (strcmp(BaseName
, "gb_ExecBase") ? BaseName
: "gb_ExecLib"),
3222 "#ifndef BASE_EXT_DECL\n"
3223 "#define BASE_EXT_DECL\n"
3224 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3225 "#endif /* !BASE_EXT_DECL */\n"
3226 "#ifndef BASE_PAR_DECL\n"
3227 "#define BASE_PAR_DECL\n"
3228 "#define BASE_PAR_DECL0 void\n"
3229 "#endif /* !BASE_PAR_DECL */\n"
3230 "#ifndef BASE_NAME\n"
3231 "#define BASE_NAME %s\n"
3232 "#endif /* !BASE_NAME */\n\n"
3233 "BASE_EXT_DECL0\n\n", StdLib
, BaseName
, BaseName
);
3236 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3238 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3240 fD_write(outfile
, arrdefs
[count
]);
3241 fD_dtor(arrdefs
[count
]);
3242 arrdefs
[count
]=NULL
;
3245 if (output_mode
!=NEW
)
3248 "#undef BASE_EXT_DECL\n"
3249 "#undef BASE_EXT_DECL0\n"
3250 "#undef BASE_PAR_DECL\n"
3251 "#undef BASE_PAR_DECL0\n"
3252 "#undef BASE_NAME\n\n");
3254 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
)
3256 fprintf(outfile
, "#endif /* !%sINLINE_%s_H */\n",
3257 (target
==M68K_POS
? "__INC_POS_P" : "_"), BaseNamU
);
3268 return EXIT_SUCCESS
;