1 /******************************************************************************
5 * Should be able to parse CBM fd files and generate vanilla inline calls
6 * for gcc. Works as a filter.
8 * by Wolfgang Baron, all rights reserved.
10 * improved, updated, simply made workable by Rainer F. Trunz 1/95
12 * Completely reworked Version, cleaned up and removed a whole lot of bugs
13 * found by Kamil Iskra.
15 * Expect miracles now (hopefully...). Ok, I am just kidding :)
17 * Version 0.99a by Rainer F. Trunz 6/95
19 * Version 0.99b and later by Kamil Iskra.
21 * Version 1.3x by Martin Blom
22 * See fd2inline.guide/fd2inline.info for details.
24 * version 1.38 by AROS development team
26 *****************************************************************************/
34 /******************************************************************************
35 * The program has a few sort of class definitions, which are the result of
36 * object oriented thinking, to be imlemented in plain C. I just haven't
37 * had the time to learn C++ or install the compiler. The design does however
38 * improve robustness, which allows the source to be used over and over again.
39 * if you use this code, please leave a little origin note.
40 ******************************************************************************/
43 const static char version_str
[]="$VER: fd2inline " VERSION
" (24.2.2002)";
46 /******************************************************************************
47 * These are general definitions including types for defining registers etc.
48 ******************************************************************************/
56 #if (defined(__GNUC__) || defined(__SASC)) && 0
57 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
62 #define REGS 16 /* d0=0,...,a7=15 */
65 /* To prevent the enum below from getting broken when building on AROS */
70 d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
, a0
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, illegal
73 typedef unsigned char shortcard
;
75 typedef enum { false, nodef
, real_error
} Error
;
77 enum { NEW
, OLD
, STUBS
, PROTO
, GATESTUBS
, GATEPROTO
} output_mode
=NEW
;
78 enum { IX86BE_AMITHLON
, AROS
, M68K_AMIGAOS
, M68K_POS
, PPC_POWERUP
, PPC_MORPHOS
} target
= M68K_AMIGAOS
;
81 int DirectVarargsCalls
= 0;
85 char *gateprefix
= "";
88 char BaseName
[64], BaseNamU
[64], BaseNamL
[64], BaseNamC
[64];
91 const static char *LibExcTable
[]=
93 "BattClockBase", "Node",
94 "BattMemBase", "Node",
95 "ConsoleDevice", "Device",
96 "DiskBase", "DiskResource",
97 "DOSBase", "DosLibrary",
98 "SysBase", "ExecBase",
99 "ExpansionBase", "ExpansionBase",
100 "GfxBase", "GfxBase",
101 "InputBase", "Device",
102 "IntuitionBase", "IntuitionBase",
103 "LocaleBase", "LocaleBase",
104 "MathIeeeDoubBasBase", "MathIEEEBase",
105 "MathIeeeDoubTransBase","MathIEEEBase",
106 "MathIeeeSingBasBase", "MathIEEEBase",
107 "MathIeeeSingTransBase","MathIEEEBase",
110 "RamdriveDevice", "Device",
111 "RealTimeBase", "RealTimeBase",
112 "RexxSysBase", "RxsLib",
113 "TimerBase", "Device",
114 "UtilityBase", "UtilityBase"
116 const char *StdLib
; /* global lib-name ptr */
118 /*******************************************
119 * just some support functions, no checking
120 *******************************************/
123 NewString(char** new, const char* old
)
128 while (*old
&& (*old
==' ' || *old
=='\t'))
131 for (high
=old
+len
-1; high
>=old
&& (*high
==' ' || *high
=='\t'); high
--);
137 strncpy(*new, old
, len
);
141 fprintf(stderr
, "No mem for string\n");
146 illparams(const char* funcname
)
148 fprintf(stderr
, "%s: illegal Parameters\n", funcname
);
151 static INLINE
const char*
154 const static char *aosregs
[]=
156 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
157 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
184 return (target
!=M68K_POS
? aosregs
[reg
] : posregs
[reg
]);
187 static INLINE
const char*
190 const static char *aosregs
[]=
192 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
193 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
200 return (target
!=M68K_POS
? aosregs
[reg
] : RegStr(reg
));
205 /******************************************************************************
208 * searches string in from position at downwards, as long as in does not
209 * contain any character in not.
211 ******************************************************************************/
214 StrNRBrk(const char* in
, const char* not, const char* at
)
219 chcheck
=""; /* if at<in, the result will be NULL */
220 for (ready
=false; ready
==false && at
>=in
;)
222 for (chcheck
=not; *chcheck
&& *chcheck
!= *at
; chcheck
++);
228 DBP(fprintf(stderr
, "{%c}", *chcheck
));
229 return *chcheck
? at
: NULL
;
233 Our own "strupr", since it is a non-standard function.
246 MatchGlob( char* glob
, char* str
)
263 if( c
== 0 || *str
!= c
)
277 if( MatchGlob( glob
, str
) )
300 /******************************************************************************
303 * stores a file with a temporary buffer (static length, sorry), a line number,
304 * an offset (used for library offsets and an error field.
305 * When there's no error, line will contain line #lineno and offset will be
306 * the last offset set by the interpretation of the last line. If there's been
307 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
308 * It is assumed offsets are always negative.
309 ******************************************************************************/
311 #define fF_BUFSIZE 1024
313 /* all you need to know about an fdFile you parse */
315 typedef enum {FD_PRIVATE
=1, FD_SHADOW
=2} fdflags
;
319 FILE* file
; /* the file we're reading from */
320 char line
[fF_BUFSIZE
]; /* the current line */
321 unsigned long lineno
; /* current line number */
322 long offset
; /* current fd offset (-bias) */
323 Error error
; /* is everything o.k. */
324 fdflags flags
; /* for ##private, ##shadow (p.OS) */
328 fF_ctor (const char* fname
);
330 fF_dtor (fdFile
* obj
);
332 fF_SetError (fdFile
* obj
, Error error
);
334 fF_SetOffset (fdFile
* obj
, long at
);
336 fF_readln (fdFile
* obj
);
338 fF_GetError (const fdFile
* obj
);
340 fF_GetOffset (const fdFile
* obj
);
342 fF_FuncName (fdFile
* obj
); /* return name or null */
344 fF_SetFlags (fdFile
* obj
, fdflags flags
);
346 fF_GetFlags (const fdFile
* obj
);
356 fF_SetError(fdFile
* obj
, Error error
)
361 illparams("fF_SetError");
364 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
367 fF_SetOffset(fdFile
* obj
, long at
)
372 illparams("fFSetOffset");
376 fF_SetFlags(fdFile
* obj
, fdflags flags
)
381 illparams("fF_SetFlags");
385 fF_ctor(const char* fname
)
391 result
=malloc(sizeof(fdFile
));
394 result
->file
=fopen(fname
, "r");
398 fF_SetOffset(result
, -30);
399 fF_SetError(result
, false);
400 fF_SetFlags(result
, 0);
401 result
->line
[0]='\0';
413 illparams("fF_ctor");
419 fF_readln(fdFile
* obj
)
422 long glen
, /* the length we read until now */
423 len
; /* the length of the last segment */
433 if (!fgets(low
, fF_BUFSIZE
-1-glen
, obj
->file
))
435 fF_SetError(obj
, real_error
);
439 if (low
==strpbrk(low
, "*#/"))
441 DBP(fprintf(stderr
, "in# %s\n", obj
->line
));
446 while (len
&& isspace(*bpoint
))
451 if (*bpoint
==';' || *bpoint
==')')
453 DBP(fprintf(stderr
, "\nin: %s\n", obj
->line
));
458 if (glen
>=fF_BUFSIZE
-10) /* somewhat pessimistic? */
460 fF_SetError(obj
, real_error
);
461 fprintf(stderr
, "Line %lu too long.\n", obj
->lineno
);
464 DBP(fprintf(stderr
, "+"));
467 illparams("fF_readln");
472 fF_GetError(const fdFile
* obj
)
476 illparams("fF_GetError");
481 fF_GetOffset(const fdFile
* obj
)
485 illparams("fF_GetOffset");
489 /******************************************************************************
492 * checks if it can find a function-name and return it's address, or NULL
493 * if the current line does not seem to contain one. The return value will
494 * be a pointer into a malloced buffer, thus the caller will have to free().
495 ******************************************************************************/
498 fF_FuncName(fdFile
* obj
)
503 long obraces
; /* count of open braces */
504 Error ready
; /* ready with searching */
506 if (!obj
|| fF_GetError(obj
)==real_error
)
508 illparams("fF_FuncName");
513 while (*lower
&& (*lower
==' ' || *lower
=='\t'))
516 if (!*lower
|| (!isalpha(*lower
) && *lower
!='_'))
518 fF_SetError(obj
, nodef
);
524 if (!isalnum(*lower
) && !isspace(*lower
) && *lower
!='*' && *lower
!=','
525 && *lower
!='.' && *lower
!=';' && *lower
!='(' && *lower
!=')' &&
526 *lower
!='[' && *lower
!=']' && *lower
!='_' && *lower
!='\\')
528 fF_SetError(obj
, nodef
);
537 if (obj
&& fF_GetError(obj
)==false)
539 if ((upper
=strrchr(obj
->line
, ')'))!=0)
541 DBP(fprintf(stderr
, "end:%s:", upper
));
543 for (obraces
=1, ready
=false; ready
==false; upper
=lower
)
545 lower
=StrNRBrk(obj
->line
, "()", --upper
);
552 DBP(fprintf(stderr
, " )%ld%s", obraces
, lower
));
556 DBP(fprintf(stderr
, " (%ld%s", obraces
, lower
));
561 fprintf(stderr
, "Faulty StrNRBrk\n");
566 fprintf(stderr
, "'(' or ')' expected in line %lu.\n",
571 if (ready
==nodef
) /* we found the matching '(' */
578 while (upper
>=obj
->line
&& (*upper
==' ' || *upper
=='\t'))
581 lower
=StrNRBrk(obj
->line
, " \t*)", upper
);
588 for (name
=lower
; name
<=upper
; name
++)
589 if (!isalnum(*name
) && *name
!='_')
591 fF_SetError(obj
, nodef
);
595 newlen
=upper
-lower
+1;
596 buf
=malloc(newlen
+1);
600 strncpy(buf
, lower
, newlen
);
604 fprintf(stderr
, "No mem for fF_FuncName");
609 illparams("fF_FuncName");
613 static INLINE fdflags
614 fF_GetFlags(const fdFile
* obj
)
618 illparams("fF_GetFlags");
622 /*********************
624 *********************/
634 regs funcpar
; /* number of argument that has type "pointer to function" */
640 fD_dtor (fdDef
* obj
);
642 fD_NewName (fdDef
* obj
, const char* newname
);
644 fD_NewParam (fdDef
* obj
, shortcard at
, const char* newstr
);
646 fD_NewProto (fdDef
* obj
, shortcard at
, char* newstr
);
648 fD_NewReg (fdDef
* obj
, shortcard at
, regs reg
);
650 fD_NewType (fdDef
* obj
, const char* newstr
);
652 fD_SetOffset (fdDef
* obj
, long off
);
654 fD_parsefd (fdDef
* obj
, fdFile
* infile
);
656 fD_parsepr (fdDef
* obj
, fdFile
* infile
);
658 fD_GetName (const fdDef
* obj
);
660 fD_GetOffset (const fdDef
* obj
);
662 fD_GetParam (const fdDef
* obj
, shortcard at
);
664 fD_GetReg (const fdDef
* obj
, shortcard at
);
666 fD_GetRegStr (const fdDef
* obj
, shortcard at
);
668 fD_GetRegStrU (const fdDef
* obj
, shortcard at
);
670 fD_GetType (const fdDef
* obj
);
672 fD_ParamNum (const fdDef
* obj
);
674 fD_ProtoNum (const fdDef
* obj
);
676 fD_RegNum (const fdDef
* obj
);
678 fD_cmpName (const void* big
, const void* small
);
680 fD_write (FILE* outfile
, const fdDef
* obj
);
682 fD_GetFuncParNum (const fdDef
* obj
);
684 fD_SetFuncParNum (fdDef
* obj
, shortcard at
);
686 fD_adjustargnames(fdDef
*obj
);
691 char *fD_nostring
="";
699 result
=malloc(sizeof(fdDef
));
703 result
->name
=fD_nostring
;
704 result
->type
=fD_nostring
;
705 result
->funcpar
=illegal
;
707 for (count
=d0
; count
<illegal
; count
++ )
709 result
->reg
[count
]=illegal
;
710 result
->param
[count
]=fD_nostring
; /* if (!strlen) dont't free() */
711 result
->proto
[count
]=fD_nostring
;
717 /* free all resources and make the object as illegal as possible */
727 fprintf(stderr
, "fD_dtor: null name");
729 if (obj
->name
!=fD_nostring
)
733 fprintf(stderr
, "fD_dtor: null type");
735 if (obj
->type
!=fD_nostring
)
738 obj
->name
=obj
->type
=NULL
;
740 for (count
=d0
; count
<illegal
; count
++)
742 obj
->reg
[count
]=illegal
;
744 if (!obj
->param
[count
])
745 fprintf(stderr
, "fD_dtor: null param");
747 if (obj
->param
[count
]!=fD_nostring
)
748 free(obj
->param
[count
]);
750 if (!obj
->proto
[count
])
751 fprintf(stderr
, "fD_dtor: null proto");
753 if (obj
->proto
[count
]!=fD_nostring
)
754 free(obj
->proto
[count
]);
756 obj
->param
[count
]=obj
->proto
[count
]=NULL
;
762 fprintf(stderr
, "fd_dtor(NULL)\n");
766 fD_NewName(fdDef
* obj
, const char* newname
)
770 if (obj
->name
&& obj
->name
!=fD_nostring
)
772 if (!NewString(&obj
->name
, newname
))
773 obj
->name
=fD_nostring
;
776 illparams("fD_NewName");
780 fD_NewParam(fdDef
* obj
, shortcard at
, const char* newstr
)
784 if (newstr
&& obj
&& at
<illegal
)
788 if (pa
&& pa
!=fD_nostring
)
791 while (*newstr
==' ' || *newstr
=='\t')
794 if (NewString(&pa
, newstr
))
798 prefix_pa
= malloc( strlen( pa
) + 4 );
800 if( prefix_pa
== NULL
)
802 fprintf(stderr
, "No mem for string\n");
806 sprintf( prefix_pa
, "___%s", pa
);
807 obj
->param
[at
]=prefix_pa
;
812 obj
->param
[at
]=fD_nostring
;
815 illparams("fD_NewParam");
818 /* get first free *reg or illegal */
820 static INLINE shortcard
821 fD_RegNum(const fdDef
* obj
)
827 for (count
=d0
; count
<illegal
&& obj
->reg
[count
]!=illegal
; count
++);
832 illparams("fD_RegNum");
838 fD_NewReg(fdDef
* obj
, shortcard at
, regs reg
)
840 if (obj
&& at
<illegal
&& reg
>=d0
&& reg
<=illegal
)
843 illparams("fD_NewReg");
847 fD_GetReg(const fdDef
* obj
, shortcard at
)
849 if (obj
&& at
<illegal
)
853 illparams("fD_GetReg");
858 static INLINE shortcard
859 fD_GetFuncParNum(const fdDef
* obj
)
862 return (shortcard
)obj
->funcpar
;
865 illparams("fD_GetFuncParNum");
871 fD_SetFuncParNum(fdDef
* obj
, shortcard at
)
873 if (obj
&& at
<illegal
)
876 illparams("fD_SetFuncParNum");
880 fD_NewProto(fdDef
* obj
, shortcard at
, char* newstr
)
884 if (newstr
&& obj
&& at
<illegal
)
886 char *t
, arr
[200]; /* I hope 200 will be enough... */
890 if (pr
&& pr
!=fD_nostring
)
893 while (*newstr
==' ' || *newstr
=='\t')
894 newstr
++; /* Skip leading spaces */
897 while ((*t
++=*newstr
)!=0)
899 /* Copy the rest, counting number of words */
900 if ((*newstr
==' ' || *newstr
=='\t') && newstr
[1] && newstr
[1]!=' ' &&
907 while (*t
==' ' || *t
=='\t')
909 t
[1]='\0'; /* Get rid of tailing spaces */
911 if (at
!=fD_GetFuncParNum(obj
))
913 if (numwords
>1) /* One word - must be type */
916 /* '*' on the end - no parameter name used */
917 while (*t
!=' ' && *t
!='\t' && *t
!='*')
920 if (strcmp(t
, "char") && strcmp(t
, "short") && strcmp(t
, "int")
921 && strcmp(t
, "long") && strcmp(t
, "APTR"))
923 /* Not one of applicable keywords - must be parameter name.
926 while (*t
==' ' || *t
=='\t')
934 /* Parameter of type "pointer to function". */
938 while (*t
==' ' || *t
=='\t')
944 if (target
!=M68K_POS
)
946 memmove(t
+2, end
, strlen(end
)+1);
951 memmove(t
, end
, strlen(end
)+1);
954 if (NewString(&pr
, arr
))
957 while (*pr
==' ' || *pr
=='\t')
959 if (!strcasecmp(pr
, "double"))
961 /* "double" needs two data registers */
962 int count
, regs
=fD_RegNum(obj
);
963 for (count
=at
+1; count
<regs
; count
++)
964 fD_NewReg(obj
, count
, fD_GetReg(obj
, count
+1));
968 obj
->proto
[at
]=fD_nostring
;
971 illparams("fD_NewProto");
977 fD_NewType(fdDef
* obj
, const char* newtype
)
981 if (obj
->type
&& obj
->type
!=fD_nostring
)
983 if (!NewString(&obj
->type
, newtype
))
984 obj
->type
=fD_nostring
;
987 illparams("fD_NewType");
991 fD_SetOffset(fdDef
* obj
, long off
)
996 illparams("fD_SetOffset");
999 static INLINE
const char*
1000 fD_GetName(const fdDef
* obj
)
1002 if (obj
&& obj
->name
)
1006 illparams("fD_GetName");
1012 fD_GetOffset(const fdDef
* obj
)
1018 illparams("fD_GetOffset");
1023 static INLINE
const char*
1024 fD_GetProto(const fdDef
* obj
, shortcard at
)
1026 if (obj
&& at
<illegal
&& obj
->proto
[at
])
1027 return obj
->proto
[at
];
1030 illparams("fD_GetProto");
1035 static INLINE
const char*
1036 fD_GetParam(const fdDef
* obj
, shortcard at
)
1038 if (obj
&& at
<illegal
&& obj
->param
[at
])
1039 return obj
->param
[at
];
1042 illparams("fD_GetParam");
1047 static INLINE
const char*
1048 fD_GetRegStr(const fdDef
* obj
, shortcard at
)
1050 if (obj
&& at
<illegal
)
1051 return RegStr(obj
->reg
[at
]);
1054 illparams("fD_GetReg");
1055 return RegStr(illegal
);
1059 static INLINE
const char*
1060 fD_GetRegStrU(const fdDef
* obj
, shortcard at
)
1062 if (obj
&& at
<illegal
)
1063 return RegStrU(obj
->reg
[at
]);
1066 illparams("fD_GetReg");
1067 return RegStrU(illegal
);
1071 static INLINE
const char*
1072 fD_GetType(const fdDef
* obj
)
1074 if (obj
&& obj
->type
)
1078 illparams("fD_GetType");
1083 /* get first free param or illegal */
1085 static INLINE shortcard
1086 fD_ParamNum(const fdDef
* obj
)
1092 for (count
=d0
; count
<illegal
&& obj
->param
[count
]!=fD_nostring
;
1098 illparams("fD_ParamNum");
1103 static INLINE shortcard
1104 fD_ProtoNum(const fdDef
* obj
)
1110 for (count
=d0
; count
<illegal
&& obj
->proto
[count
]!=fD_nostring
;
1116 illparams("fD_ProtoNum");
1121 /******************************************************************************
1124 * parse the current line. Needs to copy input, in order to insert \0's
1126 * fF_GetError(infile):
1127 * false = read a definition.
1128 * nodef = not a definition on line (so try again)
1129 * error = real error
1130 ******************************************************************************/
1133 fD_parsefd(fdDef
* obj
, fdFile
* infile
)
1135 enum parse_info
{ name
, params
, regs
, ready
} parsing
;
1136 char *buf
, *bpoint
, *bnext
;
1137 unsigned long index
;
1139 if (obj
&& infile
&& fF_GetError(infile
)==false)
1143 if (!NewString(&buf
, infile
->line
))
1145 fprintf(stderr
, "No mem for line %lu\n", infile
->lineno
);
1146 fF_SetError(infile
, real_error
);
1148 bpoint
=buf
; /* so -Wall keeps quiet */
1150 /* try to parse the line until there's an error or we are done */
1152 while (parsing
!=ready
&& fF_GetError(infile
)==false)
1160 if (strncmp("##base", buf
, 6)==0)
1163 while (*bnext
==' ' || *bnext
=='\t' || *bnext
=='_')
1165 strcpy(BaseName
, bnext
);
1166 BaseName
[strlen(BaseName
)-1]='\0';
1169 if (strncmp("##bias", buf
, 6)==0)
1171 if (!sscanf(buf
+6, "%ld", &infile
->offset
))
1173 fprintf(stderr
, "Illegal ##bias in line %lu: %s\n",
1174 infile
->lineno
, infile
->line
);
1175 fF_SetError(infile
, real_error
);
1176 break; /* avoid nodef */
1180 if (fF_GetOffset(infile
)>0)
1181 fF_SetOffset(infile
, -fF_GetOffset(infile
));
1182 DBP(fprintf(stderr
, "set offset to %ld\n",
1183 fF_GetOffset(infile
)));
1188 if (strncmp("##private", buf
, 9)==0)
1189 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1191 else if (strncmp("##public", buf
, 8)==0)
1192 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1194 else if (strncmp("##shadow", buf
, 8)==0)
1195 fF_SetFlags(infile
, fF_GetFlags(infile
) |
1198 /* drop through for error comment */
1201 /* try again somewhere else */
1202 fF_SetError(infile
, nodef
);
1206 /* assume a regular line here */
1207 if (fF_GetFlags(infile
) & (FD_PRIVATE
| FD_SHADOW
))
1209 /* don't store names of privates */
1210 fF_SetError(infile
, nodef
);
1211 if (!(fF_GetFlags(infile
) & FD_SHADOW
))
1212 fF_SetOffset(infile
,
1213 fF_GetOffset(infile
)-FUNCTION_GAP
);
1215 /* Shadow is valid for one line only. */
1216 fF_SetFlags(infile
, fF_GetFlags(infile
) &
1220 parsing
=name
; /* switch (parsing) */
1221 for (index
=0; buf
[index
] && buf
[index
]!='('; index
++);
1226 fprintf(stderr
, "Not an fd, line %lu: %s\n",
1227 infile
->lineno
, buf
/* infile->line */);
1228 fF_SetError(infile
, nodef
);
1229 } /* maybe next time */
1234 fD_NewName(obj
, buf
);
1235 fD_SetOffset(obj
, fF_GetOffset(infile
));
1238 parsing
=params
; /* continue the loop */
1245 char *bptmp
; /* needed for fD_NewParam */
1247 /* look for parameters now */
1249 for (bnext
= bpoint
; *bnext
&& *bnext
!=',' && *bnext
!=')';
1258 if (bnext
[1] != '(')
1260 fprintf(stderr
, "Registers expected in line %lu: %s\n",
1261 infile
->lineno
, infile
->line
);
1262 fF_SetError(infile
, nodef
);
1273 /* terminate string and advance to next item */
1276 fD_NewParam(obj
, fD_ParamNum(obj
), bptmp
);
1280 fF_SetError(infile
, nodef
);
1281 fprintf(stderr
, "Param expected in line %lu: %s\n",
1282 infile
->lineno
, infile
->line
);
1284 break; /* switch parsing */
1288 /* look for parameters now */
1290 for (bnext
=bpoint
; *bnext
&& *bnext
!='/' && *bnext
!=',' &&
1291 *bnext
!=')'; bnext
++);
1297 /* wow, we've finished */
1298 fF_SetOffset(infile
, fF_GetOffset(infile
)-FUNCTION_GAP
);
1303 bpoint
[0]=tolower(bpoint
[0]);
1305 if ((bpoint
[0]=='d' || bpoint
[0]=='a') && bpoint
[1]>='0' &&
1306 bpoint
[1]<='8' && bnext
==bpoint
+2)
1307 fD_NewReg(obj
, fD_RegNum(obj
),
1308 bpoint
[1]-'0'+(bpoint
[0]=='a'? 8 : 0));
1312 /* it is when our function is void */
1313 fprintf(stderr
, "Illegal register %s in line %ld\n",
1314 bpoint
, infile
->lineno
);
1315 fF_SetError(infile
, nodef
);
1321 fF_SetError(infile
, nodef
);
1322 fprintf(stderr
, "Reg expected in line %lu\n",
1325 break; /* switch parsing */
1328 fprintf(stderr
, "Internal error, use another compiler.\n");
1334 return fF_GetError(infile
);
1338 illparams("fD_parsefd");
1344 fD_adjustargnames(fdDef
*obj
)
1348 if (output_mode
!=NEW
)
1351 /* For #define-base output mode, we have to check if argument names are not
1352 the same as some words in type names. We check from the first argument
1353 to the last, resolving conflicts by changing argument names, if
1356 for (parnum
=0; parnum
<fD_ParamNum(obj
); parnum
++)
1358 const char *parname
=fD_GetParam(obj
, parnum
);
1363 const char *type
=fD_GetType(obj
);
1368 if ((str
=strstr(type
, parname
))!=0 && (str
==type
||
1369 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1370 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_')))
1372 char buf
[300]; /* Hope will be enough... */
1373 strcpy(buf
, parname
);
1375 fD_NewParam(obj
, parnum
, buf
);
1376 parname
=fD_GetParam(obj
, parnum
);
1380 for (num
=0; num
<fD_ParamNum(obj
); num
++)
1382 const char *name
=fD_GetParam(obj
, num
);
1383 const char *proto
=fD_GetProto(obj
, num
);
1384 if ((num
<parnum
&& strcmp(name
, parname
)==0) ||
1385 ((str
=strstr(proto
, parname
))!=0 && (str
==proto
||
1386 (!isalnum(str
[-1]) && str
[-1]!='_')) &&
1387 (!*(str
+=strlen(parname
)) || (!isalnum(*str
) && *str
!='_'))))
1389 char buf
[300]; /* Hope will be enough... */
1390 strcpy(buf
, parname
);
1392 fD_NewParam(obj
, parnum
, buf
);
1393 parname
=fD_GetParam(obj
, parnum
);
1398 } while (!finished
);
1403 fD_parsepr(fdDef
* obj
, fdFile
* infile
)
1405 char *buf
; /* a copy of infile->line */
1406 char *bpoint
, /* cursor in buf */
1407 *bnext
, /* looking for the end */
1408 *lowarg
; /* beginning of this argument */
1409 long obraces
; /* count of open braces */
1410 regs count
, /* count parameter number */
1411 args
; /* the number of arguments for this function */
1413 if (!(obj
&& infile
&& fF_GetError(infile
)==false))
1415 illparams("fD_parsepr");
1416 fF_SetError(infile
, real_error
);
1419 if (!NewString(&buf
, infile
->line
))
1421 fprintf(stderr
, "No mem for fD_parsepr\n");
1422 fF_SetError(infile
, real_error
);
1425 fF_SetError(infile
, false);
1427 bpoint
=strchr(buf
, '(');
1428 while (--bpoint
>=buf
&& strstr(bpoint
, fD_GetName(obj
))!=bpoint
);
1431 while (--bpoint
>= buf
&& (*bpoint
==' ' || *bpoint
=='\t'));
1434 fD_NewType(obj
, buf
);
1436 while (bpoint
&& *bpoint
++!='('); /* one beyond '(' */
1441 for (count
=0, args
=fD_RegNum(obj
); count
<args
; bpoint
=bnext
+1)
1443 while (*bpoint
&& (*bpoint
==' ' || *bpoint
=='\t')) /* ignore spaces */
1446 if (!obraces
&& target
==M68K_POS
&& strncmp(bpoint
, "_R_", 3)==0 &&
1447 isalnum(bpoint
[3]) && isalnum(bpoint
[4]) && isspace(bpoint
[5]))
1450 bnext
=strpbrk(bpoint
, "(),");
1459 if (target
==M68K_AMIGAOS
|| target
==M68K_POS
)
1461 if (fD_GetFuncParNum(obj
)!=illegal
&&
1462 fD_GetFuncParNum(obj
)!=count
&&
1464 fprintf(stderr
, "Warning: two parameters of type "
1465 "pointer to function are used.\n"
1466 "This is not supported!\n");
1469 fD_SetFuncParNum(obj
, count
);
1472 DBP(fprintf(stderr
, "< (%ld%s >", obraces
, bnext
));
1478 DBP(fprintf(stderr
, "< )%ld%s >", obraces
, bnext
));
1484 DBP(fprintf(stderr
, "< )0> [LAST PROTO=%s]", lowarg
));
1485 if (fD_NewProto(obj
, count
, lowarg
))
1486 fprintf(stderr
, "Parser confused in line %ld\n",
1492 DBP(fprintf(stderr
, "%s needs %u arguments and got %u.\n",
1493 fD_GetName(obj
), args
, count
+1));
1494 fF_SetError(infile
, nodef
);
1504 DBP(fprintf(stderr
, " [PROTO=%s] ", lowarg
));
1505 if (fD_NewProto(obj
, count
, lowarg
))
1506 fprintf(stderr
, "Parser confused in line %ld\n",
1514 fprintf(stderr
, "Faulty strpbrk in line %lu.\n",
1520 DBP(fprintf(stderr
, "Faulty argument %u in line %lu.\n", count
+1,
1522 count
=args
; /* this will effectively quit the for loop */
1523 fF_SetError(infile
, nodef
);
1526 if (fD_ProtoNum(obj
)!=fD_RegNum(obj
))
1527 fF_SetError(infile
, nodef
);
1531 fprintf(stderr
, "fD_parsepr was fooled in line %lu\n", infile
->lineno
);
1532 fprintf(stderr
, "function , definition %s.\n",
1533 /* fD_GetName(obj),*/ infile
->line
);
1534 fF_SetError(infile
, nodef
);
1539 fD_adjustargnames(obj
);
1541 return fF_GetError(infile
);
1545 fD_cmpName(const void* big
, const void* small
) /* for qsort and bsearch */
1547 return strcmp(fD_GetName(*(fdDef
**)big
), fD_GetName(*(fdDef
**)small
));
1550 const static char *TagExcTable
[]=
1552 "BuildEasyRequestArgs", "BuildEasyRequest",
1553 "DoDTMethodA", "DoDTMethod",
1554 "DoGadgetMethodA", "DoGadgetMethod",
1555 "EasyRequestArgs", "EasyRequest",
1556 "MUI_MakeObjectA", "MUI_MakeObject",
1557 "MUI_RequestA", "MUI_Request",
1558 "PrintDTObjectA", "PrintDTObject",
1559 "RefreshDTObjectA", "RefreshDTObjects",
1560 "UMSVLog", "UMSLog",
1561 "VFWritef", "FWritef",
1562 "VFPrintf", "FPrintf",
1563 "VPrintf", "Printf",
1567 getvarargsfunction(const fdDef
* obj
)
1570 const char *name
= fD_GetName(obj
);
1572 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1574 if (strcmp(name
, TagExcTable
[count
])==0)
1576 return TagExcTable
[count
+1];
1583 taggedfunction(const fdDef
* obj
)
1585 shortcard numregs
=fD_RegNum(obj
);
1588 const char *name
=fD_GetName(obj
);
1589 static char newname
[200]; /* Hope will be enough... static because used
1590 out of the function. */
1591 const char *lastarg
;
1592 const static char *TagExcTable2
[]=
1600 "PackStructureTags",
1601 "RefreshTagItemClones",
1602 "UnpackStructureTags",
1608 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0]; count
+=2)
1609 if (strcmp(name
, TagExcTable
[count
])==0)
1611 // lcs return TagExcTable[count+1];
1613 for (count
=0; count
<sizeof TagExcTable2
/sizeof TagExcTable2
[0]; count
++)
1614 if (strcmp(name
, TagExcTable2
[count
])==0)
1617 lastarg
=fD_GetProto(obj
, numregs
-1);
1618 if (strncmp(lastarg
, "const", 5)==0 || strncmp(lastarg
, "CONST", 5)==0)
1620 while (*lastarg
==' ' || *lastarg
=='\t')
1622 if (strncmp(lastarg
, "struct", 6))
1625 while (*lastarg
==' ' || *lastarg
=='\t')
1628 if (strncmp(lastarg
, "TagItem", 7) &&
1629 (target
!=M68K_POS
|| ((aos_tagitem
=strncmp(lastarg
, "pOS_TagItem", 11))!=0)))
1631 lastarg
+=(aos_tagitem
? 7 : 11);
1632 while (*lastarg
==' ' || *lastarg
=='\t')
1634 if (strcmp(lastarg
, "*"))
1637 strcpy(newname
, name
);
1638 if (newname
[strlen(newname
)-1]=='A')
1639 newname
[strlen(newname
)-1]='\0';
1641 if (strlen(newname
)>7 && !strcmp(newname
+strlen(newname
)-7, "TagList"))
1642 strcpy(newname
+strlen(newname
)-4, "s");
1644 strcat(newname
, "Tags");
1649 aliasfunction(const char* name
)
1651 const static char *AliasTable
[]=
1653 "AllocDosObject", "AllocDosObjectTagList",
1654 "CreateNewProc", "CreateNewProcTagList",
1655 "NewLoadSeg", "NewLoadSegTagList",
1656 "System", "SystemTagList",
1659 for (count
=0; count
<sizeof AliasTable
/sizeof AliasTable
[0]; count
++)
1660 if (strcmp(name
, AliasTable
[count
])==0)
1661 return AliasTable
[count
+(count
%2 ? -1 : 1)];
1666 fD_write(FILE* outfile
, const fdDef
* obj
)
1668 shortcard count
, numregs
;
1669 const char *chtmp
, *tagname
, *varname
, *name
, *rettype
;
1670 int vd
=0, a45
=0, d7
=0;
1672 DBP(fprintf(stderr
, "func %s\n", fD_GetName(obj
)));
1674 numregs
=fD_RegNum(obj
);
1676 if ((rettype
=fD_GetType(obj
))==fD_nostring
)
1678 fprintf(stderr
, "%s has no prototype.\n", fD_GetName(obj
));
1681 if (!strcasecmp(rettype
, "void"))
1682 vd
= 1; /* set flag */
1683 for (count
=d0
; count
<numregs
; count
++)
1685 const char *reg
=fD_GetRegStr(obj
, count
);
1686 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1688 if (strcmp(reg
, "a4")==0 || strcmp(reg
, "a5")==0)
1691 a45
=(strcmp(reg
, "a4") ? 5 : 4); /* set flag */
1692 else /* Security check */
1694 fprintf(stderr
, "Warning: both a4 and a5 are used. "
1695 "This is not supported!\n");
1698 if (strcmp(reg
, "d7")==0) /* Used only when a45!=0 */
1702 if (!((output_mode
== NEW
) && (target
== PPC_POWERUP
)))
1704 if (a45
&& d7
) /* Security check */
1706 fprintf(stderr
, "Warning: d7 and a4 or a5 are used. This is not "
1710 name
=fD_GetName(obj
);
1712 if (fD_ProtoNum(obj
)!=numregs
)
1714 fprintf(stderr
, "%s gets %d fd args and %d proto%s.\n", name
, numregs
,
1715 fD_ProtoNum(obj
), fD_ProtoNum(obj
)!= 1 ? "s" : "");
1719 if (output_mode
==NEW
)
1721 fprintf(outfile
, "#define %s(", name
);
1725 for (count
=d0
; count
<numregs
-1; count
++)
1726 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
1727 fprintf(outfile
, "%s", fD_GetParam(obj
, count
));
1730 if (target
==M68K_AMIGAOS
)
1732 fprintf(outfile
, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs
,
1733 (vd
? "NR" : ""), (a45
? (a45
==4 ? "A4" : "A5") : ""),
1734 (BaseName
[0] ? "" : "UB"),
1735 (fD_GetFuncParNum(obj
)==illegal
? "" : "FP"), -fD_GetOffset(obj
));
1737 fprintf(outfile
, "%s, ", rettype
);
1738 fprintf(outfile
, "%s, ", name
);
1740 for (count
=d0
; count
<numregs
; count
++)
1742 chtmp
=fD_GetRegStr(obj
, count
);
1743 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1745 fprintf(outfile
, "%s, %s, %s%s", (fD_GetFuncParNum(obj
)==count
?
1746 "__fpt" : fD_GetProto(obj
, count
)),
1747 fD_GetParam(obj
, count
),
1748 chtmp
, (count
==numregs
-1 && !BaseName
[0] ? "" : ", "));
1751 if (BaseName
[0]) /* was "##base" used? */
1752 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1753 if (fD_GetFuncParNum(obj
)!=illegal
)
1755 fprintf(outfile
, ", ");
1756 fprintf(outfile
, fD_GetProto(obj
, fD_GetFuncParNum(obj
)), "__fpt");
1758 fprintf(outfile
, ")\n\n");
1760 else if(target
==M68K_POS
)
1762 fprintf(outfile
, ") \\\n\t__INLINE_FUN_%d(", numregs
);
1763 fprintf(outfile
, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1764 BaseNamU
, BaseNamU
, -fD_GetOffset(obj
), rettype
, name
,
1765 (numregs
? ", \\\n\t" : ""));
1767 for (count
=d0
; count
<numregs
; count
++)
1768 fprintf(outfile
, "%s, %s, %s%s", fD_GetProto(obj
, count
),
1769 fD_GetParam(obj
, count
), fD_GetRegStr(obj
, count
),
1770 (count
==numregs
-1 ? "" : ", "));
1771 fprintf(outfile
, ")\n\n");
1773 else if (target
==PPC_POWERUP
|| target
==PPC_MORPHOS
)
1775 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1778 (BaseName
[0] ? "" : "UB"),
1779 -fD_GetOffset(obj
));
1782 fprintf(outfile
, "%s, ", rettype
);
1783 fprintf(outfile
, "%s, ", name
);
1785 for (count
=d0
; count
<numregs
; count
++)
1787 chtmp
=fD_GetRegStr(obj
, count
);
1789 if (strchr(fD_GetProto(obj
, count
),'%'))
1792 fD_GetProto(obj
, count
),
1795 fprintf(outfile
, "%s, %s, %s%s",
1797 fD_GetParam(obj
, count
),
1799 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1803 fprintf(outfile
, "%s, %s, %s%s",
1804 fD_GetProto(obj
, count
),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1805 fD_GetParam(obj
, count
),
1807 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1812 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1815 * Here it would make sense to create a database file to
1816 * integrate optimizations automaticly into every new
1817 * build. Not every function needs a complete flush. For
1818 * example functions with no parameter wouldn`t need a
1819 * PPC flush normally. Or Read(File,Addr,Size); would
1820 * only need a flush for Addr with the Size
1823 fprintf(outfile
, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1824 fprintf(outfile
, ")\n\n");
1826 else if (target
==IX86BE_AMITHLON
)
1828 fprintf(outfile
, ") \\\n\tLP%d%s%s(0x%lx, ",
1831 (BaseName
[0] ? "" : "UB"),
1832 -fD_GetOffset(obj
));
1835 fprintf(outfile
, "%s, ", rettype
);
1836 fprintf(outfile
, "%s, ", name
);
1838 for (count
=d0
; count
<numregs
; count
++)
1840 chtmp
=fD_GetRegStr(obj
, count
);
1842 if (strchr(fD_GetProto(obj
, count
),'%'))
1845 fD_GetProto(obj
, count
),
1848 fprintf(outfile
, "%s, %s, %s%s",
1850 fD_GetParam(obj
, count
),
1852 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1856 fprintf(outfile
, "%s, %s, %s%s",
1857 fD_GetProto(obj
, count
),
1858 fD_GetParam(obj
, count
),
1860 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
1865 fprintf(outfile
, "\\\n\t, %s_BASE_NAME", BaseNamU
);
1867 fprintf(outfile
, ")\n\n");
1869 else if (target
==AROS
)
1871 fprintf(outfile
, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1873 (BaseName
[0] ? "" : "I"),
1874 (vd
? "void" : rettype
),
1877 for (count
=d0
; count
<numregs
; count
++)
1879 chtmp
=fD_GetRegStrU(obj
, count
);
1880 fprintf(outfile
, "\tAROS_LCA(%s, (%s), %s), \\\n",
1881 fD_GetProto(obj
, count
),
1882 fD_GetParam(obj
, count
),
1886 if (BaseName
[0]) /* was "##base" used? */
1888 fprintf(outfile
, "\tstruct %s *, %s_BASE_NAME, ", StdLib
, BaseNamU
);
1892 fprintf(outfile
, "\t/* bt */, /* bn */, ");
1895 "%ld, /* s */)\n\n",
1896 -fD_GetOffset(obj
) / 6);
1900 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
1904 else if (output_mode
==OLD
|| output_mode
==STUBS
)
1906 fprintf(outfile
, "%s__inline %s\n%s(%s",
1907 (output_mode
==STUBS
? "" : "extern "), rettype
, name
,
1908 (BaseName
[0] ? (numregs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1910 if (target
==M68K_AMIGAOS
)
1912 for (count
=d0
; count
<numregs
; count
++)
1914 chtmp
=fD_GetProto(obj
, count
);
1915 if (fD_GetFuncParNum(obj
)==count
)
1916 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1918 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+strlen(chtmp
)-1)=='*' ?
1919 "" : " "), fD_GetParam(obj
, count
));
1920 if (count
<numregs
-1)
1921 fprintf(outfile
, ", ");
1924 fprintf(outfile
, ")\n{\n%s", (BaseName
[0] ? " BASE_EXT_DECL\n" : ""));
1926 fprintf(outfile
, " register %s%sres __asm(\"d0\");\n", rettype
,
1927 (*(rettype
+strlen(rettype
)-1)=='*' ? "" : " "));
1930 fprintf(outfile
, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1933 for (count
=d0
; count
<numregs
; count
++)
1935 chtmp
=fD_GetRegStr(obj
, count
);
1936 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1938 if (fD_GetFuncParNum(obj
)==count
)
1940 fprintf(outfile
, " register ");
1941 fprintf(outfile
, fD_GetProto(obj
, count
), chtmp
);
1942 fprintf(outfile
, " __asm(\"%s\") = %s;\n", chtmp
, fD_GetParam(obj
,
1947 const char *proto
=fD_GetProto(obj
, count
);
1948 fprintf(outfile
, " register %s%s%s __asm(\"%s\") = %s;\n",
1949 proto
, (*(proto
+strlen(proto
)-1)=='*' ? "" : " "), chtmp
,
1950 chtmp
, fD_GetParam(obj
, count
));
1954 fprintf(outfile
, " __asm volatile (\"exg d7,%s\\n\\t"
1955 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45
==4 ? "a4" : "a5"),
1956 -fD_GetOffset(obj
), (a45
==4 ? "a4" : "a5"));
1958 fprintf(outfile
, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1959 -fD_GetOffset(obj
));
1961 fprintf(outfile
, (vd
? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1963 fprintf(outfile
, " : ");
1965 fprintf(outfile
, "\"r\" (a6)%s", (numregs
? ", ": ""));
1967 for (count
=d0
; count
<numregs
; count
++)
1969 chtmp
=fD_GetRegStr(obj
, count
);
1970 if (a45
&& (strcmp(chtmp
, "a4")==0 || strcmp(chtmp
, "a5")==0))
1972 fprintf(outfile
, "\"r\" (%s)%s", chtmp
, (count
<numregs
-1 ? ", " : ""));
1974 fprintf(outfile
, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1977 fprintf(outfile
, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1979 fprintf(outfile
, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1982 else if (target
==PPC_POWERUP
)
1984 for (count
= d0
; count
< numregs
; count
++)
1986 chtmp
= fD_GetProto(obj
, count
);
1987 if (fD_GetFuncParNum(obj
) == count
)
1988 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
1990 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
1991 "" : " "), fD_GetParam(obj
, count
));
1992 if (count
< numregs
- 1)
1993 fprintf(outfile
, ", ");
1996 fprintf(outfile
, ")\t\n");
1997 fprintf(outfile
, "{\t\n");
1998 fprintf(outfile
, "struct Caos\tMyCaos;\n");
1999 fprintf(outfile
, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2000 fprintf(outfile
, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
2001 fprintf(outfile
, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2002 fprintf(outfile
, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2003 fprintf(outfile
, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2004 fprintf(outfile
, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2008 for (count
= d0
; count
< numregs
; count
++)
2010 fprintf(outfile
, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2011 fD_GetRegStr(obj
, count
),
2012 fD_GetParam(obj
, count
));
2016 fprintf(outfile
, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj
));
2018 * was "##base" used?
2021 fprintf(outfile
, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2025 fprintf(outfile
, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2029 fprintf(outfile
, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2033 else if (target
==PPC_MORPHOS
)
2035 for (count
= d0
; count
< numregs
; count
++)
2037 chtmp
= fD_GetProto(obj
, count
);
2038 if (fD_GetFuncParNum(obj
) == count
)
2039 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2041 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2042 "" : " "), fD_GetParam(obj
, count
));
2043 if (count
< numregs
- 1)
2044 fprintf(outfile
, ", ");
2047 fprintf(outfile
, ")\t\n{\t\n");
2051 for (count
= d0
; count
< numregs
; count
++)
2053 fprintf(outfile
, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2054 fD_GetRegStrU(obj
, count
), fD_GetParam(obj
, count
));
2059 * was "##base" used?
2062 fprintf(outfile
, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2066 fprintf(outfile
, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj
));
2070 fprintf(outfile
, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2071 rettype
, fD_GetOffset(obj
));
2074 else if (target
==IX86BE_AMITHLON
)
2077 for (count
= d0
; count
< numregs
; count
++)
2079 chtmp
= fD_GetProto(obj
, count
);
2080 if (fD_GetFuncParNum(obj
) == count
)
2081 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2083 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2084 "" : " "), fD_GetParam(obj
, count
));
2085 if (count
< numregs
- 1)
2086 fprintf(outfile
, ", ");
2089 fprintf(outfile
, ")\n{\n");
2090 fprintf(outfile
, "\tstruct _Regs _regs;\n");
2094 for (count
= d0
; count
< numregs
; count
++)
2096 fprintf(outfile
, "\t_regs.reg_%s = (ULONG) (%s);\n",
2097 fD_GetRegStr(obj
, count
),
2098 fD_GetParam(obj
, count
));
2104 fprintf(outfile
, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2109 fprintf(outfile
, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2110 -fD_GetOffset(obj
));
2114 fprintf(outfile
, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2115 rettype
,-fD_GetOffset(obj
));
2118 for (count
= d0
; count
< numregs
; count
++)
2120 chtmp
= fD_GetProto(obj
, count
);
2121 if (fD_GetFuncParNum(obj
) == count
)
2122 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2124 fprintf(outfile
, "%s%s%s", chtmp
, (*(chtmp
+ strlen(chtmp
) - 1) == '*' ?
2125 "" : " "), fD_GetParam(obj
, count
));
2126 if (count
< numregs
- 1)
2127 fprintf(outfile
, ", ");
2130 fprintf(outfile
, ")\n{\n");
2131 fprintf(outfile
, "\t%s LP%d%s%s(0x%lx, ",
2132 (vd
? "" : "return "),
2135 (BaseName
[0] ? "" : "UB"),
2136 -fD_GetOffset(obj
));
2139 fprintf(outfile
, "%s, ", rettype
);
2140 fprintf(outfile
, "%s, ", name
);
2142 for (count
=d0
; count
<numregs
; count
++)
2144 chtmp
=fD_GetRegStr(obj
, count
);
2146 if (strchr(fD_GetProto(obj
, count
),'%'))
2149 fD_GetProto(obj
, count
),
2152 fprintf(outfile
, "%s, %s, %s%s",
2154 fD_GetParam(obj
, count
),
2156 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2160 fprintf(outfile
, "%s, %s, %s%s",
2161 fD_GetProto(obj
, count
),
2162 fD_GetParam(obj
, count
),
2164 (count
== numregs
- 1 && !BaseName
[0] ? "" : ", "));
2169 fprintf(outfile
, "\\\n\t, BASE_NAME");
2171 fprintf(outfile
, ");\n}\n\n");
2176 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2180 else if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
2182 int has_base
= (BaseName
[0] && fD_GetOffset(obj
) != 0);
2187 for (count
=d0
; count
<numregs
; count
++)
2189 if (fD_GetFuncParNum(obj
) == count
)
2191 char funcproto
[200]; /* Hope will be enough... */
2192 sprintf(funcproto
, "%s_%s_funcproto_%d",
2193 BaseNamC
, name
, count
);
2194 fprintf(outfile
, "typedef ");
2195 fprintf(outfile
, fD_GetProto(obj
, count
), funcproto
);
2196 fprintf(outfile
, ";\n");
2201 if (output_mode
==GATESTUBS
)
2203 fprintf(outfile
, "%s %s%s(",
2208 for (count
=d0
; count
<numregs
; count
++)
2210 chtmp
= fD_GetProto(obj
, count
);
2212 fprintf(outfile
, chtmp
, "");
2213 fprintf(outfile
, "%s",
2214 (count
== numregs
- 1 && !has_base
? ");\n" : ", "));
2218 fprintf(outfile
, "struct %s *);\n", StdLib
);
2221 if (target
==M68K_AMIGAOS
)
2223 fprintf(outfile
, "%s %s%s(\n",
2228 for (count
=d0
; count
<numregs
; count
++)
2230 chtmp
= fD_GetProto(obj
, count
);
2232 if (fD_GetFuncParNum(obj
) == count
)
2234 fprintf(outfile
, "\t");
2235 fprintf(outfile
, chtmp
,
2236 fD_GetParam(obj
, count
));
2237 fprintf(outfile
, " __asm(\"%s\")%s",
2238 fD_GetRegStr(obj
, count
),
2239 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2243 fprintf(outfile
, "\t%s %s __asm(\"%s\")%s",
2245 fD_GetParam(obj
, count
),
2246 fD_GetRegStr(obj
, count
),
2247 (count
== numregs
- 1 && !has_base
? ")\n" : ",\n"));
2252 fprintf(outfile
, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib
);
2254 if (output_mode
==GATESTUBS
)
2255 fprintf(outfile
, "{\n");
2257 else if (target
==AROS
)
2259 fprintf(outfile
, "AROS_LH%d%s(%s, %s%s,\n",
2261 has_base
? "" : "I",
2266 for (count
=d0
; count
<numregs
; count
++)
2268 char funcproto
[200]; /* Hope will be enough... */
2270 if (fD_GetFuncParNum(obj
) == count
)
2272 sprintf(funcproto
, "%s_%s_funcproto_%d",
2273 BaseNamC
, name
, count
);
2276 fprintf(outfile
, "\tAROS_LHA(%s, %s, %s),\n",
2277 fD_GetFuncParNum(obj
) == count
? funcproto
: fD_GetProto(obj
, count
),
2278 fD_GetParam(obj
, count
),
2279 fD_GetRegStrU(obj
, count
));
2282 fprintf(outfile
, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2284 -fD_GetOffset(obj
) / 6,
2287 if (output_mode
==GATESTUBS
)
2288 fprintf(outfile
, "{\n");
2290 else if (target
==PPC_MORPHOS
)
2292 fprintf(outfile
, "%s %s%s(void)\n",
2297 if (output_mode
==GATESTUBS
)
2299 fprintf(outfile
, "{\n");
2301 for (count
=d0
; count
<numregs
; count
++)
2303 chtmp
= fD_GetProto(obj
, count
);
2305 if (fD_GetFuncParNum(obj
) == count
)
2307 fprintf(outfile
, "\t");
2308 fprintf(outfile
, chtmp
,
2309 fD_GetParam(obj
, count
));
2310 fprintf(outfile
, " = (");
2311 fprintf(outfile
, chtmp
, "");
2312 fprintf(outfile
, ") REG_%s;\n",
2313 fD_GetRegStrU(obj
, count
));
2317 fprintf(outfile
, "\t%s %s = (%s) REG_%s;\n",
2318 fD_GetProto(obj
, count
),
2319 fD_GetParam(obj
, count
),
2320 fD_GetProto(obj
, count
),
2321 fD_GetRegStrU(obj
, count
));
2327 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2330 fprintf(outfile
, "\n");
2333 else if (target
==IX86BE_AMITHLON
)
2335 fprintf(outfile
, "%s %s%s( struct _Regs _regs )\n",
2340 if (output_mode
==GATESTUBS
)
2342 fprintf(outfile
, "{\n");
2344 for (count
=d0
; count
<numregs
; count
++)
2346 chtmp
= fD_GetProto(obj
, count
);
2348 if (fD_GetFuncParNum(obj
) == count
)
2350 fprintf(outfile
, "\t");
2351 fprintf(outfile
, chtmp
,
2352 fD_GetParam(obj
, count
));
2353 fprintf(outfile
, " = (");
2354 fprintf(outfile
, chtmp
, "");
2355 fprintf(outfile
, ") _regs.%s;\n",
2356 fD_GetRegStr(obj
, count
));
2360 fprintf(outfile
, "\t%s %s = (%s) _regs.%s;\n",
2361 fD_GetProto(obj
, count
),
2362 fD_GetParam(obj
, count
),
2363 fD_GetProto(obj
, count
),
2364 fD_GetRegStr(obj
, count
));
2370 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2373 fprintf(outfile
, "\n");
2378 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2382 if (output_mode
==GATESTUBS
)
2384 fprintf(outfile
,"\treturn %s%s(",
2388 for (count
=d0
; count
<numregs
; count
++)
2390 fprintf(outfile
, "%s%s",
2391 fD_GetParam(obj
, count
),
2392 (count
== numregs
- 1 && !has_base
? ");" : ", "));
2396 fprintf(outfile
, "BASE_NAME);");
2398 fprintf(outfile
,"\n}\n\n");
2402 fprintf(outfile
,";\n");
2406 fprintf(outfile
, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2409 BaseNamC
,fD_GetOffset(obj
));
2412 fprintf(outfile
,"\n");
2417 fprintf(stderr
, "Internal error: Unknown output mode in fD_write().\n");
2421 if ((tagname
=aliasfunction(fD_GetName(obj
)))!=0 &&
2422 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2424 fprintf(outfile
, "#define %s(", tagname
);
2425 for (count
=d0
; count
<numregs
-1; count
++)
2426 fprintf(outfile
, "a%d, ", count
);
2427 fprintf(outfile
, "a%d) %s (", count
, name
);
2428 for (count
=d0
; count
<numregs
-1; count
++)
2429 fprintf(outfile
, "(a%d), ", count
);
2430 fprintf(outfile
, "(a%d))\n\n", count
);
2433 if ((tagname
=taggedfunction(obj
))!=0 &&
2434 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2436 if (output_mode
!=STUBS
)
2439 "#ifndef %sNO_INLINE_STDARG\n"
2441 (target
==M68K_POS
? "__" : ""),
2444 for (count
=d0
; count
<numregs
-1; count
++)
2445 fprintf(outfile
, "a%d, ", count
);
2447 fprintf(outfile
, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2450 for (count
=d0
; count
<numregs
-1; count
++)
2451 fprintf(outfile
, "(a%d), ", count
);
2453 fprintf(outfile
, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2454 fD_GetProto(obj
, fD_RegNum(obj
)-1),
2455 (target
==M68K_POS
? "__" : ""));
2460 if (target
==M68K_AMIGAOS
|| target
==IX86BE_AMITHLON
)
2462 fprintf(outfile
, "__inline %s\n%s(", rettype
, tagname
);
2464 for (count
=d0
; count
<numregs
-1; count
++)
2466 chtmp
=fD_GetProto(obj
, count
);
2467 if (count
==fD_GetFuncParNum(obj
))
2468 fprintf(outfile
, chtmp
, fD_GetParam(obj
, count
));
2470 fprintf(outfile
, "%s%s%s", chtmp
,
2471 (*(chtmp
+strlen(chtmp
)-1)=='*' ? "" : " "),
2472 fD_GetParam(obj
, count
));
2473 fprintf(outfile
, ", ");
2476 fprintf(outfile
, "int tag, ...)\n{\n ");
2478 fprintf(outfile
, "return ");
2480 fprintf(outfile
, "%s(", name
);
2481 for (count
=d0
; count
<numregs
-1; count
++)
2482 fprintf(outfile
, "%s, ", fD_GetParam(obj
, count
));
2484 fprintf(outfile
, "(%s)&tag);\n}\n\n", fD_GetProto(obj
, fD_RegNum(obj
)-1));
2486 else if (target
==PPC_MORPHOS
)
2488 int n
= 9 - numregs
; /* number of regs that contain varargs */
2489 int d
= n
& 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2490 int taglist
= 8; /* offset of the start of the taglist */
2491 int local
= (taglist
+ n
* 4 + d
+ 8 + 15) & ~15; /* size of the stack frame */
2496 * 0 - 3: next frame ptr
2498 * 8 - 8+n*4+d+8-1: tag list start
2499 * ? - local-1: padding
2506 " .type %s,@function\n"
2508 " stwu 1,-%d(1) \n" /* create stack frame */
2511 tagname
, tagname
, tagname
, local
, local
+ 4);
2514 * If n is odd, one tag is split between regs and stack.
2515 * Copy its ti_Data together with the ti_Tag.
2518 fprintf(outfile
, " lwz 0,%d(1)\n", local
+ 8); /* read ti_Data */
2520 * Save the registers
2522 for (count
= numregs
; count
<= 8; count
++)
2523 fprintf(outfile
, " stw %d,%d(1)\n", count
+ 2, (count
- numregs
) * 4 + taglist
);
2526 fprintf(outfile
, " stw 0,%d(1)\n", taglist
+ n
* 4); /* write ti_Data */
2531 fprintf(outfile
, " li 11,2 \n"
2533 " stw 11,%d(1) \n" /* add TAG_MORE */
2534 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2536 taglist
+ n
* 4 + d
,
2537 taglist
+ n
* 4 + d
+ 4);
2540 if (DirectVarargsCalls
)
2543 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2545 numregs
+ 2, taglist
, name
);
2550 * Save the non-varargs registers in the EmulHandle struct.
2552 for (count
= 0; count
< numregs
- 1; count
++)
2554 int r
= fD_GetReg(obj
, count
);
2556 fprintf(outfile
, " stw %d,%d(2)\n", count
+ 3, r
* 4);
2562 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2563 " stw 0,%d(2) \n" /* REG_?? = taglist */
2565 " lwz 12,%s@l(12)\n"
2566 " li 3,%ld \n" /* r3 = lvo */
2567 " stw 12,56(2) \n" /* REG_A6 = libbase */
2568 " bctrl \n",/* EmulCallOS() */
2569 BaseName
, taglist
, 4 * fD_GetReg(obj
, numregs
- 1), BaseName
,
2573 fprintf(outfile
," lwz 0,%d(1) \n" /* clear stack frame & return */
2578 " .size\t%s,.L%se1-%s\n"
2581 tagname
, tagname
, tagname
, tagname
);
2585 fprintf(stderr
, "Internal error: Unknown target in fD_write().\n");
2590 else if ((varname
= getvarargsfunction(obj
)) != 0 &&
2591 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2593 if (output_mode
!= STUBS
)
2596 "#ifndef NO_INLINE_VARARGS\n"
2597 "#define %s(", varname
);
2599 for (count
= d0
; count
< numregs
- 1; count
++)
2600 fprintf(outfile
, "a%d, ", count
);
2604 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2607 for (count
= d0
; count
< numregs
- 1; count
++)
2608 fprintf(outfile
, "(a%d), ", count
);
2612 "#endif /* !NO_INLINE_VARARGS */\n\n",
2613 fD_GetProto(obj
, fD_RegNum(obj
) - 1));
2617 fprintf(stderr
, "can`t create a varargs stub function for %s\n",
2622 if (strcmp(name
, "DoPkt")==0 &&
2623 output_mode
!=GATESTUBS
&& output_mode
!=GATEPROTO
)
2625 fdDef
*objnc
=(fdDef
*)obj
;
2626 char newname
[7]="DoPkt0";
2627 objnc
->name
=newname
;
2628 for (count
=2; count
<7; count
++)
2630 regs reg
=objnc
->reg
[count
];
2631 char *proto
=objnc
->proto
[count
];
2632 objnc
->reg
[count
]=illegal
;
2633 objnc
->proto
[count
]=fD_nostring
;
2634 fD_write(outfile
, objnc
);
2635 objnc
->reg
[count
]=reg
;
2636 objnc
->proto
[count
]=proto
;
2639 objnc
->name
=(char*)name
;
2644 varargsfunction(const char* proto
, const char* funcname
)
2646 const char *end
=proto
+strlen(proto
)-1;
2647 while (isspace(*end
))
2651 while (isspace(*end
))
2655 while (isspace(*end
))
2657 if (!strncmp(end
-2, "...", 3))
2659 /* Seems to be a varargs function. Check if it will be recognized
2662 char fixedname
[200]; /* Hope will be enough... */
2665 for (count
=0; count
<sizeof TagExcTable
/sizeof TagExcTable
[0];
2667 if (strcmp(funcname
, TagExcTable
[count
+1])==0)
2670 if (!(tmpdef
=fD_ctor()))
2672 fprintf(stderr
, "No mem for FDs\n");
2676 strcpy(fixedname
, funcname
);
2677 if (strlen(funcname
)>4 &&
2678 !strcmp(funcname
+strlen(funcname
)-4, "Tags"))
2680 /* Might be either nothing or "TagList". */
2681 fixedname
[strlen(fixedname
)-4]='\0';
2682 fD_NewName(tmpdef
, fixedname
);
2683 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2687 strcat(fixedname
, "TagList");
2688 fD_NewName(tmpdef
, fixedname
);
2689 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2695 strcat(fixedname
, "A");
2696 fD_NewName(tmpdef
, fixedname
);
2697 if (bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
2708 ishandleddifferently(const char* proto
, const char* funcname
)
2710 /* First check if this is a vararg call? */
2711 if (varargsfunction(proto
, funcname
))
2714 /* It might be a dos.library "alias" name. */
2715 if (aliasfunction(funcname
))
2718 /* It might be one from dos.library/DoPkt() family. */
2719 if (strlen(funcname
)==6 && !strncmp(funcname
, "DoPkt", 5) &&
2720 funcname
[5]>='0' && funcname
[6]<='4')
2723 /* Finally, it can be intuition.library/ReportMouse1(). */
2724 return !strcmp(funcname
, "ReportMouse1");
2728 printusage(const char* exename
)
2731 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2734 "--mode=MODE\t\tMODE is one of the following:\n"
2735 "\tnew\t\t\tPreprocessor based (default)\n"
2736 "\told\t\t\tInline based\n"
2737 "\tstubs\t\t\tLibrary stubs\n"
2738 "\tgatestubs\t\tLibrary gate stubs\n"
2739 "\tgateproto\t\tLibrary gate prototypes\n"
2740 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2742 "--target=OS\t\tOS is one of the following: \n"
2743 "\t*-aros\t\t\tAROS (any CPU)\n"
2744 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2745 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2746 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2747 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2748 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2750 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2751 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2752 "--libprefix=PREFIX\tLocal function name prefix\n"
2753 "--local\t\t\tUse local includes\n"
2754 "--quiet\t\t\tDon't display warnings\n"
2755 "--version\t\tPrint version number and exit\n\n"
2756 "Compatibility options:\n"
2757 "--new\t\t\tSame as --mode=new\n"
2758 "--old\t\t\tSame as --mode=old\n"
2759 "--stubs\t\t\tSame as --mode=stubs\n"
2760 "--gatestubs\t\tSame as --mode=gatestubs\n"
2761 "--proto\t\t\tSame as --mode=prot\n"
2762 "--pos\t\t\tSame as --target=m68k-pos\n"
2763 "--morphos\t\tSame as --target=powerpc-morphos\n"
2764 "--powerup\t\tSame as --target=powerpc-powerup\n"
2768 void output_proto(FILE* outfile
)
2771 "/* Automatically generated header! Do not edit! */\n\n"
2772 "#ifndef PROTO_%s_H\n"
2773 "#define PROTO_%s_H\n\n",
2774 BaseNamU
, BaseNamU
);
2778 "#ifndef __NOLIBBASE__\n"
2779 "extern struct %s *\n"
2780 "#ifdef __CONSTLIBBASEDECL__\n"
2781 "__CONSTLIBBASEDECL__\n"
2782 "#endif /* __CONSTLIBBASEDECL__ */\n"
2784 "#endif /* !__NOLIBBASE__ */\n\n",
2788 "#ifdef __amigaos4__\n"
2789 "#include <interfaces/%s.h>\n"
2790 "#ifdef __USE_INLINE__\n"
2791 "#include <inline4/%s.h>\n"
2792 "#endif /* __USE_INLINE__ */\n"
2793 "#ifndef CLIB_%s_PROTOS_H\n"
2794 "#define CLIB_%s_PROTOS_H\n"
2795 "#endif /* CLIB_%s_PROTOS_H */\n"
2796 "#ifndef __NOGLOBALIFACE__\n"
2797 "extern struct %sIFace *I%s;\n"
2798 "#endif /* __NOGLOBALIFACE__ */\n"
2799 "#else /* __amigaos4__ */\n"
2800 "#include <clib/%s_protos.h>\n"
2803 "#ifndef NOLIBDEFINES\n"
2804 "#ifndef %s_NOLIBDEFINES\n"
2805 "#include <defines/%s.h>\n"
2806 "#endif /* %s_NOLIBDEFINES */\n"
2807 "#endif /* NOLIBDEFINES */\n"
2810 "#ifndef _NO_PPCINLINE\n"
2811 "#include <ppcinline/%s.h>\n"
2812 "#endif /* _NO_PPCINLINE */\n"
2814 "#ifndef _NO_INLINE\n"
2815 "#include <inline/%s.h>\n"
2816 "#endif /* _NO_INLINE */\n"
2817 "#endif /* __PPC__ */\n"
2818 "#endif /* __AROS__ */\n"
2820 "#include <pragmas/%s_pragmas.h>\n"
2821 "#endif /* __GNUC__ */\n"
2822 "#endif /* __amigaos4__ */\n\n"
2823 "#endif /* !PROTO_%s_H */\n",
2824 BaseNamL
, BaseNamL
, BaseNamU
, BaseNamU
, BaseNamU
, BaseNamC
, BaseNamC
,
2826 BaseNamU
, BaseNamL
, BaseNamU
,
2827 BaseNamL
, BaseNamL
, BaseNamL
,
2831 /******************************************************************************/
2834 main(int argc
, char** argv
)
2836 fdDef
*tmpdef
, /* a dummy to contain the name to look for */
2837 *founddef
; /* the fdDef for which we found a prototype */
2842 char *fdfilename
=0, *clibfilename
=0, *outfilename
=0;
2847 for (count
=1; count
<argc
; count
++)
2849 char *option
=argv
[count
];
2853 if (strcmp(option
, "o")==0)
2855 if (count
==argc
-1 || outfilename
)
2857 printusage(argv
[0]);
2858 return EXIT_FAILURE
;
2860 if (strcmp(argv
[++count
], "-"))
2861 outfilename
=argv
[count
];
2865 if (*option
=='-') /* Accept GNU-style '--' options */
2867 if (strncmp(option
, "mode=", 5)==0)
2869 if (strcmp(option
+5, "new")==0)
2871 else if (strcmp(option
+5, "old")==0)
2873 else if (strcmp(option
+5, "stubs")==0)
2875 else if (strcmp(option
+5, "gatestubs")==0)
2876 output_mode
=GATESTUBS
;
2877 else if (strcmp(option
+5, "gateproto")==0)
2878 output_mode
=GATEPROTO
;
2879 else if (strcmp(option
+5, "proto")==0)
2882 else if (strncmp(option
, "target=", 7)==0)
2884 if (MatchGlob("*-aros",option
+7))
2886 else if (MatchGlob("i?86be*-amithlon",option
+7))
2887 target
=IX86BE_AMITHLON
;
2888 else if (MatchGlob("m68k*-amigaos",option
+7))
2889 target
=M68K_AMIGAOS
;
2890 else if (MatchGlob("m68k*-pos",option
+7))
2892 else if (MatchGlob("powerpc*-powerup",option
+7))
2894 else if (MatchGlob("powerpc*-morphos",option
+7))
2898 printusage(argv
[0]);
2899 return EXIT_FAILURE
;
2902 else if (strcmp(option
, "direct-varargs-calls") == 0)
2903 DirectVarargsCalls
= 1;
2904 else if (strncmp(option
, "gateprefix=", 11)==0)
2905 gateprefix
= option
+11;
2906 else if (strncmp(option
, "libprefix=", 10)==0)
2907 libprefix
= option
+10;
2908 else if (strcmp(option
, "quiet") == 0)
2910 else if (strcmp(option
, "version")==0)
2912 fprintf(stderr
, "fd2inline version " VERSION
"\n");
2913 return EXIT_SUCCESS
;
2915 /* Compatibility options */
2916 else if (strcmp(option
, "new")==0)
2918 else if (strcmp(option
, "old")==0)
2920 else if (strcmp(option
, "stubs")==0)
2922 else if (strcmp(option
, "gatestubs")==0)
2923 output_mode
=GATESTUBS
;
2924 else if (strcmp(option
, "proto")==0)
2926 else if (strcmp(option
, "pos")==0)
2928 else if (strcmp(option
, "powerup")==0)
2930 else if (strcmp(option
, "morphos")==0)
2932 /* Unknown option */
2935 printusage(argv
[0]);
2936 return EXIT_FAILURE
;
2942 /* One of the filenames */
2945 else if (!clibfilename
)
2946 clibfilename
=option
;
2947 else if (!outfilename
)
2951 printusage(argv
[0]);
2952 return EXIT_FAILURE
;
2957 if (!fdfilename
|| (!clibfilename
&& output_mode
!=PROTO
))
2959 printusage(argv
[0]);
2960 return EXIT_FAILURE
;
2963 if (target
==M68K_POS
&& output_mode
!=NEW
)
2965 fprintf(stderr
, "Target is not compatible with the mode.\n");
2966 return EXIT_FAILURE
;
2969 if (!(arrdefs
=malloc(FDS
*sizeof(fdDef
*))))
2971 fprintf(stderr
, "No mem for FDs\n");
2972 return EXIT_FAILURE
;
2974 for (count
=0; count
<FDS
; count
++)
2975 arrdefs
[count
]=NULL
;
2977 if (!(myfile
=fF_ctor(fdfilename
)))
2979 fprintf(stderr
, "Couldn't open file '%s'.\n", fdfilename
);
2980 return EXIT_FAILURE
;
2985 for (count
=0; count
<FDS
&& lerror
==false; count
++)
2987 if (!(arrdefs
[count
]=fD_ctor()))
2989 fprintf(stderr
, "No mem for FDs\n" );
2990 return EXIT_FAILURE
;
2994 if ((lerror
=fF_readln(myfile
))==false)
2996 fF_SetError(myfile
, false);
2997 lerror
=fD_parsefd(arrdefs
[count
], myfile
);
3000 while (lerror
==nodef
);
3005 fD_dtor(arrdefs
[count
]);
3006 arrdefs
[count
]=NULL
;
3010 qsort(arrdefs
, count
, sizeof arrdefs
[0], fD_cmpName
);
3012 if (output_mode
!=NEW
|| target
==AROS
)
3014 unsigned int count2
;
3017 for (count2
=0; count2
<sizeof LibExcTable
/sizeof LibExcTable
[0]; count2
+=2)
3018 if (strcmp(BaseName
, LibExcTable
[count2
])==0)
3020 StdLib
=LibExcTable
[count2
+1];
3027 if (output_mode
!=PROTO
)
3029 if (!(myfile
=fF_ctor(clibfilename
)))
3031 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3032 return EXIT_FAILURE
;
3035 if (!(tmpdef
=fD_ctor()))
3037 fprintf(stderr
, "No mem for FDs\n");
3038 return EXIT_FAILURE
;
3041 for (lerror
=false; lerror
==false || lerror
==nodef
;)
3042 if ((lerror
=fF_readln(myfile
))==false)
3044 fF_SetError(myfile
, false); /* continue even on errors */
3045 tmpstr
=fF_FuncName(myfile
);
3050 fD_NewName(tmpdef
, tmpstr
);
3051 res
=(fdDef
**)bsearch(&tmpdef
, arrdefs
, fds
, sizeof arrdefs
[0],
3057 DBP(fprintf(stderr
, "found (%s).\n", fD_GetName(founddef
)));
3058 fF_SetError(myfile
, false);
3059 lerror
=fD_parsepr(founddef
, myfile
);
3062 if (!ishandleddifferently(myfile
->line
, tmpstr
))
3064 fprintf(stderr
, "Don't know what to do with <%s> in line %lu.\n",
3065 tmpstr
, myfile
->lineno
);
3075 if (strlen(fdfilename
)>7 &&
3076 !strcmp(fdfilename
+strlen(fdfilename
)-7, "_lib.fd"))
3078 char *str
=fdfilename
+strlen(fdfilename
)-8;
3079 while (str
!=fdfilename
&& str
[-1]!='/' && str
[-1]!=':')
3081 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3082 strncpy(BaseNamU
, str
, strlen(str
)-7);
3083 BaseNamU
[strlen(str
)-7]='\0';
3084 strcpy(BaseNamL
, BaseNamU
);
3085 strcpy(BaseNamC
, BaseNamU
);
3089 strcpy(BaseNamU
, BaseName
);
3090 if (strlen(BaseNamU
)>4 && strcmp(BaseNamU
+strlen(BaseNamU
)-4, "Base")==0)
3091 BaseNamU
[strlen(BaseNamU
)-4]='\0';
3092 if (target
==M68K_POS
&& strncmp(BaseNamU
, "gb_", 3)==0)
3093 memmove(BaseNamU
, &BaseNamU
[3], strlen(&BaseNamU
[3])+1);
3094 strcpy(BaseNamL
, BaseNamU
);
3095 strcpy(BaseNamC
, BaseNamU
);
3098 BaseNamC
[0]=toupper(BaseNamC
[0]);
3102 if (!(outfile
=fopen(outfilename
, "w")))
3104 fprintf(stderr
, "Couldn't open output file.\n");
3105 return EXIT_FAILURE
;
3115 if (output_mode
==PROTO
)
3116 output_proto(outfile
);
3119 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
||
3120 output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3122 if (output_mode
==GATESTUBS
|| output_mode
==GATEPROTO
)
3125 "/* Automatically generated stubs! Do not edit! */\n\n");
3130 "/* Automatically generated header! Do not edit! */\n\n"
3131 "#ifndef %sINLINE_%s_H\n"
3132 "#define %sINLINE_%s_H\n\n",
3133 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3135 (target
==M68K_POS
? "__INC_POS_P" : "_"),
3139 if (output_mode
==NEW
)
3141 if(target
==M68K_POS
)
3144 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3145 "#include <pInline/macros.h>\n"
3146 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3148 else if(target
==AROS
)
3151 "#ifndef AROS_LIBCALL_H\n"
3152 "#include <aros/libcall.h>\n"
3153 "#endif /* !AROS_LIBCALL_H */\n\n");
3158 "#ifndef __INLINE_MACROS_H\n"
3159 "#include <inline/macros.h>\n"
3160 "#endif /* !__INLINE_MACROS_H */\n\n");
3168 "#ifndef __INLINE_STUB_H\n"
3169 "#include <inline/stubs.h>\n"
3170 "#endif /* !__INLINE_STUB_H */\n\n");
3172 fprintf(outfile
, "#ifdef __CLIB_TYPES__\n" );
3174 clib
= fopen( clibfilename
, "r" );
3178 fprintf(stderr
, "Couldn't open file '%s'.\n", clibfilename
);
3182 char* buffer
= malloc( 1024 );
3184 if( buffer
== NULL
)
3186 fprintf(stderr
, "No memory for line buffer.\n " );
3190 while( fgets( buffer
, 1023, clib
) != NULL
)
3192 if( buffer
[ 0 ] == '#' /* Pre-processor instruction */ ||
3193 strncmp( buffer
, "typedef", 7 ) == 0 )
3195 fputs(buffer
, outfile
);
3205 fprintf(outfile
, "#endif /* __CLIB_TYPES__ */\n\n" );
3210 "#include <aros/libcall.h>\n\n" );
3212 else if(target
==IX86BE_AMITHLON
)
3215 "#ifndef __INLINE_MACROS_H\n"
3216 "#include <inline/macros.h>\n"
3217 "#endif /* __INLINE_MACROS_H */\n\n");
3219 else if (target
== PPC_MORPHOS
)
3222 "#include <emul/emulregs.h>\n\n" );
3228 fprintf(stderr
, "Internal error: Unknown output mode in main().\n");
3235 return EXIT_FAILURE
;
3240 if (output_mode
==NEW
)
3243 "#ifndef %s%s_BASE_NAME\n"
3244 "#define %s%s_BASE_NAME %s\n"
3245 "#endif /* !%s%s_BASE_NAME */\n\n",
3246 (target
==M68K_POS
? "__" : ""), BaseNamU
,
3247 (target
==M68K_POS
? "__" : ""), BaseNamU
, BaseName
,
3248 (target
==M68K_POS
? "__" : ""), BaseNamU
);
3249 if (target
==M68K_POS
)
3251 "#ifndef __%s_LIB_NAME\n"
3252 "#define __%s_LIB_NAME %s\n"
3253 "#endif /* !__%s_LIB_NAME */\n\n",
3255 (strcmp(BaseName
, "gb_ExecBase") ? BaseName
: "gb_ExecLib"),
3260 "#ifndef BASE_EXT_DECL\n"
3261 "#define BASE_EXT_DECL\n"
3262 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3263 "#endif /* !BASE_EXT_DECL */\n"
3264 "#ifndef BASE_PAR_DECL\n"
3265 "#define BASE_PAR_DECL\n"
3266 "#define BASE_PAR_DECL0 void\n"
3267 "#endif /* !BASE_PAR_DECL */\n"
3268 "#ifndef BASE_NAME\n"
3269 "#define BASE_NAME %s\n"
3270 "#endif /* !BASE_NAME */\n\n"
3271 "BASE_EXT_DECL0\n\n", StdLib
, BaseName
, BaseName
);
3274 for (count
=0; count
<FDS
&& arrdefs
[count
]; count
++)
3276 DBP(fprintf(stderr
, "outputting %ld...\n", count
));
3278 fD_write(outfile
, arrdefs
[count
]);
3279 fD_dtor(arrdefs
[count
]);
3280 arrdefs
[count
]=NULL
;
3283 if (output_mode
!=NEW
)
3286 "#undef BASE_EXT_DECL\n"
3287 "#undef BASE_EXT_DECL0\n"
3288 "#undef BASE_PAR_DECL\n"
3289 "#undef BASE_PAR_DECL0\n"
3290 "#undef BASE_NAME\n\n");
3292 if (output_mode
==NEW
|| output_mode
==OLD
|| output_mode
==STUBS
)
3294 fprintf(outfile
, "#endif /* !%sINLINE_%s_H */\n",
3295 (target
==M68K_POS
? "__INC_POS_P" : "_"), BaseNamU
);
3306 return EXIT_SUCCESS
;