make sure we always skip the private area
[AROS.git] / tools / fd2inline / fd2inline.c
blob459d994cfa9c020e3d8895a0a38d46a8a1911be6
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 } 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==strpbrk(low, "*#/"))
441 DBP(fprintf(stderr, "in# %s\n", obj->line));
442 return false;
444 len=strlen(low);
445 bpoint=low+len-1;
446 while (len && isspace(*bpoint))
448 bpoint--;
449 len--;
451 if (*bpoint==';' || *bpoint==')')
453 DBP(fprintf(stderr, "\nin: %s\n", obj->line));
454 return false;
456 glen+=len;
457 low+=len;
458 if (glen>=fF_BUFSIZE-10) /* somewhat pessimistic? */
460 fF_SetError(obj, real_error);
461 fprintf(stderr, "Line %lu too long.\n", obj->lineno);
462 return real_error;
464 DBP(fprintf(stderr, "+"));
467 illparams("fF_readln");
468 return real_error;
471 static INLINE Error
472 fF_GetError(const fdFile* obj)
474 if (obj)
475 return obj->error;
476 illparams("fF_GetError");
477 return real_error;
480 static INLINE long
481 fF_GetOffset(const fdFile* obj)
483 if (obj)
484 return obj->offset;
485 illparams("fF_GetOffset");
486 return -1;
489 /******************************************************************************
490 * fF_FuncName
492 * checks if it can find a function-name and return it's address, or NULL
493 * if the current line does not seem to contain one. The return value will
494 * be a pointer into a malloced buffer, thus the caller will have to free().
495 ******************************************************************************/
497 char*
498 fF_FuncName(fdFile* obj)
500 const char *lower;
501 const char *upper;
502 char *buf;
503 long obraces; /* count of open braces */
504 Error ready; /* ready with searching */
506 if (!obj || fF_GetError(obj)==real_error)
508 illparams("fF_FuncName");
509 return NULL;
512 lower=obj->line;
513 while (*lower && (*lower==' ' || *lower=='\t'))
514 lower++;
516 if (!*lower || (!isalpha(*lower) && *lower!='_'))
518 fF_SetError(obj, nodef);
519 return NULL;
522 while (*lower)
524 if (!isalnum(*lower) && !isspace(*lower) && *lower!='*' && *lower!=','
525 && *lower!='.' && *lower!=';' && *lower!='(' && *lower!=')' &&
526 *lower!='[' && *lower!=']' && *lower!='_' && *lower!='\\')
528 fF_SetError(obj, nodef);
529 return NULL;
531 lower++;
534 lower=NULL;
535 buf=NULL;
537 if (obj && fF_GetError(obj)==false)
539 if ((upper=strrchr(obj->line, ')'))!=0)
541 DBP(fprintf(stderr, "end:%s:", upper));
543 for (obraces=1, ready=false; ready==false; upper=lower)
545 lower=StrNRBrk(obj->line, "()", --upper);
546 if (lower)
548 switch (*lower)
550 case ')':
551 obraces++;
552 DBP(fprintf(stderr, " )%ld%s", obraces, lower));
553 break;
554 case '(':
555 obraces--;
556 DBP(fprintf(stderr, " (%ld%s", obraces, lower));
557 if (!obraces)
558 ready=nodef;
559 break;
560 default:
561 fprintf(stderr, "Faulty StrNRBrk\n");
564 else
566 fprintf(stderr, "'(' or ')' expected in line %lu.\n",
567 obj->lineno);
568 ready=real_error;
571 if (ready==nodef) /* we found the matching '(' */
573 long newlen;
574 const char* name;
576 upper--;
578 while (upper>=obj->line && (*upper==' ' || *upper=='\t'))
579 upper--;
581 lower=StrNRBrk(obj->line, " \t*)", upper);
583 if (!lower)
584 lower=obj->line;
585 else
586 lower++;
588 for (name=lower; name<=upper; name++)
589 if (!isalnum(*name) && *name!='_')
591 fF_SetError(obj, nodef);
592 return NULL;
595 newlen=upper-lower+1;
596 buf=malloc(newlen+1);
598 if (buf)
600 strncpy(buf, lower, newlen);
601 buf[newlen]='\0';
603 else
604 fprintf(stderr, "No mem for fF_FuncName");
608 else
609 illparams("fF_FuncName");
610 return buf;
613 static INLINE fdflags
614 fF_GetFlags(const fdFile* obj)
616 if (obj)
617 return obj->flags;
618 illparams("fF_GetFlags");
619 return 0;
622 /*********************
623 * CLASS fdDef *
624 *********************/
626 typedef struct
628 char* name;
629 char* type;
630 long offset;
631 regs reg[REGS];
632 char* param[REGS];
633 char* proto[REGS];
634 regs funcpar; /* number of argument that has type "pointer to function" */
635 } fdDef;
637 fdDef*
638 fD_ctor (void);
639 void
640 fD_dtor (fdDef* obj);
641 static void
642 fD_NewName (fdDef* obj, const char* newname);
643 void
644 fD_NewParam (fdDef* obj, shortcard at, const char* newstr);
646 fD_NewProto (fdDef* obj, shortcard at, char* newstr);
647 static void
648 fD_NewReg (fdDef* obj, shortcard at, regs reg);
649 static void
650 fD_NewType (fdDef* obj, const char* newstr);
651 static void
652 fD_SetOffset (fdDef* obj, long off);
653 Error
654 fD_parsefd (fdDef* obj, fdFile* infile);
655 Error
656 fD_parsepr (fdDef* obj, fdFile* infile);
657 static const char*
658 fD_GetName (const fdDef* obj);
659 static long
660 fD_GetOffset (const fdDef* obj);
661 static const char*
662 fD_GetParam (const fdDef* obj, shortcard at);
663 static regs
664 fD_GetReg (const fdDef* obj, shortcard at);
665 static const char*
666 fD_GetRegStr (const fdDef* obj, shortcard at);
667 static const char*
668 fD_GetRegStrU (const fdDef* obj, shortcard at);
669 static const char*
670 fD_GetType (const fdDef* obj);
671 static shortcard
672 fD_ParamNum (const fdDef* obj);
673 static shortcard
674 fD_ProtoNum (const fdDef* obj);
675 static shortcard
676 fD_RegNum (const fdDef* obj);
678 fD_cmpName (const void* big, const void* small);
679 void
680 fD_write (FILE* outfile, const fdDef* obj);
681 static shortcard
682 fD_GetFuncParNum (const fdDef* obj);
683 static void
684 fD_SetFuncParNum (fdDef* obj, shortcard at);
685 static void
686 fD_adjustargnames(fdDef *obj);
688 fdDef **arrdefs;
689 long fds;
691 char *fD_nostring="";
693 fdDef*
694 fD_ctor(void)
696 fdDef *result;
697 regs count;
699 result=malloc(sizeof(fdDef));
701 if (result)
703 result->name=fD_nostring;
704 result->type=fD_nostring;
705 result->funcpar=illegal;
707 for (count=d0; count<illegal; count++ )
709 result->reg[count]=illegal;
710 result->param[count]=fD_nostring; /* if (!strlen) dont't free() */
711 result->proto[count]=fD_nostring;
714 return result;
717 /* free all resources and make the object as illegal as possible */
719 void
720 fD_dtor(fdDef* obj)
722 regs count;
724 if (obj)
726 if (!obj->name)
727 fprintf(stderr, "fD_dtor: null name");
728 else
729 if (obj->name!=fD_nostring)
730 free(obj->name);
732 if (!obj->type)
733 fprintf(stderr, "fD_dtor: null type");
734 else
735 if (obj->type!=fD_nostring)
736 free(obj->type);
738 obj->name=obj->type=NULL;
740 for (count=d0; count<illegal; count++)
742 obj->reg[count]=illegal;
744 if (!obj->param[count])
745 fprintf(stderr, "fD_dtor: null param");
746 else
747 if (obj->param[count]!=fD_nostring)
748 free(obj->param[count]);
750 if (!obj->proto[count])
751 fprintf(stderr, "fD_dtor: null proto");
752 else
753 if (obj->proto[count]!=fD_nostring)
754 free(obj->proto[count]);
756 obj->param[count]=obj->proto[count]=NULL;
759 free(obj);
761 else
762 fprintf(stderr, "fd_dtor(NULL)\n");
765 static INLINE void
766 fD_NewName(fdDef* obj, const char* newname)
768 if (obj && newname)
770 if (obj->name && obj->name!=fD_nostring)
771 free(obj->name);
772 if (!NewString(&obj->name, newname))
773 obj->name=fD_nostring;
775 else
776 illparams("fD_NewName");
779 void
780 fD_NewParam(fdDef* obj, shortcard at, const char* newstr)
782 char *pa;
784 if (newstr && obj && at<illegal)
786 pa=obj->param[at];
788 if (pa && pa!=fD_nostring)
789 free(pa);
791 while (*newstr==' ' || *newstr=='\t')
792 newstr++;
794 if (NewString(&pa, newstr))
796 char* prefix_pa;
798 prefix_pa = malloc( strlen( pa ) + 4 );
800 if( prefix_pa == NULL )
802 fprintf(stderr, "No mem for string\n");
804 else
806 sprintf( prefix_pa, "___%s", pa );
807 obj->param[at]=prefix_pa;
808 free( pa );
811 else
812 obj->param[at]=fD_nostring;
814 else
815 illparams("fD_NewParam");
818 /* get first free *reg or illegal */
820 static INLINE shortcard
821 fD_RegNum(const fdDef* obj)
823 shortcard count;
825 if (obj)
827 for (count=d0; count<illegal && obj->reg[count]!=illegal; count++);
828 return count;
830 else
832 illparams("fD_RegNum");
833 return illegal;
837 static INLINE void
838 fD_NewReg(fdDef* obj, shortcard at, regs reg)
840 if (obj && at<illegal && reg>=d0 && reg<=illegal)
841 obj->reg[at]=reg;
842 else
843 illparams("fD_NewReg");
846 static INLINE regs
847 fD_GetReg(const fdDef* obj, shortcard at)
849 if (obj && at<illegal)
850 return obj->reg[at];
851 else
853 illparams("fD_GetReg");
854 return illegal;
858 static INLINE shortcard
859 fD_GetFuncParNum(const fdDef* obj)
861 if (obj)
862 return (shortcard)obj->funcpar;
863 else
865 illparams("fD_GetFuncParNum");
866 return illegal;
870 static INLINE void
871 fD_SetFuncParNum(fdDef* obj, shortcard at)
873 if (obj && at<illegal)
874 obj->funcpar=at;
875 else
876 illparams("fD_SetFuncParNum");
880 fD_NewProto(fdDef* obj, shortcard at, char* newstr)
882 char *pr;
884 if (newstr && obj && at<illegal)
886 char *t, arr[200]; /* I hope 200 will be enough... */
887 int numwords=1;
888 pr=obj->proto[at];
890 if (pr && pr!=fD_nostring)
891 free(pr);
893 while (*newstr==' ' || *newstr=='\t')
894 newstr++; /* Skip leading spaces */
896 t=arr;
897 while ((*t++=*newstr)!=0)
899 /* Copy the rest, counting number of words */
900 if ((*newstr==' ' || *newstr=='\t') && newstr[1] && newstr[1]!=' ' &&
901 newstr[1]!='\t')
902 numwords++;
903 newstr++;
906 t=arr+strlen(arr)-1;
907 while (*t==' ' || *t=='\t')
908 t--;
909 t[1]='\0'; /* Get rid of tailing spaces */
911 if (at!=fD_GetFuncParNum(obj))
913 if (numwords>1) /* One word - must be type */
914 if (*t!='*')
916 /* '*' on the end - no parameter name used */
917 while (*t!=' ' && *t!='\t' && *t!='*')
918 t--;
919 t++;
920 if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
921 && strcmp(t, "long") && strcmp(t, "APTR"))
923 /* Not one of applicable keywords - must be parameter name.
924 Get rid of it. */
925 t--;
926 while (*t==' ' || *t=='\t')
927 t--;
928 t[1]='\0';
932 else
934 /* Parameter of type "pointer to function". */
935 char *end;
936 t=strchr(arr, '(');
937 t++;
938 while (*t==' ' || *t=='\t')
939 t++;
940 if (*t!='*')
941 return 1;
942 t++;
943 end=strchr(t, ')');
944 if (target!=M68K_POS)
946 memmove(t+2, end, strlen(end)+1);
947 *t='%';
948 t[1]='s';
950 else
951 memmove(t, end, strlen(end)+1);
954 if (NewString(&pr, arr))
956 obj->proto[at]=pr;
957 while (*pr==' ' || *pr=='\t')
958 pr++;
959 if (!strcasecmp(pr, "double"))
961 /* "double" needs two data registers */
962 int count, regs=fD_RegNum(obj);
963 for (count=at+1; count<regs; count++)
964 fD_NewReg(obj, count, fD_GetReg(obj, count+1));
967 else
968 obj->proto[at]=fD_nostring;
970 else
971 illparams("fD_NewProto");
973 return 0;
976 static INLINE void
977 fD_NewType(fdDef* obj, const char* newtype)
979 if (obj && newtype)
981 if (obj->type && obj->type!=fD_nostring)
982 free(obj->type);
983 if (!NewString(&obj->type, newtype))
984 obj->type=fD_nostring;
986 else
987 illparams("fD_NewType");
990 static INLINE void
991 fD_SetOffset(fdDef* obj, long off)
993 if (obj)
994 obj->offset=off;
995 else
996 illparams("fD_SetOffset");
999 static INLINE const char*
1000 fD_GetName(const fdDef* obj)
1002 if (obj && obj->name)
1003 return obj->name;
1004 else
1006 illparams("fD_GetName");
1007 return fD_nostring;
1011 static INLINE long
1012 fD_GetOffset(const fdDef* obj)
1014 if (obj)
1015 return obj->offset;
1016 else
1018 illparams("fD_GetOffset");
1019 return 0;
1023 static INLINE const char*
1024 fD_GetProto(const fdDef* obj, shortcard at)
1026 if (obj && at<illegal && obj->proto[at])
1027 return obj->proto[at];
1028 else
1030 illparams("fD_GetProto");
1031 return fD_nostring;
1035 static INLINE const char*
1036 fD_GetParam(const fdDef* obj, shortcard at)
1038 if (obj && at<illegal && obj->param[at])
1039 return obj->param[at];
1040 else
1042 illparams("fD_GetParam");
1043 return fD_nostring;
1047 static INLINE const char*
1048 fD_GetRegStr(const fdDef* obj, shortcard at)
1050 if (obj && at<illegal)
1051 return RegStr(obj->reg[at]);
1052 else
1054 illparams("fD_GetReg");
1055 return RegStr(illegal);
1059 static INLINE const char*
1060 fD_GetRegStrU(const fdDef* obj, shortcard at)
1062 if (obj && at<illegal)
1063 return RegStrU(obj->reg[at]);
1064 else
1066 illparams("fD_GetReg");
1067 return RegStrU(illegal);
1071 static INLINE const char*
1072 fD_GetType(const fdDef* obj)
1074 if (obj && obj->type)
1075 return obj->type;
1076 else
1078 illparams("fD_GetType");
1079 return fD_nostring;
1083 /* get first free param or illegal */
1085 static INLINE shortcard
1086 fD_ParamNum(const fdDef* obj)
1088 shortcard count;
1090 if (obj)
1092 for (count=d0; count<illegal && obj->param[count]!=fD_nostring;
1093 count++);
1094 return count;
1096 else
1098 illparams("fD_ParamNum");
1099 return illegal;
1103 static INLINE shortcard
1104 fD_ProtoNum(const fdDef* obj)
1106 shortcard count;
1108 if (obj)
1110 for (count=d0; count<illegal && obj->proto[count]!=fD_nostring;
1111 count++);
1112 return count;
1114 else
1116 illparams("fD_ProtoNum");
1117 return illegal;
1121 /******************************************************************************
1122 * fD_parsefd
1124 * parse the current line. Needs to copy input, in order to insert \0's
1125 * RETURN
1126 * fF_GetError(infile):
1127 * false = read a definition.
1128 * nodef = not a definition on line (so try again)
1129 * error = real error
1130 ******************************************************************************/
1132 Error
1133 fD_parsefd(fdDef* obj, fdFile* infile)
1135 enum parse_info { name, params, regs, ready } parsing;
1136 char *buf, *bpoint, *bnext;
1137 unsigned long index;
1139 if (obj && infile && fF_GetError(infile)==false)
1141 parsing=name;
1143 if (!NewString(&buf, infile->line))
1145 fprintf(stderr, "No mem for line %lu\n", infile->lineno);
1146 fF_SetError(infile, real_error);
1148 bpoint=buf; /* so -Wall keeps quiet */
1150 /* try to parse the line until there's an error or we are done */
1152 while (parsing!=ready && fF_GetError(infile)==false)
1154 switch (parsing)
1156 case name:
1157 switch (buf[0])
1159 case '#':
1160 if (strncmp("##base", buf, 6)==0)
1162 bnext=buf+6;
1163 while (*bnext==' ' || *bnext=='\t' || *bnext=='_')
1164 bnext++;
1165 strcpy(BaseName, bnext);
1166 BaseName[strlen(BaseName)-1]='\0';
1168 else
1169 if (strncmp("##bias", buf, 6)==0)
1171 if (!sscanf(buf+6, "%ld", &infile->offset))
1173 fprintf(stderr, "Illegal ##bias in line %lu: %s\n",
1174 infile->lineno, infile->line);
1175 fF_SetError(infile, real_error);
1176 break; /* avoid nodef */
1178 else
1180 if (fF_GetOffset(infile)>0)
1181 fF_SetOffset(infile, -fF_GetOffset(infile));
1182 DBP(fprintf(stderr, "set offset to %ld\n",
1183 fF_GetOffset(infile)));
1186 else
1188 if (strncmp("##private", buf, 9)==0)
1189 fF_SetFlags(infile, fF_GetFlags(infile) |
1190 FD_PRIVATE);
1191 else if (strncmp("##public", buf, 8)==0)
1192 fF_SetFlags(infile, fF_GetFlags(infile) &
1193 ~FD_PRIVATE);
1194 else if (strncmp("##shadow", buf, 8)==0)
1195 fF_SetFlags(infile, fF_GetFlags(infile) |
1196 FD_SHADOW);
1198 /* drop through for error comment */
1200 case '*':
1201 /* try again somewhere else */
1202 fF_SetError(infile, nodef);
1203 break;
1205 default:
1206 /* assume a regular line here */
1207 if (fF_GetFlags(infile) & (FD_PRIVATE | FD_SHADOW))
1209 /* don't store names of privates */
1210 fF_SetError(infile, nodef);
1211 if (!(fF_GetFlags(infile) & FD_SHADOW))
1212 fF_SetOffset(infile,
1213 fF_GetOffset(infile)-FUNCTION_GAP);
1214 else
1215 /* Shadow is valid for one line only. */
1216 fF_SetFlags(infile, fF_GetFlags(infile) &
1217 ~FD_SHADOW);
1218 break;
1220 parsing=name; /* switch (parsing) */
1221 for (index=0; buf[index] && buf[index]!='('; index++);
1223 if (!buf[index])
1225 /* oops, no fd ? */
1226 fprintf(stderr, "Not an fd, line %lu: %s\n",
1227 infile->lineno, buf /* infile->line */);
1228 fF_SetError(infile, nodef);
1229 } /* maybe next time */
1230 else
1232 buf[index]=0;
1234 fD_NewName(obj, buf);
1235 fD_SetOffset(obj, fF_GetOffset(infile));
1237 bpoint=buf+index+1;
1238 parsing=params; /* continue the loop */
1241 break;
1243 case params:
1245 char *bptmp; /* needed for fD_NewParam */
1247 /* look for parameters now */
1249 for (bnext = bpoint; *bnext && *bnext!=',' && *bnext!=')';
1250 bnext++);
1252 if (*bnext)
1254 bptmp=bpoint;
1256 if (*bnext == ')')
1258 if (bnext[1] != '(')
1260 fprintf(stderr, "Registers expected in line %lu: %s\n",
1261 infile->lineno, infile->line);
1262 fF_SetError(infile, nodef);
1264 else
1266 parsing=regs;
1267 bpoint=bnext+2;
1270 else
1271 bpoint = bnext+1;
1273 /* terminate string and advance to next item */
1275 *bnext='\0';
1276 fD_NewParam(obj, fD_ParamNum(obj), bptmp);
1278 else
1280 fF_SetError(infile, nodef);
1281 fprintf(stderr, "Param expected in line %lu: %s\n",
1282 infile->lineno, infile->line);
1284 break; /* switch parsing */
1287 case regs:
1288 /* look for parameters now */
1290 for (bnext=bpoint; *bnext && *bnext!='/' && *bnext!=',' &&
1291 *bnext!=')'; bnext++);
1293 if (*bnext)
1295 if (')'==*bnext)
1297 /* wow, we've finished */
1298 fF_SetOffset(infile, fF_GetOffset(infile)-FUNCTION_GAP);
1299 parsing=ready;
1301 *bnext = '\0';
1303 bpoint[0]=tolower(bpoint[0]);
1305 if ((bpoint[0]=='d' || bpoint[0]=='a') && bpoint[1]>='0' &&
1306 bpoint[1]<='8' && bnext==bpoint+2)
1307 fD_NewReg(obj, fD_RegNum(obj),
1308 bpoint[1]-'0'+(bpoint[0]=='a'? 8 : 0));
1309 else
1310 if (bnext!=bpoint)
1312 /* it is when our function is void */
1313 fprintf(stderr, "Illegal register %s in line %ld\n",
1314 bpoint, infile->lineno);
1315 fF_SetError(infile, nodef);
1317 bpoint = bnext+1;
1319 else
1321 fF_SetError(infile, nodef);
1322 fprintf(stderr, "Reg expected in line %lu\n",
1323 infile->lineno);
1325 break; /* switch parsing */
1327 case ready:
1328 fprintf(stderr, "Internal error, use another compiler.\n");
1329 break;
1333 free(buf);
1334 return fF_GetError(infile);
1336 else
1338 illparams("fD_parsefd");
1339 return real_error;
1343 static void
1344 fD_adjustargnames(fdDef *obj)
1346 int parnum;
1348 if (output_mode!=NEW)
1349 return;
1351 /* For #define-base output mode, we have to check if argument names are not
1352 the same as some words in type names. We check from the first argument
1353 to the last, resolving conflicts by changing argument names, if
1354 necessary. */
1356 for (parnum=0; parnum<fD_ParamNum(obj); parnum++)
1358 const char *parname=fD_GetParam(obj, parnum);
1359 int finished;
1362 int num;
1363 const char *type=fD_GetType(obj);
1364 char *str;
1366 finished=1;
1368 if ((str=strstr(type, parname))!=0 && (str==type ||
1369 (!isalnum(str[-1]) && str[-1]!='_')) &&
1370 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_')))
1372 char buf[300]; /* Hope will be enough... */
1373 strcpy(buf, parname);
1374 strcat(buf, "_");
1375 fD_NewParam(obj, parnum, buf);
1376 parname=fD_GetParam(obj, parnum);
1377 finished=0;
1379 else
1380 for (num=0; num<fD_ParamNum(obj); num++)
1382 const char *name=fD_GetParam(obj, num);
1383 const char *proto=fD_GetProto(obj, num);
1384 if ((num<parnum && strcmp(name, parname)==0) ||
1385 ((str=strstr(proto, parname))!=0 && (str==proto ||
1386 (!isalnum(str[-1]) && str[-1]!='_')) &&
1387 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_'))))
1389 char buf[300]; /* Hope will be enough... */
1390 strcpy(buf, parname);
1391 strcat(buf, "_");
1392 fD_NewParam(obj, parnum, buf);
1393 parname=fD_GetParam(obj, parnum);
1394 // lcs finished=0;
1395 break;
1398 } while (!finished);
1402 Error
1403 fD_parsepr(fdDef* obj, fdFile* infile)
1405 char *buf; /* a copy of infile->line */
1406 char *bpoint, /* cursor in buf */
1407 *bnext, /* looking for the end */
1408 *lowarg; /* beginning of this argument */
1409 long obraces; /* count of open braces */
1410 regs count, /* count parameter number */
1411 args; /* the number of arguments for this function */
1413 if (!(obj && infile && fF_GetError(infile)==false))
1415 illparams("fD_parsepr");
1416 fF_SetError(infile, real_error);
1417 return real_error;
1419 if (!NewString(&buf, infile->line))
1421 fprintf(stderr, "No mem for fD_parsepr\n");
1422 fF_SetError(infile, real_error);
1423 return real_error;
1425 fF_SetError(infile, false);
1427 bpoint=strchr(buf, '(');
1428 while (--bpoint>=buf && strstr(bpoint, fD_GetName(obj))!=bpoint);
1429 if (bpoint>=buf)
1431 while (--bpoint >= buf && (*bpoint==' ' || *bpoint=='\t'));
1432 *++bpoint='\0';
1434 fD_NewType(obj, buf);
1436 while (bpoint && *bpoint++!='('); /* one beyond '(' */
1438 lowarg=bpoint;
1439 obraces=0;
1441 for (count=0, args=fD_RegNum(obj); count<args; bpoint=bnext+1)
1443 while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
1444 bpoint++;
1446 if (!obraces && target==M68K_POS && strncmp(bpoint, "_R_", 3)==0 &&
1447 isalnum(bpoint[3]) && isalnum(bpoint[4]) && isspace(bpoint[5]))
1448 lowarg=bpoint+5;
1450 bnext=strpbrk(bpoint, "(),");
1452 if (bnext)
1454 switch (*bnext)
1456 case '(':
1457 if (!obraces)
1459 if (target==M68K_AMIGAOS || target==M68K_POS)
1461 if (fD_GetFuncParNum(obj)!=illegal &&
1462 fD_GetFuncParNum(obj)!=count &&
1463 !Quiet)
1464 fprintf(stderr, "Warning: two parameters of type "
1465 "pointer to function are used.\n"
1466 "This is not supported!\n");
1469 fD_SetFuncParNum(obj, count);
1471 obraces++;
1472 DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
1473 break;
1475 case ')':
1476 if (obraces)
1478 DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
1479 obraces--;
1481 else
1483 *bnext='\0';
1484 DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
1485 if (fD_NewProto(obj, count, lowarg))
1486 fprintf(stderr, "Parser confused in line %ld\n",
1487 infile->lineno);
1488 lowarg=bnext+1;
1490 if (count!=args-1)
1492 DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
1493 fD_GetName(obj), args, count+1));
1494 fF_SetError(infile, nodef);
1496 count++;
1498 break;
1500 case ',':
1501 if (!obraces)
1503 *bnext='\0';
1504 DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
1505 if (fD_NewProto(obj, count, lowarg))
1506 fprintf(stderr, "Parser confused in line %ld\n",
1507 infile->lineno);
1508 lowarg=bnext+1;
1509 count++;
1511 break;
1513 default:
1514 fprintf(stderr, "Faulty strpbrk in line %lu.\n",
1515 infile->lineno);
1518 else
1520 DBP(fprintf(stderr, "Faulty argument %u in line %lu.\n", count+1,
1521 infile->lineno));
1522 count=args; /* this will effectively quit the for loop */
1523 fF_SetError(infile, nodef);
1526 if (fD_ProtoNum(obj)!=fD_RegNum(obj))
1527 fF_SetError(infile, nodef);
1529 else
1531 fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
1532 fprintf(stderr, "function , definition %s.\n",
1533 /* fD_GetName(obj),*/ infile->line);
1534 fF_SetError(infile, nodef);
1537 free(buf);
1539 fD_adjustargnames(obj);
1541 return fF_GetError(infile);
1545 fD_cmpName(const void* big, const void* small) /* for qsort and bsearch */
1547 return strcmp(fD_GetName(*(fdDef**)big), fD_GetName(*(fdDef**)small));
1550 const static char *TagExcTable[]=
1552 "BuildEasyRequestArgs", "BuildEasyRequest",
1553 "DoDTMethodA", "DoDTMethod",
1554 "DoGadgetMethodA", "DoGadgetMethod",
1555 "EasyRequestArgs", "EasyRequest",
1556 "MUI_MakeObjectA", "MUI_MakeObject",
1557 "MUI_RequestA", "MUI_Request",
1558 "PrintDTObjectA", "PrintDTObject",
1559 "RefreshDTObjectA", "RefreshDTObjects",
1560 "UMSVLog", "UMSLog",
1561 "VFWritef", "FWritef",
1562 "VFPrintf", "FPrintf",
1563 "VPrintf", "Printf",
1566 const char*
1567 getvarargsfunction(const fdDef * obj)
1569 unsigned int count;
1570 const char *name = fD_GetName(obj);
1572 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1574 if (strcmp(name, TagExcTable[count])==0)
1576 return TagExcTable[count+1];
1579 return(NULL);
1582 const char*
1583 taggedfunction(const fdDef* obj)
1585 shortcard numregs=fD_RegNum(obj);
1586 unsigned int count;
1587 int aos_tagitem;
1588 const char *name=fD_GetName(obj);
1589 static char newname[200]; /* Hope will be enough... static because used
1590 out of the function. */
1591 const char *lastarg;
1592 const static char *TagExcTable2[]=
1594 "ApplyTagChanges",
1595 "CloneTagItems",
1596 "FindTagItem",
1597 "FreeTagItems",
1598 "GetTagData",
1599 "PackBoolTags",
1600 "PackStructureTags",
1601 "RefreshTagItemClones",
1602 "UnpackStructureTags",
1605 if (!numregs)
1606 return NULL;
1608 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1609 if (strcmp(name, TagExcTable[count])==0)
1610 return NULL;
1611 // lcs return TagExcTable[count+1];
1613 for (count=0; count<sizeof TagExcTable2/sizeof TagExcTable2[0]; count++)
1614 if (strcmp(name, TagExcTable2[count])==0)
1615 return NULL;
1617 lastarg=fD_GetProto(obj, numregs-1);
1618 if (strncmp(lastarg, "const", 5)==0 || strncmp(lastarg, "CONST", 5)==0)
1619 lastarg+=5;
1620 while (*lastarg==' ' || *lastarg=='\t')
1621 lastarg++;
1622 if (strncmp(lastarg, "struct", 6))
1623 return NULL;
1624 lastarg+=6;
1625 while (*lastarg==' ' || *lastarg=='\t')
1626 lastarg++;
1627 aos_tagitem=1;
1628 if (strncmp(lastarg, "TagItem", 7) &&
1629 (target!=M68K_POS || ((aos_tagitem=strncmp(lastarg, "pOS_TagItem", 11))!=0)))
1630 return NULL;
1631 lastarg+=(aos_tagitem ? 7 : 11);
1632 while (*lastarg==' ' || *lastarg=='\t')
1633 lastarg++;
1634 if (strcmp(lastarg, "*"))
1635 return NULL;
1637 strcpy(newname, name);
1638 if (newname[strlen(newname)-1]=='A')
1639 newname[strlen(newname)-1]='\0';
1640 else
1641 if (strlen(newname)>7 && !strcmp(newname+strlen(newname)-7, "TagList"))
1642 strcpy(newname+strlen(newname)-4, "s");
1643 else
1644 strcat(newname, "Tags");
1645 return newname;
1648 const char*
1649 aliasfunction(const char* name)
1651 const static char *AliasTable[]=
1653 "AllocDosObject", "AllocDosObjectTagList",
1654 "CreateNewProc", "CreateNewProcTagList",
1655 "NewLoadSeg", "NewLoadSegTagList",
1656 "System", "SystemTagList",
1658 unsigned int count;
1659 for (count=0; count<sizeof AliasTable/sizeof AliasTable[0]; count++)
1660 if (strcmp(name, AliasTable[count])==0)
1661 return AliasTable[count+(count%2 ? -1 : 1)];
1662 return NULL;
1665 void
1666 fD_write(FILE* outfile, const fdDef* obj)
1668 shortcard count, numregs;
1669 const char *chtmp, *tagname, *varname, *name, *rettype;
1670 int vd=0, a45=0, d7=0;
1672 DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
1674 numregs=fD_RegNum(obj);
1676 if ((rettype=fD_GetType(obj))==fD_nostring)
1678 fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
1679 return;
1681 if (!strcasecmp(rettype, "void"))
1682 vd = 1; /* set flag */
1683 for (count=d0; count<numregs; count++)
1685 const char *reg=fD_GetRegStr(obj, count);
1686 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1688 if (strcmp(reg, "a4")==0 || strcmp(reg, "a5")==0)
1690 if (!a45)
1691 a45=(strcmp(reg, "a4") ? 5 : 4); /* set flag */
1692 else /* Security check */
1693 if (!Quiet)
1694 fprintf(stderr, "Warning: both a4 and a5 are used. "
1695 "This is not supported!\n");
1698 if (strcmp(reg, "d7")==0) /* Used only when a45!=0 */
1699 d7=1;
1702 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1704 if (a45 && d7) /* Security check */
1705 if (!Quiet)
1706 fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
1707 "supported!\n");
1710 name=fD_GetName(obj);
1712 if (fD_ProtoNum(obj)!=numregs)
1714 fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
1715 fD_ProtoNum(obj), fD_ProtoNum(obj)!= 1 ? "s" : "");
1716 return;
1719 if (output_mode==NEW)
1721 fprintf(outfile, "#define %s(", name);
1723 if (numregs>0)
1725 for (count=d0; count<numregs-1; count++)
1726 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
1727 fprintf(outfile, "%s", fD_GetParam(obj, count));
1730 if (target==M68K_AMIGAOS)
1732 fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
1733 (vd ? "NR" : ""), (a45 ? (a45==4 ? "A4" : "A5") : ""),
1734 (BaseName[0] ? "" : "UB"),
1735 (fD_GetFuncParNum(obj)==illegal ? "" : "FP"), -fD_GetOffset(obj));
1736 if (!vd)
1737 fprintf(outfile, "%s, ", rettype);
1738 fprintf(outfile, "%s, ", name);
1740 for (count=d0; count<numregs; count++)
1742 chtmp=fD_GetRegStr(obj, count);
1743 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1744 chtmp="d7";
1745 fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj)==count ?
1746 "__fpt" : fD_GetProto(obj, count)),
1747 fD_GetParam(obj, count),
1748 chtmp, (count==numregs-1 && !BaseName[0] ? "" : ", "));
1751 if (BaseName[0]) /* was "##base" used? */
1752 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1753 if (fD_GetFuncParNum(obj)!=illegal)
1755 fprintf(outfile, ", ");
1756 fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
1758 fprintf(outfile, ")\n\n");
1760 else if(target==M68K_POS)
1762 fprintf(outfile, ") \\\n\t__INLINE_FUN_%d(", numregs);
1763 fprintf(outfile, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1764 BaseNamU, BaseNamU, -fD_GetOffset(obj), rettype, name,
1765 (numregs ? ", \\\n\t" : ""));
1767 for (count=d0; count<numregs; count++)
1768 fprintf(outfile, "%s, %s, %s%s", fD_GetProto(obj, count),
1769 fD_GetParam(obj, count), fD_GetRegStr(obj, count),
1770 (count==numregs-1 ? "" : ", "));
1771 fprintf(outfile, ")\n\n");
1773 else if (target==PPC_POWERUP || target==PPC_MORPHOS)
1775 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1776 numregs,
1777 (vd ? "NR" : ""),
1778 (BaseName[0] ? "" : "UB"),
1779 -fD_GetOffset(obj));
1781 if (!vd)
1782 fprintf(outfile, "%s, ", rettype);
1783 fprintf(outfile, "%s, ", name);
1785 for (count=d0; count<numregs; count++)
1787 chtmp=fD_GetRegStr(obj, count);
1789 if (strchr(fD_GetProto(obj, count),'%'))
1791 sprintf(Buffer,
1792 fD_GetProto(obj, count),
1793 "");
1795 fprintf(outfile, "%s, %s, %s%s",
1796 Buffer,
1797 fD_GetParam(obj, count),
1798 chtmp,
1799 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1801 else
1803 fprintf(outfile, "%s, %s, %s%s",
1804 fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1805 fD_GetParam(obj, count),
1806 chtmp,
1807 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1811 if (BaseName[0])
1812 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1815 * Here it would make sense to create a database file to
1816 * integrate optimizations automaticly into every new
1817 * build. Not every function needs a complete flush. For
1818 * example functions with no parameter wouldn`t need a
1819 * PPC flush normally. Or Read(File,Addr,Size); would
1820 * only need a flush for Addr with the Size
1823 fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1824 fprintf(outfile, ")\n\n");
1826 else if (target==IX86BE_AMITHLON)
1828 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1829 numregs,
1830 (vd ? "NR" : ""),
1831 (BaseName[0] ? "" : "UB"),
1832 -fD_GetOffset(obj));
1834 if (!vd)
1835 fprintf(outfile, "%s, ", rettype);
1836 fprintf(outfile, "%s, ", name);
1838 for (count=d0; count<numregs; count++)
1840 chtmp=fD_GetRegStr(obj, count);
1842 if (strchr(fD_GetProto(obj, count),'%'))
1844 sprintf(Buffer,
1845 fD_GetProto(obj, count),
1846 "");
1848 fprintf(outfile, "%s, %s, %s%s",
1849 Buffer,
1850 fD_GetParam(obj, count),
1851 chtmp,
1852 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1854 else
1856 fprintf(outfile, "%s, %s, %s%s",
1857 fD_GetProto(obj, count),
1858 fD_GetParam(obj, count),
1859 chtmp,
1860 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1864 if (BaseName[0])
1865 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1867 fprintf(outfile, ")\n\n");
1869 else if (target==AROS)
1871 fprintf(outfile, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1872 numregs,
1873 (BaseName[0] ? "" : "I"),
1874 (vd ? "void" : rettype),
1875 name);
1877 for (count=d0; count<numregs; count++)
1879 chtmp=fD_GetRegStrU(obj, count);
1880 fprintf(outfile, "\tAROS_LCA(%s, (%s), %s), \\\n",
1881 fD_GetProto(obj, count),
1882 fD_GetParam(obj, count),
1883 chtmp);
1886 if (BaseName[0]) /* was "##base" used? */
1888 fprintf(outfile, "\tstruct %s *, %s_BASE_NAME, ", StdLib, BaseNamU);
1890 else
1892 fprintf(outfile, "\t/* bt */, /* bn */, ");
1894 fprintf(outfile,
1895 "%ld, /* s */)\n\n",
1896 -fD_GetOffset(obj) / 6);
1898 else
1900 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
1901 return;
1904 else if (output_mode==OLD || output_mode==STUBS)
1906 fprintf(outfile, "%s__inline %s\n%s(%s",
1907 (output_mode==STUBS ? "" : "extern "), rettype, name,
1908 (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1910 if (target==M68K_AMIGAOS)
1912 for (count=d0; count<numregs; count++)
1914 chtmp=fD_GetProto(obj, count);
1915 if (fD_GetFuncParNum(obj)==count)
1916 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1917 else
1918 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
1919 "" : " "), fD_GetParam(obj, count));
1920 if (count<numregs-1)
1921 fprintf(outfile, ", ");
1924 fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
1925 if (!vd)
1926 fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
1927 (*(rettype+strlen(rettype)-1)=='*' ? "" : " "));
1929 if (BaseName[0])
1930 fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1931 StdLib);
1933 for (count=d0; count<numregs; count++)
1935 chtmp=fD_GetRegStr(obj, count);
1936 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1937 chtmp="d7";
1938 if (fD_GetFuncParNum(obj)==count)
1940 fprintf(outfile, " register ");
1941 fprintf(outfile, fD_GetProto(obj, count), chtmp);
1942 fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
1943 count));
1945 else
1947 const char *proto=fD_GetProto(obj, count);
1948 fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
1949 proto, (*(proto+strlen(proto)-1)=='*' ? "" : " "), chtmp,
1950 chtmp, fD_GetParam(obj, count));
1953 if (a45)
1954 fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
1955 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45==4 ? "a4" : "a5"),
1956 -fD_GetOffset(obj), (a45==4 ? "a4" : "a5"));
1957 else
1958 fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1959 -fD_GetOffset(obj));
1961 fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1963 fprintf(outfile, " : ");
1964 if (BaseName[0])
1965 fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", ": ""));
1967 for (count=d0; count<numregs; count++)
1969 chtmp=fD_GetRegStr(obj, count);
1970 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1971 chtmp="d7";
1972 fprintf(outfile, "\"r\" (%s)%s", chtmp, (count<numregs-1 ? ", " : ""));
1974 fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1976 if (vd)
1977 fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1978 else
1979 fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1982 else if (target==PPC_POWERUP)
1984 for (count = d0; count < numregs; count++)
1986 chtmp = fD_GetProto(obj, count);
1987 if (fD_GetFuncParNum(obj) == count)
1988 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1989 else
1990 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
1991 "" : " "), fD_GetParam(obj, count));
1992 if (count < numregs - 1)
1993 fprintf(outfile, ", ");
1996 fprintf(outfile, ")\t\n");
1997 fprintf(outfile, "{\t\n");
1998 fprintf(outfile, "struct Caos\tMyCaos;\n");
1999 fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2000 fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
2001 fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
2002 fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
2003 fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
2004 fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
2006 if (numregs > 0)
2008 for (count = d0; count < numregs; count++)
2010 fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2011 fD_GetRegStr(obj, count),
2012 fD_GetParam(obj, count));
2016 fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
2017 if (BaseName[0]) /*
2018 * was "##base" used?
2021 fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2023 if (vd)
2025 fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2027 else
2029 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2030 rettype);
2033 else if (target==PPC_MORPHOS)
2035 for (count = d0; count < numregs; count++)
2037 chtmp = fD_GetProto(obj, count);
2038 if (fD_GetFuncParNum(obj) == count)
2039 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2040 else
2041 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2042 "" : " "), fD_GetParam(obj, count));
2043 if (count < numregs - 1)
2044 fprintf(outfile, ", ");
2047 fprintf(outfile, ")\t\n{\t\n");
2049 if (numregs > 0)
2051 for (count = d0; count < numregs; count++)
2053 fprintf(outfile, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2054 fD_GetRegStrU(obj, count), fD_GetParam(obj, count));
2058 if (BaseName[0]) /*
2059 * was "##base" used?
2062 fprintf(outfile, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2064 if (vd)
2066 fprintf(outfile, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj));
2068 else
2070 fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2071 rettype, fD_GetOffset(obj));
2074 else if (target==IX86BE_AMITHLON)
2076 #if 0
2077 for (count = d0; count < numregs; count++)
2079 chtmp = fD_GetProto(obj, count);
2080 if (fD_GetFuncParNum(obj) == count)
2081 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2082 else
2083 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2084 "" : " "), fD_GetParam(obj, count));
2085 if (count < numregs - 1)
2086 fprintf(outfile, ", ");
2089 fprintf(outfile, ")\n{\n");
2090 fprintf(outfile, "\tstruct _Regs _regs;\n");
2092 if (numregs > 0)
2094 for (count = d0; count < numregs; count++)
2096 fprintf(outfile, "\t_regs.reg_%s = (ULONG) (%s);\n",
2097 fD_GetRegStr(obj, count),
2098 fD_GetParam(obj, count));
2102 if (BaseName[0])
2104 fprintf(outfile, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2107 if (vd)
2109 fprintf(outfile, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2110 -fD_GetOffset(obj));
2112 else
2114 fprintf(outfile, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2115 rettype,-fD_GetOffset(obj));
2117 #else
2118 for (count = d0; count < numregs; count++)
2120 chtmp = fD_GetProto(obj, count);
2121 if (fD_GetFuncParNum(obj) == count)
2122 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2123 else
2124 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2125 "" : " "), fD_GetParam(obj, count));
2126 if (count < numregs - 1)
2127 fprintf(outfile, ", ");
2130 fprintf(outfile, ")\n{\n");
2131 fprintf(outfile, "\t%s LP%d%s%s(0x%lx, ",
2132 (vd ? "" : "return "),
2133 numregs,
2134 (vd ? "NR" : ""),
2135 (BaseName[0] ? "" : "UB"),
2136 -fD_GetOffset(obj));
2138 if (!vd)
2139 fprintf(outfile, "%s, ", rettype);
2140 fprintf(outfile, "%s, ", name);
2142 for (count=d0; count<numregs; count++)
2144 chtmp=fD_GetRegStr(obj, count);
2146 if (strchr(fD_GetProto(obj, count),'%'))
2148 sprintf(Buffer,
2149 fD_GetProto(obj, count),
2150 "");
2152 fprintf(outfile, "%s, %s, %s%s",
2153 Buffer,
2154 fD_GetParam(obj, count),
2155 chtmp,
2156 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2158 else
2160 fprintf(outfile, "%s, %s, %s%s",
2161 fD_GetProto(obj, count),
2162 fD_GetParam(obj, count),
2163 chtmp,
2164 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2168 if (BaseName[0])
2169 fprintf(outfile, "\\\n\t, BASE_NAME");
2171 fprintf(outfile, ");\n}\n\n");
2172 #endif
2174 else
2176 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2177 return;
2180 else if (output_mode==GATESTUBS || output_mode==GATEPROTO)
2182 int has_base = (BaseName[0] && fD_GetOffset(obj) != 0);
2184 //lcs
2185 if (target==AROS)
2187 for (count=d0; count<numregs; count++)
2189 if (fD_GetFuncParNum(obj) == count)
2191 char funcproto[200]; /* Hope will be enough... */
2192 sprintf(funcproto, "%s_%s_funcproto_%d",
2193 BaseNamC, name, count );
2194 fprintf(outfile, "typedef ");
2195 fprintf(outfile, fD_GetProto(obj, count), funcproto);
2196 fprintf(outfile, ";\n");
2201 if (output_mode==GATESTUBS)
2203 fprintf(outfile, "%s %s%s(",
2204 rettype,
2205 libprefix,
2206 name);
2208 for (count=d0; count<numregs; count++)
2210 chtmp = fD_GetProto(obj, count);
2212 fprintf(outfile, chtmp, "");
2213 fprintf(outfile, "%s",
2214 (count == numregs - 1 && !has_base ? ");\n" : ", "));
2217 if (has_base)
2218 fprintf(outfile, "struct %s *);\n", StdLib);
2221 if (target==M68K_AMIGAOS)
2223 fprintf(outfile, "%s %s%s(\n",
2224 rettype,
2225 gateprefix,
2226 name);
2228 for (count=d0; count<numregs; count++)
2230 chtmp = fD_GetProto(obj, count);
2232 if (fD_GetFuncParNum(obj) == count)
2234 fprintf(outfile, "\t");
2235 fprintf(outfile, chtmp,
2236 fD_GetParam(obj, count));
2237 fprintf(outfile, " __asm(\"%s\")%s",
2238 fD_GetRegStr(obj, count),
2239 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2241 else
2243 fprintf(outfile, "\t%s %s __asm(\"%s\")%s",
2244 chtmp,
2245 fD_GetParam(obj, count),
2246 fD_GetRegStr(obj, count),
2247 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2251 if (has_base)
2252 fprintf(outfile, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib);
2254 if (output_mode==GATESTUBS)
2255 fprintf(outfile, "{\n");
2257 else if (target==AROS)
2259 fprintf(outfile, "AROS_LH%d%s(%s, %s%s,\n",
2260 numregs,
2261 has_base ? "" : "I",
2262 rettype,
2263 gateprefix,
2264 name);
2266 for (count=d0; count<numregs; count++)
2268 char funcproto[200]; /* Hope will be enough... */
2270 if (fD_GetFuncParNum(obj) == count)
2272 sprintf(funcproto, "%s_%s_funcproto_%d",
2273 BaseNamC, name, count );
2276 fprintf(outfile, "\tAROS_LHA(%s, %s, %s),\n",
2277 fD_GetFuncParNum(obj) == count ? funcproto : fD_GetProto(obj, count),
2278 fD_GetParam(obj, count),
2279 fD_GetRegStrU(obj, count));
2282 fprintf(outfile, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2283 StdLib,
2284 -fD_GetOffset(obj) / 6,
2285 BaseNamC);
2287 if (output_mode==GATESTUBS)
2288 fprintf(outfile, "{\n");
2290 else if (target==PPC_MORPHOS)
2292 fprintf(outfile, "%s %s%s(void)\n",
2293 rettype,
2294 gateprefix,
2295 name);
2297 if (output_mode==GATESTUBS)
2299 fprintf(outfile, "{\n");
2301 for (count=d0; count<numregs; count++)
2303 chtmp = fD_GetProto(obj, count);
2305 if (fD_GetFuncParNum(obj) == count)
2307 fprintf(outfile, "\t");
2308 fprintf(outfile, chtmp,
2309 fD_GetParam(obj, count));
2310 fprintf(outfile, " = (");
2311 fprintf(outfile, chtmp, "");
2312 fprintf(outfile, ") REG_%s;\n",
2313 fD_GetRegStrU(obj, count));
2315 else
2317 fprintf(outfile, "\t%s %s = (%s) REG_%s;\n",
2318 fD_GetProto(obj, count),
2319 fD_GetParam(obj, count),
2320 fD_GetProto(obj, count),
2321 fD_GetRegStrU(obj, count));
2325 if (has_base)
2326 fprintf(outfile,
2327 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2328 StdLib, StdLib);
2330 fprintf(outfile, "\n");
2333 else if (target==IX86BE_AMITHLON)
2335 fprintf(outfile, "%s %s%s( struct _Regs _regs )\n",
2336 rettype,
2337 gateprefix,
2338 name);
2340 if (output_mode==GATESTUBS)
2342 fprintf(outfile, "{\n");
2344 for (count=d0; count<numregs; count++)
2346 chtmp = fD_GetProto(obj, count);
2348 if (fD_GetFuncParNum(obj) == count)
2350 fprintf(outfile, "\t");
2351 fprintf(outfile, chtmp,
2352 fD_GetParam(obj, count));
2353 fprintf(outfile, " = (");
2354 fprintf(outfile, chtmp, "");
2355 fprintf(outfile, ") _regs.%s;\n",
2356 fD_GetRegStr(obj, count));
2358 else
2360 fprintf(outfile, "\t%s %s = (%s) _regs.%s;\n",
2361 fD_GetProto(obj, count),
2362 fD_GetParam(obj, count),
2363 fD_GetProto(obj, count),
2364 fD_GetRegStr(obj, count));
2368 if (has_base)
2369 fprintf(outfile,
2370 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2371 StdLib, StdLib);
2373 fprintf(outfile, "\n");
2376 else
2378 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2379 return;
2382 if (output_mode==GATESTUBS)
2384 fprintf(outfile,"\treturn %s%s(",
2385 libprefix,
2386 name);
2388 for (count=d0; count<numregs; count++)
2390 fprintf(outfile, "%s%s",
2391 fD_GetParam(obj, count),
2392 (count == numregs - 1 && !has_base ? ");" : ", "));
2395 if (has_base)
2396 fprintf(outfile, "BASE_NAME);");
2398 fprintf(outfile,"\n}\n\n");
2400 else
2402 fprintf(outfile,";\n");
2404 if (target==AROS)
2406 fprintf(outfile, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s,%ld)\n",
2407 gateprefix, name,
2408 gateprefix, name,
2409 BaseNamC,fD_GetOffset(obj));
2412 fprintf(outfile,"\n");
2415 else
2417 fprintf(stderr, "Internal error: Unknown output mode in fD_write().\n");
2418 return;
2421 if ((tagname=aliasfunction(fD_GetName(obj)))!=0 &&
2422 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2424 fprintf(outfile, "#define %s(", tagname);
2425 for (count=d0; count<numregs-1; count++)
2426 fprintf(outfile, "a%d, ", count);
2427 fprintf(outfile, "a%d) %s (", count, name);
2428 for (count=d0; count<numregs-1; count++)
2429 fprintf(outfile, "(a%d), ", count);
2430 fprintf(outfile, "(a%d))\n\n", count);
2433 if ((tagname=taggedfunction(obj))!=0 &&
2434 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2436 if (output_mode!=STUBS)
2438 fprintf( outfile,
2439 "#ifndef %sNO_INLINE_STDARG\n"
2440 "#define %s(",
2441 (target==M68K_POS ? "__" : ""),
2442 tagname);
2444 for (count=d0; count<numregs-1; count++)
2445 fprintf(outfile, "a%d, ", count);
2447 fprintf(outfile, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2448 name);
2450 for (count=d0; count<numregs-1; count++)
2451 fprintf(outfile, "(a%d), ", count);
2453 fprintf(outfile, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2454 fD_GetProto(obj, fD_RegNum(obj)-1),
2455 (target==M68K_POS ? "__" : ""));
2458 else
2460 if (target==M68K_AMIGAOS || target==IX86BE_AMITHLON)
2462 fprintf(outfile, "__inline %s\n%s(", rettype, tagname);
2464 for (count=d0; count<numregs-1; count++)
2466 chtmp=fD_GetProto(obj, count);
2467 if (count==fD_GetFuncParNum(obj))
2468 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2469 else
2470 fprintf(outfile, "%s%s%s", chtmp,
2471 (*(chtmp+strlen(chtmp)-1)=='*' ? "" : " "),
2472 fD_GetParam(obj, count));
2473 fprintf(outfile, ", ");
2476 fprintf(outfile, "int tag, ...)\n{\n ");
2477 if (!vd)
2478 fprintf(outfile, "return ");
2480 fprintf(outfile, "%s(", name);
2481 for (count=d0; count<numregs-1; count++)
2482 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
2484 fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj)-1));
2486 else if (target==PPC_MORPHOS)
2488 int n = 9 - numregs; /* number of regs that contain varargs */
2489 int d = n & 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2490 int taglist = 8; /* offset of the start of the taglist */
2491 int local = (taglist + n * 4 + d + 8 + 15) & ~15; /* size of the stack frame */
2494 * Stack frame:
2496 * 0 - 3: next frame ptr
2497 * 4 - 7: save lr
2498 * 8 - 8+n*4+d+8-1: tag list start
2499 * ? - local-1: padding
2502 fprintf(outfile,
2503 "asm(\"\n"
2504 " .align 2 \n"
2505 " .globl %s \n"
2506 " .type %s,@function\n"
2507 "%s: \n"
2508 " stwu 1,-%d(1) \n" /* create stack frame */
2509 " mflr 0 \n"
2510 " stw 0,%d(1) \n",
2511 tagname, tagname, tagname, local, local + 4);
2514 * If n is odd, one tag is split between regs and stack.
2515 * Copy its ti_Data together with the ti_Tag.
2517 if (d)
2518 fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
2520 * Save the registers
2522 for (count = numregs; count <= 8; count++)
2523 fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
2525 if (d)
2526 fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
2529 * Add TAG_MORE
2531 fprintf(outfile, " li 11,2 \n"
2532 " addi 0,1,%d \n"
2533 " stw 11,%d(1) \n" /* add TAG_MORE */
2534 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2535 local + 8 + d,
2536 taglist + n * 4 + d,
2537 taglist + n * 4 + d + 4);
2540 if (DirectVarargsCalls)
2542 fprintf(outfile,
2543 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2544 " bl %s \n",
2545 numregs + 2, taglist, name);
2547 else
2550 * Save the non-varargs registers in the EmulHandle struct.
2552 for (count = 0; count < numregs - 1; count++)
2554 int r = fD_GetReg(obj, count);
2556 fprintf(outfile, " stw %d,%d(2)\n", count + 3, r * 4);
2559 fprintf(outfile,
2560 " lis 12,%s@ha \n"
2561 " addi 0,1,%d \n"
2562 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2563 " stw 0,%d(2) \n" /* REG_?? = taglist */
2564 " mtctr 11 \n"
2565 " lwz 12,%s@l(12)\n"
2566 " li 3,%ld \n" /* r3 = lvo */
2567 " stw 12,56(2) \n" /* REG_A6 = libbase */
2568 " bctrl \n",/* EmulCallOS() */
2569 BaseName, taglist, 4 * fD_GetReg(obj, numregs - 1), BaseName,
2570 fD_GetOffset(obj));
2573 fprintf(outfile," lwz 0,%d(1) \n" /* clear stack frame & return */
2574 " mtlr 0 \n"
2575 " addi 1,1,%d \n"
2576 " blr \n"
2577 ".L%se1: \n"
2578 " .size\t%s,.L%se1-%s\n"
2579 "\");\n\n",
2580 local + 4, local,
2581 tagname, tagname, tagname, tagname);
2583 else
2585 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2586 return;
2590 else if ((varname = getvarargsfunction(obj)) != 0 &&
2591 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2593 if (output_mode != STUBS)
2595 fprintf(outfile,
2596 "#ifndef NO_INLINE_VARARGS\n"
2597 "#define %s(", varname);
2599 for (count = d0; count < numregs - 1; count++)
2600 fprintf(outfile, "a%d, ", count);
2602 fprintf(outfile,
2603 "...) \\\n"
2604 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2605 name);
2607 for (count = d0; count < numregs - 1; count++)
2608 fprintf(outfile, "(a%d), ", count);
2610 fprintf(outfile,
2611 "(%s)_tags);})\n"
2612 "#endif /* !NO_INLINE_VARARGS */\n\n",
2613 fD_GetProto(obj, fD_RegNum(obj) - 1));
2615 else
2617 fprintf(stderr, "can`t create a varargs stub function for %s\n",
2618 varname);
2622 if (strcmp(name, "DoPkt")==0 &&
2623 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2625 fdDef *objnc=(fdDef*)obj;
2626 char newname[7]="DoPkt0";
2627 objnc->name=newname;
2628 for (count=2; count<7; count++)
2630 regs reg=objnc->reg[count];
2631 char *proto=objnc->proto[count];
2632 objnc->reg[count]=illegal;
2633 objnc->proto[count]=fD_nostring;
2634 fD_write(outfile, objnc);
2635 objnc->reg[count]=reg;
2636 objnc->proto[count]=proto;
2637 newname[5]++;
2639 objnc->name=(char*)name;
2644 varargsfunction(const char* proto, const char* funcname)
2646 const char *end=proto+strlen(proto)-1;
2647 while (isspace(*end))
2648 end--;
2649 if (*end--==';')
2651 while (isspace(*end))
2652 end--;
2653 if (*end--==')')
2655 while (isspace(*end))
2656 end--;
2657 if (!strncmp(end-2, "...", 3))
2659 /* Seems to be a varargs function. Check if it will be recognized
2660 as "tagged". */
2661 unsigned int count;
2662 char fixedname[200]; /* Hope will be enough... */
2663 fdDef *tmpdef;
2665 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0];
2666 count+=2)
2667 if (strcmp(funcname, TagExcTable[count+1])==0)
2668 return 1;
2670 if (!(tmpdef=fD_ctor()))
2672 fprintf(stderr, "No mem for FDs\n");
2673 exit(EXIT_FAILURE);
2676 strcpy(fixedname, funcname);
2677 if (strlen(funcname)>4 &&
2678 !strcmp(funcname+strlen(funcname)-4, "Tags"))
2680 /* Might be either nothing or "TagList". */
2681 fixedname[strlen(fixedname)-4]='\0';
2682 fD_NewName(tmpdef, fixedname);
2683 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2684 fD_cmpName))
2685 return 1;
2687 strcat(fixedname, "TagList");
2688 fD_NewName(tmpdef, fixedname);
2689 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2690 fD_cmpName))
2691 return 1;
2693 else
2695 strcat(fixedname, "A");
2696 fD_NewName(tmpdef, fixedname);
2697 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2698 fD_cmpName))
2699 return 1;
2704 return 0;
2708 ishandleddifferently(const char* proto, const char* funcname)
2710 /* First check if this is a vararg call? */
2711 if (varargsfunction(proto, funcname))
2712 return 1;
2714 /* It might be a dos.library "alias" name. */
2715 if (aliasfunction(funcname))
2716 return 1;
2718 /* It might be one from dos.library/DoPkt() family. */
2719 if (strlen(funcname)==6 && !strncmp(funcname, "DoPkt", 5) &&
2720 funcname[5]>='0' && funcname[6]<='4')
2721 return 1;
2723 /* Finally, it can be intuition.library/ReportMouse1(). */
2724 return !strcmp(funcname, "ReportMouse1");
2727 void
2728 printusage(const char* exename)
2730 fprintf(stderr,
2731 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2732 "Options:\n"
2734 "--mode=MODE\t\tMODE is one of the following:\n"
2735 "\tnew\t\t\tPreprocessor based (default)\n"
2736 "\told\t\t\tInline based\n"
2737 "\tstubs\t\t\tLibrary stubs\n"
2738 "\tgatestubs\t\tLibrary gate stubs\n"
2739 "\tgateproto\t\tLibrary gate prototypes\n"
2740 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2742 "--target=OS\t\tOS is one of the following: \n"
2743 "\t*-aros\t\t\tAROS (any CPU)\n"
2744 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2745 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2746 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2747 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2748 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2750 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2751 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2752 "--libprefix=PREFIX\tLocal function name prefix\n"
2753 "--local\t\t\tUse local includes\n"
2754 "--quiet\t\t\tDon't display warnings\n"
2755 "--version\t\tPrint version number and exit\n\n"
2756 "Compatibility options:\n"
2757 "--new\t\t\tSame as --mode=new\n"
2758 "--old\t\t\tSame as --mode=old\n"
2759 "--stubs\t\t\tSame as --mode=stubs\n"
2760 "--gatestubs\t\tSame as --mode=gatestubs\n"
2761 "--proto\t\t\tSame as --mode=prot\n"
2762 "--pos\t\t\tSame as --target=m68k-pos\n"
2763 "--morphos\t\tSame as --target=powerpc-morphos\n"
2764 "--powerup\t\tSame as --target=powerpc-powerup\n"
2765 , exename);
2768 void output_proto(FILE* outfile)
2770 fprintf(outfile,
2771 "/* Automatically generated header! Do not edit! */\n\n"
2772 "#ifndef PROTO_%s_H\n"
2773 "#define PROTO_%s_H\n\n",
2774 BaseNamU, BaseNamU);
2776 if (BaseName[0])
2777 fprintf(outfile,
2778 "#ifndef __NOLIBBASE__\n"
2779 "extern struct %s *\n"
2780 "#ifdef __CONSTLIBBASEDECL__\n"
2781 "__CONSTLIBBASEDECL__\n"
2782 "#endif /* __CONSTLIBBASEDECL__ */\n"
2783 "%s;\n"
2784 "#endif /* !__NOLIBBASE__ */\n\n",
2785 StdLib, BaseName);
2787 fprintf(outfile,
2788 "#ifdef __amigaos4__\n"
2789 "#include <interfaces/%s.h>\n"
2790 "#ifdef __USE_INLINE__\n"
2791 "#include <inline4/%s.h>\n"
2792 "#endif /* __USE_INLINE__ */\n"
2793 "#ifndef CLIB_%s_PROTOS_H\n"
2794 "#define CLIB_%s_PROTOS_H\n"
2795 "#endif /* CLIB_%s_PROTOS_H */\n"
2796 "#ifndef __NOGLOBALIFACE__\n"
2797 "extern struct %sIFace *I%s;\n"
2798 "#endif /* __NOGLOBALIFACE__ */\n"
2799 "#else /* __amigaos4__ */\n"
2800 "#include <clib/%s_protos.h>\n"
2801 "#ifdef __GNUC__\n"
2802 "#ifdef __AROS__\n"
2803 "#ifndef NOLIBDEFINES\n"
2804 "#ifndef %s_NOLIBDEFINES\n"
2805 "#include <defines/%s.h>\n"
2806 "#endif /* %s_NOLIBDEFINES */\n"
2807 "#endif /* NOLIBDEFINES */\n"
2808 "#else\n"
2809 "#ifdef __PPC__\n"
2810 "#ifndef _NO_PPCINLINE\n"
2811 "#include <ppcinline/%s.h>\n"
2812 "#endif /* _NO_PPCINLINE */\n"
2813 "#else\n"
2814 "#ifndef _NO_INLINE\n"
2815 "#include <inline/%s.h>\n"
2816 "#endif /* _NO_INLINE */\n"
2817 "#endif /* __PPC__ */\n"
2818 "#endif /* __AROS__ */\n"
2819 "#else\n"
2820 "#include <pragmas/%s_pragmas.h>\n"
2821 "#endif /* __GNUC__ */\n"
2822 "#endif /* __amigaos4__ */\n\n"
2823 "#endif /* !PROTO_%s_H */\n",
2824 BaseNamL, BaseNamL, BaseNamU, BaseNamU, BaseNamU, BaseNamC, BaseNamC,
2825 BaseNamL,
2826 BaseNamU, BaseNamL, BaseNamU,
2827 BaseNamL, BaseNamL, BaseNamL,
2828 BaseNamU);
2831 /******************************************************************************/
2834 main(int argc, char** argv)
2836 fdDef *tmpdef, /* a dummy to contain the name to look for */
2837 *founddef; /* the fdDef for which we found a prototype */
2838 fdFile *myfile;
2839 char *tmpstr;
2840 FILE *outfile;
2841 int closeoutfile=0;
2842 char *fdfilename=0, *clibfilename=0, *outfilename=0;
2844 int count;
2845 Error lerror;
2847 for (count=1; count<argc; count++)
2849 char *option=argv[count];
2850 if (*option=='-')
2852 option++;
2853 if (strcmp(option, "o")==0)
2855 if (count==argc-1 || outfilename)
2857 printusage(argv[0]);
2858 return EXIT_FAILURE;
2860 if (strcmp(argv[++count], "-"))
2861 outfilename=argv[count];
2863 else
2865 if (*option=='-') /* Accept GNU-style '--' options */
2866 option++;
2867 if (strncmp(option, "mode=", 5)==0)
2869 if (strcmp(option+5, "new")==0)
2870 output_mode=NEW;
2871 else if (strcmp(option+5, "old")==0)
2872 output_mode=OLD;
2873 else if (strcmp(option+5, "stubs")==0)
2874 output_mode=STUBS;
2875 else if (strcmp(option+5, "gatestubs")==0)
2876 output_mode=GATESTUBS;
2877 else if (strcmp(option+5, "gateproto")==0)
2878 output_mode=GATEPROTO;
2879 else if (strcmp(option+5, "proto")==0)
2880 output_mode=PROTO;
2882 else if (strncmp(option, "target=", 7)==0)
2884 if (MatchGlob("*-aros",option+7))
2885 target=AROS;
2886 else if (MatchGlob("i?86be*-amithlon",option+7))
2887 target=IX86BE_AMITHLON;
2888 else if (MatchGlob("m68k*-amigaos",option+7))
2889 target=M68K_AMIGAOS;
2890 else if (MatchGlob("m68k*-pos",option+7))
2891 target=M68K_POS;
2892 else if (MatchGlob("powerpc*-powerup",option+7))
2893 target=PPC_POWERUP;
2894 else if (MatchGlob("powerpc*-morphos",option+7))
2895 target=PPC_MORPHOS;
2896 else
2898 printusage(argv[0]);
2899 return EXIT_FAILURE;
2902 else if (strcmp(option, "direct-varargs-calls") == 0)
2903 DirectVarargsCalls = 1;
2904 else if (strncmp(option, "gateprefix=", 11)==0)
2905 gateprefix = option+11;
2906 else if (strncmp(option, "libprefix=", 10)==0)
2907 libprefix = option+10;
2908 else if (strcmp(option, "quiet") == 0)
2909 Quiet = 1;
2910 else if (strcmp(option, "version")==0)
2912 fprintf(stderr, "fd2inline version " VERSION "\n");
2913 return EXIT_SUCCESS;
2915 /* Compatibility options */
2916 else if (strcmp(option, "new")==0)
2917 output_mode=NEW;
2918 else if (strcmp(option, "old")==0)
2919 output_mode=OLD;
2920 else if (strcmp(option, "stubs")==0)
2921 output_mode=STUBS;
2922 else if (strcmp(option, "gatestubs")==0)
2923 output_mode=GATESTUBS;
2924 else if (strcmp(option, "proto")==0)
2925 output_mode=PROTO;
2926 else if (strcmp(option, "pos")==0)
2927 target=M68K_POS;
2928 else if (strcmp(option, "powerup")==0)
2929 target=PPC_POWERUP;
2930 else if (strcmp(option, "morphos")==0)
2931 target=PPC_MORPHOS;
2932 /* Unknown option */
2933 else
2935 printusage(argv[0]);
2936 return EXIT_FAILURE;
2940 else
2942 /* One of the filenames */
2943 if (!fdfilename)
2944 fdfilename=option;
2945 else if (!clibfilename)
2946 clibfilename=option;
2947 else if (!outfilename)
2948 outfilename=option;
2949 else
2951 printusage(argv[0]);
2952 return EXIT_FAILURE;
2957 if (!fdfilename || (!clibfilename && output_mode!=PROTO))
2959 printusage(argv[0]);
2960 return EXIT_FAILURE;
2963 if (target==M68K_POS && output_mode!=NEW)
2965 fprintf(stderr, "Target is not compatible with the mode.\n");
2966 return EXIT_FAILURE;
2969 if (!(arrdefs=malloc(FDS*sizeof(fdDef*))))
2971 fprintf(stderr, "No mem for FDs\n");
2972 return EXIT_FAILURE;
2974 for (count=0; count<FDS; count++)
2975 arrdefs[count]=NULL;
2977 if (!(myfile=fF_ctor(fdfilename)))
2979 fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
2980 return EXIT_FAILURE;
2983 lerror=false;
2985 for (count=0; count<FDS && lerror==false; count++)
2987 if (!(arrdefs[count]=fD_ctor()))
2989 fprintf(stderr, "No mem for FDs\n" );
2990 return EXIT_FAILURE;
2994 if ((lerror=fF_readln(myfile))==false)
2996 fF_SetError(myfile, false);
2997 lerror=fD_parsefd(arrdefs[count], myfile);
3000 while (lerror==nodef);
3002 if (count<FDS)
3004 count--;
3005 fD_dtor(arrdefs[count]);
3006 arrdefs[count]=NULL;
3008 fds=count;
3010 qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
3012 if (output_mode!=NEW || target==AROS)
3014 unsigned int count2;
3015 StdLib="Library";
3017 for (count2=0; count2<sizeof LibExcTable/sizeof LibExcTable[0]; count2+=2)
3018 if (strcmp(BaseName, LibExcTable[count2])==0)
3020 StdLib=LibExcTable[count2+1];
3021 break;
3025 fF_dtor(myfile);
3027 if (output_mode!=PROTO)
3029 if (!(myfile=fF_ctor(clibfilename)))
3031 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3032 return EXIT_FAILURE;
3035 if (!(tmpdef=fD_ctor()))
3037 fprintf(stderr, "No mem for FDs\n");
3038 return EXIT_FAILURE;
3041 for (lerror=false; lerror==false || lerror==nodef;)
3042 if ((lerror=fF_readln(myfile))==false)
3044 fF_SetError(myfile, false); /* continue even on errors */
3045 tmpstr=fF_FuncName(myfile);
3047 if (tmpstr)
3049 fdDef **res;
3050 fD_NewName(tmpdef, tmpstr);
3051 res=(fdDef**)bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
3052 fD_cmpName);
3054 if (res)
3056 founddef=*res;
3057 DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
3058 fF_SetError(myfile, false);
3059 lerror=fD_parsepr(founddef, myfile);
3061 else
3062 if (!ishandleddifferently(myfile->line, tmpstr))
3063 if (!Quiet)
3064 fprintf(stderr, "Don't know what to do with <%s> in line %lu.\n",
3065 tmpstr, myfile->lineno);
3066 free(tmpstr);
3070 fD_dtor(tmpdef);
3072 fF_dtor(myfile);
3075 if (strlen(fdfilename)>7 &&
3076 !strcmp(fdfilename+strlen(fdfilename)-7, "_lib.fd"))
3078 char *str=fdfilename+strlen(fdfilename)-8;
3079 while (str!=fdfilename && str[-1]!='/' && str[-1]!=':')
3080 str--;
3081 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3082 strncpy(BaseNamU, str, strlen(str)-7);
3083 BaseNamU[strlen(str)-7]='\0';
3084 strcpy(BaseNamL, BaseNamU);
3085 strcpy(BaseNamC, BaseNamU);
3087 else
3089 strcpy(BaseNamU, BaseName);
3090 if (strlen(BaseNamU)>4 && strcmp(BaseNamU+strlen(BaseNamU)-4, "Base")==0)
3091 BaseNamU[strlen(BaseNamU)-4]='\0';
3092 if (target==M68K_POS && strncmp(BaseNamU, "gb_", 3)==0)
3093 memmove(BaseNamU, &BaseNamU[3], strlen(&BaseNamU[3])+1);
3094 strcpy(BaseNamL, BaseNamU);
3095 strcpy(BaseNamC, BaseNamU);
3097 StrUpr(BaseNamU);
3098 BaseNamC[0]=toupper(BaseNamC[0]);
3100 if (outfilename)
3102 if (!(outfile=fopen(outfilename, "w")))
3104 fprintf(stderr, "Couldn't open output file.\n");
3105 return EXIT_FAILURE;
3107 else
3109 closeoutfile=1;
3112 else
3113 outfile=stdout;
3115 if (output_mode==PROTO)
3116 output_proto(outfile);
3117 else
3119 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS ||
3120 output_mode==GATESTUBS || output_mode==GATEPROTO)
3122 if (output_mode==GATESTUBS || output_mode==GATEPROTO)
3124 fprintf(outfile,
3125 "/* Automatically generated stubs! Do not edit! */\n\n");
3127 else
3129 fprintf(outfile,
3130 "/* Automatically generated header! Do not edit! */\n\n"
3131 "#ifndef %sINLINE_%s_H\n"
3132 "#define %sINLINE_%s_H\n\n",
3133 (target==M68K_POS ? "__INC_POS_P" : "_"),
3134 BaseNamU,
3135 (target==M68K_POS ? "__INC_POS_P" : "_"),
3136 BaseNamU );
3139 if (output_mode==NEW)
3141 if(target==M68K_POS)
3143 fprintf(outfile,
3144 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3145 "#include <pInline/macros.h>\n"
3146 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3148 else if(target==AROS)
3150 fprintf(outfile,
3151 "#ifndef AROS_LIBCALL_H\n"
3152 "#include <aros/libcall.h>\n"
3153 "#endif /* !AROS_LIBCALL_H */\n\n");
3155 else
3157 fprintf(outfile,
3158 "#ifndef __INLINE_MACROS_H\n"
3159 "#include <inline/macros.h>\n"
3160 "#endif /* !__INLINE_MACROS_H */\n\n");
3163 else
3165 FILE* clib;
3167 fprintf(outfile,
3168 "#ifndef __INLINE_STUB_H\n"
3169 "#include <inline/stubs.h>\n"
3170 "#endif /* !__INLINE_STUB_H */\n\n");
3172 fprintf(outfile, "#ifdef __CLIB_TYPES__\n" );
3174 clib = fopen( clibfilename, "r" );
3176 if( clib == NULL )
3178 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3180 else
3182 char* buffer = malloc( 1024 );
3184 if( buffer == NULL )
3186 fprintf(stderr, "No memory for line buffer.\n " );
3188 else
3190 while( fgets( buffer, 1023, clib ) != NULL )
3192 if( buffer[ 0 ] == '#' /* Pre-processor instruction */ ||
3193 strncmp( buffer, "typedef", 7 ) == 0 )
3195 fputs(buffer, outfile );
3199 free( buffer );
3202 fclose( clib );
3205 fprintf(outfile, "#endif /* __CLIB_TYPES__ */\n\n" );
3207 if(target==AROS)
3209 fprintf(outfile,
3210 "#include <aros/libcall.h>\n\n" );
3212 else if(target==IX86BE_AMITHLON)
3214 fprintf(outfile,
3215 "#ifndef __INLINE_MACROS_H\n"
3216 "#include <inline/macros.h>\n"
3217 "#endif /* __INLINE_MACROS_H */\n\n");
3219 else if (target == PPC_MORPHOS)
3221 fprintf(outfile,
3222 "#include <emul/emulregs.h>\n\n" );
3226 else
3228 fprintf(stderr, "Internal error: Unknown output mode in main().\n");
3230 if (closeoutfile)
3232 fclose(outfile);
3235 return EXIT_FAILURE;
3238 if (BaseName[0])
3240 if (output_mode==NEW)
3242 fprintf(outfile,
3243 "#ifndef %s%s_BASE_NAME\n"
3244 "#define %s%s_BASE_NAME %s\n"
3245 "#endif /* !%s%s_BASE_NAME */\n\n",
3246 (target==M68K_POS ? "__" : ""), BaseNamU,
3247 (target==M68K_POS ? "__" : ""), BaseNamU, BaseName,
3248 (target==M68K_POS ? "__" : ""), BaseNamU);
3249 if (target==M68K_POS)
3250 fprintf(outfile,
3251 "#ifndef __%s_LIB_NAME\n"
3252 "#define __%s_LIB_NAME %s\n"
3253 "#endif /* !__%s_LIB_NAME */\n\n",
3254 BaseNamU, BaseNamU,
3255 (strcmp(BaseName, "gb_ExecBase") ? BaseName : "gb_ExecLib"),
3256 BaseNamU);
3258 else
3259 fprintf(outfile,
3260 "#ifndef BASE_EXT_DECL\n"
3261 "#define BASE_EXT_DECL\n"
3262 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3263 "#endif /* !BASE_EXT_DECL */\n"
3264 "#ifndef BASE_PAR_DECL\n"
3265 "#define BASE_PAR_DECL\n"
3266 "#define BASE_PAR_DECL0 void\n"
3267 "#endif /* !BASE_PAR_DECL */\n"
3268 "#ifndef BASE_NAME\n"
3269 "#define BASE_NAME %s\n"
3270 "#endif /* !BASE_NAME */\n\n"
3271 "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
3274 for (count=0; count<FDS && arrdefs[count]; count++)
3276 DBP(fprintf(stderr, "outputting %ld...\n", count));
3278 fD_write(outfile, arrdefs[count]);
3279 fD_dtor(arrdefs[count]);
3280 arrdefs[count]=NULL;
3283 if (output_mode!=NEW)
3284 if (BaseName[0])
3285 fprintf(outfile,
3286 "#undef BASE_EXT_DECL\n"
3287 "#undef BASE_EXT_DECL0\n"
3288 "#undef BASE_PAR_DECL\n"
3289 "#undef BASE_PAR_DECL0\n"
3290 "#undef BASE_NAME\n\n");
3292 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS)
3294 fprintf(outfile, "#endif /* !%sINLINE_%s_H */\n",
3295 (target==M68K_POS ? "__INC_POS_P" : "_"), BaseNamU);
3299 free(arrdefs);
3301 if (closeoutfile)
3303 fclose(outfile);
3306 return EXIT_SUCCESS;