Specify in alert code what library couldn't be opened (where possible).
[AROS.git] / tools / fd2inline / fd2inline.c
blobdf221e3c24a9b111f30ebc9e557b9a22aeeb4fdd
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 const static char version_str[]="$VER: fd2inline " VERSION " (24.2.2002)";
44 /******************************************************************************
45 * These are general definitions including types for defining registers etc.
46 ******************************************************************************/
48 #ifdef DEBUG
49 #define DBP(a) a
50 #else /* !DEBUG */
51 #define DBP(a)
52 #endif /* !DEBUG */
54 #if (defined(__GNUC__) || defined(__SASC)) && 0
55 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
56 #else
57 #define INLINE
58 #endif
60 #define REGS 16 /* d0=0,...,a7=15 */
61 #define FDS 1000
63 /* To prevent the enum below from getting broken when building on AROS */
64 #undef AROS
66 typedef enum
68 d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
69 } regs;
71 typedef unsigned char shortcard;
73 typedef enum { false, nodef, real_error } Error;
75 enum { NEW, OLD, STUBS, PROTO, GATESTUBS, GATEPROTO } output_mode=NEW;
76 enum { IX86BE_AMITHLON, AROS, M68K_AMIGAOS, M68K_POS, PPC_POWERUP, PPC_MORPHOS } target = M68K_AMIGAOS;
78 int Quiet = 0;
79 int DirectVarargsCalls = 0;
80 int RegLibFlag = 0;
81 int PreLibFlag = 0;
82 int PostLibFlag = 0;
83 char *gateprefix = "";
84 char *libprefix = "";
86 char BaseName[64], BaseNamU[64], BaseNamL[64], BaseNamC[64];
87 char Buffer[512];
89 const static char *LibExcTable[]=
91 "BattClockBase", "Node",
92 "BattMemBase", "Node",
93 "ConsoleDevice", "Device",
94 "DiskBase", "DiskResource",
95 "DOSBase", "DosLibrary",
96 "SysBase", "ExecBase",
97 "ExpansionBase", "ExpansionBase",
98 "GfxBase", "GfxBase",
99 "InputBase", "Device",
100 "IntuitionBase", "IntuitionBase",
101 "LocaleBase", "LocaleBase",
102 "MathIeeeDoubBasBase", "MathIEEEBase",
103 "MathIeeeDoubTransBase","MathIEEEBase",
104 "MathIeeeSingBasBase", "MathIEEEBase",
105 "MathIeeeSingTransBase","MathIEEEBase",
106 "MiscBase", "Node",
107 "PotgoBase", "Node",
108 "RamdriveDevice", "Device",
109 "RealTimeBase", "RealTimeBase",
110 "RexxSysBase", "RxsLib",
111 "TimerBase", "Device",
112 "UtilityBase", "UtilityBase"
114 const char *StdLib; /* global lib-name ptr */
116 /*******************************************
117 * just some support functions, no checking
118 *******************************************/
120 char*
121 NewString(char** new, const char* old)
123 const char *high;
124 unsigned long len;
126 while (*old && (*old==' ' || *old=='\t'))
127 old++;
128 len=strlen(old);
129 for (high=old+len-1; high>=old && (*high==' ' || *high=='\t'); high--);
130 high++;
131 len=high-old;
132 *new=malloc(1+len);
133 if (*new)
135 strncpy(*new, old, len);
136 (*new)[len]='\0';
138 else
139 fprintf(stderr, "No mem for string\n");
140 return *new;
143 static INLINE void
144 illparams(const char* funcname)
146 fprintf(stderr, "%s: illegal Parameters\n", funcname);
149 static INLINE const char*
150 RegStr(regs reg)
152 const static char *aosregs[]=
154 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
155 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
157 *posregs[]=
159 "__INLINE_REG_D0",
160 "__INLINE_REG_D1",
161 "__INLINE_REG_D2",
162 "__INLINE_REG_D3",
163 "__INLINE_REG_D4",
164 "__INLINE_REG_D5",
165 "__INLINE_REG_D6",
166 "__INLINE_REG_D7",
167 "__INLINE_REG_A0",
168 "__INLINE_REG_A1",
169 "__INLINE_REG_A2",
170 "__INLINE_REG_A3",
171 "__INLINE_REG_A4",
172 "__INLINE_REG_A5",
173 "__INLINE_REG_A6",
174 "__INLINE_REG_A7",
175 "illegal"
178 if (reg>illegal)
179 reg=illegal;
180 if (reg<d0)
181 reg=d0;
182 return (target!=M68K_POS ? aosregs[reg] : posregs[reg]);
185 static INLINE const char*
186 RegStrU(regs reg)
188 const static char *aosregs[]=
190 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
191 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
194 if (reg>illegal)
195 reg=illegal;
196 if (reg<d0)
197 reg=d0;
198 return (target!=M68K_POS ? aosregs[reg] : RegStr(reg));
201 static INLINE
203 /******************************************************************************
204 * StrNRBrk
206 * searches string in from position at downwards, as long as in does not
207 * contain any character in not.
209 ******************************************************************************/
211 const char*
212 StrNRBrk(const char* in, const char* not, const char* at)
214 const char *chcheck;
215 Error ready;
217 chcheck=""; /* if at<in, the result will be NULL */
218 for (ready=false; ready==false && at>=in;)
220 for (chcheck=not; *chcheck && *chcheck != *at; chcheck++);
221 if (*chcheck)
222 ready=real_error;
223 else
224 at--;
226 DBP(fprintf(stderr, "{%c}", *chcheck));
227 return *chcheck ? at : NULL;
231 Our own "strupr", since it is a non-standard function.
233 void
234 StrUpr(char* str)
236 while (*str)
238 *str=toupper(*str);
239 str++;
244 MatchGlob( char* glob, char* str )
246 while( *glob )
248 char c = *glob++;
250 switch( c )
252 case '?':
253 if( *str == 0 )
255 return 0;
257 break;
259 case '\\':
260 c = *glob++;
261 if( c == 0 || *str != c )
263 return 0;
265 break;
267 case '*':
268 if( *glob == 0 )
270 return 1;
273 while( *str )
275 if( MatchGlob( glob, str ) )
277 return 1;
279 ++str;
281 return 0;
283 default:
284 if( *str != c )
286 return 0;
288 break;
291 ++str;
294 return *str == 0;
298 /******************************************************************************
299 * CLASS fdFile
301 * stores a file with a temporary buffer (static length, sorry), a line number,
302 * an offset (used for library offsets and an error field.
303 * When there's no error, line will contain line #lineno and offset will be
304 * the last offset set by the interpretation of the last line. If there's been
305 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
306 * It is assumed offsets are always negative.
307 ******************************************************************************/
309 #define fF_BUFSIZE 1024
311 /* all you need to know about an fdFile you parse */
313 typedef enum {FD_PRIVATE=1, FD_SHADOW=2} fdflags;
315 typedef struct
317 FILE* file; /* the file we're reading from */
318 char line[fF_BUFSIZE]; /* the current line */
319 unsigned long lineno; /* current line number */
320 long offset; /* current fd offset (-bias) */
321 Error error; /* is everything o.k. */
322 fdflags flags; /* for ##private, ##shadow (p.OS) */
323 } fdFile;
325 fdFile*
326 fF_ctor (const char* fname);
327 static void
328 fF_dtor (fdFile* obj);
329 static void
330 fF_SetError (fdFile* obj, Error error);
331 static void
332 fF_SetOffset (fdFile* obj, long at);
333 Error
334 fF_readln (fdFile* obj);
335 static Error
336 fF_GetError (const fdFile* obj);
337 static long
338 fF_GetOffset (const fdFile* obj);
339 char*
340 fF_FuncName (fdFile* obj); /* return name or null */
341 static void
342 fF_SetFlags (fdFile* obj, fdflags flags);
343 static fdflags
344 fF_GetFlags (const fdFile* obj);
346 static INLINE void
347 fF_dtor(fdFile* obj)
349 fclose(obj->file);
350 free(obj);
353 static INLINE void
354 fF_SetError(fdFile* obj, Error error)
356 if (obj)
357 obj->error=error;
358 else
359 illparams("fF_SetError");
362 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
364 static INLINE void
365 fF_SetOffset(fdFile* obj, long at)
367 if (obj)
368 obj->offset= at;
369 else
370 illparams("fFSetOffset");
373 static INLINE void
374 fF_SetFlags(fdFile* obj, fdflags flags)
376 if (obj)
377 obj->flags=flags;
378 else
379 illparams("fF_SetFlags");
382 fdFile*
383 fF_ctor(const char* fname)
385 fdFile *result;
387 if (fname)
389 result=malloc(sizeof(fdFile));
390 if (result)
392 result->file=fopen(fname, "r");
393 if (result->file)
395 result->lineno=0;
396 fF_SetOffset(result, -30);
397 fF_SetError(result, false);
398 fF_SetFlags(result, 0);
399 result->line[0]='\0';
401 else
403 free(result);
404 result=NULL;
408 else
410 result=NULL;
411 illparams("fF_ctor");
413 return result;
416 Error
417 fF_readln(fdFile* obj)
419 char *low, *bpoint;
420 long glen, /* the length we read until now */
421 len; /* the length of the last segment */
423 if (obj)
425 low=obj->line;
426 glen=0;
428 for (;;)
430 obj->lineno++;
431 if (!fgets(low, fF_BUFSIZE-1-glen, obj->file))
433 fF_SetError(obj, real_error);
434 obj->line[0]='\0';
435 return real_error;
437 if (low==strpbrk(low, "*#/"))
439 DBP(fprintf(stderr, "in# %s\n", obj->line));
440 return false;
442 len=strlen(low);
443 bpoint=low+len-1;
444 while (len && isspace(*bpoint))
446 bpoint--;
447 len--;
449 if (*bpoint==';' || *bpoint==')')
451 DBP(fprintf(stderr, "\nin: %s\n", obj->line));
452 return false;
454 glen+=len;
455 low+=len;
456 if (glen>=fF_BUFSIZE-10) /* somewhat pessimistic? */
458 fF_SetError(obj, real_error);
459 fprintf(stderr, "Line %lu too long.\n", obj->lineno);
460 return real_error;
462 DBP(fprintf(stderr, "+"));
465 illparams("fF_readln");
466 return real_error;
469 static INLINE Error
470 fF_GetError(const fdFile* obj)
472 if (obj)
473 return obj->error;
474 illparams("fF_GetError");
475 return real_error;
478 static INLINE long
479 fF_GetOffset(const fdFile* obj)
481 if (obj)
482 return obj->offset;
483 illparams("fF_GetOffset");
484 return -1;
487 /******************************************************************************
488 * fF_FuncName
490 * checks if it can find a function-name and return it's address, or NULL
491 * if the current line does not seem to contain one. The return value will
492 * be a pointer into a malloced buffer, thus the caller will have to free().
493 ******************************************************************************/
495 char*
496 fF_FuncName(fdFile* obj)
498 const char *lower;
499 const char *upper;
500 char *buf;
501 long obraces; /* count of open braces */
502 Error ready; /* ready with searching */
504 if (!obj || fF_GetError(obj)==real_error)
506 illparams("fF_FuncName");
507 return NULL;
510 lower=obj->line;
511 while (*lower && (*lower==' ' || *lower=='\t'))
512 lower++;
514 if (!*lower || (!isalpha(*lower) && *lower!='_'))
516 fF_SetError(obj, nodef);
517 return NULL;
520 while (*lower)
522 if (!isalnum(*lower) && !isspace(*lower) && *lower!='*' && *lower!=','
523 && *lower!='.' && *lower!=';' && *lower!='(' && *lower!=')' &&
524 *lower!='[' && *lower!=']' && *lower!='_' && *lower!='\\')
526 fF_SetError(obj, nodef);
527 return NULL;
529 lower++;
532 lower=NULL;
533 buf=NULL;
535 if (obj && fF_GetError(obj)==false)
537 if ((upper=strrchr(obj->line, ')'))!=0)
539 DBP(fprintf(stderr, "end:%s:", upper));
541 for (obraces=1, ready=false; ready==false; upper=lower)
543 lower=StrNRBrk(obj->line, "()", --upper);
544 if (lower)
546 switch (*lower)
548 case ')':
549 obraces++;
550 DBP(fprintf(stderr, " )%ld%s", obraces, lower));
551 break;
552 case '(':
553 obraces--;
554 DBP(fprintf(stderr, " (%ld%s", obraces, lower));
555 if (!obraces)
556 ready=nodef;
557 break;
558 default:
559 fprintf(stderr, "Faulty StrNRBrk\n");
562 else
564 fprintf(stderr, "'(' or ')' expected in line %lu.\n",
565 obj->lineno);
566 ready=real_error;
569 if (ready==nodef) /* we found the matching '(' */
571 long newlen;
572 const char* name;
574 upper--;
576 while (upper>=obj->line && (*upper==' ' || *upper=='\t'))
577 upper--;
579 lower=StrNRBrk(obj->line, " \t*)", upper);
581 if (!lower)
582 lower=obj->line;
583 else
584 lower++;
586 for (name=lower; name<=upper; name++)
587 if (!isalnum(*name) && *name!='_')
589 fF_SetError(obj, nodef);
590 return NULL;
593 newlen=upper-lower+1;
594 buf=malloc(newlen+1);
596 if (buf)
598 strncpy(buf, lower, newlen);
599 buf[newlen]='\0';
601 else
602 fprintf(stderr, "No mem for fF_FuncName");
606 else
607 illparams("fF_FuncName");
608 return buf;
611 static INLINE fdflags
612 fF_GetFlags(const fdFile* obj)
614 if (obj)
615 return obj->flags;
616 illparams("fF_GetFlags");
617 return 0;
620 /*********************
621 * CLASS fdDef *
622 *********************/
624 typedef struct
626 char* name;
627 char* type;
628 long offset;
629 regs reg[REGS];
630 char* param[REGS];
631 char* proto[REGS];
632 regs funcpar; /* number of argument that has type "pointer to function" */
633 } fdDef;
635 fdDef*
636 fD_ctor (void);
637 void
638 fD_dtor (fdDef* obj);
639 static void
640 fD_NewName (fdDef* obj, const char* newname);
641 void
642 fD_NewParam (fdDef* obj, shortcard at, const char* newstr);
644 fD_NewProto (fdDef* obj, shortcard at, char* newstr);
645 static void
646 fD_NewReg (fdDef* obj, shortcard at, regs reg);
647 static void
648 fD_NewType (fdDef* obj, const char* newstr);
649 static void
650 fD_SetOffset (fdDef* obj, long off);
651 Error
652 fD_parsefd (fdDef* obj, fdFile* infile);
653 Error
654 fD_parsepr (fdDef* obj, fdFile* infile);
655 static const char*
656 fD_GetName (const fdDef* obj);
657 static long
658 fD_GetOffset (const fdDef* obj);
659 static const char*
660 fD_GetParam (const fdDef* obj, shortcard at);
661 static regs
662 fD_GetReg (const fdDef* obj, shortcard at);
663 static const char*
664 fD_GetRegStr (const fdDef* obj, shortcard at);
665 static const char*
666 fD_GetRegStrU (const fdDef* obj, shortcard at);
667 static const char*
668 fD_GetType (const fdDef* obj);
669 static shortcard
670 fD_ParamNum (const fdDef* obj);
671 static shortcard
672 fD_ProtoNum (const fdDef* obj);
673 static shortcard
674 fD_RegNum (const fdDef* obj);
676 fD_cmpName (const void* big, const void* small);
677 void
678 fD_write (FILE* outfile, const fdDef* obj);
679 static shortcard
680 fD_GetFuncParNum (const fdDef* obj);
681 static void
682 fD_SetFuncParNum (fdDef* obj, shortcard at);
683 static void
684 fD_adjustargnames(fdDef *obj);
686 fdDef **arrdefs;
687 long fds;
689 char *fD_nostring="";
691 fdDef*
692 fD_ctor(void)
694 fdDef *result;
695 regs count;
697 result=malloc(sizeof(fdDef));
699 if (result)
701 result->name=fD_nostring;
702 result->type=fD_nostring;
703 result->funcpar=illegal;
705 for (count=d0; count<illegal; count++ )
707 result->reg[count]=illegal;
708 result->param[count]=fD_nostring; /* if (!strlen) dont't free() */
709 result->proto[count]=fD_nostring;
712 return result;
715 /* free all resources and make the object as illegal as possible */
717 void
718 fD_dtor(fdDef* obj)
720 regs count;
722 if (obj)
724 if (!obj->name)
725 fprintf(stderr, "fD_dtor: null name");
726 else
727 if (obj->name!=fD_nostring)
728 free(obj->name);
730 if (!obj->type)
731 fprintf(stderr, "fD_dtor: null type");
732 else
733 if (obj->type!=fD_nostring)
734 free(obj->type);
736 obj->name=obj->type=NULL;
738 for (count=d0; count<illegal; count++)
740 obj->reg[count]=illegal;
742 if (!obj->param[count])
743 fprintf(stderr, "fD_dtor: null param");
744 else
745 if (obj->param[count]!=fD_nostring)
746 free(obj->param[count]);
748 if (!obj->proto[count])
749 fprintf(stderr, "fD_dtor: null proto");
750 else
751 if (obj->proto[count]!=fD_nostring)
752 free(obj->proto[count]);
754 obj->param[count]=obj->proto[count]=NULL;
757 free(obj);
759 else
760 fprintf(stderr, "fd_dtor(NULL)\n");
763 static INLINE void
764 fD_NewName(fdDef* obj, const char* newname)
766 if (obj && newname)
768 if (obj->name && obj->name!=fD_nostring)
769 free(obj->name);
770 if (!NewString(&obj->name, newname))
771 obj->name=fD_nostring;
773 else
774 illparams("fD_NewName");
777 void
778 fD_NewParam(fdDef* obj, shortcard at, const char* newstr)
780 char *pa;
782 if (newstr && obj && at<illegal)
784 pa=obj->param[at];
786 if (pa && pa!=fD_nostring)
787 free(pa);
789 while (*newstr==' ' || *newstr=='\t')
790 newstr++;
792 if (NewString(&pa, newstr))
794 char* prefix_pa;
796 prefix_pa = malloc( strlen( pa ) + 4 );
798 if( prefix_pa == NULL )
800 fprintf(stderr, "No mem for string\n");
802 else
804 sprintf( prefix_pa, "___%s", pa );
805 obj->param[at]=prefix_pa;
806 free( pa );
809 else
810 obj->param[at]=fD_nostring;
812 else
813 illparams("fD_NewParam");
816 /* get first free *reg or illegal */
818 static INLINE shortcard
819 fD_RegNum(const fdDef* obj)
821 shortcard count;
823 if (obj)
825 for (count=d0; count<illegal && obj->reg[count]!=illegal; count++);
826 return count;
828 else
830 illparams("fD_RegNum");
831 return illegal;
835 static INLINE void
836 fD_NewReg(fdDef* obj, shortcard at, regs reg)
838 if (obj && at<illegal && reg>=d0 && reg<=illegal)
839 obj->reg[at]=reg;
840 else
841 illparams("fD_NewReg");
844 static INLINE regs
845 fD_GetReg(const fdDef* obj, shortcard at)
847 if (obj && at<illegal)
848 return obj->reg[at];
849 else
851 illparams("fD_GetReg");
852 return illegal;
856 static INLINE shortcard
857 fD_GetFuncParNum(const fdDef* obj)
859 if (obj)
860 return (shortcard)obj->funcpar;
861 else
863 illparams("fD_GetFuncParNum");
864 return illegal;
868 static INLINE void
869 fD_SetFuncParNum(fdDef* obj, shortcard at)
871 if (obj && at<illegal)
872 obj->funcpar=at;
873 else
874 illparams("fD_SetFuncParNum");
878 fD_NewProto(fdDef* obj, shortcard at, char* newstr)
880 char *pr;
882 if (newstr && obj && at<illegal)
884 char *t, arr[200]; /* I hope 200 will be enough... */
885 int numwords=1;
886 pr=obj->proto[at];
888 if (pr && pr!=fD_nostring)
889 free(pr);
891 while (*newstr==' ' || *newstr=='\t')
892 newstr++; /* Skip leading spaces */
894 t=arr;
895 while ((*t++=*newstr)!=0)
897 /* Copy the rest, counting number of words */
898 if ((*newstr==' ' || *newstr=='\t') && newstr[1] && newstr[1]!=' ' &&
899 newstr[1]!='\t')
900 numwords++;
901 newstr++;
904 t=arr+strlen(arr)-1;
905 while (*t==' ' || *t=='\t')
906 t--;
907 t[1]='\0'; /* Get rid of tailing spaces */
909 if (at!=fD_GetFuncParNum(obj))
911 if (numwords>1) /* One word - must be type */
912 if (*t!='*')
914 /* '*' on the end - no parameter name used */
915 while (*t!=' ' && *t!='\t' && *t!='*')
916 t--;
917 t++;
918 if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
919 && strcmp(t, "long") && strcmp(t, "APTR"))
921 /* Not one of applicable keywords - must be parameter name.
922 Get rid of it. */
923 t--;
924 while (*t==' ' || *t=='\t')
925 t--;
926 t[1]='\0';
930 else
932 /* Parameter of type "pointer to function". */
933 char *end;
934 t=strchr(arr, '(');
935 t++;
936 while (*t==' ' || *t=='\t')
937 t++;
938 if (*t!='*')
939 return 1;
940 t++;
941 end=strchr(t, ')');
942 if (target!=M68K_POS)
944 memmove(t+2, end, strlen(end)+1);
945 *t='%';
946 t[1]='s';
948 else
949 memmove(t, end, strlen(end)+1);
952 if (NewString(&pr, arr))
954 obj->proto[at]=pr;
955 while (*pr==' ' || *pr=='\t')
956 pr++;
957 if (!strcasecmp(pr, "double"))
959 /* "double" needs two data registers */
960 int count, regs=fD_RegNum(obj);
961 for (count=at+1; count<regs; count++)
962 fD_NewReg(obj, count, fD_GetReg(obj, count+1));
965 else
966 obj->proto[at]=fD_nostring;
968 else
969 illparams("fD_NewProto");
971 return 0;
974 static INLINE void
975 fD_NewType(fdDef* obj, const char* newtype)
977 if (obj && newtype)
979 if (obj->type && obj->type!=fD_nostring)
980 free(obj->type);
981 if (!NewString(&obj->type, newtype))
982 obj->type=fD_nostring;
984 else
985 illparams("fD_NewType");
988 static INLINE void
989 fD_SetOffset(fdDef* obj, long off)
991 if (obj)
992 obj->offset=off;
993 else
994 illparams("fD_SetOffset");
997 static INLINE const char*
998 fD_GetName(const fdDef* obj)
1000 if (obj && obj->name)
1001 return obj->name;
1002 else
1004 illparams("fD_GetName");
1005 return fD_nostring;
1009 static INLINE long
1010 fD_GetOffset(const fdDef* obj)
1012 if (obj)
1013 return obj->offset;
1014 else
1016 illparams("fD_GetOffset");
1017 return 0;
1021 static INLINE const char*
1022 fD_GetProto(const fdDef* obj, shortcard at)
1024 if (obj && at<illegal && obj->proto[at])
1025 return obj->proto[at];
1026 else
1028 illparams("fD_GetProto");
1029 return fD_nostring;
1033 static INLINE const char*
1034 fD_GetParam(const fdDef* obj, shortcard at)
1036 if (obj && at<illegal && obj->param[at])
1037 return obj->param[at];
1038 else
1040 illparams("fD_GetParam");
1041 return fD_nostring;
1045 static INLINE const char*
1046 fD_GetRegStr(const fdDef* obj, shortcard at)
1048 if (obj && at<illegal)
1049 return RegStr(obj->reg[at]);
1050 else
1052 illparams("fD_GetReg");
1053 return RegStr(illegal);
1057 static INLINE const char*
1058 fD_GetRegStrU(const fdDef* obj, shortcard at)
1060 if (obj && at<illegal)
1061 return RegStrU(obj->reg[at]);
1062 else
1064 illparams("fD_GetReg");
1065 return RegStrU(illegal);
1069 static INLINE const char*
1070 fD_GetType(const fdDef* obj)
1072 if (obj && obj->type)
1073 return obj->type;
1074 else
1076 illparams("fD_GetType");
1077 return fD_nostring;
1081 /* get first free param or illegal */
1083 static INLINE shortcard
1084 fD_ParamNum(const fdDef* obj)
1086 shortcard count;
1088 if (obj)
1090 for (count=d0; count<illegal && obj->param[count]!=fD_nostring;
1091 count++);
1092 return count;
1094 else
1096 illparams("fD_ParamNum");
1097 return illegal;
1101 static INLINE shortcard
1102 fD_ProtoNum(const fdDef* obj)
1104 shortcard count;
1106 if (obj)
1108 for (count=d0; count<illegal && obj->proto[count]!=fD_nostring;
1109 count++);
1110 return count;
1112 else
1114 illparams("fD_ProtoNum");
1115 return illegal;
1119 /******************************************************************************
1120 * fD_parsefd
1122 * parse the current line. Needs to copy input, in order to insert \0's
1123 * RETURN
1124 * fF_GetError(infile):
1125 * false = read a definition.
1126 * nodef = not a definition on line (so try again)
1127 * error = real error
1128 ******************************************************************************/
1130 Error
1131 fD_parsefd(fdDef* obj, fdFile* infile)
1133 enum parse_info { name, params, regs, ready } parsing;
1134 char *buf, *bpoint, *bnext;
1135 unsigned long index;
1137 if (obj && infile && fF_GetError(infile)==false)
1139 parsing=name;
1141 if (!NewString(&buf, infile->line))
1143 fprintf(stderr, "No mem for line %lu\n", infile->lineno);
1144 fF_SetError(infile, real_error);
1146 bpoint=buf; /* so -Wall keeps quiet */
1148 /* try to parse the line until there's an error or we are done */
1150 while (parsing!=ready && fF_GetError(infile)==false)
1152 switch (parsing)
1154 case name:
1155 switch (buf[0])
1157 case '#':
1158 if (strncmp("##base", buf, 6)==0)
1160 bnext=buf+6;
1161 while (*bnext==' ' || *bnext=='\t' || *bnext=='_')
1162 bnext++;
1163 strcpy(BaseName, bnext);
1164 BaseName[strlen(BaseName)-1]='\0';
1166 else
1167 if (strncmp("##bias", buf, 6)==0)
1169 if (!sscanf(buf+6, "%ld", &infile->offset))
1171 fprintf(stderr, "Illegal ##bias in line %lu: %s\n",
1172 infile->lineno, infile->line);
1173 fF_SetError(infile, real_error);
1174 break; /* avoid nodef */
1176 else
1178 if (fF_GetOffset(infile)>0)
1179 fF_SetOffset(infile, -fF_GetOffset(infile));
1180 DBP(fprintf(stderr, "set offset to %ld\n",
1181 fF_GetOffset(infile)));
1184 else
1186 if (strncmp("##private", buf, 9)==0)
1187 fF_SetFlags(infile, fF_GetFlags(infile) |
1188 FD_PRIVATE);
1189 else if (strncmp("##public", buf, 8)==0)
1190 fF_SetFlags(infile, fF_GetFlags(infile) &
1191 ~FD_PRIVATE);
1192 else if (strncmp("##shadow", buf, 8)==0)
1193 fF_SetFlags(infile, fF_GetFlags(infile) |
1194 FD_SHADOW);
1196 /* drop through for error comment */
1198 case '*':
1199 /* try again somewhere else */
1200 fF_SetError(infile, nodef);
1201 break;
1203 default:
1204 /* assume a regular line here */
1205 if (fF_GetFlags(infile) & (FD_PRIVATE | FD_SHADOW))
1207 /* don't store names of privates */
1208 fF_SetError(infile, nodef);
1209 if (!(fF_GetFlags(infile) & FD_SHADOW))
1210 fF_SetOffset(infile,
1211 fF_GetOffset(infile)-FUNCTION_GAP);
1212 else
1213 /* Shadow is valid for one line only. */
1214 fF_SetFlags(infile, fF_GetFlags(infile) &
1215 ~FD_SHADOW);
1216 break;
1218 parsing=name; /* switch (parsing) */
1219 for (index=0; buf[index] && buf[index]!='('; index++);
1221 if (!buf[index])
1223 /* oops, no fd ? */
1224 fprintf(stderr, "Not an fd, line %lu: %s\n",
1225 infile->lineno, buf /* infile->line */);
1226 fF_SetError(infile, nodef);
1227 } /* maybe next time */
1228 else
1230 buf[index]=0;
1232 fD_NewName(obj, buf);
1233 fD_SetOffset(obj, fF_GetOffset(infile));
1235 bpoint=buf+index+1;
1236 parsing=params; /* continue the loop */
1239 break;
1241 case params:
1243 char *bptmp; /* needed for fD_NewParam */
1245 /* look for parameters now */
1247 for (bnext = bpoint; *bnext && *bnext!=',' && *bnext!=')';
1248 bnext++);
1250 if (*bnext)
1252 bptmp=bpoint;
1254 if (*bnext == ')')
1256 if (bnext[1] != '(')
1258 fprintf(stderr, "Registers expected in line %lu: %s\n",
1259 infile->lineno, infile->line);
1260 fF_SetError(infile, nodef);
1262 else
1264 parsing=regs;
1265 bpoint=bnext+2;
1268 else
1269 bpoint = bnext+1;
1271 /* terminate string and advance to next item */
1273 *bnext='\0';
1274 fD_NewParam(obj, fD_ParamNum(obj), bptmp);
1276 else
1278 fF_SetError(infile, nodef);
1279 fprintf(stderr, "Param expected in line %lu: %s\n",
1280 infile->lineno, infile->line);
1282 break; /* switch parsing */
1285 case regs:
1286 /* look for parameters now */
1288 for (bnext=bpoint; *bnext && *bnext!='/' && *bnext!=',' &&
1289 *bnext!=')'; bnext++);
1291 if (*bnext)
1293 if (')'==*bnext)
1295 /* wow, we've finished */
1296 fF_SetOffset(infile, fF_GetOffset(infile)-FUNCTION_GAP);
1297 parsing=ready;
1299 *bnext = '\0';
1301 bpoint[0]=tolower(bpoint[0]);
1303 if ((bpoint[0]=='d' || bpoint[0]=='a') && bpoint[1]>='0' &&
1304 bpoint[1]<='8' && bnext==bpoint+2)
1305 fD_NewReg(obj, fD_RegNum(obj),
1306 bpoint[1]-'0'+(bpoint[0]=='a'? 8 : 0));
1307 else
1308 if (bnext!=bpoint)
1310 /* it is when our function is void */
1311 fprintf(stderr, "Illegal register %s in line %ld\n",
1312 bpoint, infile->lineno);
1313 fF_SetError(infile, nodef);
1315 bpoint = bnext+1;
1317 else
1319 fF_SetError(infile, nodef);
1320 fprintf(stderr, "Reg expected in line %lu\n",
1321 infile->lineno);
1323 break; /* switch parsing */
1325 case ready:
1326 fprintf(stderr, "Internal error, use another compiler.\n");
1327 break;
1331 free(buf);
1332 return fF_GetError(infile);
1334 else
1336 illparams("fD_parsefd");
1337 return real_error;
1341 static void
1342 fD_adjustargnames(fdDef *obj)
1344 int parnum;
1346 if (output_mode!=NEW)
1347 return;
1349 /* For #define-base output mode, we have to check if argument names are not
1350 the same as some words in type names. We check from the first argument
1351 to the last, resolving conflicts by changing argument names, if
1352 necessary. */
1354 for (parnum=0; parnum<fD_ParamNum(obj); parnum++)
1356 const char *parname=fD_GetParam(obj, parnum);
1357 int finished;
1360 int num;
1361 const char *type=fD_GetType(obj);
1362 char *str;
1364 finished=1;
1366 if ((str=strstr(type, parname))!=0 && (str==type ||
1367 (!isalnum(str[-1]) && str[-1]!='_')) &&
1368 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_')))
1370 char buf[300]; /* Hope will be enough... */
1371 strcpy(buf, parname);
1372 strcat(buf, "_");
1373 fD_NewParam(obj, parnum, buf);
1374 parname=fD_GetParam(obj, parnum);
1375 finished=0;
1377 else
1378 for (num=0; num<fD_ParamNum(obj); num++)
1380 const char *name=fD_GetParam(obj, num);
1381 const char *proto=fD_GetProto(obj, num);
1382 if ((num<parnum && strcmp(name, parname)==0) ||
1383 ((str=strstr(proto, parname))!=0 && (str==proto ||
1384 (!isalnum(str[-1]) && str[-1]!='_')) &&
1385 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_'))))
1387 char buf[300]; /* Hope will be enough... */
1388 strcpy(buf, parname);
1389 strcat(buf, "_");
1390 fD_NewParam(obj, parnum, buf);
1391 parname=fD_GetParam(obj, parnum);
1392 // lcs finished=0;
1393 break;
1396 } while (!finished);
1400 Error
1401 fD_parsepr(fdDef* obj, fdFile* infile)
1403 char *buf; /* a copy of infile->line */
1404 char *bpoint, /* cursor in buf */
1405 *bnext, /* looking for the end */
1406 *lowarg; /* beginning of this argument */
1407 long obraces; /* count of open braces */
1408 regs count, /* count parameter number */
1409 args; /* the number of arguments for this function */
1411 if (!(obj && infile && fF_GetError(infile)==false))
1413 illparams("fD_parsepr");
1414 fF_SetError(infile, real_error);
1415 return real_error;
1417 if (!NewString(&buf, infile->line))
1419 fprintf(stderr, "No mem for fD_parsepr\n");
1420 fF_SetError(infile, real_error);
1421 return real_error;
1423 fF_SetError(infile, false);
1425 bpoint=strchr(buf, '(');
1426 while (--bpoint>=buf && strstr(bpoint, fD_GetName(obj))!=bpoint);
1427 if (bpoint>=buf)
1429 while (--bpoint >= buf && (*bpoint==' ' || *bpoint=='\t'));
1430 *++bpoint='\0';
1432 fD_NewType(obj, buf);
1434 while (bpoint && *bpoint++!='('); /* one beyond '(' */
1436 lowarg=bpoint;
1437 obraces=0;
1439 for (count=0, args=fD_RegNum(obj); count<args; bpoint=bnext+1)
1441 while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
1442 bpoint++;
1444 if (!obraces && target==M68K_POS && strncmp(bpoint, "_R_", 3)==0 &&
1445 isalnum(bpoint[3]) && isalnum(bpoint[4]) && isspace(bpoint[5]))
1446 lowarg=bpoint+5;
1448 bnext=strpbrk(bpoint, "(),");
1450 if (bnext)
1452 switch (*bnext)
1454 case '(':
1455 if (!obraces)
1457 if (target==M68K_AMIGAOS || target==M68K_POS)
1459 if (fD_GetFuncParNum(obj)!=illegal &&
1460 fD_GetFuncParNum(obj)!=count &&
1461 !Quiet)
1462 fprintf(stderr, "Warning: two parameters of type "
1463 "pointer to function are used.\n"
1464 "This is not supported!\n");
1467 fD_SetFuncParNum(obj, count);
1469 obraces++;
1470 DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
1471 break;
1473 case ')':
1474 if (obraces)
1476 DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
1477 obraces--;
1479 else
1481 *bnext='\0';
1482 DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
1483 if (fD_NewProto(obj, count, lowarg))
1484 fprintf(stderr, "Parser confused in line %ld\n",
1485 infile->lineno);
1486 lowarg=bnext+1;
1488 if (count!=args-1)
1490 DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
1491 fD_GetName(obj), args, count+1));
1492 fF_SetError(infile, nodef);
1494 count++;
1496 break;
1498 case ',':
1499 if (!obraces)
1501 *bnext='\0';
1502 DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
1503 if (fD_NewProto(obj, count, lowarg))
1504 fprintf(stderr, "Parser confused in line %ld\n",
1505 infile->lineno);
1506 lowarg=bnext+1;
1507 count++;
1509 break;
1511 default:
1512 fprintf(stderr, "Faulty strpbrk in line %lu.\n",
1513 infile->lineno);
1516 else
1518 DBP(fprintf(stderr, "Faulty argument %u in line %lu.\n", count+1,
1519 infile->lineno));
1520 count=args; /* this will effectively quit the for loop */
1521 fF_SetError(infile, nodef);
1524 if (fD_ProtoNum(obj)!=fD_RegNum(obj))
1525 fF_SetError(infile, nodef);
1527 else
1529 fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
1530 fprintf(stderr, "function , definition %s.\n",
1531 /* fD_GetName(obj),*/ infile->line);
1532 fF_SetError(infile, nodef);
1535 free(buf);
1537 fD_adjustargnames(obj);
1539 return fF_GetError(infile);
1543 fD_cmpName(const void* big, const void* small) /* for qsort and bsearch */
1545 return strcmp(fD_GetName(*(fdDef**)big), fD_GetName(*(fdDef**)small));
1548 const static char *TagExcTable[]=
1550 "BuildEasyRequestArgs", "BuildEasyRequest",
1551 "DoDTMethodA", "DoDTMethod",
1552 "DoGadgetMethodA", "DoGadgetMethod",
1553 "EasyRequestArgs", "EasyRequest",
1554 "MUI_MakeObjectA", "MUI_MakeObject",
1555 "MUI_RequestA", "MUI_Request",
1556 "PrintDTObjectA", "PrintDTObject",
1557 "RefreshDTObjectA", "RefreshDTObjects",
1558 "UMSVLog", "UMSLog",
1559 "VFWritef", "FWritef",
1560 "VFPrintf", "FPrintf",
1561 "VPrintf", "Printf",
1564 const char*
1565 getvarargsfunction(const fdDef * obj)
1567 unsigned int count;
1568 const char *name = fD_GetName(obj);
1570 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1572 if (strcmp(name, TagExcTable[count])==0)
1574 return TagExcTable[count+1];
1577 return(NULL);
1580 const char*
1581 taggedfunction(const fdDef* obj)
1583 shortcard numregs=fD_RegNum(obj);
1584 unsigned int count;
1585 int aos_tagitem;
1586 const char *name=fD_GetName(obj);
1587 static char newname[200]; /* Hope will be enough... static because used
1588 out of the function. */
1589 const char *lastarg;
1590 const static char *TagExcTable2[]=
1592 "ApplyTagChanges",
1593 "CloneTagItems",
1594 "FindTagItem",
1595 "FreeTagItems",
1596 "GetTagData",
1597 "PackBoolTags",
1598 "PackStructureTags",
1599 "RefreshTagItemClones",
1600 "UnpackStructureTags",
1603 if (!numregs)
1604 return NULL;
1606 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1607 if (strcmp(name, TagExcTable[count])==0)
1608 return NULL;
1609 // lcs return TagExcTable[count+1];
1611 for (count=0; count<sizeof TagExcTable2/sizeof TagExcTable2[0]; count++)
1612 if (strcmp(name, TagExcTable2[count])==0)
1613 return NULL;
1615 lastarg=fD_GetProto(obj, numregs-1);
1616 if (strncmp(lastarg, "const", 5)==0 || strncmp(lastarg, "CONST", 5)==0)
1617 lastarg+=5;
1618 while (*lastarg==' ' || *lastarg=='\t')
1619 lastarg++;
1620 if (strncmp(lastarg, "struct", 6))
1621 return NULL;
1622 lastarg+=6;
1623 while (*lastarg==' ' || *lastarg=='\t')
1624 lastarg++;
1625 aos_tagitem=1;
1626 if (strncmp(lastarg, "TagItem", 7) &&
1627 (target!=M68K_POS || ((aos_tagitem=strncmp(lastarg, "pOS_TagItem", 11))!=0)))
1628 return NULL;
1629 lastarg+=(aos_tagitem ? 7 : 11);
1630 while (*lastarg==' ' || *lastarg=='\t')
1631 lastarg++;
1632 if (strcmp(lastarg, "*"))
1633 return NULL;
1635 strcpy(newname, name);
1636 if (newname[strlen(newname)-1]=='A')
1637 newname[strlen(newname)-1]='\0';
1638 else
1639 if (strlen(newname)>7 && !strcmp(newname+strlen(newname)-7, "TagList"))
1640 strcpy(newname+strlen(newname)-4, "s");
1641 else
1642 strcat(newname, "Tags");
1643 return newname;
1646 const char*
1647 aliasfunction(const char* name)
1649 const static char *AliasTable[]=
1651 "AllocDosObject", "AllocDosObjectTagList",
1652 "CreateNewProc", "CreateNewProcTagList",
1653 "NewLoadSeg", "NewLoadSegTagList",
1654 "System", "SystemTagList",
1656 unsigned int count;
1657 for (count=0; count<sizeof AliasTable/sizeof AliasTable[0]; count++)
1658 if (strcmp(name, AliasTable[count])==0)
1659 return AliasTable[count+(count%2 ? -1 : 1)];
1660 return NULL;
1663 void
1664 fD_write(FILE* outfile, const fdDef* obj)
1666 shortcard count, numregs;
1667 const char *chtmp, *tagname, *varname, *name, *rettype;
1668 int vd=0, a45=0, d7=0;
1670 DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
1672 numregs=fD_RegNum(obj);
1674 if ((rettype=fD_GetType(obj))==fD_nostring)
1676 fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
1677 return;
1679 if (!strcasecmp(rettype, "void"))
1680 vd = 1; /* set flag */
1681 for (count=d0; count<numregs; count++)
1683 const char *reg=fD_GetRegStr(obj, count);
1684 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1686 if (strcmp(reg, "a4")==0 || strcmp(reg, "a5")==0)
1688 if (!a45)
1689 a45=(strcmp(reg, "a4") ? 5 : 4); /* set flag */
1690 else /* Security check */
1691 if (!Quiet)
1692 fprintf(stderr, "Warning: both a4 and a5 are used. "
1693 "This is not supported!\n");
1696 if (strcmp(reg, "d7")==0) /* Used only when a45!=0 */
1697 d7=1;
1700 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1702 if (a45 && d7) /* Security check */
1703 if (!Quiet)
1704 fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
1705 "supported!\n");
1708 name=fD_GetName(obj);
1710 if (fD_ProtoNum(obj)!=numregs)
1712 fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
1713 fD_ProtoNum(obj), fD_ProtoNum(obj)!= 1 ? "s" : "");
1714 return;
1717 if (output_mode==NEW)
1719 fprintf(outfile, "#define %s(", name);
1721 if (numregs>0)
1723 for (count=d0; count<numregs-1; count++)
1724 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
1725 fprintf(outfile, "%s", fD_GetParam(obj, count));
1728 if (target==M68K_AMIGAOS)
1730 fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
1731 (vd ? "NR" : ""), (a45 ? (a45==4 ? "A4" : "A5") : ""),
1732 (BaseName[0] ? "" : "UB"),
1733 (fD_GetFuncParNum(obj)==illegal ? "" : "FP"), -fD_GetOffset(obj));
1734 if (!vd)
1735 fprintf(outfile, "%s, ", rettype);
1736 fprintf(outfile, "%s, ", name);
1738 for (count=d0; count<numregs; count++)
1740 chtmp=fD_GetRegStr(obj, count);
1741 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1742 chtmp="d7";
1743 fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj)==count ?
1744 "__fpt" : fD_GetProto(obj, count)),
1745 fD_GetParam(obj, count),
1746 chtmp, (count==numregs-1 && !BaseName[0] ? "" : ", "));
1749 if (BaseName[0]) /* was "##base" used? */
1750 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1751 if (fD_GetFuncParNum(obj)!=illegal)
1753 fprintf(outfile, ", ");
1754 fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
1756 fprintf(outfile, ")\n\n");
1758 else if(target==M68K_POS)
1760 fprintf(outfile, ") \\\n\t__INLINE_FUN_%d(", numregs);
1761 fprintf(outfile, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1762 BaseNamU, BaseNamU, -fD_GetOffset(obj), rettype, name,
1763 (numregs ? ", \\\n\t" : ""));
1765 for (count=d0; count<numregs; count++)
1766 fprintf(outfile, "%s, %s, %s%s", fD_GetProto(obj, count),
1767 fD_GetParam(obj, count), fD_GetRegStr(obj, count),
1768 (count==numregs-1 ? "" : ", "));
1769 fprintf(outfile, ")\n\n");
1771 else if (target==PPC_POWERUP || target==PPC_MORPHOS)
1773 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1774 numregs,
1775 (vd ? "NR" : ""),
1776 (BaseName[0] ? "" : "UB"),
1777 -fD_GetOffset(obj));
1779 if (!vd)
1780 fprintf(outfile, "%s, ", rettype);
1781 fprintf(outfile, "%s, ", name);
1783 for (count=d0; count<numregs; count++)
1785 chtmp=fD_GetRegStr(obj, count);
1787 if (strchr(fD_GetProto(obj, count),'%'))
1789 sprintf(Buffer,
1790 fD_GetProto(obj, count),
1791 "");
1793 fprintf(outfile, "%s, %s, %s%s",
1794 Buffer,
1795 fD_GetParam(obj, count),
1796 chtmp,
1797 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1799 else
1801 fprintf(outfile, "%s, %s, %s%s",
1802 fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1803 fD_GetParam(obj, count),
1804 chtmp,
1805 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1809 if (BaseName[0])
1810 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1813 * Here it would make sense to create a database file to
1814 * integrate optimizations automaticly into every new
1815 * build. Not every function needs a complete flush. For
1816 * example functions with no parameter wouldn`t need a
1817 * PPC flush normally. Or Read(File,Addr,Size); would
1818 * only need a flush for Addr with the Size
1821 fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1822 fprintf(outfile, ")\n\n");
1824 else if (target==IX86BE_AMITHLON)
1826 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1827 numregs,
1828 (vd ? "NR" : ""),
1829 (BaseName[0] ? "" : "UB"),
1830 -fD_GetOffset(obj));
1832 if (!vd)
1833 fprintf(outfile, "%s, ", rettype);
1834 fprintf(outfile, "%s, ", name);
1836 for (count=d0; count<numregs; count++)
1838 chtmp=fD_GetRegStr(obj, count);
1840 if (strchr(fD_GetProto(obj, count),'%'))
1842 sprintf(Buffer,
1843 fD_GetProto(obj, count),
1844 "");
1846 fprintf(outfile, "%s, %s, %s%s",
1847 Buffer,
1848 fD_GetParam(obj, count),
1849 chtmp,
1850 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1852 else
1854 fprintf(outfile, "%s, %s, %s%s",
1855 fD_GetProto(obj, count),
1856 fD_GetParam(obj, count),
1857 chtmp,
1858 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1862 if (BaseName[0])
1863 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1865 fprintf(outfile, ")\n\n");
1867 else if (target==AROS)
1869 fprintf(outfile, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1870 numregs,
1871 (BaseName[0] ? "" : "I"),
1872 (vd ? "void" : rettype),
1873 name);
1875 for (count=d0; count<numregs; count++)
1877 chtmp=fD_GetRegStrU(obj, count);
1878 fprintf(outfile, "\tAROS_LCA(%s, (%s), %s), \\\n",
1879 fD_GetProto(obj, count),
1880 fD_GetParam(obj, count),
1881 chtmp);
1884 if (BaseName[0]) /* was "##base" used? */
1886 fprintf(outfile, "\tstruct %s *, %s_BASE_NAME, ", StdLib, BaseNamU);
1888 else
1890 fprintf(outfile, "\t/* bt */, /* bn */, ");
1892 fprintf(outfile,
1893 "%ld, /* s */)\n\n",
1894 -fD_GetOffset(obj) / 6);
1896 else
1898 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
1899 return;
1902 else if (output_mode==OLD || output_mode==STUBS)
1904 fprintf(outfile, "%s__inline %s\n%s(%s",
1905 (output_mode==STUBS ? "" : "extern "), rettype, name,
1906 (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1908 if (target==M68K_AMIGAOS)
1910 for (count=d0; count<numregs; count++)
1912 chtmp=fD_GetProto(obj, count);
1913 if (fD_GetFuncParNum(obj)==count)
1914 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1915 else
1916 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
1917 "" : " "), fD_GetParam(obj, count));
1918 if (count<numregs-1)
1919 fprintf(outfile, ", ");
1922 fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
1923 if (!vd)
1924 fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
1925 (*(rettype+strlen(rettype)-1)=='*' ? "" : " "));
1927 if (BaseName[0])
1928 fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1929 StdLib);
1931 for (count=d0; count<numregs; count++)
1933 chtmp=fD_GetRegStr(obj, count);
1934 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1935 chtmp="d7";
1936 if (fD_GetFuncParNum(obj)==count)
1938 fprintf(outfile, " register ");
1939 fprintf(outfile, fD_GetProto(obj, count), chtmp);
1940 fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
1941 count));
1943 else
1945 const char *proto=fD_GetProto(obj, count);
1946 fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
1947 proto, (*(proto+strlen(proto)-1)=='*' ? "" : " "), chtmp,
1948 chtmp, fD_GetParam(obj, count));
1951 if (a45)
1952 fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
1953 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45==4 ? "a4" : "a5"),
1954 -fD_GetOffset(obj), (a45==4 ? "a4" : "a5"));
1955 else
1956 fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1957 -fD_GetOffset(obj));
1959 fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1961 fprintf(outfile, " : ");
1962 if (BaseName[0])
1963 fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", ": ""));
1965 for (count=d0; count<numregs; count++)
1967 chtmp=fD_GetRegStr(obj, count);
1968 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1969 chtmp="d7";
1970 fprintf(outfile, "\"r\" (%s)%s", chtmp, (count<numregs-1 ? ", " : ""));
1972 fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1974 if (vd)
1975 fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1976 else
1977 fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1980 else if (target==PPC_POWERUP)
1982 for (count = d0; count < numregs; count++)
1984 chtmp = fD_GetProto(obj, count);
1985 if (fD_GetFuncParNum(obj) == count)
1986 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1987 else
1988 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
1989 "" : " "), fD_GetParam(obj, count));
1990 if (count < numregs - 1)
1991 fprintf(outfile, ", ");
1994 fprintf(outfile, ")\t\n");
1995 fprintf(outfile, "{\t\n");
1996 fprintf(outfile, "struct Caos\tMyCaos;\n");
1997 fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1998 fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
1999 fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2000 fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2001 fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2002 fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2004 if (numregs > 0)
2006 for (count = d0; count < numregs; count++)
2008 fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2009 fD_GetRegStr(obj, count),
2010 fD_GetParam(obj, count));
2014 fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
2015 if (BaseName[0]) /*
2016 * was "##base" used?
2019 fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2021 if (vd)
2023 fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2025 else
2027 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2028 rettype);
2031 else if (target==PPC_MORPHOS)
2033 for (count = d0; count < numregs; count++)
2035 chtmp = fD_GetProto(obj, count);
2036 if (fD_GetFuncParNum(obj) == count)
2037 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2038 else
2039 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2040 "" : " "), fD_GetParam(obj, count));
2041 if (count < numregs - 1)
2042 fprintf(outfile, ", ");
2045 fprintf(outfile, ")\t\n{\t\n");
2047 if (numregs > 0)
2049 for (count = d0; count < numregs; count++)
2051 fprintf(outfile, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2052 fD_GetRegStrU(obj, count), fD_GetParam(obj, count));
2056 if (BaseName[0]) /*
2057 * was "##base" used?
2060 fprintf(outfile, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2062 if (vd)
2064 fprintf(outfile, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj));
2066 else
2068 fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2069 rettype, fD_GetOffset(obj));
2072 else if (target==IX86BE_AMITHLON)
2074 #if 0
2075 for (count = d0; count < numregs; count++)
2077 chtmp = fD_GetProto(obj, count);
2078 if (fD_GetFuncParNum(obj) == count)
2079 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2080 else
2081 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2082 "" : " "), fD_GetParam(obj, count));
2083 if (count < numregs - 1)
2084 fprintf(outfile, ", ");
2087 fprintf(outfile, ")\n{\n");
2088 fprintf(outfile, "\tstruct _Regs _regs;\n");
2090 if (numregs > 0)
2092 for (count = d0; count < numregs; count++)
2094 fprintf(outfile, "\t_regs.reg_%s = (ULONG) (%s);\n",
2095 fD_GetRegStr(obj, count),
2096 fD_GetParam(obj, count));
2100 if (BaseName[0])
2102 fprintf(outfile, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2105 if (vd)
2107 fprintf(outfile, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2108 -fD_GetOffset(obj));
2110 else
2112 fprintf(outfile, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2113 rettype,-fD_GetOffset(obj));
2115 #else
2116 for (count = d0; count < numregs; count++)
2118 chtmp = fD_GetProto(obj, count);
2119 if (fD_GetFuncParNum(obj) == count)
2120 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2121 else
2122 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2123 "" : " "), fD_GetParam(obj, count));
2124 if (count < numregs - 1)
2125 fprintf(outfile, ", ");
2128 fprintf(outfile, ")\n{\n");
2129 fprintf(outfile, "\t%s LP%d%s%s(0x%lx, ",
2130 (vd ? "" : "return "),
2131 numregs,
2132 (vd ? "NR" : ""),
2133 (BaseName[0] ? "" : "UB"),
2134 -fD_GetOffset(obj));
2136 if (!vd)
2137 fprintf(outfile, "%s, ", rettype);
2138 fprintf(outfile, "%s, ", name);
2140 for (count=d0; count<numregs; count++)
2142 chtmp=fD_GetRegStr(obj, count);
2144 if (strchr(fD_GetProto(obj, count),'%'))
2146 sprintf(Buffer,
2147 fD_GetProto(obj, count),
2148 "");
2150 fprintf(outfile, "%s, %s, %s%s",
2151 Buffer,
2152 fD_GetParam(obj, count),
2153 chtmp,
2154 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2156 else
2158 fprintf(outfile, "%s, %s, %s%s",
2159 fD_GetProto(obj, count),
2160 fD_GetParam(obj, count),
2161 chtmp,
2162 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2166 if (BaseName[0])
2167 fprintf(outfile, "\\\n\t, BASE_NAME");
2169 fprintf(outfile, ");\n}\n\n");
2170 #endif
2172 else
2174 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2175 return;
2178 else if (output_mode==GATESTUBS || output_mode==GATEPROTO)
2180 int has_base = (BaseName[0] && fD_GetOffset(obj) != 0);
2182 //lcs
2183 if (target==AROS)
2185 for (count=d0; count<numregs; count++)
2187 if (fD_GetFuncParNum(obj) == count)
2189 char funcproto[200]; /* Hope will be enough... */
2190 sprintf(funcproto, "%s_%s_funcproto_%d",
2191 BaseNamC, name, count );
2192 fprintf(outfile, "typedef ");
2193 fprintf(outfile, fD_GetProto(obj, count), funcproto);
2194 fprintf(outfile, ";\n");
2199 if (output_mode==GATESTUBS)
2201 fprintf(outfile, "%s %s%s(",
2202 rettype,
2203 libprefix,
2204 name);
2206 for (count=d0; count<numregs; count++)
2208 chtmp = fD_GetProto(obj, count);
2210 fprintf(outfile, chtmp, "");
2211 fprintf(outfile, "%s",
2212 (count == numregs - 1 && !has_base ? ");\n" : ", "));
2215 if (has_base)
2216 fprintf(outfile, "struct %s *);\n", StdLib);
2219 if (target==M68K_AMIGAOS)
2221 fprintf(outfile, "%s %s%s(\n",
2222 rettype,
2223 gateprefix,
2224 name);
2226 for (count=d0; count<numregs; count++)
2228 chtmp = fD_GetProto(obj, count);
2230 if (fD_GetFuncParNum(obj) == count)
2232 fprintf(outfile, "\t");
2233 fprintf(outfile, chtmp,
2234 fD_GetParam(obj, count));
2235 fprintf(outfile, " __asm(\"%s\")%s",
2236 fD_GetRegStr(obj, count),
2237 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2239 else
2241 fprintf(outfile, "\t%s %s __asm(\"%s\")%s",
2242 chtmp,
2243 fD_GetParam(obj, count),
2244 fD_GetRegStr(obj, count),
2245 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2249 if (has_base)
2250 fprintf(outfile, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib);
2252 if (output_mode==GATESTUBS)
2253 fprintf(outfile, "{\n");
2255 else if (target==AROS)
2257 fprintf(outfile, "AROS_LH%d%s(%s, %s%s,\n",
2258 numregs,
2259 has_base ? "" : "I",
2260 rettype,
2261 gateprefix,
2262 name);
2264 for (count=d0; count<numregs; count++)
2266 char funcproto[200]; /* Hope will be enough... */
2268 if (fD_GetFuncParNum(obj) == count)
2270 sprintf(funcproto, "%s_%s_funcproto_%d",
2271 BaseNamC, name, count );
2274 fprintf(outfile, "\tAROS_LHA(%s, %s, %s),\n",
2275 fD_GetFuncParNum(obj) == count ? funcproto : fD_GetProto(obj, count),
2276 fD_GetParam(obj, count),
2277 fD_GetRegStrU(obj, count));
2280 fprintf(outfile, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2281 StdLib,
2282 -fD_GetOffset(obj) / 6,
2283 BaseNamC);
2285 if (output_mode==GATESTUBS)
2286 fprintf(outfile, "{\n");
2288 else if (target==PPC_MORPHOS)
2290 fprintf(outfile, "%s %s%s(void)\n",
2291 rettype,
2292 gateprefix,
2293 name);
2295 if (output_mode==GATESTUBS)
2297 fprintf(outfile, "{\n");
2299 for (count=d0; count<numregs; count++)
2301 chtmp = fD_GetProto(obj, count);
2303 if (fD_GetFuncParNum(obj) == count)
2305 fprintf(outfile, "\t");
2306 fprintf(outfile, chtmp,
2307 fD_GetParam(obj, count));
2308 fprintf(outfile, " = (");
2309 fprintf(outfile, chtmp, "");
2310 fprintf(outfile, ") REG_%s;\n",
2311 fD_GetRegStrU(obj, count));
2313 else
2315 fprintf(outfile, "\t%s %s = (%s) REG_%s;\n",
2316 fD_GetProto(obj, count),
2317 fD_GetParam(obj, count),
2318 fD_GetProto(obj, count),
2319 fD_GetRegStrU(obj, count));
2323 if (has_base)
2324 fprintf(outfile,
2325 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2326 StdLib, StdLib);
2328 fprintf(outfile, "\n");
2331 else if (target==IX86BE_AMITHLON)
2333 fprintf(outfile, "%s %s%s( struct _Regs _regs )\n",
2334 rettype,
2335 gateprefix,
2336 name);
2338 if (output_mode==GATESTUBS)
2340 fprintf(outfile, "{\n");
2342 for (count=d0; count<numregs; count++)
2344 chtmp = fD_GetProto(obj, count);
2346 if (fD_GetFuncParNum(obj) == count)
2348 fprintf(outfile, "\t");
2349 fprintf(outfile, chtmp,
2350 fD_GetParam(obj, count));
2351 fprintf(outfile, " = (");
2352 fprintf(outfile, chtmp, "");
2353 fprintf(outfile, ") _regs.%s;\n",
2354 fD_GetRegStr(obj, count));
2356 else
2358 fprintf(outfile, "\t%s %s = (%s) _regs.%s;\n",
2359 fD_GetProto(obj, count),
2360 fD_GetParam(obj, count),
2361 fD_GetProto(obj, count),
2362 fD_GetRegStr(obj, count));
2366 if (has_base)
2367 fprintf(outfile,
2368 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2369 StdLib, StdLib);
2371 fprintf(outfile, "\n");
2374 else
2376 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2377 return;
2380 if (output_mode==GATESTUBS)
2382 fprintf(outfile,"\treturn %s%s(",
2383 libprefix,
2384 name);
2386 for (count=d0; count<numregs; count++)
2388 fprintf(outfile, "%s%s",
2389 fD_GetParam(obj, count),
2390 (count == numregs - 1 && !has_base ? ");" : ", "));
2393 if (has_base)
2394 fprintf(outfile, "BASE_NAME);");
2396 fprintf(outfile,"\n}\n\n");
2398 else
2400 fprintf(outfile,";\n");
2402 if (target==AROS)
2404 fprintf(outfile, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2405 gateprefix, name,
2406 gateprefix, name,
2407 BaseNamC,fD_GetOffset(obj));
2410 fprintf(outfile,"\n");
2413 else
2415 fprintf(stderr, "Internal error: Unknown output mode in fD_write().\n");
2416 return;
2419 if ((tagname=aliasfunction(fD_GetName(obj)))!=0 &&
2420 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2422 fprintf(outfile, "#define %s(", tagname);
2423 for (count=d0; count<numregs-1; count++)
2424 fprintf(outfile, "a%d, ", count);
2425 fprintf(outfile, "a%d) %s (", count, name);
2426 for (count=d0; count<numregs-1; count++)
2427 fprintf(outfile, "(a%d), ", count);
2428 fprintf(outfile, "(a%d))\n\n", count);
2431 if ((tagname=taggedfunction(obj))!=0 &&
2432 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2434 if (output_mode!=STUBS)
2436 fprintf( outfile,
2437 "#ifndef %sNO_INLINE_STDARG\n"
2438 "#define %s(",
2439 (target==M68K_POS ? "__" : ""),
2440 tagname);
2442 for (count=d0; count<numregs-1; count++)
2443 fprintf(outfile, "a%d, ", count);
2445 fprintf(outfile, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2446 name);
2448 for (count=d0; count<numregs-1; count++)
2449 fprintf(outfile, "(a%d), ", count);
2451 fprintf(outfile, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2452 fD_GetProto(obj, fD_RegNum(obj)-1),
2453 (target==M68K_POS ? "__" : ""));
2456 else
2458 if (target==M68K_AMIGAOS || target==IX86BE_AMITHLON)
2460 fprintf(outfile, "__inline %s\n%s(", rettype, tagname);
2462 for (count=d0; count<numregs-1; count++)
2464 chtmp=fD_GetProto(obj, count);
2465 if (count==fD_GetFuncParNum(obj))
2466 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2467 else
2468 fprintf(outfile, "%s%s%s", chtmp,
2469 (*(chtmp+strlen(chtmp)-1)=='*' ? "" : " "),
2470 fD_GetParam(obj, count));
2471 fprintf(outfile, ", ");
2474 fprintf(outfile, "int tag, ...)\n{\n ");
2475 if (!vd)
2476 fprintf(outfile, "return ");
2478 fprintf(outfile, "%s(", name);
2479 for (count=d0; count<numregs-1; count++)
2480 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
2482 fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj)-1));
2484 else if (target==PPC_MORPHOS)
2486 int n = 9 - numregs; /* number of regs that contain varargs */
2487 int d = n & 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2488 int taglist = 8; /* offset of the start of the taglist */
2489 int local = (taglist + n * 4 + d + 8 + 15) & ~15; /* size of the stack frame */
2492 * Stack frame:
2494 * 0 - 3: next frame ptr
2495 * 4 - 7: save lr
2496 * 8 - 8+n*4+d+8-1: tag list start
2497 * ? - local-1: padding
2500 fprintf(outfile,
2501 "asm(\"\n"
2502 " .align 2 \n"
2503 " .globl %s \n"
2504 " .type %s,@function\n"
2505 "%s: \n"
2506 " stwu 1,-%d(1) \n" /* create stack frame */
2507 " mflr 0 \n"
2508 " stw 0,%d(1) \n",
2509 tagname, tagname, tagname, local, local + 4);
2512 * If n is odd, one tag is split between regs and stack.
2513 * Copy its ti_Data together with the ti_Tag.
2515 if (d)
2516 fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
2518 * Save the registers
2520 for (count = numregs; count <= 8; count++)
2521 fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
2523 if (d)
2524 fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
2527 * Add TAG_MORE
2529 fprintf(outfile, " li 11,2 \n"
2530 " addi 0,1,%d \n"
2531 " stw 11,%d(1) \n" /* add TAG_MORE */
2532 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2533 local + 8 + d,
2534 taglist + n * 4 + d,
2535 taglist + n * 4 + d + 4);
2538 if (DirectVarargsCalls)
2540 fprintf(outfile,
2541 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2542 " bl %s \n",
2543 numregs + 2, taglist, name);
2545 else
2548 * Save the non-varargs registers in the EmulHandle struct.
2550 for (count = 0; count < numregs - 1; count++)
2552 int r = fD_GetReg(obj, count);
2554 fprintf(outfile, " stw %d,%d(2)\n", count + 3, r * 4);
2557 fprintf(outfile,
2558 " lis 12,%s@ha \n"
2559 " addi 0,1,%d \n"
2560 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2561 " stw 0,%d(2) \n" /* REG_?? = taglist */
2562 " mtctr 11 \n"
2563 " lwz 12,%s@l(12)\n"
2564 " li 3,%ld \n" /* r3 = lvo */
2565 " stw 12,56(2) \n" /* REG_A6 = libbase */
2566 " bctrl \n",/* EmulCallOS() */
2567 BaseName, taglist, 4 * fD_GetReg(obj, numregs - 1), BaseName,
2568 fD_GetOffset(obj));
2571 fprintf(outfile," lwz 0,%d(1) \n" /* clear stack frame & return */
2572 " mtlr 0 \n"
2573 " addi 1,1,%d \n"
2574 " blr \n"
2575 ".L%se1: \n"
2576 " .size\t%s,.L%se1-%s\n"
2577 "\");\n\n",
2578 local + 4, local,
2579 tagname, tagname, tagname, tagname);
2581 else
2583 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2584 return;
2588 else if ((varname = getvarargsfunction(obj)) != 0 &&
2589 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2591 if (output_mode != STUBS)
2593 fprintf(outfile,
2594 "#ifndef NO_INLINE_VARARGS\n"
2595 "#define %s(", varname);
2597 for (count = d0; count < numregs - 1; count++)
2598 fprintf(outfile, "a%d, ", count);
2600 fprintf(outfile,
2601 "...) \\\n"
2602 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2603 name);
2605 for (count = d0; count < numregs - 1; count++)
2606 fprintf(outfile, "(a%d), ", count);
2608 fprintf(outfile,
2609 "(%s)_tags);})\n"
2610 "#endif /* !NO_INLINE_VARARGS */\n\n",
2611 fD_GetProto(obj, fD_RegNum(obj) - 1));
2613 else
2615 fprintf(stderr, "can`t create a varargs stub function for %s\n",
2616 varname);
2620 if (strcmp(name, "DoPkt")==0 &&
2621 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2623 fdDef *objnc=(fdDef*)obj;
2624 char newname[7]="DoPkt0";
2625 objnc->name=newname;
2626 for (count=2; count<7; count++)
2628 regs reg=objnc->reg[count];
2629 char *proto=objnc->proto[count];
2630 objnc->reg[count]=illegal;
2631 objnc->proto[count]=fD_nostring;
2632 fD_write(outfile, objnc);
2633 objnc->reg[count]=reg;
2634 objnc->proto[count]=proto;
2635 newname[5]++;
2637 objnc->name=(char*)name;
2642 varargsfunction(const char* proto, const char* funcname)
2644 const char *end=proto+strlen(proto)-1;
2645 while (isspace(*end))
2646 end--;
2647 if (*end--==';')
2649 while (isspace(*end))
2650 end--;
2651 if (*end--==')')
2653 while (isspace(*end))
2654 end--;
2655 if (!strncmp(end-2, "...", 3))
2657 /* Seems to be a varargs function. Check if it will be recognized
2658 as "tagged". */
2659 unsigned int count;
2660 char fixedname[200]; /* Hope will be enough... */
2661 fdDef *tmpdef;
2663 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0];
2664 count+=2)
2665 if (strcmp(funcname, TagExcTable[count+1])==0)
2666 return 1;
2668 if (!(tmpdef=fD_ctor()))
2670 fprintf(stderr, "No mem for FDs\n");
2671 exit(EXIT_FAILURE);
2674 strcpy(fixedname, funcname);
2675 if (strlen(funcname)>4 &&
2676 !strcmp(funcname+strlen(funcname)-4, "Tags"))
2678 /* Might be either nothing or "TagList". */
2679 fixedname[strlen(fixedname)-4]='\0';
2680 fD_NewName(tmpdef, fixedname);
2681 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2682 fD_cmpName))
2683 return 1;
2685 strcat(fixedname, "TagList");
2686 fD_NewName(tmpdef, fixedname);
2687 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2688 fD_cmpName))
2689 return 1;
2691 else
2693 strcat(fixedname, "A");
2694 fD_NewName(tmpdef, fixedname);
2695 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2696 fD_cmpName))
2697 return 1;
2702 return 0;
2706 ishandleddifferently(const char* proto, const char* funcname)
2708 /* First check if this is a vararg call? */
2709 if (varargsfunction(proto, funcname))
2710 return 1;
2712 /* It might be a dos.library "alias" name. */
2713 if (aliasfunction(funcname))
2714 return 1;
2716 /* It might be one from dos.library/DoPkt() family. */
2717 if (strlen(funcname)==6 && !strncmp(funcname, "DoPkt", 5) &&
2718 funcname[5]>='0' && funcname[6]<='4')
2719 return 1;
2721 /* Finally, it can be intuition.library/ReportMouse1(). */
2722 return !strcmp(funcname, "ReportMouse1");
2725 void
2726 printusage(const char* exename)
2728 fprintf(stderr,
2729 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2730 "Options:\n"
2732 "--mode=MODE\t\tMODE is one of the following:\n"
2733 "\tnew\t\t\tPreprocessor based (default)\n"
2734 "\told\t\t\tInline based\n"
2735 "\tstubs\t\t\tLibrary stubs\n"
2736 "\tgatestubs\t\tLibrary gate stubs\n"
2737 "\tgateproto\t\tLibrary gate prototypes\n"
2738 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2740 "--target=OS\t\tOS is one of the following: \n"
2741 "\t*-aros\t\t\tAROS (any CPU)\n"
2742 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2743 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2744 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2745 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2746 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2748 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2749 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2750 "--libprefix=PREFIX\tLocal function name prefix\n"
2751 "--local\t\t\tUse local includes\n"
2752 "--quiet\t\t\tDon't display warnings\n"
2753 "--version\t\tPrint version number and exit\n\n"
2754 "Compatibility options:\n"
2755 "--new\t\t\tSame as --mode=new\n"
2756 "--old\t\t\tSame as --mode=old\n"
2757 "--stubs\t\t\tSame as --mode=stubs\n"
2758 "--gatestubs\t\tSame as --mode=gatestubs\n"
2759 "--proto\t\t\tSame as --mode=prot\n"
2760 "--pos\t\t\tSame as --target=m68k-pos\n"
2761 "--morphos\t\tSame as --target=powerpc-morphos\n"
2762 "--powerup\t\tSame as --target=powerpc-powerup\n"
2763 , exename);
2766 void output_proto(FILE* outfile)
2768 fprintf(outfile,
2769 "/* Automatically generated header! Do not edit! */\n\n"
2770 "#ifndef PROTO_%s_H\n"
2771 "#define PROTO_%s_H\n\n",
2772 BaseNamU, BaseNamU);
2774 if (BaseName[0])
2775 fprintf(outfile,
2776 "#ifndef __NOLIBBASE__\n"
2777 "extern struct %s *\n"
2778 "#ifdef __CONSTLIBBASEDECL__\n"
2779 "__CONSTLIBBASEDECL__\n"
2780 "#endif /* __CONSTLIBBASEDECL__ */\n"
2781 "%s;\n"
2782 "#endif /* !__NOLIBBASE__ */\n\n",
2783 StdLib, BaseName);
2785 fprintf(outfile,
2786 "#ifdef __amigaos4__\n"
2787 "#include <interfaces/%s.h>\n"
2788 "#ifdef __USE_INLINE__\n"
2789 "#include <inline4/%s.h>\n"
2790 "#endif /* __USE_INLINE__ */\n"
2791 "#ifndef CLIB_%s_PROTOS_H\n"
2792 "#define CLIB_%s_PROTOS_H\n"
2793 "#endif /* CLIB_%s_PROTOS_H */\n"
2794 "#ifndef __NOGLOBALIFACE__\n"
2795 "extern struct %sIFace *I%s;\n"
2796 "#endif /* __NOGLOBALIFACE__ */\n"
2797 "#else /* __amigaos4__ */\n"
2798 "#include <clib/%s_protos.h>\n"
2799 "#ifdef __GNUC__\n"
2800 "#ifdef __AROS__\n"
2801 "#ifndef NOLIBDEFINES\n"
2802 "#ifndef %s_NOLIBDEFINES\n"
2803 "#include <defines/%s.h>\n"
2804 "#endif /* %s_NOLIBDEFINES */\n"
2805 "#endif /* NOLIBDEFINES */\n"
2806 "#else\n"
2807 "#ifdef __PPC__\n"
2808 "#ifndef _NO_PPCINLINE\n"
2809 "#include <ppcinline/%s.h>\n"
2810 "#endif /* _NO_PPCINLINE */\n"
2811 "#else\n"
2812 "#ifndef _NO_INLINE\n"
2813 "#include <inline/%s.h>\n"
2814 "#endif /* _NO_INLINE */\n"
2815 "#endif /* __PPC__ */\n"
2816 "#endif /* __AROS__ */\n"
2817 "#else\n"
2818 "#include <pragmas/%s_pragmas.h>\n"
2819 "#endif /* __GNUC__ */\n"
2820 "#endif /* __amigaos4__ */\n\n"
2821 "#endif /* !PROTO_%s_H */\n",
2822 BaseNamL, BaseNamL, BaseNamU, BaseNamU, BaseNamU, BaseNamC, BaseNamC,
2823 BaseNamL,
2824 BaseNamU, BaseNamL, BaseNamU,
2825 BaseNamL, BaseNamL, BaseNamL,
2826 BaseNamU);
2829 /******************************************************************************/
2832 main(int argc, char** argv)
2834 fdDef *tmpdef, /* a dummy to contain the name to look for */
2835 *founddef; /* the fdDef for which we found a prototype */
2836 fdFile *myfile;
2837 char *tmpstr;
2838 FILE *outfile;
2839 int closeoutfile=0;
2840 char *fdfilename=0, *clibfilename=0, *outfilename=0;
2842 int count;
2843 Error lerror;
2845 for (count=1; count<argc; count++)
2847 char *option=argv[count];
2848 if (*option=='-')
2850 option++;
2851 if (strcmp(option, "o")==0)
2853 if (count==argc-1 || outfilename)
2855 printusage(argv[0]);
2856 return EXIT_FAILURE;
2858 if (strcmp(argv[++count], "-"))
2859 outfilename=argv[count];
2861 else
2863 if (*option=='-') /* Accept GNU-style '--' options */
2864 option++;
2865 if (strncmp(option, "mode=", 5)==0)
2867 if (strcmp(option+5, "new")==0)
2868 output_mode=NEW;
2869 else if (strcmp(option+5, "old")==0)
2870 output_mode=OLD;
2871 else if (strcmp(option+5, "stubs")==0)
2872 output_mode=STUBS;
2873 else if (strcmp(option+5, "gatestubs")==0)
2874 output_mode=GATESTUBS;
2875 else if (strcmp(option+5, "gateproto")==0)
2876 output_mode=GATEPROTO;
2877 else if (strcmp(option+5, "proto")==0)
2878 output_mode=PROTO;
2880 else if (strncmp(option, "target=", 7)==0)
2882 if (MatchGlob("*-aros",option+7))
2883 target=AROS;
2884 else if (MatchGlob("i?86be*-amithlon",option+7))
2885 target=IX86BE_AMITHLON;
2886 else if (MatchGlob("m68k*-amigaos",option+7))
2887 target=M68K_AMIGAOS;
2888 else if (MatchGlob("m68k*-pos",option+7))
2889 target=M68K_POS;
2890 else if (MatchGlob("powerpc*-powerup",option+7))
2891 target=PPC_POWERUP;
2892 else if (MatchGlob("powerpc*-morphos",option+7))
2893 target=PPC_MORPHOS;
2894 else
2896 printusage(argv[0]);
2897 return EXIT_FAILURE;
2900 else if (strcmp(option, "direct-varargs-calls") == 0)
2901 DirectVarargsCalls = 1;
2902 else if (strncmp(option, "gateprefix=", 11)==0)
2903 gateprefix = option+11;
2904 else if (strncmp(option, "libprefix=", 10)==0)
2905 libprefix = option+10;
2906 else if (strcmp(option, "quiet") == 0)
2907 Quiet = 1;
2908 else if (strcmp(option, "version")==0)
2910 fprintf(stderr, "fd2inline version " VERSION "\n");
2911 return EXIT_SUCCESS;
2913 /* Compatibility options */
2914 else if (strcmp(option, "new")==0)
2915 output_mode=NEW;
2916 else if (strcmp(option, "old")==0)
2917 output_mode=OLD;
2918 else if (strcmp(option, "stubs")==0)
2919 output_mode=STUBS;
2920 else if (strcmp(option, "gatestubs")==0)
2921 output_mode=GATESTUBS;
2922 else if (strcmp(option, "proto")==0)
2923 output_mode=PROTO;
2924 else if (strcmp(option, "pos")==0)
2925 target=M68K_POS;
2926 else if (strcmp(option, "powerup")==0)
2927 target=PPC_POWERUP;
2928 else if (strcmp(option, "morphos")==0)
2929 target=PPC_MORPHOS;
2930 /* Unknown option */
2931 else
2933 printusage(argv[0]);
2934 return EXIT_FAILURE;
2938 else
2940 /* One of the filenames */
2941 if (!fdfilename)
2942 fdfilename=option;
2943 else if (!clibfilename)
2944 clibfilename=option;
2945 else if (!outfilename)
2946 outfilename=option;
2947 else
2949 printusage(argv[0]);
2950 return EXIT_FAILURE;
2955 if (!fdfilename || (!clibfilename && output_mode!=PROTO))
2957 printusage(argv[0]);
2958 return EXIT_FAILURE;
2961 if (target==M68K_POS && output_mode!=NEW)
2963 fprintf(stderr, "Target is not compatible with the mode.\n");
2964 return EXIT_FAILURE;
2967 if (!(arrdefs=malloc(FDS*sizeof(fdDef*))))
2969 fprintf(stderr, "No mem for FDs\n");
2970 return EXIT_FAILURE;
2972 for (count=0; count<FDS; count++)
2973 arrdefs[count]=NULL;
2975 if (!(myfile=fF_ctor(fdfilename)))
2977 fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
2978 return EXIT_FAILURE;
2981 lerror=false;
2983 for (count=0; count<FDS && lerror==false; count++)
2985 if (!(arrdefs[count]=fD_ctor()))
2987 fprintf(stderr, "No mem for FDs\n" );
2988 return EXIT_FAILURE;
2992 if ((lerror=fF_readln(myfile))==false)
2994 fF_SetError(myfile, false);
2995 lerror=fD_parsefd(arrdefs[count], myfile);
2998 while (lerror==nodef);
3000 if (count<FDS)
3002 count--;
3003 fD_dtor(arrdefs[count]);
3004 arrdefs[count]=NULL;
3006 fds=count;
3008 qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
3010 if (output_mode!=NEW || target==AROS)
3012 unsigned int count2;
3013 StdLib="Library";
3015 for (count2=0; count2<sizeof LibExcTable/sizeof LibExcTable[0]; count2+=2)
3016 if (strcmp(BaseName, LibExcTable[count2])==0)
3018 StdLib=LibExcTable[count2+1];
3019 break;
3023 fF_dtor(myfile);
3025 if (output_mode!=PROTO)
3027 if (!(myfile=fF_ctor(clibfilename)))
3029 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3030 return EXIT_FAILURE;
3033 if (!(tmpdef=fD_ctor()))
3035 fprintf(stderr, "No mem for FDs\n");
3036 return EXIT_FAILURE;
3039 for (lerror=false; lerror==false || lerror==nodef;)
3040 if ((lerror=fF_readln(myfile))==false)
3042 fF_SetError(myfile, false); /* continue even on errors */
3043 tmpstr=fF_FuncName(myfile);
3045 if (tmpstr)
3047 fdDef **res;
3048 fD_NewName(tmpdef, tmpstr);
3049 res=(fdDef**)bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
3050 fD_cmpName);
3052 if (res)
3054 founddef=*res;
3055 DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
3056 fF_SetError(myfile, false);
3057 lerror=fD_parsepr(founddef, myfile);
3059 else
3060 if (!ishandleddifferently(myfile->line, tmpstr))
3061 if (!Quiet)
3062 fprintf(stderr, "Don't know what to do with <%s> in line %lu.\n",
3063 tmpstr, myfile->lineno);
3064 free(tmpstr);
3068 fD_dtor(tmpdef);
3070 fF_dtor(myfile);
3073 if (strlen(fdfilename)>7 &&
3074 !strcmp(fdfilename+strlen(fdfilename)-7, "_lib.fd"))
3076 char *str=fdfilename+strlen(fdfilename)-8;
3077 while (str!=fdfilename && str[-1]!='/' && str[-1]!=':')
3078 str--;
3079 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3080 strncpy(BaseNamU, str, strlen(str)-7);
3081 BaseNamU[strlen(str)-7]='\0';
3082 strcpy(BaseNamL, BaseNamU);
3083 strcpy(BaseNamC, BaseNamU);
3085 else
3087 strcpy(BaseNamU, BaseName);
3088 if (strlen(BaseNamU)>4 && strcmp(BaseNamU+strlen(BaseNamU)-4, "Base")==0)
3089 BaseNamU[strlen(BaseNamU)-4]='\0';
3090 if (target==M68K_POS && strncmp(BaseNamU, "gb_", 3)==0)
3091 memmove(BaseNamU, &BaseNamU[3], strlen(&BaseNamU[3])+1);
3092 strcpy(BaseNamL, BaseNamU);
3093 strcpy(BaseNamC, BaseNamU);
3095 StrUpr(BaseNamU);
3096 BaseNamC[0]=toupper(BaseNamC[0]);
3098 if (outfilename)
3100 if (!(outfile=fopen(outfilename, "w")))
3102 fprintf(stderr, "Couldn't open output file.\n");
3103 return EXIT_FAILURE;
3105 else
3107 closeoutfile=1;
3110 else
3111 outfile=stdout;
3113 if (output_mode==PROTO)
3114 output_proto(outfile);
3115 else
3117 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS ||
3118 output_mode==GATESTUBS || output_mode==GATEPROTO)
3120 if (output_mode==GATESTUBS || output_mode==GATEPROTO)
3122 fprintf(outfile,
3123 "/* Automatically generated stubs! Do not edit! */\n\n");
3125 else
3127 fprintf(outfile,
3128 "/* Automatically generated header! Do not edit! */\n\n"
3129 "#ifndef %sINLINE_%s_H\n"
3130 "#define %sINLINE_%s_H\n\n",
3131 (target==M68K_POS ? "__INC_POS_P" : "_"),
3132 BaseNamU,
3133 (target==M68K_POS ? "__INC_POS_P" : "_"),
3134 BaseNamU );
3137 if (output_mode==NEW)
3139 if(target==M68K_POS)
3141 fprintf(outfile,
3142 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3143 "#include <pInline/macros.h>\n"
3144 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3146 else if(target==AROS)
3148 fprintf(outfile,
3149 "#ifndef AROS_LIBCALL_H\n"
3150 "#include <aros/libcall.h>\n"
3151 "#endif /* !AROS_LIBCALL_H */\n\n");
3153 else
3155 fprintf(outfile,
3156 "#ifndef __INLINE_MACROS_H\n"
3157 "#include <inline/macros.h>\n"
3158 "#endif /* !__INLINE_MACROS_H */\n\n");
3161 else
3163 FILE* clib;
3165 fprintf(outfile,
3166 "#ifndef __INLINE_STUB_H\n"
3167 "#include <inline/stubs.h>\n"
3168 "#endif /* !__INLINE_STUB_H */\n\n");
3170 fprintf(outfile, "#ifdef __CLIB_TYPES__\n" );
3172 clib = fopen( clibfilename, "r" );
3174 if( clib == NULL )
3176 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3178 else
3180 char* buffer = malloc( 1024 );
3182 if( buffer == NULL )
3184 fprintf(stderr, "No memory for line buffer.\n " );
3186 else
3188 while( fgets( buffer, 1023, clib ) != NULL )
3190 if( buffer[ 0 ] == '#' /* Pre-processor instruction */ ||
3191 strncmp( buffer, "typedef", 7 ) == 0 )
3193 fputs(buffer, outfile );
3197 free( buffer );
3200 fclose( clib );
3203 fprintf(outfile, "#endif /* __CLIB_TYPES__ */\n\n" );
3205 if(target==AROS)
3207 fprintf(outfile,
3208 "#include <aros/libcall.h>\n\n" );
3210 else if(target==IX86BE_AMITHLON)
3212 fprintf(outfile,
3213 "#ifndef __INLINE_MACROS_H\n"
3214 "#include <inline/macros.h>\n"
3215 "#endif /* __INLINE_MACROS_H */\n\n");
3217 else if (target == PPC_MORPHOS)
3219 fprintf(outfile,
3220 "#include <emul/emulregs.h>\n\n" );
3224 else
3226 fprintf(stderr, "Internal error: Unknown output mode in main().\n");
3228 if (closeoutfile)
3230 fclose(outfile);
3233 return EXIT_FAILURE;
3236 if (BaseName[0])
3238 if (output_mode==NEW)
3240 fprintf(outfile,
3241 "#ifndef %s%s_BASE_NAME\n"
3242 "#define %s%s_BASE_NAME %s\n"
3243 "#endif /* !%s%s_BASE_NAME */\n\n",
3244 (target==M68K_POS ? "__" : ""), BaseNamU,
3245 (target==M68K_POS ? "__" : ""), BaseNamU, BaseName,
3246 (target==M68K_POS ? "__" : ""), BaseNamU);
3247 if (target==M68K_POS)
3248 fprintf(outfile,
3249 "#ifndef __%s_LIB_NAME\n"
3250 "#define __%s_LIB_NAME %s\n"
3251 "#endif /* !__%s_LIB_NAME */\n\n",
3252 BaseNamU, BaseNamU,
3253 (strcmp(BaseName, "gb_ExecBase") ? BaseName : "gb_ExecLib"),
3254 BaseNamU);
3256 else
3257 fprintf(outfile,
3258 "#ifndef BASE_EXT_DECL\n"
3259 "#define BASE_EXT_DECL\n"
3260 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3261 "#endif /* !BASE_EXT_DECL */\n"
3262 "#ifndef BASE_PAR_DECL\n"
3263 "#define BASE_PAR_DECL\n"
3264 "#define BASE_PAR_DECL0 void\n"
3265 "#endif /* !BASE_PAR_DECL */\n"
3266 "#ifndef BASE_NAME\n"
3267 "#define BASE_NAME %s\n"
3268 "#endif /* !BASE_NAME */\n\n"
3269 "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
3272 for (count=0; count<FDS && arrdefs[count]; count++)
3274 DBP(fprintf(stderr, "outputting %ld...\n", count));
3276 fD_write(outfile, arrdefs[count]);
3277 fD_dtor(arrdefs[count]);
3278 arrdefs[count]=NULL;
3281 if (output_mode!=NEW)
3282 if (BaseName[0])
3283 fprintf(outfile,
3284 "#undef BASE_EXT_DECL\n"
3285 "#undef BASE_EXT_DECL0\n"
3286 "#undef BASE_PAR_DECL\n"
3287 "#undef BASE_PAR_DECL0\n"
3288 "#undef BASE_NAME\n\n");
3290 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS)
3292 fprintf(outfile, "#endif /* !%sINLINE_%s_H */\n",
3293 (target==M68K_POS ? "__INC_POS_P" : "_"), BaseNamU);
3297 free(arrdefs);
3299 if (closeoutfile)
3301 fclose(outfile);
3304 return EXIT_SUCCESS;