Indentation fix, cleanup.
[AROS.git] / tools / fd2inline / fd2inline.c
blobfddccc2b5919d28e7bf8bcc8da6fd07938978738
1 /******************************************************************************
3 * fd2inline
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 *****************************************************************************/
28 #include <ctype.h>
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
34 /******************************************************************************
35 * The program has a few sort of class definitions, which are the result of
36 * object oriented thinking, to be imlemented in plain C. I just haven't
37 * had the time to learn C++ or install the compiler. The design does however
38 * improve robustness, which allows the source to be used over and over again.
39 * if you use this code, please leave a little origin note.
40 ******************************************************************************/
42 #if defined(__AROS__)
43 const static char version_str[]="$VER: fd2inline " VERSION " (24.2.2002)";
44 #endif
46 /******************************************************************************
47 * These are general definitions including types for defining registers etc.
48 ******************************************************************************/
50 #ifdef DEBUG
51 #define DBP(a) a
52 #else /* !DEBUG */
53 #define DBP(a)
54 #endif /* !DEBUG */
56 #if (defined(__GNUC__) || defined(__SASC)) && 0
57 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
58 #else
59 #define INLINE
60 #endif
62 #define REGS 16 /* d0=0,...,a7=15 */
63 #define FDS 1000
65 /* To prevent the enum below from getting broken when building on AROS */
66 #undef AROS
68 typedef enum
70 d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
71 } regs;
73 typedef unsigned char shortcard;
75 typedef enum { false, nodef, real_error } Error;
77 enum { NEW, OLD, STUBS, PROTO, GATESTUBS, GATEPROTO, GENMODULE } output_mode=NEW;
78 enum { IX86BE_AMITHLON, AROS, M68K_AMIGAOS, M68K_POS, PPC_POWERUP, PPC_MORPHOS } target = M68K_AMIGAOS;
80 int Quiet = 0;
81 int DirectVarargsCalls = 0;
82 int RegLibFlag = 0;
83 int PreLibFlag = 0;
84 int PostLibFlag = 0;
85 char *gateprefix = "";
86 char *libprefix = "";
88 char BaseName[64], BaseNamU[64], BaseNamL[64], BaseNamC[64];
89 char Buffer[512];
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",
108 "MiscBase", "Node",
109 "PotgoBase", "Node",
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 *******************************************/
122 char*
123 NewString(char** new, const char* old)
125 const char *high;
126 unsigned long len;
128 while (*old && (*old==' ' || *old=='\t'))
129 old++;
130 len=strlen(old);
131 for (high=old+len-1; high>=old && (*high==' ' || *high=='\t'); high--);
132 high++;
133 len=high-old;
134 *new=malloc(1+len);
135 if (*new)
137 strncpy(*new, old, len);
138 (*new)[len]='\0';
140 else
141 fprintf(stderr, "No mem for string\n");
142 return *new;
145 static INLINE void
146 illparams(const char* funcname)
148 fprintf(stderr, "%s: illegal Parameters\n", funcname);
151 static INLINE const char*
152 RegStr(regs reg)
154 const static char *aosregs[]=
156 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
157 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
159 *posregs[]=
161 "__INLINE_REG_D0",
162 "__INLINE_REG_D1",
163 "__INLINE_REG_D2",
164 "__INLINE_REG_D3",
165 "__INLINE_REG_D4",
166 "__INLINE_REG_D5",
167 "__INLINE_REG_D6",
168 "__INLINE_REG_D7",
169 "__INLINE_REG_A0",
170 "__INLINE_REG_A1",
171 "__INLINE_REG_A2",
172 "__INLINE_REG_A3",
173 "__INLINE_REG_A4",
174 "__INLINE_REG_A5",
175 "__INLINE_REG_A6",
176 "__INLINE_REG_A7",
177 "illegal"
180 if (reg>illegal)
181 reg=illegal;
182 if (reg<d0)
183 reg=d0;
184 return (target!=M68K_POS ? aosregs[reg] : posregs[reg]);
187 static INLINE const char*
188 RegStrU(regs reg)
190 const static char *aosregs[]=
192 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
193 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
196 if (reg>illegal)
197 reg=illegal;
198 if (reg<d0)
199 reg=d0;
200 return (target!=M68K_POS ? aosregs[reg] : RegStr(reg));
203 static INLINE
205 /******************************************************************************
206 * StrNRBrk
208 * searches string in from position at downwards, as long as in does not
209 * contain any character in not.
211 ******************************************************************************/
213 const char*
214 StrNRBrk(const char* in, const char* not, const char* at)
216 const char *chcheck;
217 Error ready;
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++);
223 if (*chcheck)
224 ready=real_error;
225 else
226 at--;
228 DBP(fprintf(stderr, "{%c}", *chcheck));
229 return *chcheck ? at : NULL;
233 Our own "strupr", since it is a non-standard function.
235 void
236 StrUpr(char* str)
238 while (*str)
240 *str=toupper(*str);
241 str++;
246 MatchGlob( char* glob, char* str )
248 while( *glob )
250 char c = *glob++;
252 switch( c )
254 case '?':
255 if( *str == 0 )
257 return 0;
259 break;
261 case '\\':
262 c = *glob++;
263 if( c == 0 || *str != c )
265 return 0;
267 break;
269 case '*':
270 if( *glob == 0 )
272 return 1;
275 while( *str )
277 if( MatchGlob( glob, str ) )
279 return 1;
281 ++str;
283 return 0;
285 default:
286 if( *str != c )
288 return 0;
290 break;
293 ++str;
296 return *str == 0;
300 /******************************************************************************
301 * CLASS fdFile
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;
317 typedef struct
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) */
325 } fdFile;
327 fdFile*
328 fF_ctor (const char* fname);
329 static void
330 fF_dtor (fdFile* obj);
331 static void
332 fF_SetError (fdFile* obj, Error error);
333 static void
334 fF_SetOffset (fdFile* obj, long at);
335 Error
336 fF_readln (fdFile* obj);
337 static Error
338 fF_GetError (const fdFile* obj);
339 static long
340 fF_GetOffset (const fdFile* obj);
341 char*
342 fF_FuncName (fdFile* obj); /* return name or null */
343 static void
344 fF_SetFlags (fdFile* obj, fdflags flags);
345 static fdflags
346 fF_GetFlags (const fdFile* obj);
348 static INLINE void
349 fF_dtor(fdFile* obj)
351 fclose(obj->file);
352 free(obj);
355 static INLINE void
356 fF_SetError(fdFile* obj, Error error)
358 if (obj)
359 obj->error=error;
360 else
361 illparams("fF_SetError");
364 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
366 static INLINE void
367 fF_SetOffset(fdFile* obj, long at)
369 if (obj)
370 obj->offset= at;
371 else
372 illparams("fFSetOffset");
375 static INLINE void
376 fF_SetFlags(fdFile* obj, fdflags flags)
378 if (obj)
379 obj->flags=flags;
380 else
381 illparams("fF_SetFlags");
384 fdFile*
385 fF_ctor(const char* fname)
387 fdFile *result;
389 if (fname)
391 result=malloc(sizeof(fdFile));
392 if (result)
394 result->file=fopen(fname, "r");
395 if (result->file)
397 result->lineno=0;
398 fF_SetOffset(result, -30);
399 fF_SetError(result, false);
400 fF_SetFlags(result, 0);
401 result->line[0]='\0';
403 else
405 free(result);
406 result=NULL;
410 else
412 result=NULL;
413 illparams("fF_ctor");
415 return result;
418 Error
419 fF_readln(fdFile* obj)
421 char *low, *bpoint;
422 long glen, /* the length we read until now */
423 len; /* the length of the last segment */
425 if (obj)
427 low=obj->line;
428 glen=0;
430 for (;;)
432 obj->lineno++;
433 if (!fgets(low, fF_BUFSIZE-1-glen, obj->file))
435 fF_SetError(obj, real_error);
436 obj->line[0]='\0';
437 return real_error;
439 if (*low == ' ' && *(low+1) == '*')
440 return false;
441 if (low==strpbrk(low, "*#/"))
443 DBP(fprintf(stderr, "in# %s\n", obj->line));
444 return false;
446 len=strlen(low);
447 bpoint=low+len-1;
448 while (len && isspace(*bpoint))
450 bpoint--;
451 len--;
453 if (*bpoint==';' || *bpoint==')')
455 DBP(fprintf(stderr, "\nin: %s\n", obj->line));
456 return false;
458 glen+=len;
459 low+=len;
460 if (glen>=fF_BUFSIZE-10) /* somewhat pessimistic? */
462 fF_SetError(obj, real_error);
463 fprintf(stderr, "Line %lu too long.\n", obj->lineno);
464 return real_error;
466 DBP(fprintf(stderr, "+"));
469 illparams("fF_readln");
470 return real_error;
473 static INLINE Error
474 fF_GetError(const fdFile* obj)
476 if (obj)
477 return obj->error;
478 illparams("fF_GetError");
479 return real_error;
482 static INLINE long
483 fF_GetOffset(const fdFile* obj)
485 if (obj)
486 return obj->offset;
487 illparams("fF_GetOffset");
488 return -1;
491 /******************************************************************************
492 * fF_FuncName
494 * checks if it can find a function-name and return it's address, or NULL
495 * if the current line does not seem to contain one. The return value will
496 * be a pointer into a malloced buffer, thus the caller will have to free().
497 ******************************************************************************/
499 char*
500 fF_FuncName(fdFile* obj)
502 const char *lower;
503 const char *upper;
504 char *buf;
505 long obraces; /* count of open braces */
506 Error ready; /* ready with searching */
508 if (!obj || fF_GetError(obj)==real_error)
510 illparams("fF_FuncName");
511 return NULL;
514 lower=obj->line;
515 while (*lower && (*lower==' ' || *lower=='\t'))
516 lower++;
518 if (!*lower || (!isalpha(*lower) && *lower!='_'))
520 fF_SetError(obj, nodef);
521 return NULL;
524 while (*lower)
526 if (!isalnum(*lower) && !isspace(*lower) && *lower!='*' && *lower!=','
527 && *lower!='.' && *lower!=';' && *lower!='(' && *lower!=')' &&
528 *lower!='[' && *lower!=']' && *lower!='_' && *lower!='\\')
530 fF_SetError(obj, nodef);
531 return NULL;
533 lower++;
536 lower=NULL;
537 buf=NULL;
539 if (obj && fF_GetError(obj)==false)
541 if ((upper=strrchr(obj->line, ')'))!=0)
543 DBP(fprintf(stderr, "end:%s:", upper));
545 for (obraces=1, ready=false; ready==false; upper=lower)
547 lower=StrNRBrk(obj->line, "()", --upper);
548 if (lower)
550 switch (*lower)
552 case ')':
553 obraces++;
554 DBP(fprintf(stderr, " )%ld%s", obraces, lower));
555 break;
556 case '(':
557 obraces--;
558 DBP(fprintf(stderr, " (%ld%s", obraces, lower));
559 if (!obraces)
560 ready=nodef;
561 break;
562 default:
563 fprintf(stderr, "Faulty StrNRBrk\n");
566 else
568 fprintf(stderr, "'(' or ')' expected in line %lu.\n",
569 obj->lineno);
570 ready=real_error;
573 if (ready==nodef) /* we found the matching '(' */
575 long newlen;
576 const char* name;
578 upper--;
580 while (upper>=obj->line && (*upper==' ' || *upper=='\t'))
581 upper--;
583 lower=StrNRBrk(obj->line, " \t*)", upper);
585 if (!lower)
586 lower=obj->line;
587 else
588 lower++;
590 for (name=lower; name<=upper; name++)
591 if (!isalnum(*name) && *name!='_')
593 fF_SetError(obj, nodef);
594 return NULL;
597 newlen=upper-lower+1;
598 buf=malloc(newlen+1);
600 if (buf)
602 strncpy(buf, lower, newlen);
603 buf[newlen]='\0';
605 else
606 fprintf(stderr, "No mem for fF_FuncName");
610 else
611 illparams("fF_FuncName");
612 return buf;
615 static INLINE fdflags
616 fF_GetFlags(const fdFile* obj)
618 if (obj)
619 return obj->flags;
620 illparams("fF_GetFlags");
621 return 0;
624 /*********************
625 * CLASS fdDef *
626 *********************/
628 typedef struct
630 char* name;
631 char* type;
632 long offset;
633 regs reg[REGS];
634 char* param[REGS];
635 char* proto[REGS];
636 regs funcpar; /* number of argument that has type "pointer to function" */
637 } fdDef;
639 fdDef*
640 fD_ctor (void);
641 void
642 fD_dtor (fdDef* obj);
643 static void
644 fD_NewName (fdDef* obj, const char* newname);
645 void
646 fD_NewParam (fdDef* obj, shortcard at, const char* newstr);
648 fD_NewProto (fdDef* obj, shortcard at, char* newstr);
649 static void
650 fD_NewReg (fdDef* obj, shortcard at, regs reg);
651 static void
652 fD_NewType (fdDef* obj, const char* newstr);
653 static void
654 fD_SetOffset (fdDef* obj, long off);
655 Error
656 fD_parsefd (fdDef* obj, fdFile* infile);
657 Error
658 fD_parsepr (fdDef* obj, fdFile* infile);
659 static const char*
660 fD_GetName (const fdDef* obj);
661 static long
662 fD_GetOffset (const fdDef* obj);
663 static const char*
664 fD_GetParam (const fdDef* obj, shortcard at);
665 static regs
666 fD_GetReg (const fdDef* obj, shortcard at);
667 static const char*
668 fD_GetRegStr (const fdDef* obj, shortcard at);
669 static const char*
670 fD_GetRegStrU (const fdDef* obj, shortcard at);
671 static const char*
672 fD_GetType (const fdDef* obj);
673 static shortcard
674 fD_ParamNum (const fdDef* obj);
675 static shortcard
676 fD_ProtoNum (const fdDef* obj);
677 static shortcard
678 fD_RegNum (const fdDef* obj);
680 fD_cmpName (const void* big, const void* small);
682 fD_cmpOffset (const void* big, const void* small);
683 void
684 fD_write (FILE* outfile, const fdDef* obj);
685 static shortcard
686 fD_GetFuncParNum (const fdDef* obj);
687 static void
688 fD_SetFuncParNum (fdDef* obj, shortcard at);
689 static void
690 fD_adjustargnames(fdDef *obj);
692 fdDef **arrdefs;
693 long fds;
695 char *fD_nostring="";
697 fdDef*
698 fD_ctor(void)
700 fdDef *result;
701 regs count;
703 result=malloc(sizeof(fdDef));
705 if (result)
707 result->name=fD_nostring;
708 result->type=fD_nostring;
709 result->funcpar=illegal;
711 for (count=d0; count<illegal; count++ )
713 result->reg[count]=illegal;
714 result->param[count]=fD_nostring; /* if (!strlen) dont't free() */
715 result->proto[count]=fD_nostring;
718 return result;
721 /* free all resources and make the object as illegal as possible */
723 void
724 fD_dtor(fdDef* obj)
726 regs count;
728 if (obj)
730 if (!obj->name)
731 fprintf(stderr, "fD_dtor: null name");
732 else
733 if (obj->name!=fD_nostring)
734 free(obj->name);
736 if (!obj->type)
737 fprintf(stderr, "fD_dtor: null type");
738 else
739 if (obj->type!=fD_nostring)
740 free(obj->type);
742 obj->name=obj->type=NULL;
744 for (count=d0; count<illegal; count++)
746 obj->reg[count]=illegal;
748 if (!obj->param[count])
749 fprintf(stderr, "fD_dtor: null param");
750 else
751 if (obj->param[count]!=fD_nostring)
752 free(obj->param[count]);
754 if (!obj->proto[count])
755 fprintf(stderr, "fD_dtor: null proto");
756 else
757 if (obj->proto[count]!=fD_nostring)
758 free(obj->proto[count]);
760 obj->param[count]=obj->proto[count]=NULL;
763 free(obj);
765 else
766 fprintf(stderr, "fd_dtor(NULL)\n");
769 static INLINE void
770 fD_NewName(fdDef* obj, const char* newname)
772 if (obj && newname)
774 if (obj->name && obj->name!=fD_nostring)
775 free(obj->name);
776 if (!NewString(&obj->name, newname))
777 obj->name=fD_nostring;
779 else
780 illparams("fD_NewName");
783 void
784 fD_NewParam(fdDef* obj, shortcard at, const char* newstr)
786 char *pa;
788 if (newstr && obj && at<illegal)
790 pa=obj->param[at];
792 if (pa && pa!=fD_nostring)
793 free(pa);
795 while (*newstr==' ' || *newstr=='\t')
796 newstr++;
798 if (NewString(&pa, newstr))
800 char* prefix_pa;
802 prefix_pa = malloc( strlen( pa ) + 4 );
804 if( prefix_pa == NULL )
806 fprintf(stderr, "No mem for string\n");
808 else
810 sprintf( prefix_pa, "___%s", pa );
811 obj->param[at]=prefix_pa;
812 free( pa );
815 else
816 obj->param[at]=fD_nostring;
818 else
819 illparams("fD_NewParam");
822 /* get first free *reg or illegal */
824 static INLINE shortcard
825 fD_RegNum(const fdDef* obj)
827 shortcard count;
829 if (obj)
831 for (count=d0; count<illegal && obj->reg[count]!=illegal; count++);
832 return count;
834 else
836 illparams("fD_RegNum");
837 return illegal;
841 static INLINE void
842 fD_NewReg(fdDef* obj, shortcard at, regs reg)
844 if (obj && at<illegal && reg>=d0 && reg<=illegal)
845 obj->reg[at]=reg;
846 else
847 illparams("fD_NewReg");
850 static INLINE regs
851 fD_GetReg(const fdDef* obj, shortcard at)
853 if (obj && at<illegal)
854 return obj->reg[at];
855 else
857 illparams("fD_GetReg");
858 return illegal;
862 static INLINE shortcard
863 fD_GetFuncParNum(const fdDef* obj)
865 if (obj)
866 return (shortcard)obj->funcpar;
867 else
869 illparams("fD_GetFuncParNum");
870 return illegal;
874 static INLINE void
875 fD_SetFuncParNum(fdDef* obj, shortcard at)
877 if (obj && at<illegal)
878 obj->funcpar=at;
879 else
880 illparams("fD_SetFuncParNum");
884 fD_NewProto(fdDef* obj, shortcard at, char* newstr)
886 char *pr;
888 if (newstr && obj && at<illegal)
890 char *t, arr[200]; /* I hope 200 will be enough... */
891 int numwords=1;
892 pr=obj->proto[at];
894 if (pr && pr!=fD_nostring)
895 free(pr);
897 while (*newstr==' ' || *newstr=='\t')
898 newstr++; /* Skip leading spaces */
900 t=arr;
901 while ((*t++=*newstr)!=0)
903 /* Copy the rest, counting number of words */
904 if ((*newstr==' ' || *newstr=='\t') && newstr[1] && newstr[1]!=' ' &&
905 newstr[1]!='\t')
906 numwords++;
907 newstr++;
910 t=arr+strlen(arr)-1;
911 while (*t==' ' || *t=='\t')
912 t--;
913 t[1]='\0'; /* Get rid of tailing spaces */
915 if (at!=fD_GetFuncParNum(obj))
917 if (numwords>1) /* One word - must be type */
918 if (*t!='*')
920 /* '*' on the end - no parameter name used */
921 while (*t!=' ' && *t!='\t' && *t!='*')
922 t--;
923 t++;
924 if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
925 && strcmp(t, "long") && strcmp(t, "APTR"))
927 /* Not one of applicable keywords - must be parameter name.
928 Get rid of it. */
929 t--;
930 while (*t==' ' || *t=='\t')
931 t--;
932 t[1]='\0';
936 else
938 /* Parameter of type "pointer to function". */
939 char *end;
940 t=strchr(arr, '(');
941 t++;
942 while (*t==' ' || *t=='\t')
943 t++;
944 if (*t!='*')
945 return 1;
946 t++;
947 end=strchr(t, ')');
948 if (target!=M68K_POS)
950 memmove(t+2, end, strlen(end)+1);
951 *t='%';
952 t[1]='s';
954 else
955 memmove(t, end, strlen(end)+1);
958 if (NewString(&pr, arr))
960 obj->proto[at]=pr;
961 while (*pr==' ' || *pr=='\t')
962 pr++;
963 if (!strcasecmp(pr, "double"))
965 /* "double" needs two data registers */
966 int count, regs=fD_RegNum(obj);
967 for (count=at+1; count<regs; count++)
968 fD_NewReg(obj, count, fD_GetReg(obj, count+1));
971 else
972 obj->proto[at]=fD_nostring;
974 else
975 illparams("fD_NewProto");
977 return 0;
980 static INLINE void
981 fD_NewType(fdDef* obj, const char* newtype)
983 if (obj && newtype)
985 if (obj->type && obj->type!=fD_nostring)
986 free(obj->type);
987 if (!NewString(&obj->type, newtype))
988 obj->type=fD_nostring;
990 else
991 illparams("fD_NewType");
994 static INLINE void
995 fD_SetOffset(fdDef* obj, long off)
997 if (obj)
998 obj->offset=off;
999 else
1000 illparams("fD_SetOffset");
1003 static INLINE const char*
1004 fD_GetName(const fdDef* obj)
1006 if (obj && obj->name)
1007 return obj->name;
1008 else
1010 illparams("fD_GetName");
1011 return fD_nostring;
1015 static INLINE long
1016 fD_GetOffset(const fdDef* obj)
1018 if (obj)
1019 return obj->offset;
1020 else
1022 illparams("fD_GetOffset");
1023 return 0;
1027 static INLINE const char*
1028 fD_GetProto(const fdDef* obj, shortcard at)
1030 if (obj && at<illegal && obj->proto[at])
1031 return obj->proto[at];
1032 else
1034 illparams("fD_GetProto");
1035 return fD_nostring;
1039 static INLINE const char*
1040 fD_GetParam(const fdDef* obj, shortcard at)
1042 if (obj && at<illegal && obj->param[at])
1043 return obj->param[at];
1044 else
1046 illparams("fD_GetParam");
1047 return fD_nostring;
1051 static INLINE const char*
1052 fD_GetRegStr(const fdDef* obj, shortcard at)
1054 if (obj && at<illegal)
1055 return RegStr(obj->reg[at]);
1056 else
1058 illparams("fD_GetReg");
1059 return RegStr(illegal);
1063 static INLINE const char*
1064 fD_GetRegStrU(const fdDef* obj, shortcard at)
1066 if (obj && at<illegal)
1067 return RegStrU(obj->reg[at]);
1068 else
1070 illparams("fD_GetReg");
1071 return RegStrU(illegal);
1075 static INLINE const char*
1076 fD_GetType(const fdDef* obj)
1078 if (obj && obj->type)
1079 return obj->type;
1080 else
1082 illparams("fD_GetType");
1083 return fD_nostring;
1087 /* get first free param or illegal */
1089 static INLINE shortcard
1090 fD_ParamNum(const fdDef* obj)
1092 shortcard count;
1094 if (obj)
1096 for (count=d0; count<illegal && obj->param[count]!=fD_nostring;
1097 count++);
1098 return count;
1100 else
1102 illparams("fD_ParamNum");
1103 return illegal;
1107 static INLINE shortcard
1108 fD_ProtoNum(const fdDef* obj)
1110 shortcard count;
1112 if (obj)
1114 for (count=d0; count<illegal && obj->proto[count]!=fD_nostring;
1115 count++);
1116 return count;
1118 else
1120 illparams("fD_ProtoNum");
1121 return illegal;
1125 /******************************************************************************
1126 * fD_parsefd
1128 * parse the current line. Needs to copy input, in order to insert \0's
1129 * RETURN
1130 * fF_GetError(infile):
1131 * false = read a definition.
1132 * nodef = not a definition on line (so try again)
1133 * error = real error
1134 ******************************************************************************/
1136 Error
1137 fD_parsefd(fdDef* obj, fdFile* infile)
1139 enum parse_info { name, params, regs, ready } parsing;
1140 char *buf, *bpoint, *bnext;
1141 unsigned long index;
1143 if (obj && infile && fF_GetError(infile)==false)
1145 parsing=name;
1147 if (!NewString(&buf, infile->line))
1149 fprintf(stderr, "No mem for line %lu\n", infile->lineno);
1150 fF_SetError(infile, real_error);
1152 bpoint=buf; /* so -Wall keeps quiet */
1154 /* try to parse the line until there's an error or we are done */
1156 while (parsing!=ready && fF_GetError(infile)==false)
1158 switch (parsing)
1160 case name:
1161 switch (buf[0])
1163 case '#':
1164 if (strncmp("##base", buf, 6)==0)
1166 bnext=buf+6;
1167 while (*bnext==' ' || *bnext=='\t' || *bnext=='_')
1168 bnext++;
1169 strcpy(BaseName, bnext);
1170 BaseName[strlen(BaseName)-1]='\0';
1172 else
1173 if (strncmp("##bias", buf, 6)==0)
1175 if (!sscanf(buf+6, "%ld", &infile->offset))
1177 fprintf(stderr, "Illegal ##bias in line %lu: %s\n",
1178 infile->lineno, infile->line);
1179 fF_SetError(infile, real_error);
1180 break; /* avoid nodef */
1182 else
1184 if (fF_GetOffset(infile)>0)
1185 fF_SetOffset(infile, -fF_GetOffset(infile));
1186 DBP(fprintf(stderr, "set offset to %ld\n",
1187 fF_GetOffset(infile)));
1190 else
1192 if (strncmp("##private", buf, 9)==0)
1193 fF_SetFlags(infile, fF_GetFlags(infile) |
1194 FD_PRIVATE);
1195 else if (strncmp("##public", buf, 8)==0)
1196 fF_SetFlags(infile, fF_GetFlags(infile) &
1197 ~FD_PRIVATE);
1198 else if (strncmp("##shadow", buf, 8)==0)
1199 fF_SetFlags(infile, fF_GetFlags(infile) |
1200 FD_SHADOW);
1202 /* drop through for error comment */
1204 case '*':
1205 /* try again somewhere else */
1206 fF_SetError(infile, nodef);
1207 break;
1209 default:
1210 /* assume a regular line here */
1211 if (fF_GetFlags(infile) & (FD_PRIVATE | FD_SHADOW))
1213 /* don't store names of privates */
1214 fF_SetError(infile, nodef);
1215 if (!(fF_GetFlags(infile) & FD_SHADOW))
1216 fF_SetOffset(infile,
1217 fF_GetOffset(infile)-FUNCTION_GAP);
1218 else
1219 /* Shadow is valid for one line only. */
1220 fF_SetFlags(infile, fF_GetFlags(infile) &
1221 ~FD_SHADOW);
1222 break;
1224 parsing=name; /* switch (parsing) */
1225 for (index=0; buf[index] && buf[index]!='('; index++);
1227 if (!buf[index])
1229 /* oops, no fd ? */
1230 fprintf(stderr, "Not an fd, line %lu: %s\n",
1231 infile->lineno, buf /* infile->line */);
1232 fF_SetError(infile, nodef);
1233 } /* maybe next time */
1234 else
1236 buf[index]=0;
1238 fD_NewName(obj, buf);
1239 fD_SetOffset(obj, fF_GetOffset(infile));
1241 bpoint=buf+index+1;
1242 parsing=params; /* continue the loop */
1245 break;
1247 case params:
1249 char *bptmp; /* needed for fD_NewParam */
1251 /* look for parameters now */
1253 for (bnext = bpoint; *bnext && *bnext!=',' && *bnext!=')';
1254 bnext++);
1256 if (*bnext)
1258 bptmp=bpoint;
1260 if (*bnext == ')')
1262 if (bnext[1] != '(')
1264 fprintf(stderr, "Registers expected in line %lu: %s\n",
1265 infile->lineno, infile->line);
1266 fF_SetError(infile, nodef);
1268 else
1270 parsing=regs;
1271 bpoint=bnext+2;
1274 else
1275 bpoint = bnext+1;
1277 /* terminate string and advance to next item */
1279 *bnext='\0';
1280 fD_NewParam(obj, fD_ParamNum(obj), bptmp);
1282 else
1284 fF_SetError(infile, nodef);
1285 fprintf(stderr, "Param expected in line %lu: %s\n",
1286 infile->lineno, infile->line);
1288 break; /* switch parsing */
1291 case regs:
1292 /* look for parameters now */
1294 for (bnext=bpoint; *bnext && *bnext!='/' && *bnext!=',' &&
1295 *bnext!=')'; bnext++);
1297 if (*bnext)
1299 if (')'==*bnext)
1301 /* wow, we've finished */
1302 fF_SetOffset(infile, fF_GetOffset(infile)-FUNCTION_GAP);
1303 parsing=ready;
1305 *bnext = '\0';
1307 bpoint[0]=tolower(bpoint[0]);
1309 if ((bpoint[0]=='d' || bpoint[0]=='a') && bpoint[1]>='0' &&
1310 bpoint[1]<='8' && bnext==bpoint+2)
1311 fD_NewReg(obj, fD_RegNum(obj),
1312 bpoint[1]-'0'+(bpoint[0]=='a'? 8 : 0));
1313 else
1314 if (bnext!=bpoint)
1316 /* it is when our function is void */
1317 fprintf(stderr, "Illegal register %s in line %ld\n",
1318 bpoint, infile->lineno);
1319 fF_SetError(infile, nodef);
1321 bpoint = bnext+1;
1323 else
1325 fF_SetError(infile, nodef);
1326 fprintf(stderr, "Reg expected in line %lu\n",
1327 infile->lineno);
1329 break; /* switch parsing */
1331 case ready:
1332 fprintf(stderr, "Internal error, use another compiler.\n");
1333 break;
1337 free(buf);
1338 return fF_GetError(infile);
1340 else
1342 illparams("fD_parsefd");
1343 return real_error;
1347 static void
1348 fD_adjustargnames(fdDef *obj)
1350 int parnum;
1352 if (output_mode!=NEW && output_mode!=GENMODULE)
1353 return;
1355 /* For #define-base output mode, we have to check if argument names are not
1356 the same as some words in type names. We check from the first argument
1357 to the last, resolving conflicts by changing argument names, if
1358 necessary. */
1360 for (parnum=0; parnum<fD_ParamNum(obj); parnum++)
1362 const char *parname=fD_GetParam(obj, parnum);
1363 int finished;
1366 int num;
1367 const char *type=fD_GetType(obj);
1368 char *str;
1370 finished=1;
1372 if ((str=strstr(type, parname))!=0 && (str==type ||
1373 (!isalnum(str[-1]) && str[-1]!='_')) &&
1374 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_')))
1376 char buf[300]; /* Hope will be enough... */
1377 strcpy(buf, parname);
1378 strcat(buf, "_");
1379 fD_NewParam(obj, parnum, buf);
1380 parname=fD_GetParam(obj, parnum);
1381 finished=0;
1383 else
1384 for (num=0; num<fD_ParamNum(obj); num++)
1386 const char *name=fD_GetParam(obj, num);
1387 const char *proto=fD_GetProto(obj, num);
1388 if ((num<parnum && strcmp(name, parname)==0) ||
1389 ((str=strstr(proto, parname))!=0 && (str==proto ||
1390 (!isalnum(str[-1]) && str[-1]!='_')) &&
1391 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_'))))
1393 char buf[300]; /* Hope will be enough... */
1394 strcpy(buf, parname);
1395 strcat(buf, "_");
1396 fD_NewParam(obj, parnum, buf);
1397 parname=fD_GetParam(obj, parnum);
1398 // lcs finished=0;
1399 break;
1402 } while (!finished);
1406 Error
1407 fD_parsepr(fdDef* obj, fdFile* infile)
1409 char *buf; /* a copy of infile->line */
1410 char *bpoint, /* cursor in buf */
1411 *bnext, /* looking for the end */
1412 *lowarg; /* beginning of this argument */
1413 long obraces; /* count of open braces */
1414 regs count, /* count parameter number */
1415 args; /* the number of arguments for this function */
1417 if (!(obj && infile && fF_GetError(infile)==false))
1419 illparams("fD_parsepr");
1420 fF_SetError(infile, real_error);
1421 return real_error;
1423 if (!NewString(&buf, infile->line))
1425 fprintf(stderr, "No mem for fD_parsepr\n");
1426 fF_SetError(infile, real_error);
1427 return real_error;
1429 fF_SetError(infile, false);
1431 bpoint=strchr(buf, '(');
1432 while (--bpoint>=buf && strstr(bpoint, fD_GetName(obj))!=bpoint);
1433 if (bpoint>=buf)
1435 while (--bpoint >= buf && (*bpoint==' ' || *bpoint=='\t'));
1436 *++bpoint='\0';
1438 fD_NewType(obj, buf);
1440 while (bpoint && *bpoint++!='('); /* one beyond '(' */
1442 lowarg=bpoint;
1443 obraces=0;
1445 for (count=0, args=fD_RegNum(obj); count<args; bpoint=bnext+1)
1447 while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
1448 bpoint++;
1450 if (!obraces && target==M68K_POS && strncmp(bpoint, "_R_", 3)==0 &&
1451 isalnum(bpoint[3]) && isalnum(bpoint[4]) && isspace(bpoint[5]))
1452 lowarg=bpoint+5;
1454 bnext=strpbrk(bpoint, "(),");
1456 if (bnext)
1458 switch (*bnext)
1460 case '(':
1461 if (!obraces)
1463 if (target==M68K_AMIGAOS || target==M68K_POS)
1465 if (fD_GetFuncParNum(obj)!=illegal &&
1466 fD_GetFuncParNum(obj)!=count &&
1467 !Quiet)
1468 fprintf(stderr, "Warning: two parameters of type "
1469 "pointer to function are used.\n"
1470 "This is not supported!\n");
1473 fD_SetFuncParNum(obj, count);
1475 obraces++;
1476 DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
1477 break;
1479 case ')':
1480 if (obraces)
1482 DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
1483 obraces--;
1485 else
1487 *bnext='\0';
1488 DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
1489 if (fD_NewProto(obj, count, lowarg))
1490 fprintf(stderr, "Parser confused in line %ld\n",
1491 infile->lineno);
1492 lowarg=bnext+1;
1494 if (count!=args-1)
1496 DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
1497 fD_GetName(obj), args, count+1));
1498 fF_SetError(infile, nodef);
1500 count++;
1502 break;
1504 case ',':
1505 if (!obraces)
1507 *bnext='\0';
1508 DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
1509 if (fD_NewProto(obj, count, lowarg))
1510 fprintf(stderr, "Parser confused in line %ld\n",
1511 infile->lineno);
1512 lowarg=bnext+1;
1513 count++;
1515 break;
1517 default:
1518 fprintf(stderr, "Faulty strpbrk in line %lu.\n",
1519 infile->lineno);
1522 else
1524 DBP(fprintf(stderr, "Faulty argument %u in line %lu.\n", count+1,
1525 infile->lineno));
1526 count=args; /* this will effectively quit the for loop */
1527 fF_SetError(infile, nodef);
1530 if (fD_ProtoNum(obj)!=fD_RegNum(obj))
1531 fF_SetError(infile, nodef);
1533 else
1535 fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
1536 fprintf(stderr, "function , definition %s.\n",
1537 /* fD_GetName(obj),*/ infile->line);
1538 fF_SetError(infile, nodef);
1541 free(buf);
1543 fD_adjustargnames(obj);
1545 return fF_GetError(infile);
1549 fD_cmpName(const void* big, const void* small) /* for qsort and bsearch */
1551 return strcmp(fD_GetName(*(fdDef**)big), fD_GetName(*(fdDef**)small));
1555 fD_cmpOffset(const void* big, const void* small) /* for qsort and bsearch */
1557 return fD_GetOffset(*(fdDef**)small) - fD_GetOffset(*(fdDef**)big);
1560 const static char *TagExcTable[]=
1562 "BuildEasyRequestArgs", "BuildEasyRequest",
1563 "DoDTMethodA", "DoDTMethod",
1564 "DoGadgetMethodA", "DoGadgetMethod",
1565 "EasyRequestArgs", "EasyRequest",
1566 "MUI_MakeObjectA", "MUI_MakeObject",
1567 "MUI_RequestA", "MUI_Request",
1568 "PrintDTObjectA", "PrintDTObject",
1569 "RefreshDTObjectA", "RefreshDTObjects",
1570 "UMSVLog", "UMSLog",
1571 "VFWritef", "FWritef",
1572 "VFPrintf", "FPrintf",
1573 "VPrintf", "Printf",
1576 const char*
1577 getvarargsfunction(const fdDef * obj)
1579 unsigned int count;
1580 const char *name = fD_GetName(obj);
1582 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1584 if (strcmp(name, TagExcTable[count])==0)
1586 return TagExcTable[count+1];
1589 return(NULL);
1592 const char*
1593 taggedfunction(const fdDef* obj)
1595 shortcard numregs=fD_RegNum(obj);
1596 unsigned int count;
1597 int aos_tagitem;
1598 const char *name=fD_GetName(obj);
1599 static char newname[200]; /* Hope will be enough... static because used
1600 out of the function. */
1601 const char *lastarg;
1602 const static char *TagExcTable2[]=
1604 "ApplyTagChanges",
1605 "CloneTagItems",
1606 "FindTagItem",
1607 "FreeTagItems",
1608 "GetTagData",
1609 "PackBoolTags",
1610 "PackStructureTags",
1611 "RefreshTagItemClones",
1612 "UnpackStructureTags",
1615 if (!numregs)
1616 return NULL;
1618 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1619 if (strcmp(name, TagExcTable[count])==0)
1620 return NULL;
1621 // lcs return TagExcTable[count+1];
1623 for (count=0; count<sizeof TagExcTable2/sizeof TagExcTable2[0]; count++)
1624 if (strcmp(name, TagExcTable2[count])==0)
1625 return NULL;
1627 lastarg=fD_GetProto(obj, numregs-1);
1628 if (strncmp(lastarg, "const", 5)==0 || strncmp(lastarg, "CONST", 5)==0)
1629 lastarg+=5;
1630 while (*lastarg==' ' || *lastarg=='\t')
1631 lastarg++;
1632 if (strncmp(lastarg, "struct", 6))
1633 return NULL;
1634 lastarg+=6;
1635 while (*lastarg==' ' || *lastarg=='\t')
1636 lastarg++;
1637 aos_tagitem=1;
1638 if (strncmp(lastarg, "TagItem", 7) &&
1639 (target!=M68K_POS || ((aos_tagitem=strncmp(lastarg, "pOS_TagItem", 11))!=0)))
1640 return NULL;
1641 lastarg+=(aos_tagitem ? 7 : 11);
1642 while (*lastarg==' ' || *lastarg=='\t')
1643 lastarg++;
1644 if (strcmp(lastarg, "*"))
1645 return NULL;
1647 strcpy(newname, name);
1648 if (newname[strlen(newname)-1]=='A')
1649 newname[strlen(newname)-1]='\0';
1650 else
1651 if (strlen(newname)>7 && !strcmp(newname+strlen(newname)-7, "TagList"))
1652 strcpy(newname+strlen(newname)-4, "s");
1653 else
1654 strcat(newname, "Tags");
1655 return newname;
1658 const char*
1659 aliasfunction(const char* name)
1661 const static char *AliasTable[]=
1663 "AllocDosObject", "AllocDosObjectTagList",
1664 "CreateNewProc", "CreateNewProcTagList",
1665 "NewLoadSeg", "NewLoadSegTagList",
1666 "System", "SystemTagList",
1668 unsigned int count;
1669 for (count=0; count<sizeof AliasTable/sizeof AliasTable[0]; count++)
1670 if (strcmp(name, AliasTable[count])==0)
1671 return AliasTable[count+(count%2 ? -1 : 1)];
1672 return NULL;
1675 void
1676 fD_write(FILE* outfile, const fdDef* obj)
1678 shortcard count, numregs;
1679 const char *chtmp, *tagname, *varname, *name, *rettype;
1680 int vd=0, a45=0, d7=0;
1682 DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
1684 numregs=fD_RegNum(obj);
1686 if ((rettype=fD_GetType(obj))==fD_nostring)
1688 fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
1689 return;
1691 if (!strcasecmp(rettype, "void"))
1692 vd = 1; /* set flag */
1693 for (count=d0; count<numregs; count++)
1695 const char *reg=fD_GetRegStr(obj, count);
1696 if (!((output_mode == NEW || output_mode == GENMODULE) && (target == PPC_POWERUP)))
1698 if (strcmp(reg, "a4")==0 || strcmp(reg, "a5")==0)
1700 if (!a45)
1701 a45=(strcmp(reg, "a4") ? 5 : 4); /* set flag */
1702 else /* Security check */
1703 if (!Quiet)
1704 fprintf(stderr, "Warning: both a4 and a5 are used. "
1705 "This is not supported!\n");
1708 if (strcmp(reg, "d7")==0) /* Used only when a45!=0 */
1709 d7=1;
1712 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1714 if (a45 && d7) /* Security check */
1715 if (!Quiet)
1716 fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
1717 "supported!\n");
1720 name=fD_GetName(obj);
1722 if (fD_ProtoNum(obj)!=numregs)
1724 fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
1725 fD_ProtoNum(obj), fD_ProtoNum(obj)!= 1 ? "s" : "");
1726 return;
1729 if (output_mode==GENMODULE)
1731 fprintf(outfile, "%s %s(", rettype, name);
1732 for (count=d0; count<numregs; count++)
1734 chtmp=fD_GetProto(obj, count);
1735 if (fD_GetFuncParNum(obj)==count)
1736 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1737 else
1738 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
1739 "" : " "), fD_GetParam(obj, count));
1740 if (count<numregs-1)
1741 fprintf(outfile, ", ");
1744 fprintf(outfile,") (");
1745 for (count=d0; count<numregs; count++)
1747 chtmp=fD_GetRegStr(obj, count);
1748 /* AROS wants the registers in UPPERCASE */
1749 while (*chtmp)
1750 fprintf(outfile, "%c", toupper(*(chtmp++)));
1751 if (count<numregs-1)
1752 fprintf(outfile, ", ");
1754 fprintf(outfile, ")\n");
1756 else if (output_mode==NEW)
1758 fprintf(outfile, "#define %s(", name);
1760 if (numregs>0)
1762 for (count=d0; count<numregs-1; count++)
1763 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
1764 fprintf(outfile, "%s", fD_GetParam(obj, count));
1767 if (target==M68K_AMIGAOS)
1769 fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
1770 (vd ? "NR" : ""), (a45 ? (a45==4 ? "A4" : "A5") : ""),
1771 (BaseName[0] ? "" : "UB"),
1772 (fD_GetFuncParNum(obj)==illegal ? "" : "FP"), -fD_GetOffset(obj));
1773 if (!vd)
1774 fprintf(outfile, "%s, ", rettype);
1775 fprintf(outfile, "%s, ", name);
1777 for (count=d0; count<numregs; count++)
1779 chtmp=fD_GetRegStr(obj, count);
1780 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1781 chtmp="d7";
1782 fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj)==count ?
1783 "__fpt" : fD_GetProto(obj, count)),
1784 fD_GetParam(obj, count),
1785 chtmp, (count==numregs-1 && !BaseName[0] ? "" : ", "));
1788 if (BaseName[0]) /* was "##base" used? */
1789 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1790 if (fD_GetFuncParNum(obj)!=illegal)
1792 fprintf(outfile, ", ");
1793 fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
1795 fprintf(outfile, ")\n\n");
1797 else if(target==M68K_POS)
1799 fprintf(outfile, ") \\\n\t__INLINE_FUN_%d(", numregs);
1800 fprintf(outfile, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1801 BaseNamU, BaseNamU, -fD_GetOffset(obj), rettype, name,
1802 (numregs ? ", \\\n\t" : ""));
1804 for (count=d0; count<numregs; count++)
1805 fprintf(outfile, "%s, %s, %s%s", fD_GetProto(obj, count),
1806 fD_GetParam(obj, count), fD_GetRegStr(obj, count),
1807 (count==numregs-1 ? "" : ", "));
1808 fprintf(outfile, ")\n\n");
1810 else if (target==PPC_POWERUP || target==PPC_MORPHOS)
1812 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1813 numregs,
1814 (vd ? "NR" : ""),
1815 (BaseName[0] ? "" : "UB"),
1816 -fD_GetOffset(obj));
1818 if (!vd)
1819 fprintf(outfile, "%s, ", rettype);
1820 fprintf(outfile, "%s, ", name);
1822 for (count=d0; count<numregs; count++)
1824 chtmp=fD_GetRegStr(obj, count);
1826 if (strchr(fD_GetProto(obj, count),'%'))
1828 sprintf(Buffer,
1829 fD_GetProto(obj, count),
1830 "");
1832 fprintf(outfile, "%s, %s, %s%s",
1833 Buffer,
1834 fD_GetParam(obj, count),
1835 chtmp,
1836 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1838 else
1840 fprintf(outfile, "%s, %s, %s%s",
1841 fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1842 fD_GetParam(obj, count),
1843 chtmp,
1844 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1848 if (BaseName[0])
1849 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1852 * Here it would make sense to create a database file to
1853 * integrate optimizations automaticly into every new
1854 * build. Not every function needs a complete flush. For
1855 * example functions with no parameter wouldn`t need a
1856 * PPC flush normally. Or Read(File,Addr,Size); would
1857 * only need a flush for Addr with the Size
1860 fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1861 fprintf(outfile, ")\n\n");
1863 else if (target==IX86BE_AMITHLON)
1865 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1866 numregs,
1867 (vd ? "NR" : ""),
1868 (BaseName[0] ? "" : "UB"),
1869 -fD_GetOffset(obj));
1871 if (!vd)
1872 fprintf(outfile, "%s, ", rettype);
1873 fprintf(outfile, "%s, ", name);
1875 for (count=d0; count<numregs; count++)
1877 chtmp=fD_GetRegStr(obj, count);
1879 if (strchr(fD_GetProto(obj, count),'%'))
1881 sprintf(Buffer,
1882 fD_GetProto(obj, count),
1883 "");
1885 fprintf(outfile, "%s, %s, %s%s",
1886 Buffer,
1887 fD_GetParam(obj, count),
1888 chtmp,
1889 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1891 else
1893 fprintf(outfile, "%s, %s, %s%s",
1894 fD_GetProto(obj, count),
1895 fD_GetParam(obj, count),
1896 chtmp,
1897 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1901 if (BaseName[0])
1902 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1904 fprintf(outfile, ")\n\n");
1906 else if (target==AROS)
1908 fprintf(outfile, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1909 numregs,
1910 (BaseName[0] ? "" : "I"),
1911 (vd ? "void" : rettype),
1912 name);
1914 for (count=d0; count<numregs; count++)
1916 chtmp=fD_GetRegStrU(obj, count);
1917 fprintf(outfile, "\tAROS_LCA(%s, (%s), %s), \\\n",
1918 fD_GetProto(obj, count),
1919 fD_GetParam(obj, count),
1920 chtmp);
1923 if (BaseName[0]) /* was "##base" used? */
1925 fprintf(outfile, "\tstruct %s *, %s_BASE_NAME, ", StdLib, BaseNamU);
1927 else
1929 fprintf(outfile, "\t/* bt */, /* bn */, ");
1931 fprintf(outfile,
1932 "%ld, /* s */)\n\n",
1933 -fD_GetOffset(obj) / 6);
1935 else
1937 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
1938 return;
1941 else if (output_mode==OLD || output_mode==STUBS)
1943 fprintf(outfile, "%s__inline %s\n%s(%s",
1944 (output_mode==STUBS ? "" : "extern "), rettype, name,
1945 (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1947 if (target==M68K_AMIGAOS)
1949 for (count=d0; count<numregs; count++)
1951 chtmp=fD_GetProto(obj, count);
1952 if (fD_GetFuncParNum(obj)==count)
1953 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1954 else
1955 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
1956 "" : " "), fD_GetParam(obj, count));
1957 if (count<numregs-1)
1958 fprintf(outfile, ", ");
1961 fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
1962 if (!vd)
1963 fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
1964 (*(rettype+strlen(rettype)-1)=='*' ? "" : " "));
1966 if (BaseName[0])
1967 fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1968 StdLib);
1970 for (count=d0; count<numregs; count++)
1972 chtmp=fD_GetRegStr(obj, count);
1973 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1974 chtmp="d7";
1975 if (fD_GetFuncParNum(obj)==count)
1977 fprintf(outfile, " register ");
1978 fprintf(outfile, fD_GetProto(obj, count), chtmp);
1979 fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
1980 count));
1982 else
1984 const char *proto=fD_GetProto(obj, count);
1985 fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
1986 proto, (*(proto+strlen(proto)-1)=='*' ? "" : " "), chtmp,
1987 chtmp, fD_GetParam(obj, count));
1990 if (a45)
1991 fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
1992 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45==4 ? "a4" : "a5"),
1993 -fD_GetOffset(obj), (a45==4 ? "a4" : "a5"));
1994 else
1995 fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1996 -fD_GetOffset(obj));
1998 fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
2000 fprintf(outfile, " : ");
2001 if (BaseName[0])
2002 fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", ": ""));
2004 for (count=d0; count<numregs; count++)
2006 chtmp=fD_GetRegStr(obj, count);
2007 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
2008 chtmp="d7";
2009 fprintf(outfile, "\"r\" (%s)%s", chtmp, (count<numregs-1 ? ", " : ""));
2011 fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
2013 if (vd)
2014 fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n"); /* { */
2015 else
2016 fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
2019 else if (target==PPC_POWERUP)
2021 for (count = d0; count < numregs; count++)
2023 chtmp = fD_GetProto(obj, count);
2024 if (fD_GetFuncParNum(obj) == count)
2025 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2026 else
2027 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2028 "" : " "), fD_GetParam(obj, count));
2029 if (count < numregs - 1)
2030 fprintf(outfile, ", ");
2033 fprintf(outfile, ")\t\n");
2034 fprintf(outfile, "{\t\n");
2035 fprintf(outfile, "struct Caos\tMyCaos;\n");
2036 fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2037 fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
2038 fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2039 fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2040 fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2041 fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2043 if (numregs > 0)
2045 for (count = d0; count < numregs; count++)
2047 fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2048 fD_GetRegStr(obj, count),
2049 fD_GetParam(obj, count));
2053 fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
2054 if (BaseName[0]) /*
2055 * was "##base" used?
2058 fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2060 if (vd)
2062 fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2064 else
2066 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2067 rettype);
2070 else if (target==PPC_MORPHOS)
2072 for (count = d0; count < numregs; count++)
2074 chtmp = fD_GetProto(obj, count);
2075 if (fD_GetFuncParNum(obj) == count)
2076 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2077 else
2078 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2079 "" : " "), fD_GetParam(obj, count));
2080 if (count < numregs - 1)
2081 fprintf(outfile, ", ");
2084 fprintf(outfile, ")\t\n{\t\n");
2086 if (numregs > 0)
2088 for (count = d0; count < numregs; count++)
2090 fprintf(outfile, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2091 fD_GetRegStrU(obj, count), fD_GetParam(obj, count));
2095 if (BaseName[0]) /*
2096 * was "##base" used?
2099 fprintf(outfile, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2101 if (vd)
2103 fprintf(outfile, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj));
2105 else
2107 fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2108 rettype, fD_GetOffset(obj));
2111 else if (target==IX86BE_AMITHLON)
2113 #if 0
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));
2119 else
2120 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2121 "" : " "), fD_GetParam(obj, count));
2122 if (count < numregs - 1)
2123 fprintf(outfile, ", ");
2126 fprintf(outfile, ")\n{\n");
2127 fprintf(outfile, "\tstruct _Regs _regs;\n");
2129 if (numregs > 0)
2131 for (count = d0; count < numregs; count++)
2133 fprintf(outfile, "\t_regs.reg_%s = (ULONG) (%s);\n",
2134 fD_GetRegStr(obj, count),
2135 fD_GetParam(obj, count));
2139 if (BaseName[0])
2141 fprintf(outfile, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2144 if (vd)
2146 fprintf(outfile, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2147 -fD_GetOffset(obj));
2149 else
2151 fprintf(outfile, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2152 rettype,-fD_GetOffset(obj));
2154 #else
2155 for (count = d0; count < numregs; count++)
2157 chtmp = fD_GetProto(obj, count);
2158 if (fD_GetFuncParNum(obj) == count)
2159 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2160 else
2161 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2162 "" : " "), fD_GetParam(obj, count));
2163 if (count < numregs - 1)
2164 fprintf(outfile, ", ");
2167 fprintf(outfile, ")\n{\n");
2168 fprintf(outfile, "\t%s LP%d%s%s(0x%lx, ",
2169 (vd ? "" : "return "),
2170 numregs,
2171 (vd ? "NR" : ""),
2172 (BaseName[0] ? "" : "UB"),
2173 -fD_GetOffset(obj));
2175 if (!vd)
2176 fprintf(outfile, "%s, ", rettype);
2177 fprintf(outfile, "%s, ", name);
2179 for (count=d0; count<numregs; count++)
2181 chtmp=fD_GetRegStr(obj, count);
2183 if (strchr(fD_GetProto(obj, count),'%'))
2185 sprintf(Buffer,
2186 fD_GetProto(obj, count),
2187 "");
2189 fprintf(outfile, "%s, %s, %s%s",
2190 Buffer,
2191 fD_GetParam(obj, count),
2192 chtmp,
2193 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2195 else
2197 fprintf(outfile, "%s, %s, %s%s",
2198 fD_GetProto(obj, count),
2199 fD_GetParam(obj, count),
2200 chtmp,
2201 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2205 if (BaseName[0])
2206 fprintf(outfile, "\\\n\t, BASE_NAME");
2208 fprintf(outfile, ");\n}\n\n");
2209 #endif
2211 else
2213 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2214 return;
2217 else if (output_mode==GATESTUBS || output_mode==GATEPROTO)
2219 int has_base = (BaseName[0] && fD_GetOffset(obj) != 0);
2221 //lcs
2222 if (target==AROS)
2224 for (count=d0; count<numregs; count++)
2226 if (fD_GetFuncParNum(obj) == count)
2228 char funcproto[200]; /* Hope will be enough... */
2229 sprintf(funcproto, "%s_%s_funcproto_%d",
2230 BaseNamC, name, count );
2231 fprintf(outfile, "typedef ");
2232 fprintf(outfile, fD_GetProto(obj, count), funcproto);
2233 fprintf(outfile, ";\n");
2238 if (output_mode==GATESTUBS)
2240 fprintf(outfile, "%s %s%s(",
2241 rettype,
2242 libprefix,
2243 name);
2245 for (count=d0; count<numregs; count++)
2247 chtmp = fD_GetProto(obj, count);
2249 fprintf(outfile, chtmp, "");
2250 fprintf(outfile, "%s",
2251 (count == numregs - 1 && !has_base ? ");\n" : ", "));
2254 if (has_base)
2255 fprintf(outfile, "struct %s *);\n", StdLib);
2258 if (target==M68K_AMIGAOS)
2260 fprintf(outfile, "%s %s%s(\n",
2261 rettype,
2262 gateprefix,
2263 name);
2265 for (count=d0; count<numregs; count++)
2267 chtmp = fD_GetProto(obj, count);
2269 if (fD_GetFuncParNum(obj) == count)
2271 fprintf(outfile, "\t");
2272 fprintf(outfile, chtmp,
2273 fD_GetParam(obj, count));
2274 fprintf(outfile, " __asm(\"%s\")%s",
2275 fD_GetRegStr(obj, count),
2276 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2278 else
2280 fprintf(outfile, "\t%s %s __asm(\"%s\")%s",
2281 chtmp,
2282 fD_GetParam(obj, count),
2283 fD_GetRegStr(obj, count),
2284 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2288 if (has_base)
2289 fprintf(outfile, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib);
2291 if (output_mode==GATESTUBS)
2292 fprintf(outfile, "{\n");
2294 else if (target==AROS)
2296 fprintf(outfile, "AROS_LH%d%s(%s, %s%s,\n",
2297 numregs,
2298 has_base ? "" : "I",
2299 rettype,
2300 gateprefix,
2301 name);
2303 for (count=d0; count<numregs; count++)
2305 char funcproto[200]; /* Hope will be enough... */
2307 if (fD_GetFuncParNum(obj) == count)
2309 sprintf(funcproto, "%s_%s_funcproto_%d",
2310 BaseNamC, name, count );
2313 fprintf(outfile, "\tAROS_LHA(%s, %s, %s),\n",
2314 fD_GetFuncParNum(obj) == count ? funcproto : fD_GetProto(obj, count),
2315 fD_GetParam(obj, count),
2316 fD_GetRegStrU(obj, count));
2319 fprintf(outfile, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2320 StdLib,
2321 -fD_GetOffset(obj) / 6,
2322 BaseNamC);
2324 if (output_mode==GATESTUBS)
2325 fprintf(outfile, "{\n");
2327 else if (target==PPC_MORPHOS)
2329 fprintf(outfile, "%s %s%s(void)\n",
2330 rettype,
2331 gateprefix,
2332 name);
2334 if (output_mode==GATESTUBS)
2336 fprintf(outfile, "{\n");
2338 for (count=d0; count<numregs; count++)
2340 chtmp = fD_GetProto(obj, count);
2342 if (fD_GetFuncParNum(obj) == count)
2344 fprintf(outfile, "\t");
2345 fprintf(outfile, chtmp,
2346 fD_GetParam(obj, count));
2347 fprintf(outfile, " = (");
2348 fprintf(outfile, chtmp, "");
2349 fprintf(outfile, ") REG_%s;\n",
2350 fD_GetRegStrU(obj, count));
2352 else
2354 fprintf(outfile, "\t%s %s = (%s) REG_%s;\n",
2355 fD_GetProto(obj, count),
2356 fD_GetParam(obj, count),
2357 fD_GetProto(obj, count),
2358 fD_GetRegStrU(obj, count));
2362 if (has_base)
2363 fprintf(outfile,
2364 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2365 StdLib, StdLib);
2367 fprintf(outfile, "\n");
2370 else if (target==IX86BE_AMITHLON)
2372 fprintf(outfile, "%s %s%s( struct _Regs _regs )\n",
2373 rettype,
2374 gateprefix,
2375 name);
2377 if (output_mode==GATESTUBS)
2379 fprintf(outfile, "{\n");
2381 for (count=d0; count<numregs; count++)
2383 chtmp = fD_GetProto(obj, count);
2385 if (fD_GetFuncParNum(obj) == count)
2387 fprintf(outfile, "\t");
2388 fprintf(outfile, chtmp,
2389 fD_GetParam(obj, count));
2390 fprintf(outfile, " = (");
2391 fprintf(outfile, chtmp, "");
2392 fprintf(outfile, ") _regs.%s;\n",
2393 fD_GetRegStr(obj, count));
2395 else
2397 fprintf(outfile, "\t%s %s = (%s) _regs.%s;\n",
2398 fD_GetProto(obj, count),
2399 fD_GetParam(obj, count),
2400 fD_GetProto(obj, count),
2401 fD_GetRegStr(obj, count));
2405 if (has_base)
2406 fprintf(outfile,
2407 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2408 StdLib, StdLib);
2410 fprintf(outfile, "\n");
2413 else
2415 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2416 return;
2419 if (output_mode==GATESTUBS)
2421 fprintf(outfile,"\treturn %s%s(",
2422 libprefix,
2423 name);
2425 for (count=d0; count<numregs; count++)
2427 fprintf(outfile, "%s%s",
2428 fD_GetParam(obj, count),
2429 (count == numregs - 1 && !has_base ? ");" : ", "));
2432 if (has_base)
2433 fprintf(outfile, "BASE_NAME);");
2435 fprintf(outfile,"\n}\n\n");
2437 else
2439 fprintf(outfile,";\n");
2441 if (target==AROS)
2443 fprintf(outfile, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2444 gateprefix, name,
2445 gateprefix, name,
2446 BaseNamC,fD_GetOffset(obj));
2449 fprintf(outfile,"\n");
2452 else
2454 fprintf(stderr, "Internal error: Unknown output mode in fD_write().\n");
2455 return;
2458 if ((tagname=aliasfunction(fD_GetName(obj)))!=0 &&
2459 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2461 fprintf(outfile, "#define %s(", tagname);
2462 for (count=d0; count<numregs-1; count++)
2463 fprintf(outfile, "a%d, ", count);
2464 fprintf(outfile, "a%d) %s (", count, name);
2465 for (count=d0; count<numregs-1; count++)
2466 fprintf(outfile, "(a%d), ", count);
2467 fprintf(outfile, "(a%d))\n\n", count);
2470 if ((tagname=taggedfunction(obj))!=0 &&
2471 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2473 if (output_mode==GENMODULE)
2475 /* Nothing to do */
2477 else if (output_mode!=STUBS)
2479 fprintf( outfile,
2480 "#ifndef %sNO_INLINE_STDARG\n"
2481 "#define %s(",
2482 (target==M68K_POS ? "__" : ""),
2483 tagname);
2485 for (count=d0; count<numregs-1; count++)
2486 fprintf(outfile, "a%d, ", count);
2488 fprintf(outfile, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2489 name);
2491 for (count=d0; count<numregs-1; count++)
2492 fprintf(outfile, "(a%d), ", count);
2494 fprintf(outfile, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2495 fD_GetProto(obj, fD_RegNum(obj)-1),
2496 (target==M68K_POS ? "__" : ""));
2499 else
2501 if (target==M68K_AMIGAOS || target==IX86BE_AMITHLON)
2503 fprintf(outfile, "__inline %s\n%s(", rettype, tagname);
2505 for (count=d0; count<numregs-1; count++)
2507 chtmp=fD_GetProto(obj, count);
2508 if (count==fD_GetFuncParNum(obj))
2509 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2510 else
2511 fprintf(outfile, "%s%s%s", chtmp,
2512 (*(chtmp+strlen(chtmp)-1)=='*' ? "" : " "),
2513 fD_GetParam(obj, count));
2514 fprintf(outfile, ", ");
2517 fprintf(outfile, "int tag, ...)\n{\n ");
2518 if (!vd)
2519 fprintf(outfile, "return ");
2521 fprintf(outfile, "%s(", name);
2522 for (count=d0; count<numregs-1; count++)
2523 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
2525 fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj)-1));
2527 else if (target==PPC_MORPHOS)
2529 int n = 9 - numregs; /* number of regs that contain varargs */
2530 int d = n & 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2531 int taglist = 8; /* offset of the start of the taglist */
2532 int local = (taglist + n * 4 + d + 8 + 15) & ~15; /* size of the stack frame */
2535 * Stack frame:
2537 * 0 - 3: next frame ptr
2538 * 4 - 7: save lr
2539 * 8 - 8+n*4+d+8-1: tag list start
2540 * ? - local-1: padding
2543 fprintf(outfile,
2544 "asm(\"\n"
2545 " .align 2 \n"
2546 " .globl %s \n"
2547 " .type %s,@function\n"
2548 "%s: \n"
2549 " stwu 1,-%d(1) \n" /* create stack frame */
2550 " mflr 0 \n"
2551 " stw 0,%d(1) \n",
2552 tagname, tagname, tagname, local, local + 4);
2555 * If n is odd, one tag is split between regs and stack.
2556 * Copy its ti_Data together with the ti_Tag.
2558 if (d)
2559 fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
2561 * Save the registers
2563 for (count = numregs; count <= 8; count++)
2564 fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
2566 if (d)
2567 fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
2570 * Add TAG_MORE
2572 fprintf(outfile, " li 11,2 \n"
2573 " addi 0,1,%d \n"
2574 " stw 11,%d(1) \n" /* add TAG_MORE */
2575 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2576 local + 8 + d,
2577 taglist + n * 4 + d,
2578 taglist + n * 4 + d + 4);
2581 if (DirectVarargsCalls)
2583 fprintf(outfile,
2584 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2585 " bl %s \n",
2586 numregs + 2, taglist, name);
2588 else
2591 * Save the non-varargs registers in the EmulHandle struct.
2593 for (count = 0; count < numregs - 1; count++)
2595 int r = fD_GetReg(obj, count);
2597 fprintf(outfile, " stw %d,%d(2)\n", count + 3, r * 4);
2600 fprintf(outfile,
2601 " lis 12,%s@ha \n"
2602 " addi 0,1,%d \n"
2603 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2604 " stw 0,%d(2) \n" /* REG_?? = taglist */
2605 " mtctr 11 \n"
2606 " lwz 12,%s@l(12)\n"
2607 " li 3,%ld \n" /* r3 = lvo */
2608 " stw 12,56(2) \n" /* REG_A6 = libbase */
2609 " bctrl \n",/* EmulCallOS() */
2610 BaseName, taglist, 4 * fD_GetReg(obj, numregs - 1), BaseName,
2611 fD_GetOffset(obj));
2614 fprintf(outfile," lwz 0,%d(1) \n" /* clear stack frame & return */
2615 " mtlr 0 \n"
2616 " addi 1,1,%d \n"
2617 " blr \n"
2618 ".L%se1: \n"
2619 " .size\t%s,.L%se1-%s\n"
2620 "\");\n\n",
2621 local + 4, local,
2622 tagname, tagname, tagname, tagname);
2624 else
2626 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2627 return;
2631 else if ((varname = getvarargsfunction(obj)) != 0 &&
2632 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2634 if (output_mode != STUBS)
2636 fprintf(outfile,
2637 "#ifndef NO_INLINE_VARARGS\n"
2638 "#define %s(", varname);
2640 for (count = d0; count < numregs - 1; count++)
2641 fprintf(outfile, "a%d, ", count);
2643 fprintf(outfile,
2644 "...) \\\n"
2645 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2646 name);
2648 for (count = d0; count < numregs - 1; count++)
2649 fprintf(outfile, "(a%d), ", count);
2651 fprintf(outfile,
2652 "(%s)_tags);})\n"
2653 "#endif /* !NO_INLINE_VARARGS */\n\n",
2654 fD_GetProto(obj, fD_RegNum(obj) - 1));
2656 else
2658 fprintf(stderr, "can`t create a varargs stub function for %s\n",
2659 varname);
2663 if (strcmp(name, "DoPkt")==0 &&
2664 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2666 fdDef *objnc=(fdDef*)obj;
2667 char newname[7]="DoPkt0";
2668 objnc->name=newname;
2669 for (count=2; count<7; count++)
2671 regs reg=objnc->reg[count];
2672 char *proto=objnc->proto[count];
2673 objnc->reg[count]=illegal;
2674 objnc->proto[count]=fD_nostring;
2675 fD_write(outfile, objnc);
2676 objnc->reg[count]=reg;
2677 objnc->proto[count]=proto;
2678 newname[5]++;
2680 objnc->name=(char*)name;
2685 varargsfunction(const char* proto, const char* funcname)
2687 const char *end=proto+strlen(proto)-1;
2688 while (isspace(*end))
2689 end--;
2690 if (*end--==';')
2692 while (isspace(*end))
2693 end--;
2694 if (*end--==')')
2696 while (isspace(*end))
2697 end--;
2698 if (!strncmp(end-2, "...", 3))
2700 /* Seems to be a varargs function. Check if it will be recognized
2701 as "tagged". */
2702 unsigned int count;
2703 char fixedname[200]; /* Hope will be enough... */
2704 fdDef *tmpdef;
2706 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0];
2707 count+=2)
2708 if (strcmp(funcname, TagExcTable[count+1])==0)
2709 return 1;
2711 if (!(tmpdef=fD_ctor()))
2713 fprintf(stderr, "No mem for FDs\n");
2714 exit(EXIT_FAILURE);
2717 strcpy(fixedname, funcname);
2718 if (strlen(funcname)>4 &&
2719 !strcmp(funcname+strlen(funcname)-4, "Tags"))
2721 /* Might be either nothing or "TagList". */
2722 fixedname[strlen(fixedname)-4]='\0';
2723 fD_NewName(tmpdef, fixedname);
2724 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2725 fD_cmpName))
2726 return 1;
2728 strcat(fixedname, "TagList");
2729 fD_NewName(tmpdef, fixedname);
2730 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2731 fD_cmpName))
2732 return 1;
2734 else
2736 strcat(fixedname, "A");
2737 fD_NewName(tmpdef, fixedname);
2738 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2739 fD_cmpName))
2740 return 1;
2745 return 0;
2749 ishandleddifferently(const char* proto, const char* funcname)
2751 /* First check if this is a vararg call? */
2752 if (varargsfunction(proto, funcname))
2753 return 1;
2755 /* It might be a dos.library "alias" name. */
2756 if (aliasfunction(funcname))
2757 return 1;
2759 /* It might be one from dos.library/DoPkt() family. */
2760 if (strlen(funcname)==6 && !strncmp(funcname, "DoPkt", 5) &&
2761 funcname[5]>='0' && funcname[6]<='4')
2762 return 1;
2764 /* Finally, it can be intuition.library/ReportMouse1(). */
2765 return !strcmp(funcname, "ReportMouse1");
2768 void
2769 printusage(const char* exename)
2771 fprintf(stderr,
2772 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2773 "Options:\n"
2775 "--mode=MODE\t\tMODE is one of the following:\n"
2776 "\tnew\t\t\tPreprocessor based (default)\n"
2777 "\told\t\t\tInline based\n"
2778 "\tstubs\t\t\tLibrary stubs\n"
2779 "\tgatestubs\t\tLibrary gate stubs\n"
2780 "\tgateproto\t\tLibrary gate prototypes\n"
2781 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2782 "\tgenmodule\t\t\tBuild genmodule .conf file\n"
2784 "--target=OS\t\tOS is one of the following: \n"
2785 "\t*-aros\t\t\tAROS (any CPU)\n"
2786 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2787 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2788 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2789 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2790 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2792 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2793 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2794 "--libprefix=PREFIX\tLocal function name prefix\n"
2795 "--local\t\t\tUse local includes\n"
2796 "--quiet\t\t\tDon't display warnings\n"
2797 "--version\t\tPrint version number and exit\n\n"
2798 "Compatibility options:\n"
2799 "--new\t\t\tSame as --mode=new\n"
2800 "--old\t\t\tSame as --mode=old\n"
2801 "--stubs\t\t\tSame as --mode=stubs\n"
2802 "--gatestubs\t\tSame as --mode=gatestubs\n"
2803 "--proto\t\t\tSame as --mode=prot\n"
2804 "--pos\t\t\tSame as --target=m68k-pos\n"
2805 "--morphos\t\tSame as --target=powerpc-morphos\n"
2806 "--powerup\t\tSame as --target=powerpc-powerup\n"
2807 , exename);
2810 void output_proto(FILE* outfile)
2812 fprintf(outfile,
2813 "/* Automatically generated header! Do not edit! */\n\n"
2814 "#ifndef PROTO_%s_H\n"
2815 "#define PROTO_%s_H\n\n",
2816 BaseNamU, BaseNamU);
2818 if (BaseName[0])
2819 fprintf(outfile,
2820 "#ifndef __NOLIBBASE__\n"
2821 "extern struct %s *\n"
2822 "#ifdef __CONSTLIBBASEDECL__\n"
2823 "__CONSTLIBBASEDECL__\n"
2824 "#endif /* __CONSTLIBBASEDECL__ */\n"
2825 "%s;\n"
2826 "#endif /* !__NOLIBBASE__ */\n\n",
2827 StdLib, BaseName);
2829 fprintf(outfile,
2830 "#ifdef __amigaos4__\n"
2831 "#include <interfaces/%s.h>\n"
2832 "#ifdef __USE_INLINE__\n"
2833 "#include <inline4/%s.h>\n"
2834 "#endif /* __USE_INLINE__ */\n"
2835 "#ifndef CLIB_%s_PROTOS_H\n"
2836 "#define CLIB_%s_PROTOS_H\n"
2837 "#endif /* CLIB_%s_PROTOS_H */\n"
2838 "#ifndef __NOGLOBALIFACE__\n"
2839 "extern struct %sIFace *I%s;\n"
2840 "#endif /* __NOGLOBALIFACE__ */\n"
2841 "#else /* __amigaos4__ */\n"
2842 "#include <clib/%s_protos.h>\n"
2843 "#ifdef __GNUC__\n"
2844 "#ifdef __AROS__\n"
2845 "#ifndef NOLIBDEFINES\n"
2846 "#ifndef %s_NOLIBDEFINES\n"
2847 "#include <defines/%s.h>\n"
2848 "#endif /* %s_NOLIBDEFINES */\n"
2849 "#endif /* NOLIBDEFINES */\n"
2850 "#else\n"
2851 "#ifdef __PPC__\n"
2852 "#ifndef _NO_PPCINLINE\n"
2853 "#include <ppcinline/%s.h>\n"
2854 "#endif /* _NO_PPCINLINE */\n"
2855 "#else\n"
2856 "#ifndef _NO_INLINE\n"
2857 "#include <inline/%s.h>\n"
2858 "#endif /* _NO_INLINE */\n"
2859 "#endif /* __PPC__ */\n"
2860 "#endif /* __AROS__ */\n"
2861 "#else\n"
2862 "#include <pragmas/%s_pragmas.h>\n"
2863 "#endif /* __GNUC__ */\n"
2864 "#endif /* __amigaos4__ */\n\n"
2865 "#endif /* !PROTO_%s_H */\n",
2866 BaseNamL, BaseNamL, BaseNamU, BaseNamU, BaseNamU, BaseNamC, BaseNamC,
2867 BaseNamL,
2868 BaseNamU, BaseNamL, BaseNamU,
2869 BaseNamL, BaseNamL, BaseNamL,
2870 BaseNamU);
2873 /******************************************************************************/
2876 main(int argc, char** argv)
2878 fdDef *tmpdef, /* a dummy to contain the name to look for */
2879 *founddef; /* the fdDef for which we found a prototype */
2880 fdFile *myfile;
2881 char *tmpstr;
2882 FILE *outfile;
2883 int closeoutfile=0;
2884 char *fdfilename=0, *clibfilename=0, *outfilename=0;
2886 int count;
2887 Error lerror;
2889 for (count=1; count<argc; count++)
2891 char *option=argv[count];
2892 if (*option=='-')
2894 option++;
2895 if (strcmp(option, "o")==0)
2897 if (count==argc-1 || outfilename)
2899 printusage(argv[0]);
2900 return EXIT_FAILURE;
2902 if (strcmp(argv[++count], "-"))
2903 outfilename=argv[count];
2905 else
2907 if (*option=='-') /* Accept GNU-style '--' options */
2908 option++;
2909 if (strncmp(option, "mode=", 5)==0)
2911 if (strcmp(option+5, "new")==0)
2912 output_mode=NEW;
2913 else if (strcmp(option+5, "old")==0)
2914 output_mode=OLD;
2915 else if (strcmp(option+5, "stubs")==0)
2916 output_mode=STUBS;
2917 else if (strcmp(option+5, "gatestubs")==0)
2918 output_mode=GATESTUBS;
2919 else if (strcmp(option+5, "gateproto")==0)
2920 output_mode=GATEPROTO;
2921 else if (strcmp(option+5, "proto")==0)
2922 output_mode=PROTO;
2923 else if (strcmp(option+5, "genmodule")==0)
2924 output_mode=GENMODULE;
2926 else if (strncmp(option, "target=", 7)==0)
2928 if (MatchGlob("*-aros",option+7))
2929 target=AROS;
2930 else if (MatchGlob("i?86be*-amithlon",option+7))
2931 target=IX86BE_AMITHLON;
2932 else if (MatchGlob("m68k*-amigaos",option+7))
2933 target=M68K_AMIGAOS;
2934 else if (MatchGlob("m68k*-pos",option+7))
2935 target=M68K_POS;
2936 else if (MatchGlob("powerpc*-powerup",option+7))
2937 target=PPC_POWERUP;
2938 else if (MatchGlob("powerpc*-morphos",option+7))
2939 target=PPC_MORPHOS;
2940 else
2942 printusage(argv[0]);
2943 return EXIT_FAILURE;
2946 else if (strcmp(option, "direct-varargs-calls") == 0)
2947 DirectVarargsCalls = 1;
2948 else if (strncmp(option, "gateprefix=", 11)==0)
2949 gateprefix = option+11;
2950 else if (strncmp(option, "libprefix=", 10)==0)
2951 libprefix = option+10;
2952 else if (strcmp(option, "quiet") == 0)
2953 Quiet = 1;
2954 else if (strcmp(option, "version")==0)
2956 fprintf(stderr, "fd2inline version " VERSION "\n");
2957 return EXIT_SUCCESS;
2959 /* Compatibility options */
2960 else if (strcmp(option, "new")==0)
2961 output_mode=NEW;
2962 else if (strcmp(option, "old")==0)
2963 output_mode=OLD;
2964 else if (strcmp(option, "stubs")==0)
2965 output_mode=STUBS;
2966 else if (strcmp(option, "gatestubs")==0)
2967 output_mode=GATESTUBS;
2968 else if (strcmp(option, "proto")==0)
2969 output_mode=PROTO;
2970 else if (strcmp(option, "pos")==0)
2971 target=M68K_POS;
2972 else if (strcmp(option, "powerup")==0)
2973 target=PPC_POWERUP;
2974 else if (strcmp(option, "morphos")==0)
2975 target=PPC_MORPHOS;
2976 /* Unknown option */
2977 else
2979 printusage(argv[0]);
2980 return EXIT_FAILURE;
2984 else
2986 /* One of the filenames */
2987 if (!fdfilename)
2988 fdfilename=option;
2989 else if (!clibfilename)
2990 clibfilename=option;
2991 else if (!outfilename)
2992 outfilename=option;
2993 else
2995 printusage(argv[0]);
2996 return EXIT_FAILURE;
3001 if (!fdfilename || (!clibfilename && output_mode!=PROTO))
3003 printusage(argv[0]);
3004 return EXIT_FAILURE;
3007 if (target==M68K_POS && output_mode!=NEW && output_mode!=GENMODULE)
3009 fprintf(stderr, "Target is not compatible with the mode.\n");
3010 return EXIT_FAILURE;
3013 if (!(arrdefs=malloc(FDS*sizeof(fdDef*))))
3015 fprintf(stderr, "No mem for FDs\n");
3016 return EXIT_FAILURE;
3018 for (count=0; count<FDS; count++)
3019 arrdefs[count]=NULL;
3021 if (!(myfile=fF_ctor(fdfilename)))
3023 fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
3024 return EXIT_FAILURE;
3027 lerror=false;
3029 for (count=0; count<FDS && lerror==false; count++)
3031 if (!(arrdefs[count]=fD_ctor()))
3033 fprintf(stderr, "No mem for FDs\n" );
3034 return EXIT_FAILURE;
3038 if ((lerror=fF_readln(myfile))==false)
3040 fF_SetError(myfile, false);
3041 lerror=fD_parsefd(arrdefs[count], myfile);
3044 while (lerror==nodef);
3046 if (count<FDS)
3048 count--;
3049 fD_dtor(arrdefs[count]);
3050 arrdefs[count]=NULL;
3052 fds=count;
3054 qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
3056 if (output_mode!=NEW || target==AROS)
3058 unsigned int count2;
3059 StdLib="Library";
3061 for (count2=0; count2<sizeof LibExcTable/sizeof LibExcTable[0]; count2+=2)
3062 if (strcmp(BaseName, LibExcTable[count2])==0)
3064 StdLib=LibExcTable[count2+1];
3065 break;
3069 fF_dtor(myfile);
3071 if (output_mode!=PROTO)
3073 if (!(myfile=fF_ctor(clibfilename)))
3075 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3076 return EXIT_FAILURE;
3079 if (!(tmpdef=fD_ctor()))
3081 fprintf(stderr, "No mem for FDs\n");
3082 return EXIT_FAILURE;
3085 for (lerror=false; lerror==false || lerror==nodef;)
3086 if ((lerror=fF_readln(myfile))==false)
3088 fF_SetError(myfile, false); /* continue even on errors */
3089 tmpstr=fF_FuncName(myfile);
3091 if (tmpstr)
3093 fdDef **res;
3094 fD_NewName(tmpdef, tmpstr);
3095 res=(fdDef**)bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
3096 fD_cmpName);
3098 if (res)
3100 founddef=*res;
3101 DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
3102 fF_SetError(myfile, false);
3103 lerror=fD_parsepr(founddef, myfile);
3105 else
3106 if (!ishandleddifferently(myfile->line, tmpstr))
3107 if (!Quiet)
3108 fprintf(stderr, "Don't know what to do with <%s> in line %lu.\n",
3109 tmpstr, myfile->lineno);
3110 free(tmpstr);
3114 fD_dtor(tmpdef);
3116 fF_dtor(myfile);
3119 if (strlen(fdfilename)>7 &&
3120 !strcmp(fdfilename+strlen(fdfilename)-7, "_lib.fd"))
3122 char *str=fdfilename+strlen(fdfilename)-8;
3123 while (str!=fdfilename && str[-1]!='/' && str[-1]!=':')
3124 str--;
3125 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3126 strncpy(BaseNamU, str, strlen(str)-7);
3127 BaseNamU[strlen(str)-7]='\0';
3128 strcpy(BaseNamL, BaseNamU);
3129 strcpy(BaseNamC, BaseNamU);
3131 else
3133 strcpy(BaseNamU, BaseName);
3134 if (strlen(BaseNamU)>4 && strcmp(BaseNamU+strlen(BaseNamU)-4, "Base")==0)
3135 BaseNamU[strlen(BaseNamU)-4]='\0';
3136 if (target==M68K_POS && strncmp(BaseNamU, "gb_", 3)==0)
3137 memmove(BaseNamU, &BaseNamU[3], strlen(&BaseNamU[3])+1);
3138 strcpy(BaseNamL, BaseNamU);
3139 strcpy(BaseNamC, BaseNamU);
3141 StrUpr(BaseNamU);
3142 BaseNamC[0]=toupper(BaseNamC[0]);
3144 if (outfilename)
3146 if (!(outfile=fopen(outfilename, "w")))
3148 fprintf(stderr, "Couldn't open output file.\n");
3149 return EXIT_FAILURE;
3151 else
3153 closeoutfile=1;
3156 else
3157 outfile=stdout;
3159 if (output_mode==PROTO)
3160 output_proto(outfile);
3161 else if (output_mode==GENMODULE)
3163 long offset = -30;
3164 qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpOffset);
3166 fprintf(outfile,"##begin config\n"
3167 "basename %s\n"
3168 "libbase %s\n"
3169 "##end config\n"
3170 "\n"
3171 "##begin cdef\n"
3172 "##end cdef\n"
3173 "\n"
3174 "##begin functionlist\n"
3175 , BaseName, BaseName);
3178 for (count=0; count<FDS && arrdefs[count]; count++)
3180 DBP(fprintf(stderr, "outputting %ld...\n", count));
3181 long off = fD_GetOffset(arrdefs[count]);
3182 if (off < offset) {
3183 int skip = (offset - off) / 6;
3184 fprintf(outfile, ".skip %d\n", skip);
3186 offset = off - 6;
3187 fD_write(outfile, arrdefs[count]);
3188 fD_dtor(arrdefs[count]);
3189 arrdefs[count]=NULL;
3192 fprintf(outfile, "##end functionlist\n");
3194 else
3196 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS ||
3197 output_mode==GATESTUBS || output_mode==GATEPROTO)
3199 if (output_mode==GATESTUBS || output_mode==GATEPROTO)
3201 fprintf(outfile,
3202 "/* Automatically generated stubs! Do not edit! */\n\n");
3204 else
3206 fprintf(outfile,
3207 "/* Automatically generated header! Do not edit! */\n\n"
3208 "#ifndef %sINLINE_%s_H\n"
3209 "#define %sINLINE_%s_H\n\n",
3210 (target==M68K_POS ? "__INC_POS_P" : "_"),
3211 BaseNamU,
3212 (target==M68K_POS ? "__INC_POS_P" : "_"),
3213 BaseNamU );
3216 if (output_mode==NEW)
3218 if(target==M68K_POS)
3220 fprintf(outfile,
3221 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3222 "#include <pInline/macros.h>\n"
3223 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3225 else if(target==AROS)
3227 fprintf(outfile,
3228 "#ifndef AROS_LIBCALL_H\n"
3229 "#include <aros/libcall.h>\n"
3230 "#endif /* !AROS_LIBCALL_H */\n\n");
3232 else
3234 fprintf(outfile,
3235 "#ifndef __INLINE_MACROS_H\n"
3236 "#include <inline/macros.h>\n"
3237 "#endif /* !__INLINE_MACROS_H */\n\n");
3240 else
3242 FILE* clib;
3244 fprintf(outfile,
3245 "#ifndef __INLINE_STUB_H\n"
3246 "#include <inline/stubs.h>\n"
3247 "#endif /* !__INLINE_STUB_H */\n\n");
3249 fprintf(outfile, "#ifdef __CLIB_TYPES__\n" );
3251 clib = fopen( clibfilename, "r" );
3253 if( clib == NULL )
3255 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3257 else
3259 char* buffer = malloc( 1024 );
3261 if( buffer == NULL )
3263 fprintf(stderr, "No memory for line buffer.\n " );
3265 else
3267 while( fgets( buffer, 1023, clib ) != NULL )
3269 if( buffer[ 0 ] == '#' /* Pre-processor instruction */ ||
3270 strncmp( buffer, "typedef", 7 ) == 0 )
3272 fputs(buffer, outfile );
3276 free( buffer );
3279 fclose( clib );
3282 fprintf(outfile, "#endif /* __CLIB_TYPES__ */\n\n" );
3284 if(target==AROS)
3286 fprintf(outfile,
3287 "#include <aros/libcall.h>\n\n" );
3289 else if(target==IX86BE_AMITHLON)
3291 fprintf(outfile,
3292 "#ifndef __INLINE_MACROS_H\n"
3293 "#include <inline/macros.h>\n"
3294 "#endif /* __INLINE_MACROS_H */\n\n");
3296 else if (target == PPC_MORPHOS)
3298 fprintf(outfile,
3299 "#include <emul/emulregs.h>\n\n" );
3303 else
3305 fprintf(stderr, "Internal error: Unknown output mode in main().\n");
3307 if (closeoutfile)
3309 fclose(outfile);
3312 return EXIT_FAILURE;
3315 if (BaseName[0])
3317 if (output_mode==NEW)
3319 fprintf(outfile,
3320 "#ifndef %s%s_BASE_NAME\n"
3321 "#define %s%s_BASE_NAME %s\n"
3322 "#endif /* !%s%s_BASE_NAME */\n\n",
3323 (target==M68K_POS ? "__" : ""), BaseNamU,
3324 (target==M68K_POS ? "__" : ""), BaseNamU, BaseName,
3325 (target==M68K_POS ? "__" : ""), BaseNamU);
3326 if (target==M68K_POS)
3327 fprintf(outfile,
3328 "#ifndef __%s_LIB_NAME\n"
3329 "#define __%s_LIB_NAME %s\n"
3330 "#endif /* !__%s_LIB_NAME */\n\n",
3331 BaseNamU, BaseNamU,
3332 (strcmp(BaseName, "gb_ExecBase") ? BaseName : "gb_ExecLib"),
3333 BaseNamU);
3335 else
3336 fprintf(outfile,
3337 "#ifndef BASE_EXT_DECL\n"
3338 "#define BASE_EXT_DECL\n"
3339 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3340 "#endif /* !BASE_EXT_DECL */\n"
3341 "#ifndef BASE_PAR_DECL\n"
3342 "#define BASE_PAR_DECL\n"
3343 "#define BASE_PAR_DECL0 void\n"
3344 "#endif /* !BASE_PAR_DECL */\n"
3345 "#ifndef BASE_NAME\n"
3346 "#define BASE_NAME %s\n"
3347 "#endif /* !BASE_NAME */\n\n"
3348 "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
3351 for (count=0; count<FDS && arrdefs[count]; count++)
3353 DBP(fprintf(stderr, "outputting %ld...\n", count));
3355 fD_write(outfile, arrdefs[count]);
3356 fD_dtor(arrdefs[count]);
3357 arrdefs[count]=NULL;
3360 if (output_mode!=NEW)
3361 if (BaseName[0])
3362 fprintf(outfile,
3363 "#undef BASE_EXT_DECL\n"
3364 "#undef BASE_EXT_DECL0\n"
3365 "#undef BASE_PAR_DECL\n"
3366 "#undef BASE_PAR_DECL0\n"
3367 "#undef BASE_NAME\n\n");
3369 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS)
3371 fprintf(outfile, "#endif /* !%sINLINE_%s_H */\n",
3372 (target==M68K_POS ? "__INC_POS_P" : "_"), BaseNamU);
3376 free(arrdefs);
3378 if (closeoutfile)
3380 fclose(outfile);
3383 return EXIT_SUCCESS;