home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * fd2inline
- *
- * Should be able to parse CBM fd files and generate vanilla inline calls
- * for gcc. Works as a filter.
- *
- * by Wolfgang Baron, all rights reserved.
- *
- * improved, updated, simply made workable by Rainer F. Trunz 1/95
- *
- * Completely reworked Version, cleaned up and removed a whole lot of bugs
- * found by Kamil Iskra.
- *
- * Expect miracles now (hopefully...). Ok, I am just kidding :)
- *
- * Version 0.99a by Rainer F. Trunz 6/95
- *
- * Version 0.99b and later by Kamil Iskra.
- *
- * Version 1.12 by Ralph Schmidt
- * PowerUP GCC/SAS extensions
- * I hope Kamil Iskra integrates that
- * in the official ADE version.
- *
- * Version 2.00 by Ralph Schmidt and Emmanuel Leseur
- * Adding MorphOS support and a variety of new options
- ******************************************************************************/
-
- /*
- * My whole ixemul includes are messed up * so this is hacky fix
- */
-
- #include <ctype.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /******************************************************************************
- * The program has a few sort of class definitions, which are the result of
- * object oriented thinking, to be imlemented in plain C. I just haven't
- * had the time to learn C++ or install the compiler. The design does however
- * improve robustness, which allows the source to be used over and over again.
- * if you use this code, please leave a little origin note.
- ******************************************************************************/
-
- const static char version_str[] = "$VER: fd2inline " VERSION " (12.12.97)";
-
- /******************************************************************************
- * These are general definitions including types for defining registers etc.
- ******************************************************************************/
-
- #ifdef DEBUG
- #define DBP(a) a
- #else /*
- * !DEBUG
- */
- #define DBP(a)
- #endif /*
- * !DEBUG
- */
-
- #if (defined(__GNUC__) || defined(__SASC)) && 0
- #define INLINE __inline /*
- * Gives 20% *larger* executable with GCC?!
- */
- #else
- #define INLINE
- #endif
-
- #define REGS 16 /*
- * d0=0,...,a7=15
- */
- #define FDS 1000
-
- typedef enum
- {
- d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
- }
- regs;
-
- typedef unsigned char uchar, shortcard;
- typedef unsigned long ulong;
-
- #ifndef FALSE
- #define FALSE 0
- #endif
- #ifndef TRUE
- #define TRUE 1
- #endif
-
- typedef enum
- {
- false, nodef, real_error
- }
- Error;
-
- enum
- {
- NEW, OLD, STUBS, PROTO, PRAGMA, GATESTUBS
- }
- output_mode = NEW;
-
- int DirectVarargsCalls = 0;
- int PowerUP = 0, MorphOS = 0;
- int RegLibFlag = 0;
- int PreLibFlag = 0;
- int PostLibFlag = 0;
- int LocalFlag = 0;
- char *prefixname = "";
- char *subprefixname = "";
- char *premacro = "";
-
- char BaseName[32 + 32], BaseNamU[32 + 32], BaseNamL[32 + 32];
- char Buffer[512];
-
- const static char *LibExcTable[] =
- {
- "BattClockBase", "Node",
- "BattMemBase", "Node",
- "ConsoleDevice", "Device",
- "DiskBase", "DiskResource",
- "DOSBase", "DosLibrary",
- "SysBase", "ExecBase",
- "ExpansionBase", "ExpansionBase",
- "GfxBase", "GfxBase",
- "InputBase", "Device",
- "IntuitionBase", "IntuitionBase",
- "LocaleBase", "LocaleBase",
- "MathIeeeDoubBasBase", "MathIEEEBase",
- "MathIeeeDoubTransBase", "MathIEEEBase",
- "MathIeeeSingBasBase", "MathIEEEBase",
- "MathIeeeSingTransBase", "MathIEEEBase",
- "MiscBase", "Node",
- "PotgoBase", "Node",
- "RamdriveDevice", "Device",
- "RealTimeBase", "RealTimeBase",
- "RexxSysBase", "RxsLib",
- "TimerBase", "Device",
- "UtilityBase", "UtilityBase"
- };
- const char *StdLib; /*
-
- * global lib-name ptr
- */
-
- /*******************************************
- * just some support functions, no checking
- *******************************************/
-
- char *
- NewString(char **new, const char *old)
- {
- const char *high;
- ulong len;
-
- while (*old && (*old == ' ' || *old == '\t'))
- old++;
- len = strlen(old);
- for (high = old + len - 1; high >= old && (*high == ' ' || *high == '\t'); high--) ;
- high++;
- len = high - old;
- *new = malloc(1 + len);
- if (*new)
- {
- strncpy(*new, old, len);
- (*new)[len] = '\0';
- }
- else
- fprintf(stderr, "no mem for string\n");
- return *new;
- }
-
- static INLINE void
- illparams(const char *funcname)
- {
- fprintf(stderr, "%s: illegal Parameters\n", funcname);
- }
-
- static INLINE const char *
- RegStr(regs reg)
- {
- const static char *myregs[] =
- {
- "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
- "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
- };
-
- if (reg > illegal)
- reg = illegal;
- if (reg < d0)
- reg = d0;
- return myregs[reg];
- }
-
- static INLINE const char *
- RegStrU(regs reg)
- {
- const static char *myregs[] =
- {
- "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
- "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
- };
-
- if (reg > illegal)
- reg = illegal;
- if (reg < d0)
- reg = d0;
- return myregs[reg];
- }
-
- /******************************************************************************
- * StrNRBrk
- *
- * searches string in from position at downwards, as long as in does not
- * contain any character in not.
- *
- ******************************************************************************/
-
- const char *
- StrNRBrk(const char *in, const char *not, const char *at)
- {
- const char *chcheck;
- Error ready;
-
- chcheck = ""; /*
- * if at<in, the result will be NULL
- */
- for (ready = false; ready == false && at >= in;)
- {
- for (chcheck = not; *chcheck && *chcheck != *at; chcheck++) ;
- if (*chcheck)
- ready = real_error;
- else
- at--;
- }
- DBP(fprintf(stderr, "{%c}", *chcheck));
- return *chcheck ? at : NULL;
- }
-
- /*
- * Our own "strupr", since it is a non-standard function.
- */
- void
- StrUpr(char *str)
- {
- while (*str)
- {
- *str = toupper(*str);
- str++;
- }
- }
-
- /******************************************************************************
- * CLASS fdFile
- *
- * stores a file with a temporary buffer (static length, sorry), a line number,
- * an offset (used for library offsets and an error field.
- * When there's no error, line will contain line #lineno and offset will be
- * the last offset set by the interpretation of the last line. If there's been
- * no ##bias line, this field assumes a bias of 30, which is the standard bias.
- * It is assumed offsets are always negative.
- ******************************************************************************/
-
- #define fF_BUFSIZE 1024
-
- /*
- * all you need to know about an fdFile you parse
- */
-
- typedef struct
- {
- FILE *file; /*
- * the file we're reading from
- */
- char line[fF_BUFSIZE]; /*
- * the current line
- */
- ulong lineno; /*
- * current line number
- */
- long offset; /*
- * current fd offset (-bias)
- */
- Error error; /*
- * is everything o.k.
- */
- char private; /*
- * are we in ##public or ##private
- */
- }
- fdFile;
-
- fdFile *
- fF_ctor(const char *fname);
- static void
- fF_dtor(fdFile * obj);
- static void
- fF_SetError(fdFile * obj, Error error);
- static void
- fF_SetOffset(fdFile * obj, long at);
-
- Error
- fF_readln(fdFile * obj);
- static Error
- fF_GetError(const fdFile * obj);
- static long
- fF_GetOffset(const fdFile * obj);
- char *
- fF_FuncName(fdFile * obj); /*
-
- * return name or null
- */
- static void
- fF_SetPrivate(fdFile * obj, char priv);
- static char
- fF_GetPrivate(const fdFile * obj);
-
- static INLINE void
- fF_dtor(fdFile * obj)
- {
- fclose(obj->file);
- free(obj);
- }
-
- static INLINE void
- fF_SetError(fdFile * obj, Error error)
- {
- if (obj)
- obj->error = error;
- else
- illparams("fF_SetError");
- }
-
- static INLINE void
- fF_SetOffset(fdFile * obj, long at)
- {
- if (obj)
- obj->offset = at;
- else
- illparams("fFSetOffset");
- }
-
- static INLINE void
- fF_SetPrivate(fdFile * obj, char priv)
- {
- if (obj)
- obj->private = priv;
- else
- illparams("fF_SetPrivate");
- }
-
- fdFile *
- fF_ctor(const char *fname)
- {
- fdFile *result;
-
- if (fname)
- {
- result = malloc(sizeof(fdFile));
- if (result)
- {
- result->file = fopen(fname, "r");
- if (result->file)
- {
- result->lineno = 0;
- fF_SetOffset(result, -30);
- fF_SetError(result, false);
- fF_SetPrivate(result, 0);
- result->line[0] = '\0';
- }
- else
- {
- free(result);
- result = NULL;
- }
- }
- }
- else
- {
- result = NULL;
- illparams("fF_ctor");
- }
- return result;
- }
-
- Error
- fF_readln(fdFile * obj)
- {
- char *low, *bpoint;
- long glen, /*
- * the length we read until now
- */
- len; /*
-
- * the length of the last segment
- */
-
- if (obj)
- {
- low = obj->line;
- glen = 0;
-
- for (;;)
- {
- obj->lineno++;
- if (!fgets(low, fF_BUFSIZE - 1 - glen, obj->file))
- {
- fF_SetError(obj, real_error);
- obj->line[0] = '\0';
- return real_error;
- }
- if (low == strpbrk(low, "*#/"))
- {
- DBP(fprintf(stderr, "in# %s\n", obj->line));
- return false;
- }
- len = strlen(low);
- bpoint = low + len - 1;
- while (len && isspace(*bpoint))
- {
- bpoint--;
- len--;
- }
- if (*bpoint == ';' || *bpoint == ')')
- {
- DBP(fprintf(stderr, "\nin: %s\n", obj->line));
- return false;
- }
- glen += len;
- low += len;
- if (glen >= fF_BUFSIZE - 10) /*
- * somewhat pessimistic?
- */
- {
- fF_SetError(obj, real_error);
- fprintf(stderr, "line %lu too long.\n", obj->lineno);
- return real_error;
- }
- DBP(fprintf(stderr, "+"));
- }
- }
- illparams("fF_readln");
- return real_error;
- }
-
- static INLINE Error
- fF_GetError(const fdFile * obj)
- {
- if (obj)
- return obj->error;
- illparams("fF_GetError");
- return real_error;
- }
-
- static INLINE long
- fF_GetOffset(const fdFile * obj)
- {
- if (obj)
- return obj->offset;
- illparams("fF_GetOffset");
- return -1;
- }
-
- /******************************************************************************
- * fF_FuncName
- *
- * checks if it can find a function-name and return it's address, or NULL
- * if the current line does not seem to contain one. The return value will
- * be a pointer into a malloced buffer, thus the caller will have to free().
- ******************************************************************************/
-
- char *
- fF_FuncName(fdFile * obj)
- {
- const char *lower;
- const char *upper;
- char *buf;
- long obraces; /*
-
- * count of open braces
- */
- Error ready; /*
-
- * ready with searching
- */
-
- if (!obj || fF_GetError(obj) == real_error)
- {
- illparams("fF_FuncName");
- return NULL;
- }
-
- lower = obj->line;
- while (*lower && (*lower == ' ' || *lower == '\t'))
- lower++;
-
- if (!*lower || (!isalpha(*lower) && *lower != '_'))
- {
- fF_SetError(obj, nodef);
- return NULL;
- }
-
- while (*lower)
- {
- if (!isalnum(*lower) && !isspace(*lower) && *lower != '*' && *lower != ','
- && *lower != '.' && *lower != ';' && *lower != '(' && *lower != ')' &&
- *lower != '[' && *lower != ']' && *lower != '_' && *lower != '\\')
- {
- fF_SetError(obj, nodef);
- return NULL;
- }
- lower++;
- }
-
- lower = NULL;
- buf = NULL;
-
- if (obj && fF_GetError(obj) == false)
- {
- if ((upper = strrchr(obj->line, ')')) != 0)
- {
- DBP(fprintf(stderr, "end:%s:", upper));
-
- for (obraces = 1, ready = false; ready == false; upper = lower)
- {
- lower = StrNRBrk(obj->line, "()", --upper);
- if (lower)
- {
- switch (*lower)
- {
- case ')':
- obraces++;
- DBP(fprintf(stderr, " )%ld%s", obraces, lower));
- break;
- case '(':
- obraces--;
- DBP(fprintf(stderr, " (%ld%s", obraces, lower));
- if (!obraces)
- ready = nodef;
- break;
- default:
- fprintf(stderr, "faulty StrNRBrk\n");
- }
- }
- else
- {
- fprintf(stderr, "'(' or ')' expected in line %lu.\n",
- obj->lineno);
- ready = real_error;
- }
- }
- if (ready == nodef) /*
- * we found the matching '('
- */
- {
- long newlen;
- const char *name;
-
- upper--;
-
- while (upper >= obj->line && (*upper == ' ' || *upper == '\t'))
- upper--;
-
- lower = StrNRBrk(obj->line, " \t*)", upper);
-
- if (!lower)
- lower = obj->line;
- else
- lower++;
-
- for (name = lower; name <= upper; name++)
- if (!isalnum(*name) && *name != '_')
- {
- fF_SetError(obj, nodef);
- return NULL;
- }
-
- newlen = upper - lower + 1;
- buf = malloc(newlen + 1);
-
- if (buf)
- {
- strncpy(buf, lower, newlen);
- buf[newlen] = '\0';
- }
- else
- fprintf(stderr, "no mem for fF_FuncName");
- }
- }
- }
- else
- illparams("fF_FuncName");
- return buf;
- }
-
- static INLINE char
- fF_GetPrivate(const fdFile * obj)
- {
- if (obj)
- return obj->private;
- illparams("fF_GetPrivate");
- return 0;
- }
-
- /*********************
- * CLASS fdDef *
- *********************/
-
- typedef struct
- {
- char *name;
- char *type;
- long offset;
- regs reg[REGS];
- char *param[REGS];
- char *proto[REGS];
- regs funcpar; /*
- * number of argument that has type "pointer to function"
- */
- }
- fdDef;
-
- fdDef *
- fD_ctor(void);
- void
- fD_dtor(fdDef * obj);
- static void
- fD_NewName(fdDef * obj, const char *newname);
- void
- fD_NewParam(fdDef * obj, shortcard at, const char *newstr);
- void
- fD_NewProto(fdDef * obj, shortcard at, char *newstr);
- static void
- fD_NewReg(fdDef * obj, shortcard at, regs reg);
- static void
- fD_NewType(fdDef * obj, const char *newstr);
- static void
- fD_SetOffset(fdDef * obj, long off);
-
- Error
- fD_parsefd(fdDef * obj, fdFile * infile);
- Error
- fD_parsepr(fdDef * obj, fdFile * infile);
- static const char *
- fD_GetName(const fdDef * obj);
- static long
- fD_GetOffset(const fdDef * obj);
- static const char *
- fD_GetParam(const fdDef * obj, shortcard at);
- static regs
- fD_GetReg(const fdDef * obj, shortcard at);
- static const char *
- fD_GetRegStr(const fdDef * obj, shortcard at);
- static const char *
- fD_GetType(const fdDef * obj);
- static shortcard
- fD_ParamNum(const fdDef * obj);
- static shortcard
- fD_ProtoNum(const fdDef * obj);
- static shortcard
- fD_RegNum(const fdDef * obj);
- int
- fD_cmpName(const void *big, const void *small);
- void
- fD_write(FILE * outfile, const fdDef * obj);
- static shortcard
- fD_GetFuncParNum(const fdDef * obj);
- static void
- fD_SetFuncParNum(fdDef * obj, shortcard at);
- static void
- fD_adjustargnames(fdDef * obj);
-
- fdDef **arrdefs;
- long fds;
-
- char *fD_nostring = "";
-
- fdDef *
- fD_ctor(void)
- {
- fdDef *result;
- regs count;
-
- result = malloc(sizeof(fdDef));
-
- if (result)
- {
- result->name = fD_nostring;
- result->type = fD_nostring;
- result->funcpar = illegal;
-
- for (count = d0; count < illegal; count++)
- {
- result->reg[count] = illegal;
- result->param[count] = fD_nostring; /*
- * if (!strlen) dont't free()
- */
- result->proto[count] = fD_nostring;
- }
- }
- return result;
- }
-
- /*
- * free all resources and make the object as illegal as possible
- */
-
- void
- fD_dtor(fdDef * obj)
- {
- regs count;
-
- if (obj)
- {
- if (!obj->name)
- fprintf(stderr, "fD_dtor: null name");
- else if (obj->name != fD_nostring)
- free(obj->name);
-
- if (!obj->type)
- fprintf(stderr, "fD_dtor: null type");
- else if (obj->type != fD_nostring)
- free(obj->type);
-
- obj->name = obj->type = NULL;
-
- for (count = d0; count < illegal; count++)
- {
- obj->reg[count] = illegal;
-
- if (!obj->param[count])
- fprintf(stderr, "fD_dtor: null param");
- else if (obj->param[count] != fD_nostring)
- free(obj->param[count]);
-
- if (!obj->proto[count])
- fprintf(stderr, "fD_dtor: null proto");
- else if (obj->proto[count] != fD_nostring)
- free(obj->proto[count]);
-
- obj->param[count] = obj->proto[count] = NULL;
- }
-
- free(obj);
- }
- else
- fprintf(stderr, "fd_dtor(NULL)\n");
- }
-
- static INLINE void
- fD_NewName(fdDef * obj, const char *newname)
- {
- if (obj && newname)
- {
- if (obj->name && obj->name != fD_nostring)
- free(obj->name);
- if (!NewString(&obj->name, newname))
- obj->name = fD_nostring;
- }
- else
- illparams("fD_NewName");
- }
-
- void
- fD_NewParam(fdDef * obj, shortcard at, const char *newstr)
- {
- char *pa;
-
- if (newstr && obj && at < illegal)
- {
- pa = obj->param[at];
-
- if (pa && pa != fD_nostring)
- free(pa);
-
- while (*newstr == ' ' || *newstr == '\t')
- newstr++;
-
- if (NewString(&pa, newstr))
- obj->param[at] = pa;
- else
- obj->param[at] = fD_nostring;
- }
- else
- illparams("fD_NewParam");
- }
-
- /*
- * get first free *reg or illegal
- */
-
- static INLINE shortcard
- fD_RegNum(const fdDef * obj)
- {
- shortcard count;
-
- if (obj)
- {
- for (count = d0; count < illegal && obj->reg[count] != illegal; count++) ;
- DBP(fprintf(stderr, "< )0> RegNum=%ld",count));
- return count;
- }
- else
- {
- illparams("fD_RegNum");
- DBP(fprintf(stderr, "< )0> RegNum illegal"));
- return illegal;
- }
- }
-
- static INLINE void
- fD_NewReg(fdDef * obj, shortcard at, regs reg)
- {
- if (obj && at < illegal && reg >= d0 && reg <= illegal)
- obj->reg[at] = reg;
- else
- illparams("fD_NewReg");
- }
-
- static INLINE regs
- fD_GetReg(const fdDef * obj, shortcard at)
- {
- if (obj && at < illegal)
- return obj->reg[at];
- else
- {
- illparams("fD_GetReg");
- return illegal;
- }
- }
-
- static INLINE shortcard
- fD_GetFuncParNum(const fdDef * obj)
- {
- if (obj)
- return (shortcard) obj->funcpar;
- else
- {
- illparams("fD_GetFuncParNum");
- return illegal;
- }
- }
-
- static INLINE void
- fD_SetFuncParNum(fdDef * obj, shortcard at)
- {
- if (obj && at < illegal)
- obj->funcpar = at;
- else
- illparams("fD_SetFuncParNum");
- }
-
- void
- fD_NewProto(fdDef * obj, shortcard at, char *newstr)
- {
- char *pr;
-
- if (newstr && obj && at < illegal)
- {
- char *t, arr[200]; /*
-
- * I hope 200 will be enough...
- */
- int numwords = 1;
-
- pr = obj->proto[at];
-
- if (pr && pr != fD_nostring)
- free(pr);
-
- while (*newstr == ' ' || *newstr == '\t')
- newstr++; /*
- * Skip leading spaces
- */
-
- t = arr;
- while ((*t++ = *newstr) != 0)
- {
- /*
- * Copy the rest, counting number of words
- */
- if ((*newstr == ' ' || *newstr == '\t') && newstr[1] && newstr[1] != ' ' &&
- newstr[1] != '\t')
- numwords++;
- newstr++;
- }
-
- t = arr + strlen(arr) - 1;
- while (*t == ' ' || *t == '\t')
- t--;
- t[1] = '\0'; /*
- * Get rid of tailing spaces
- */
- if (at != fD_GetFuncParNum(obj))
- {
- if (numwords > 1) /*
- * One word - must be type
- */
- if (*t != '*')
- {
- /*
- * '*' on the end - no parameter name used
- */
- while (*t != ' ' && *t != '\t' && *t != '*')
- t--;
- t++;
- if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
- && strcmp(t, "long"))
- {
- /*
- * Not one of applicable keywords - must be parameter name.
- * Get rid of it.
- */
- t--;
- while (*t == ' ' || *t == '\t')
- t--;
- t[1] = '\0';
- }
- }
- }
- else
- {
- /*
- * Parameter of type "pointer to function".
- */
- char *end;
-
- t = strchr(arr, '(');
- while (*t++ != '*') ;
- end = strchr(t, ')');
- memmove(t + 2, end, strlen(end) + 1);
- *t = '%';
- t[1] = 's';
- }
-
- if (NewString(&pr, arr))
- {
- obj->proto[at] = pr;
- while (*pr == ' ' || *pr == '\t')
- pr++;
- if (!stricmp(pr, "double"))
- {
- /*
- * "double" needs two data registers
- */
- int count, regs = fD_RegNum(obj);
-
- for (count = at + 1; count < regs; count++)
- fD_NewReg(obj, count, fD_GetReg(obj, count + 1));
- }
- }
- else
- obj->proto[at] = fD_nostring;
- }
- else
- illparams("fD_NewProto");
- }
-
- static INLINE void
- fD_NewType(fdDef * obj, const char *newtype)
- {
- if (obj && newtype)
- {
- if (obj->type && obj->type != fD_nostring)
- free(obj->type);
- if (!NewString(&obj->type, newtype))
- obj->type = fD_nostring;
- }
- else
- illparams("fD_NewType");
- }
-
- static INLINE void
- fD_SetOffset(fdDef * obj, long off)
- {
- if (obj)
- obj->offset = off;
- else
- illparams("fD_SetOffset");
- }
-
- static INLINE const char *
- fD_GetName(const fdDef * obj)
- {
- if (obj && obj->name)
- return obj->name;
- else
- {
- illparams("fD_GetName");
- return fD_nostring;
- }
- }
-
- static INLINE long
- fD_GetOffset(const fdDef * obj)
- {
- if (obj)
- return obj->offset;
- else
- {
- illparams("fD_GetOffset");
- return 0;
- }
- }
-
- static INLINE const char *
- fD_GetProto(const fdDef * obj, shortcard at)
- {
- if (obj && at < illegal && obj->proto[at])
- return obj->proto[at];
- else
- {
- illparams("fD_GetProto");
- return fD_nostring;
- }
- }
-
- static INLINE const char *
- fD_GetParam(const fdDef * obj, shortcard at)
- {
- if (obj && at < illegal && obj->param[at])
- return obj->param[at];
- else
- {
- illparams("fD_GetParam");
- return fD_nostring;
- }
- }
-
- static INLINE const char *
- fD_GetRegStr(const fdDef * obj, shortcard at)
- {
- if (obj && at < illegal)
- return RegStr(obj->reg[at]);
- else
- {
- illparams("fD_GetReg");
- return RegStr(illegal);
- }
- }
-
- static INLINE const char *
- fD_GetRegStrU(const fdDef * obj, shortcard at)
- {
- if (obj && at < illegal)
- return RegStrU(obj->reg[at]);
- else
- {
- illparams("fD_GetReg");
- return RegStrU(illegal);
- }
- }
-
- static INLINE const char *
- fD_GetType(const fdDef * obj)
- {
- if (obj && obj->type)
- return obj->type;
- else
- {
- illparams("fD_GetType");
- return fD_nostring;
- }
- }
-
- /*
- * get first free param or illegal
- */
-
- static INLINE shortcard
- fD_ParamNum(const fdDef * obj)
- {
- shortcard count;
-
- if (obj)
- {
- for (count = d0; count < illegal && obj->param[count] != fD_nostring;
- count++) ;
- return count;
- }
- else
- {
- illparams("fD_ParamNum");
- return illegal;
- }
- }
-
- static INLINE shortcard
- fD_ProtoNum(const fdDef * obj)
- {
- shortcard count;
-
- if (obj)
- {
- for (count = d0; count < illegal && obj->proto[count] != fD_nostring;
- count++) ;
- return count;
- }
- else
- {
- illparams("fD_ProtoNum");
- return illegal;
- }
- }
-
- /******************************************************************************
- * fD_parsefd
- *
- * parse the current line. Needs to copy input, in order to insert \0's
- * RETURN
- * fF_GetError(infile):
- * false = read a definition.
- * nodef = not a definition on line (so try again)
- * error = real error
- ******************************************************************************/
-
- Error
- fD_parsefd(fdDef * obj, fdFile * infile)
- {
- enum parse_info
- {
- name, params, regs, ready
- }
- parsing;
- char *buf, *bpoint, *bnext;
- ulong index;
-
- if (obj && infile && fF_GetError(infile) == false)
- {
- parsing = name;
-
- if (!NewString(&buf, infile->line))
- {
- fprintf(stderr, "no mem for line %lu\n", infile->lineno);
- fF_SetError(infile, real_error);
- }
- bpoint = buf; /*
- * so -Wall keeps quiet
- */
-
- /*
- * try to parse the line until there's an error or we are done
- */
-
- while (parsing != ready && fF_GetError(infile) == false)
- {
- switch (parsing)
- {
- case name:
- switch (buf[0])
- {
- case '#':
- if (strncmp("##base", buf, 6) == 0)
- {
- bnext = buf + 6;
- while (*bnext == ' ' || *bnext == '\t' || *bnext == '_')
- bnext++;
- strcpy(BaseName, bnext);
- BaseName[strlen(BaseName) - 1] = '\0';
- }
- else if (strncmp("##bias", buf, 6) == 0)
- {
- if (!sscanf(buf + 6, "%ld", &infile->offset))
- {
- fprintf(stderr, "illegal ##bias in line %lu: %s\n",
- infile->lineno, infile->line);
- fF_SetError(infile, real_error);
- break; /*
- * avoid nodef
- */
- }
- else
- {
- if (fF_GetOffset(infile) > 0)
- fF_SetOffset(infile, -fF_GetOffset(infile));
- DBP(fprintf(stderr, "set offset to %ld\n",
- fF_GetOffset(infile)));
- }
- }
- else
- {
- if (strncmp("##private", buf, 9) == 0)
- fF_SetPrivate(infile, 1);
- else if (strncmp("##public", buf, 8) == 0)
- fF_SetPrivate(infile, 0);
- }
- /*
- * drop through for error comment
- */
-
- case '*':
- /*
- * try again somewhere else
- */
- fF_SetError(infile, nodef);
- break;
-
- default:
- /*
- * assume a regular line here
- */
- if (fF_GetPrivate(infile))
- {
- /*
- * don't store names of privates
- */
- fF_SetError(infile, nodef);
- fF_SetOffset(infile, fF_GetOffset(infile) - 6);
- break;
- }
- parsing = name; /*
- * switch (parsing)
- */
- for (index = 0; buf[index] && buf[index] != '('; index++) ;
-
- if (!buf[index])
- {
- /*
- * oops, no fd ?
- */
- fprintf(stderr, "not an fd, line %lu: %s\n",
- infile->lineno, buf /*
- * infile->line
- */ );
- fF_SetError(infile, nodef);
- } /*
- * maybe next time
- */
- else
- {
- buf[index] = 0;
-
- fD_NewName(obj, buf);
- fD_SetOffset(obj, fF_GetOffset(infile));
-
- bpoint = buf + index + 1;
- parsing = params; /*
- * continue the loop
- */
- }
- }
- break;
-
- case params:
- {
- char *bptmp; /*
-
- * needed for fD_NewParam
- */
-
- /*
- * look for parameters now
- */
-
- for (bnext = bpoint; *bnext && *bnext != ',' && *bnext != ')';
- bnext++) ;
-
- if (*bnext)
- {
- bptmp = bpoint;
-
- if (*bnext == ')')
- {
- if (bnext[1] != '(')
- {
- fprintf(stderr, "registers expected in line %lu: %s\n",
- infile->lineno, infile->line);
- fF_SetError(infile, nodef);
- }
- else
- {
- parsing = regs;
- bpoint = bnext + 2;
- }
- }
- else
- bpoint = bnext + 1;
-
- /*
- * terminate string and advance to next item
- */
-
- *bnext = '\0';
- fD_NewParam(obj, fD_ParamNum(obj), bptmp);
- }
- else
- {
- fF_SetError(infile, nodef);
- fprintf(stderr, "param expected in line %lu: %s\n",
- infile->lineno, infile->line);
- }
- break; /*
- * switch parsing
- */
- }
-
- case regs:
- /*
- * look for parameters now
- */
-
- for (bnext = bpoint; *bnext && *bnext != '/' && *bnext != ',' &&
- *bnext != ')'; bnext++) ;
-
- if (*bnext)
- {
- if (')' == *bnext)
- {
- /*
- * wow, we've finished
- */
- fF_SetOffset(infile, fF_GetOffset(infile) - 6);
- parsing = ready;
- }
- *bnext = '\0';
-
- bpoint[0] = tolower(bpoint[0]);
-
- if ((bpoint[0] == 'd' || bpoint[0] == 'a') && bpoint[1] >= '0' &&
- bpoint[1] <= '8' && bnext == bpoint + 2)
- fD_NewReg(obj, fD_RegNum(obj),
- bpoint[1] - '0' + (bpoint[0] == 'a' ? 8 : 0));
- else if (bnext != bpoint)
- {
- /*
- * it is when our function is void
- */
- fprintf(stderr, "illegal register %s in line %ld\n",
- bpoint, infile->lineno);
- fF_SetError(infile, nodef);
- }
- bpoint = bnext + 1;
- }
- else
- {
- fF_SetError(infile, nodef);
- fprintf(stderr, "reg expected in line %lu\n",
- infile->lineno);
- }
- break; /*
- * switch parsing
- */
-
- case ready:
- fprintf(stderr, "internal error, use another compiler.\n");
- break;
- }
- }
-
- free(buf);
- return fF_GetError(infile);
- }
- else
- {
- illparams("fD_parsefd");
- return real_error;
- }
- }
-
- static void
- fD_adjustargnames(fdDef * obj)
- {
- int parnum;
-
- if (output_mode == NEW)
- {
-
- /*
- * For #define-base output mode, we have to check if argument names are not
- * the same as some words in type names. We check from the first argument
- * to the last, resolving conflicts by changing argument names, if
- * necessary.
- */
-
- for (parnum = 0; parnum < fD_ParamNum(obj); parnum++)
- {
- const char *parname = fD_GetParam(obj, parnum);
- int finished;
-
- DBP(fprintf(stderr, "ParNum %ld ParName %s\n",parnum,parname));
- do
- {
- int num;
- const char *type = fD_GetType(obj);
- char *str;
-
- finished = 1;
-
- DBP(fprintf(stderr, "DoLoop\n"));
- if ((str = strstr(type, parname)) != 0 &&
- (str == type || (!isalnum(str[-1]) && str[-1] != '_')) &&
- (!*(str += strlen(parname)) || (!isalnum(*str) && *str != '_')))
- {
- char buf[300]; /*
- * Hope will be enough...
- */
-
- DBP(fprintf(stderr, "str1 %s\n",str));
- strcpy(buf, parname);
- strcat(buf, "_");
- DBP(fprintf(stderr, "NewParam1 ParNum %ld Buf %s\n",parnum,buf));
- fD_NewParam(obj, parnum, buf);
- finished = 0;
- }
- else
- {
- DBP(fprintf(stderr, "str2 %s\n",str));
- for (num = 0; num < fD_ParamNum(obj); num++)
- {
- const char *name = fD_GetParam(obj, num);
- const char *proto = fD_GetProto(obj, num);
-
- DBP(fprintf(stderr, "num %ld name %s proto %s\n",num,name,proto));
-
- if ((num < parnum && strcmp(name, parname) == 0) ||
- ((str = strstr(proto, parname)) != 0 &&
- (str == proto || (!isalnum(str[-1]) && str[-1] != '_')) &&
- (!*(str += strlen(parname)) || (!isalnum(*str) && *str != '_'))))
- {
- char buf[300]; /*
- * Hope will be enough...
- */
- strcpy(buf, parname);
- strcat(buf, "_");
- DBP(fprintf(stderr, "NewParam2 ParNum %ld Buf %s\n",parnum,buf));
- fD_NewParam(obj, parnum, buf);
- //finished = 0;
- break;
- }
- }
- }
- }
- while (!finished);
- }
- }
- }
-
- Error
- fD_parsepr(fdDef * obj, fdFile * infile)
- {
- char *buf; /*
- * a copy of infile->line
- */
- char *bpoint, /*
- * cursor in buf
- */
- *bnext, /*
- * looking for the end
- */
- *lowarg; /*
- * beginning of this argument
- */
- long obraces; /*
- * count of open braces
- */
- regs count, /*
- * count parameter number
- */
- args; /*
- * the number of arguments for this function
- */
-
- if (!(obj && infile && fF_GetError(infile) == false))
- {
- illparams("fD_parsepr");
- fF_SetError(infile, real_error);
- return real_error;
- }
- if (!NewString(&buf, infile->line))
- {
- fprintf(stderr, "no mem for fD_parsepr\n");
- fF_SetError(infile, real_error);
- return real_error;
- }
- fF_SetError(infile, false);
-
-
- DBP(fprintf(stderr,"buf %s",buf));
- bpoint = strchr(buf, '(');
- while (--bpoint >= buf && strstr(bpoint, fD_GetName(obj)) != bpoint) ;
-
- if (bpoint >= buf)
- {
- while (--bpoint >= buf && (*bpoint == ' ' || *bpoint == '\t')) ;
- *++bpoint = '\0';
-
- fD_NewType(obj, buf);
-
- while (bpoint && *bpoint++ != '(') ; /* one beyond '(' */
-
- lowarg = bpoint;
- obraces = 0;
-
- for (count = 0, args = fD_RegNum(obj); count < args; bpoint = bnext + 1)
- {
- while (*bpoint && (*bpoint == ' ' || *bpoint == '\t'))
- bpoint++;
-
- DBP(fprintf(stderr,"count %ld args %ld",count,args));
- DBP(fprintf(stderr,"bpoint %s",bpoint));
- bnext = strpbrk(bpoint, "(),");
- DBP(fprintf(stderr,"bnext %s",bnext));
-
- if (bnext)
- {
- switch (*bnext)
- {
- case '(':
- if (!obraces)
- {
- if ((PowerUP==0) && (MorphOS==0))
- {
- if (fD_GetFuncParNum(obj) != illegal &&
- fD_GetFuncParNum(obj) != count)
- fprintf(stderr, "Warning: two parameters of type "
- "pointer to function are used.\nThis is not "
- "supported!\n");
- }
- fD_SetFuncParNum(obj, count);
- }
- obraces++;
- DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
- break;
-
- case ')':
- if (obraces)
- {
- DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
- obraces--;
- }
- else
- {
- *bnext = '\0';
- DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
- fD_NewProto(obj, count, lowarg);
- lowarg = bnext + 1;
-
- if (count != args - 1)
- {
- DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
- fD_GetName(obj), args, count + 1));
- fF_SetError(infile, nodef);
- }
- count++;
- }
- break;
-
- case ',':
- if (!obraces)
- {
- *bnext = '\0';
- DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
- fD_NewProto(obj, count, lowarg);
- lowarg = bnext + 1;
- count++;
- }
- break;
-
- default:
- fprintf(stderr, "faulty strpbrk in line %lu.\n",
- infile->lineno);
- }
- }
- else
- {
- DBP(fprintf(stderr, "faulty argument %u in line %lu.\n", count + 1,
- infile->lineno));
- count = args; /*
- * this will effectively quit the for loop
- */
- fF_SetError(infile, nodef);
- }
- }
- if (fD_ProtoNum(obj) != fD_RegNum(obj))
- fF_SetError(infile, nodef);
- }
- else
- {
- fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
- fprintf(stderr, "function , definition %s.\n",
- /*
- * fD_GetName(obj),
- */ infile->line);
- fF_SetError(infile, nodef);
- }
-
- free(buf);
-
- fD_adjustargnames(obj);
-
- return fF_GetError(infile);
- }
-
- int
- fD_cmpName(const void *big, const void *small) /*
- * for qsort and bsearch
- */
- {
- return strcmp(fD_GetName(*(fdDef **) big), fD_GetName(*(fdDef **) small));
- }
-
- const static char *TagExcTable[] =
- {
- "BuildEasyRequestArgs", "BuildEasyRequest",
- "DoDTMethodA", "DoDTMethod",
- "DoGadgetMethodA", "DoGadgetMethod",
- "EasyRequestArgs", "EasyRequest",
- "MUI_MakeObjectA", "MUI_MakeObject",
- "MUI_RequestA", "MUI_Request",
- "PrintDTObjectA", "PrintDTObject",
- "RefreshDTObjectA", "RefreshDTObjects",
- "UMSVLog", "UMSLog",
- "VFWritef", "FWritef",
- "VFPrintf", "FPrintf",
- "VPrintf", "Printf",
- };
-
- const char *
- taggedfunction(const fdDef * obj)
- {
- shortcard numregs = fD_RegNum(obj);
- unsigned int count;
- const char *name = fD_GetName(obj);
- static char newname[200]; /*
-
- * Hope will be enough... static because used
- * out of the function.
- */
- const char *lastarg;
- const static char *TagExcTable2[] =
- {
- "ApplyTagChanges",
- "CloneTagItems",
- "FindTagItem",
- "FreeTagItems",
- "GetTagData",
- "PackBoolTags",
- "PackStructureTags",
- "RefreshTagItemClones",
- "UnpackStructureTags",
- };
-
- if (!numregs)
- return NULL;
-
- for (count = 0; count < sizeof TagExcTable / sizeof TagExcTable[0]; count += 2)
- if (strcmp(name, TagExcTable[count]) == 0)
- return TagExcTable[count + 1];
-
- for (count = 0; count < sizeof TagExcTable2 / sizeof TagExcTable2[0]; count++)
- if (strcmp(name, TagExcTable2[count]) == 0)
- return NULL;
-
- lastarg = fD_GetProto(obj, numregs - 1);
- if (strncmp(lastarg, "struct", 6))
- return NULL;
- lastarg += 6;
- while (*lastarg == ' ' || *lastarg == '\t')
- lastarg++;
- if (strncmp(lastarg, "TagItem", 7))
- return NULL;
- lastarg += 7;
- while (*lastarg == ' ' || *lastarg == '\t')
- lastarg++;
- if (strcmp(lastarg, "*"))
- return NULL;
-
- strcpy(newname, name);
- if (newname[strlen(newname) - 1] == 'A')
- newname[strlen(newname) - 1] = '\0';
- else if (strlen(newname) > 7 && !strcmp(newname + strlen(newname) - 7, "TagList"))
- strcpy(newname + strlen(newname) - 4, "s");
- else
- strcat(newname, "Tags");
- return newname;
- }
-
- const char *
- aliasfunction(const char *name)
- {
- const static char *AliasTable[] =
- {
- "AllocDosObject", "AllocDosObjectTagList",
- "CreateNewProc", "CreateNewProcTagList",
- "NewLoadSeg", "NewLoadSegTagList",
- "System", "SystemTagList",
- };
- unsigned int count;
-
- for (count = 0; count < sizeof AliasTable / sizeof AliasTable[0]; count++)
- if (strcmp(name, AliasTable[count]) == 0)
- return AliasTable[count + (count % 2 ? -1 : 1)];
- return NULL;
- }
-
- void
- fD_write(FILE * outfile, const fdDef * obj)
- {
- shortcard count, numregs;
- const char *chtmp, *tagname, *name, *rettype;
- int vd = 0, a45 = 0, d7 = 0;
-
- DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
-
- numregs = fD_RegNum(obj);
-
- if ((rettype = fD_GetType(obj)) == fD_nostring)
- {
- fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
- return;
- }
- if (!stricmp(rettype, "void"))
- {
- vd = 1; /*
- * set flag
- */
- }
- for (count = d0; count < numregs; count++)
- {
- const char *reg = fD_GetRegStr(obj, count);
-
- if (!((output_mode == NEW) && (PowerUP == TRUE)))
- {
- if (strcmp(reg, "a4") == 0 || strcmp(reg, "a5") == 0)
- {
- if (!a45)
- a45 = (strcmp(reg, "a4") ? 5 : 4); /*
- * set flag
- */
- else /*
- * Security check
- */
- fprintf(stderr, "Warning: both a4 and a5 are used. This is not "
- "supported!\n");
- }
- if (strcmp(reg, "d7") == 0) /*
- * Used only when a45!=0
- */
- {
- d7 = 1;
- }
- }
- }
-
- if (!((output_mode == NEW) && (PowerUP == TRUE)))
- {
- if (a45 && d7) /*
- * Security check
- */
- fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
- "supported!\n");
- }
-
- name = fD_GetName(obj);
-
- if (fD_ProtoNum(obj) != numregs)
- {
- fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
- fD_ProtoNum(obj), fD_ProtoNum(obj) != 1 ? "s" : "");
- return;
- }
-
- if ((output_mode == NEW) && (PowerUP == FALSE) && (MorphOS == FALSE))
- {
- fprintf(outfile, "#define %s(", name);
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "%s, ", fD_GetParam(obj, count));
- fprintf(outfile, "%s", fD_GetParam(obj, count));
- }
-
- fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
- (vd ? "NR" : ""), (a45 ? (a45 == 4 ? "A4" : "A5") : ""),
- (BaseName[0] ? "" : "UB"),
- (fD_GetFuncParNum(obj) == illegal ? "" : "FP"), -fD_GetOffset(obj));
- if (!vd)
- {
- fprintf(outfile, "%s, ", rettype);
- }
- fprintf(outfile, "%s, ", name);
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetRegStr(obj, count);
- if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
- chtmp = "d7";
- fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj) == count ?
- "__fpt" : fD_GetProto(obj, count)), fD_GetParam(obj, count),
- chtmp, (count == numregs - 1 && !BaseName[0] ? "" : ", "));
- }
-
- if (BaseName[0]) /*
- * was "##base" used?
- */
- fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
- if (fD_GetFuncParNum(obj) != illegal)
- {
- fprintf(outfile, ", ");
- fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
- }
- fprintf(outfile, ")\n\n");
- }
- else if ((output_mode == NEW) && (PowerUP == TRUE || MorphOS == TRUE))
- {
- fprintf(outfile, "#define %s(", name);
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "%s, ", fD_GetParam(obj, count));
-
- fprintf(outfile, "%s", fD_GetParam(obj, count));
- }
-
- #if 1
- fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
- numregs,
- (vd ? "NR" : ""),
- (BaseName[0] ? "" : "UB"),
- -fD_GetOffset(obj));
- #else
- fprintf(outfile, ") \\\n\tLP%d%s%s%s(0x%lx, ",
- numregs,
- (vd ? "NR" : ""),
- (BaseName[0] ? "" : "UB"),
- (fD_GetFuncParNum(obj) == illegal ? "" : "FP"), -fD_GetOffset(obj));
- #endif
- if (!vd)
- {
- fprintf(outfile, "%s, ", rettype);
- }
-
- fprintf(outfile, "%s, ", name);
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetRegStr(obj, count);
-
- if (strchr(fD_GetProto(obj, count),'%'))
- {
- sprintf(Buffer,
- fD_GetProto(obj, count),
- "");
-
- fprintf(outfile, "%s, %s, %s%s",
- Buffer,
- fD_GetParam(obj, count),
- chtmp,
- (count == numregs - 1 && !BaseName[0] ? "" : ", "));
- }
- else
- {
- fprintf(outfile, "%s, %s, %s%s",
- fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProto(obj, count)),
- fD_GetParam(obj, count),
- chtmp,
- (count == numregs - 1 && !BaseName[0] ? "" : ", "));
- }
- }
-
- if (BaseName[0])
- {
- fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
- }
- #if 0
- if (fD_GetFuncParNum(obj) != illegal)
- {
- fprintf(outfile, ", ");
- fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
- }
- #endif
- /*
- * Here it would make sense to create a database file to integrate optimizations * automaticly into every new
- * build. * Not every function needs a complete flush. For example functions with no parameter * wouldn`t
- * need a PPC flush normally. * Or Read(File,Addr,Size); would only need a flush for Addr with the Size
- */
- fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
- fprintf(outfile, ")\n\n");
-
- }
- else if (output_mode == PRAGMA)
- {
- if (PowerUP == TRUE || MorphOS == TRUE)
- {
-
- fprintf(outfile, "#define\t%s",
- name);
-
- if (numregs)
- {
- fprintf(outfile, "(");
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs - 1; count++)
- {
- fprintf(outfile, "%s, ", fD_GetParam(obj, count));
- }
- fprintf(outfile, "%s", fD_GetParam(obj, count));
- }
-
- fprintf(outfile, ")");
-
- if (BaseName[0]) /*
- * was "##base" used?
- */
- {
- fprintf(outfile, "\t_%s(%s_BASE_NAME%s",
- name,
- BaseNamU,
- numregs ? ", " : "");
- }
- else
- {
- fprintf(outfile, "\t_%s(",
- name);
- }
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs - 1; count++)
- {
- fprintf(outfile, "%s, ", fD_GetParam(obj, count));
- }
- fprintf(outfile, "%s", fD_GetParam(obj, count));
- }
-
- fprintf(outfile, ")\n\n");
- }
- else
- {
- if (BaseName[0]) /*
- * was "##base" used?
- */
- {
- fprintf(outfile, "()\t_%s(%s_BASE_NAME)\n\n",
- name,
- BaseNamU);
- }
- else
- {
- fprintf(outfile, "()\t_%s()\n\n",
- name);
- }
- }
-
- fprintf(outfile, "static __inline %s\n_%s(%s%s%s",
- rettype,
- name,
- BaseName[0] ? "void *" : "",
- BaseName[0] ? BaseName : "",
- (BaseName[0] ? (numregs ? ", " : "") : ""));
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetProto(obj, count);
- if (fD_GetFuncParNum(obj) == count)
- {
- fprintf(outfile, chtmp, fD_GetParam(obj, count));
- }
- else
- {
- fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
- "" : " "), fD_GetParam(obj, count));
- }
- if (count < numregs - 1)
- {
- fprintf(outfile, ", ");
- }
- }
-
- fprintf(outfile, ")\n");
- fprintf(outfile, "{\n");
- fprintf(outfile, "struct Caos\tMyCaos;\n");
- fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\n");
- fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\n");
- fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\n");
- fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\n");
- fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\n");
- fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\n");
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs; count++)
- {
- fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\n",
- fD_GetRegStr(obj, count),
- fD_GetParam(obj, count));
- }
- }
-
- fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\n",
- fD_GetOffset(obj));
-
- if (BaseName[0]) /*
- * was "##base" used?
- */
- {
- fprintf(outfile, "\tMyCaos.a6\t\t=(ULONG) %s;\t\n",
- BaseName);
- }
- if (vd)
- {
- fprintf(outfile, "\tPPCCallOS(&MyCaos);\n}\n\n");
- }
- else
- {
- fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
- rettype);
- /*
- * fprintf(outfile, "\treturn((%s)MyCaos.d0);\n}\n\n", rettype);
- */
- }
-
- }
- else
- {
- /*
- * No M68k support yet
- */
- }
- }
- else if (output_mode == GATESTUBS)
- {
- fprintf(outfile, "%s %s%s(void)\n{\n",
- rettype,
- prefixname,
- name);
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs; count++)
- {
- if (strchr(fD_GetProto(obj, count),'%'))
- {
- /* Function parameter */
- fprintf(outfile, "\t");
-
- sprintf(Buffer,
- fD_GetProto(obj, count),
- fD_GetParam(obj, count));
- fprintf(outfile, Buffer);
-
- fprintf(outfile, "\t=(");
-
- sprintf(Buffer,
- fD_GetProto(obj, count),
- "");
- fprintf(outfile, Buffer);
-
- fprintf(outfile, ") REG_%s;\n",
- fD_GetRegStrU(obj, count));
- }
- else
- {
- fprintf(outfile, "\t%s %s\t=(%s) REG_%s;\n",
- fD_GetProto(obj, count),
- fD_GetParam(obj, count),
- fD_GetProto(obj, count),
- fD_GetRegStrU(obj, count));
- }
- }
- if (PreLibFlag || PostLibFlag)
- {
- if (RegLibFlag)
- {
- fprintf(outfile, "\tvoid *___RegBase\t=(void*) REG_A6;\n");
- }
- }
-
- }
- if (vd)
- {
- fprintf(outfile, "\t(%s%s(",
- subprefixname,
- name);
- }
- else
- {
- fprintf(outfile, "\treturn(%s%s(",
- subprefixname,
- name);
- }
- if (numregs > 0)
- {
- if (PreLibFlag)
- {
- if (RegLibFlag)
- {
- fprintf(outfile, "___RegBase,");
- }
- else
- {
- fprintf(outfile, "BASE_NAME,");
- }
- }
-
- for (count = d0; count < numregs; count++)
- {
- if (count >= numregs - 1)
- {
- if (PostLibFlag)
- {
- if (RegLibFlag)
- {
- fprintf(outfile, "%s,___RegBase));\n}\n",
- fD_GetParam(obj, count));
- }
- else
- {
- fprintf(outfile, "%s,BASE_NAME));\n}\n",
- fD_GetParam(obj, count));
- }
- }
- else
- {
- fprintf(outfile, "%s));\n}\n",
- fD_GetParam(obj, count));
- }
- }
- else
- {
- fprintf(outfile, "%s,",
- fD_GetParam(obj, count));
- }
- }
- }
- else
- {
- if (PreLibFlag || PostLibFlag)
- {
- if (RegLibFlag)
- {
- fprintf(outfile, "___RegBase));\n}\n");
- }
- else
- {
- fprintf(outfile, "BASE_NAME));\n}\n");
- }
- }
- else
- {
- fprintf(outfile, "));\n}\n");
- }
- }
-
- }
- else
- {
- if (PowerUP == TRUE)
- {
- fprintf(outfile, "%sstatic __inline %s\n%s(%s",
- (output_mode == STUBS ? "" : "extern "), rettype, name,
- (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetProto(obj, count);
- if (fD_GetFuncParNum(obj) == count)
- fprintf(outfile, chtmp, fD_GetParam(obj, count));
- else
- fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
- "" : " "), fD_GetParam(obj, count));
- if (count < numregs - 1)
- fprintf(outfile, ", ");
- }
-
- fprintf(outfile, ")\t\n");
- fprintf(outfile, "{\t\n");
- fprintf(outfile, "struct Caos\tMyCaos;\n");
- fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
- fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
- fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
- fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
- fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
- fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs; count++)
- {
- fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
- fD_GetRegStr(obj, count),
- fD_GetParam(obj, count));
- }
- }
-
- fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
- if (BaseName[0]) /*
- * was "##base" used?
- */
- {
- fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) %s_BASE_NAME;\t\n",
- BaseNamU);
- }
- if (vd)
- {
- fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
- }
- else
- {
- fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
- rettype);
- /*
- * fprintf(outfile, "\treturn((%s)MyCaos.d0);\t\n}\n\n", rettype);
- */
- }
- }
- else if (MorphOS == TRUE)
- {
- fprintf(outfile, "%s%s\n%s(%s",
- (output_mode == STUBS ? "" : "static __inline "), rettype, name,
- (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetProto(obj, count);
- if (fD_GetFuncParNum(obj) == count)
- fprintf(outfile, chtmp, fD_GetParam(obj, count));
- else
- fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
- "" : " "), fD_GetParam(obj, count));
- if (count < numregs - 1)
- fprintf(outfile, ", ");
- }
-
- fprintf(outfile, ")\t\n");
- fprintf(outfile, "{\t\n");
- fprintf(outfile, "struct EmulCaos\tMyCaos;\n");
-
- if (numregs > 0)
- {
- for (count = d0; count < numregs; count++)
- {
- fprintf(outfile, "\tMyCaos.reg_%s\t\t=\t(ULONG) %s;\n",
- fD_GetRegStr(obj, count), fD_GetParam(obj, count));
- }
- }
-
- fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\n", fD_GetOffset(obj));
- if (BaseName[0]) /*
- * was "##base" used?
- */
- {
- fprintf(outfile, "\tMyCaos.reg_a6\t\t=\t(ULONG) BASE_NAME;\n");
- }
- if (vd)
- {
- fprintf(outfile, "\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
- }
- else
- {
- fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n",
- rettype);
- /*
- * fprintf(outfile, "\treturn((%s)MyCaos.d0);\t\n}\n\n", rettype);
- */
- }
- }
- else
- {
- fprintf(outfile, "%s__inline %s\n%s(%s",
- (output_mode == STUBS ? "" : "extern "), rettype, name,
- (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetProto(obj, count);
- if (fD_GetFuncParNum(obj) == count)
- fprintf(outfile, chtmp, fD_GetParam(obj, count));
- else
- fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
- "" : " "), fD_GetParam(obj, count));
- if (count < numregs - 1)
- fprintf(outfile, ", ");
- }
- fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
- if (!vd)
- fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
- (*(rettype + strlen(rettype) - 1) == '*' ? "" : " "));
-
- if (BaseName[0])
- fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
- StdLib);
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetRegStr(obj, count);
- if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
- chtmp = "d7";
- if (fD_GetFuncParNum(obj) == count)
- {
- fprintf(outfile, " register ");
- fprintf(outfile, fD_GetProto(obj, count), chtmp);
- fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
- count));
- }
- else
- {
- const char *proto = fD_GetProto(obj, count);
-
- fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
- proto, (*(proto + strlen(proto) - 1) == '*' ? "" : " "), chtmp,
- chtmp, fD_GetParam(obj, count));
- }
- }
- if (a45)
- fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
- "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45 == 4 ? "a4" : "a5"),
- -fD_GetOffset(obj), (a45 == 4 ? "a4" : "a5"));
- else
- fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
- -fD_GetOffset(obj));
-
- fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
-
- fprintf(outfile, " : ");
- if (BaseName[0])
- fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", " : ""));
-
- for (count = d0; count < numregs; count++)
- {
- chtmp = fD_GetRegStr(obj, count);
- if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
- chtmp = "d7";
- fprintf(outfile, "\"r\" (%s)%s", chtmp, (count < numregs - 1 ? ", " : ""));
- }
- fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
-
- if (vd)
- fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n"); /*
- * {
- */
- else
- fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
- }
- }
-
- if ((tagname = aliasfunction(fD_GetName(obj))) != 0)
- {
- fprintf(outfile, "#define %s(", tagname);
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "a%d, ", count);
-
- fprintf(outfile, "a%d) %s (", count, name);
-
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "(a%d), ", count);
-
- fprintf(outfile, "(a%d))\n\n", count);
- }
-
- if ((tagname = taggedfunction(obj)) != 0)
- {
- if (output_mode != STUBS)
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile, "#ifndef NO_PPCINLINE_STDARG\n#define %s(", tagname);
- }
- else
- {
- fprintf(outfile, "#ifndef NO_INLINE_STDARG\n#define %s(", tagname);
- }
-
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "a%d, ", count);
-
- fprintf(outfile, "tags...) \\\n\t({ULONG _tags[] = { tags }; %s(",
- name);
-
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "(a%d), ", count);
-
- if (PowerUP || MorphOS)
- {
- fprintf(outfile, "(%s)_tags);})\n#endif /* !NO_PPCINLINE_STDARG */\n\n",
- fD_GetProto(obj, fD_RegNum(obj) - 1));
- }
- else
- {
- fprintf(outfile, "(%s)_tags);})\n#endif /* !NO_INLINE_STDARG */\n\n",
- fD_GetProto(obj, fD_RegNum(obj) - 1));
- }
- }
- else
- {
- if (MorphOS)
- {
- int n = 9 - numregs;
- int d = n & 1 ? 4 : 0;
- int taglist = 8 + (DirectVarargsCalls ? 0 : 64);
- int local = (n * 4 + d + 8 + 15) & ~15; /* size of the stack frame */
-
- /*
- * Stack frame:
- *
- * 0 - 3: next frame ptr
- * 4 - 7: save lr
- * 8 - 71: struct Caos
- * 72 - 72+n*4+d+8-1: tag list start
- * ? - local-1: padding
- */
-
- fprintf(outfile,
- "asm(\"\n"
- " .align 2 \n"
- " .globl %s \n"
- " .type %s,@function\n"
- "%s: \n"
- " stwu 1,-%d(1) \n" /* create stack frame */
- " mflr 0 \n"
- " stw 0,%d(1) \n",
- tagname, tagname, tagname, local, local + 4);
-
- /*
- * If n is odd, one tag is split between regs and stack.
- * Copy its ti_Data together with the ti_Tag.
- */
- if (d)
- fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
-
- /*
- * Save the registers
- */
- for (count = numregs; count <= 8; count++)
- fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
-
- if (d)
- fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
-
- /*
- * Add TAG_MORE
- */
- fprintf(outfile, " li 0,2 \n"
- " stw 0,%d(1) \n" /* add TAG_MORE */
-
- " addi 0,1,%d \n"
- " stw 0,%d(1) \n", /* ti_Data = &stack_params */
- taglist + n * 4 + d,
- local + 8 + d, taglist + n * 4 + d + 4);
-
-
- if (DirectVarargsCalls)
- {
- fprintf(outfile,
- " addi %d,1,%d \n" /* vararg_reg = &saved regs */
- " bl %s \n",
- numregs + 2, taglist, name);
-
- }
- else
- {
- /*
- * Caos.Offset = -fD_GetOffset(obj)
- */
- fprintf(outfile,
- " li 0,%ld \n"
- " stw 0,8(1) \n",
- fD_GetOffset(obj));
-
- /*
- * Save the non-varargs registers in the Caos struct.
- */
- for (count = 0; count < numregs - 1; count++)
- {
- int r = fD_GetReg(obj, count);
-
- fprintf(outfile, "stw %d,%d(1)\n", count + 3, 8 + 4 + r * 4);
- }
-
- fprintf(outfile,
- " addi 0,1,%d \n"
- " lis 3,%s@ha \n"
- " stw 0,%d(1) \n" /* Caos.reg_?? = taglist */
- " lwz 12,%s@l(3)\n"
- " lwz 11,88(2) \n"
- " stw 12,68(1) \n" /* Caos.reg_a6 = libbase */
- " mtctr 11 \n"
- " addi 3,1,8 \n"
- " bctrl \n", /* EmulCallOS() */
- taglist, BaseName, 12 + 4 * fD_GetReg(obj, numregs - 1), BaseName);
- }
-
- fprintf(outfile," lwz 0,%d(1) \n" /* clear stack frame & return */
- " mtlr 0 \n"
- " addi 1,1,%d \n"
- " blr \n"
- ".L%se1: \n"
- " .size\t%s,.L%se1-%s\n"
- "\");\n\n",
- local + 4, local,
- tagname, tagname, tagname, tagname);
- }
- else
- {
- fprintf(outfile, "%s %s(", rettype, tagname);
-
- for (count = d0; count < numregs - 1; count++)
- {
- chtmp = fD_GetProto(obj, count);
- if (count == fD_GetFuncParNum(obj))
- fprintf(outfile, chtmp, fD_GetParam(obj, count));
- else
- fprintf(outfile, "%s%s%s", chtmp,
- (*(chtmp + strlen(chtmp) - 1) == '*' ? "" : " "),
- fD_GetParam(obj, count));
- fprintf(outfile, ", ");
- }
-
- fprintf(outfile, "int tag, ...)\n{\n ");
- if (!vd)
- fprintf(outfile, "return ");
-
- fprintf(outfile, "%s(", name);
- for (count = d0; count < numregs - 1; count++)
- fprintf(outfile, "%s, ", fD_GetParam(obj, count));
-
- fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj) - 1));
- }
- }
- }
-
- if (strcmp(name, "DoPkt") == 0)
- {
- fdDef *objnc = (fdDef *) obj;
- char newname[7] = "DoPkt0";
-
- objnc->name = newname;
- for (count = 2; count < 7; count++)
- {
- regs reg = objnc->reg[count];
- char *proto = objnc->proto[count];
-
- objnc->reg[count] = illegal;
- objnc->proto[count] = fD_nostring;
- fD_write(outfile, objnc);
- objnc->reg[count] = reg;
- objnc->proto[count] = proto;
- newname[5]++;
- }
- objnc->name = (char *)name;
- }
- }
-
- int
- varargsfunction(const char *proto, const char *funcname)
- {
- const char *end = proto + strlen(proto) - 1;
-
- while (isspace(*end))
- end--;
- if (*end-- == ';')
- {
- while (isspace(*end))
- end--;
- if (*end-- == ')')
- {
- while (isspace(*end))
- end--;
- if (!strncmp(end - 2, "...", 3))
- {
- /*
- * Seems to be a varargs function. Check if it will be recognized
- * as "tagged".
- */
- unsigned int count;
- char fixedname[200]; /*
-
- * Hope will be enough...
- */
- fdDef *tmpdef;
-
- for (count = 0; count < sizeof TagExcTable / sizeof TagExcTable[0];
- count += 2)
- if (strcmp(funcname, TagExcTable[count + 1]) == 0)
- return 1;
-
- if (!(tmpdef = fD_ctor()))
- {
- fprintf(stderr, "No mem for FDs\n");
- exit(EXIT_FAILURE);
- }
-
- strcpy(fixedname, funcname);
- if (strlen(funcname) > 4 &&
- !strcmp(funcname + strlen(funcname) - 4, "Tags"))
- {
- /*
- * Might be either nothing or "TagList".
- */
- fixedname[strlen(fixedname) - 4] = '\0';
- fD_NewName(tmpdef, fixedname);
- if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
- fD_cmpName))
- return 1;
-
- strcat(fixedname, "TagList");
- fD_NewName(tmpdef, fixedname);
- if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
- fD_cmpName))
- return 1;
- }
- else
- {
- strcat(fixedname, "A");
- fD_NewName(tmpdef, fixedname);
- if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
- fD_cmpName))
- return 1;
- }
- }
- }
- }
- return 0;
- }
-
- int
- ishandleddifferently(const char *proto, const char *funcname)
- {
- /*
- * First check if this is a vararg call?
- */
- if (varargsfunction(proto, funcname))
- return 1;
-
- /*
- * It might be a dos.library "alias" name.
- */
- if (aliasfunction(funcname))
- return 1;
-
- /*
- * It might be one from dos.library/DoPkt() family.
- */
- if (strlen(funcname) == 6 && !strncmp(funcname, "DoPkt", 5) &&
- funcname[5] >= '0' && funcname[6] <= '4')
- return 1;
-
- /*
- * Finally, it can be intuition.library/ReportMouse1().
- */
- return !strcmp(funcname, "ReportMouse1");
- }
-
- void
- output_proto(FILE * outfile)
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef PROTO_%s_H\n"
- "#define PROTO_%s_H\n\n"
- "#include <clib/%s_protos.h>\n\n"
- "#ifdef __GNUC__\n"
- "#ifdef __PPC__\n"
- "#include <ppcinline/%s.h>\n"
- "#else\n"
- "#include <inline/%s.h>\n"
- "#endif /* __PPC__ */\n"
- "#else\n"
- "#include <pragmas/%s_pragmas.h>\n"
- "#endif /* __GNUC__ */\n\n",
- BaseNamU, BaseNamU, BaseNamL, BaseNamL, BaseNamL, BaseNamL);
- }
- else
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef PROTO_%s_H\n"
- "#define PROTO_%s_H\n\n"
- "#include <clib/%s_protos.h>\n\n"
- "#ifdef __GNUC__\n"
- "#include <inline/%s.h>\n"
- "#endif /* __GNUC__ */\n\n",
- BaseNamU, BaseNamU, BaseNamL, BaseNamL);
- }
- if (BaseName[0])
- fprintf(outfile,
- "#ifndef __NOLIBBASE__\n"
- "extern struct %s *\n"
- "#ifdef __CONSTLIBBASEDECL__\n"
- "__CONSTLIBBASEDECL__\n"
- "#endif /* __CONSTLIBBASEDECL__ */\n"
- "%s;\n"
- "#endif /* !__NOLIBBASE__ */\n\n",
- StdLib, BaseName);
-
- if (PowerUP || MorphOS)
- {
- fprintf(outfile,
- "#endif /* !PPCPROTO_%s_H */\n", BaseNamU);
- }
- else
- {
- fprintf(outfile,
- "#endif /* !PROTO_%s_H */\n", BaseNamU);
- }
- }
-
- /******************************************************************************/
-
- void
- printusage(const char *exename)
- {
- fprintf(stderr,
- "Usage: %s [options] [--prefix name] [--subprefix name] [--premacro name] fd-file clib-file [[-o] output-file]\n"
- "Options:\n"
- "--new\t\t\tpreprocessor based (default)\n"
- "--old\t\t\tinline based\n"
- "--stubs\t\t\tlibrary stubs\n"
- "--proto\t\t\tbuild proto files (no clib-file required)\n"
- "--pragma\t\tbuild pragma file\n"
- "--powerup\t\tpowerup flag\n"
- "--morphos\t\tmorphos flag\n"
- "--gatestubs\t\tlibrary stubs\n"
- "--prelib\t\tgatestub pre library arg\n"
- "--postlib\t\tgatestub pre library arg\n"
- "--reglib\t\tgatestub uses REG_A6 arg for pre/postlib argument\n"
- "--direct-varargs-calls\n"
- "--local\t\tlocal includes\n"
- "--version\t\tprint version number and exit\n", exename);
- }
-
- int
- main(int argc, char **argv)
- {
- fdDef *tmpdef, /*
- * a dummy to contain the name to look for
- */
- *founddef; /*
-
- * the fdDef for which we found a prototype
- */
- fdFile *myfile;
- char *tmpstr;
- FILE *outfile;
- int closeoutfile=FALSE;
- char *fdfilename = 0, *clibfilename = 0, *outfilename = 0;
-
- int count;
- Error lerror;
-
- for (count = 1; count < argc; count++)
- {
- char *option = argv[count];
-
- if (*option == '-')
- {
- option++;
- if (strcmp(option, "o") == 0)
- {
- if (count == argc - 1 || outfilename)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- if (strcmp(argv[++count], "-"))
- outfilename = argv[count];
- }
- else
- {
- if (*option == '-') /*
- * Accept GNU-style '--' options
- */
- option++;
- if (strcmp(option, "new") == 0)
- output_mode = NEW;
- else if (strcmp(option, "old") == 0)
- output_mode = OLD;
- else if (strcmp(option, "stubs") == 0)
- output_mode = STUBS;
- else if (strcmp(option, "proto") == 0)
- output_mode = PROTO;
- else if (strcmp(option, "pragma") == 0)
- output_mode = PRAGMA;
- else if (strcmp(option, "gatestubs")==0)
- output_mode=GATESTUBS;
- else if (strcmp(option, "powerup") == 0)
- PowerUP = TRUE;
- else if (strcmp(option, "morphos") == 0)
- MorphOS = TRUE;
- else if (strcmp(option, "reglib") == 0)
- RegLibFlag = TRUE;
- else if (strcmp(option, "prelib") == 0)
- {
- if (PostLibFlag)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- PreLibFlag = TRUE;
- }
- else if (strcmp(option, "postlib") == 0)
- {
- if (PreLibFlag)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- PostLibFlag = TRUE;
- }
- else if (strcmp(option, "local") == 0)
- {
- LocalFlag = TRUE;
- }
- else if (strcmp(option, "prefix") == 0)
- {
-
- if (count == argc - 1 || outfilename)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- if (strcmp(argv[++count], "-"))
- {
- prefixname = argv[count];
- }
- }
- else if (strcmp(option, "subprefix") == 0)
- {
-
- if (count == argc - 1 || outfilename)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- if (strcmp(argv[++count], "-"))
- {
- subprefixname = argv[count];
- }
- }
- else if (strcmp(option, "premacro") == 0)
- {
-
- if (count == argc - 1 || outfilename)
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- if (strcmp(argv[++count], "-"))
- {
- premacro = argv[count];
- }
- }
- else if (strcmp(option, "direct-varargs-calls") == 0)
- DirectVarargsCalls = TRUE;
- else if (strcmp(option, "version") == 0)
- {
- fprintf(stderr, "fd2inline version " VERSION "\n");
- return EXIT_SUCCESS;
- }
- else
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- }
- }
- else
- {
- /*
- * One of the filenames
- */
- if (!fdfilename)
- fdfilename = option;
- else if (!clibfilename)
- clibfilename = option;
- else if (!outfilename)
- outfilename = option;
- else
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
- }
- }
-
- if (!fdfilename || (!clibfilename && output_mode != PROTO))
- {
- printusage(argv[0]);
- return EXIT_FAILURE;
- }
-
- if (!(arrdefs = malloc(FDS * sizeof(fdDef *))))
- {
- fprintf(stderr, "No mem for FDs\n");
- return EXIT_FAILURE;
- }
- for (count = 0; count < FDS; count++)
- arrdefs[count] = NULL;
-
- if (!(myfile = fF_ctor(fdfilename)))
- {
- fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
- return EXIT_FAILURE;
- }
-
- lerror = false;
-
- for (count = 0; count < FDS && lerror == false; count++)
- {
- if (!(arrdefs[count] = fD_ctor()))
- {
- fprintf(stderr, "No mem for FDs\n");
- return EXIT_FAILURE;
- }
- do
- {
- if ((lerror = fF_readln(myfile)) == false)
- {
- fF_SetError(myfile, false);
- lerror = fD_parsefd(arrdefs[count], myfile);
- }
- }
- while (lerror == nodef);
- }
- if (count < FDS)
- {
- count--;
- fD_dtor(arrdefs[count]);
- arrdefs[count] = NULL;
- }
- fds = count;
-
- qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
-
- if (output_mode != NEW)
- {
- unsigned int count2;
-
- StdLib = "Library";
-
- for (count2 = 0; count2 < sizeof LibExcTable / sizeof LibExcTable[0]; count2 += 2)
- if (strcmp(BaseName, LibExcTable[count2]) == 0)
- {
- StdLib = LibExcTable[count2 + 1];
- break;
- }
- }
-
- fF_dtor(myfile);
-
- if (output_mode != PROTO)
- {
- if (!(myfile = fF_ctor(clibfilename)))
- {
- fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
- return EXIT_FAILURE;
- }
-
- if (!(tmpdef = fD_ctor()))
- {
- fprintf(stderr, "No mem for FDs\n");
- return EXIT_FAILURE;
- }
-
- for (lerror = false; lerror == false || lerror == nodef;)
- if ((lerror = fF_readln(myfile)) == false)
- {
- fF_SetError(myfile, false); /*
- * continue even on errors
- */
- tmpstr = fF_FuncName(myfile);
-
- if (tmpstr)
- {
- fdDef **res;
-
- fD_NewName(tmpdef, tmpstr);
- res = (fdDef **) bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
- fD_cmpName);
-
- if (res)
- {
- founddef = *res;
- DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
- fF_SetError(myfile, false);
- lerror = fD_parsepr(founddef, myfile);
- }
- else if (!ishandleddifferently(myfile->line, tmpstr))
- fprintf(stderr, "don't know what to do with <%s> in line %lu.\n",
- tmpstr, myfile->lineno);
- free(tmpstr);
- }
- }
-
- fD_dtor(tmpdef);
-
- fF_dtor(myfile);
- }
-
- if (strlen(fdfilename) > 7 &&
- !strcmp(fdfilename + strlen(fdfilename) - 7, "_lib.fd"))
- {
- char *str = fdfilename + strlen(fdfilename) - 8;
-
- while (str != fdfilename && str[-1] != '/' && str[-1] != ':')
- str--;
- strncpy(BaseNamL, str, strlen(str) - 7);
- strncpy(BaseNamU, str, strlen(str) - 7);
- BaseNamU[strlen(str) - 7] = '\0';
- }
- else
- {
- /*
- * Shouldn't really happen, but...
- */
- strcpy(BaseNamU, BaseName);
- if (strlen(BaseNamU) > 4 && strcmp(BaseNamU + strlen(BaseNamU) - 4, "Base") == 0)
- BaseNamU[strlen(BaseNamU) - 4] = '\0';
- }
- StrUpr(BaseNamU);
-
- if (outfilename)
- {
- if (!(outfile = fopen(outfilename, "w")))
- {
- fprintf(stderr, "Couldn't open output file.\n");
- return EXIT_FAILURE;
- }
- else
- {
- closeoutfile=TRUE;
- }
- }
- else
- {
- outfile = stdout;
- }
-
- if (output_mode == PROTO)
- {
- output_proto(outfile);
- }
- else
- {
- if (output_mode == NEW)
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _PPCINLINE_%s_H\n"
- "#define _PPCINLINE_%s_H\n\n"
- "#ifndef __PPCINLINE_MACROS_H\n"
- "#include <ppcinline/macros.h>\n"
- "#endif /* !__PPCINLINE_MACROS_H */\n\n",
- BaseNamU,
- BaseNamU);
- }
- else
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _INLINE_%s_H\n"
- "#define _INLINE_%s_H\n\n"
- "#ifndef __INLINE_MACROS_H\n"
- "#include <inline/macros.h>\n"
- "#endif /* !__INLINE_MACROS_H */\n\n",
- BaseNamU,
- BaseNamU);
- }
- }
- else if (output_mode == PRAGMA)
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _PPCPRAGMA_%s_H\n"
- "#define _PPCPRAGMA_%s_H\n"
- "#ifdef __GNUC__\n"
- "#ifndef _PPCINLINE__%s_H\n"
- "#include <ppcinline/%s.h>\n"
- "#endif\n"
- "#else\n\n"
- "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
- "#include <ppclib/interface.h>\n"
- "#endif\n\n"
- "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
- "#include <gcclib/powerup_protos.h>\n"
- "#endif\n\n"
- "#ifndef NO_PPCINLINE_STDARG\n"
- "#define NO_PPCINLINE_STDARG\n"
- "#endif"
- "/* SAS C PPC inlines */\n\n",
- BaseNamU,
- BaseNamU,
- BaseNamU,
- BaseNamL);
- }
- else
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _INLINE__%s_H\n"
- "#include <inline/%s.h>\n\n",
- BaseNamU,
- BaseNamL);
- }
-
- }
- else if (output_mode == GATESTUBS)
- {
- if (LocalFlag)
- {
- fprintf(outfile,
- "/* Automatically generated gate stubs */\n\n"
- "%s\n"
- "#include \"%s_protos.h\"\n\n"
- "#include <emul/emulregs.h>\n",
- premacro,
- BaseNamL);
- }
- else
- {
- fprintf(outfile,
- "/* Automatically generated gate stubs */\n\n"
- "%s\n"
- "#include <clib/%s_protos.h>\n\n"
- "#include <emul/emulregs.h>\n",
- premacro,
- BaseNamL);
- }
- }
- else
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _PPCINLINE_%s_H\n"
- "#define _PPCINLINE_%s_H\n\n"
- "#ifndef __PPCINLINE_STUB_H\n"
- "#include <ppcinline/stubs.h>\n"
- "#endif /* !__PPCINLINE_STUB_H */\n\n",
- BaseNamU,
- BaseNamU);
- if (MorphOS)
- fprintf(outfile, "#include <emul/emulregs.h>\n");
- }
- else
- {
- fprintf(outfile,
- "/* Automatically generated header! Do not edit! */\n\n"
- "#ifndef _INLINE_%s_H\n"
- "#define _INLINE_%s_H\n\n"
- "#ifndef __INLINE_STUB_H\n"
- "#include <inline/stubs.h>\n"
- "#endif /* !__INLINE_STUB_H */\n\n",
- BaseNamU,
- BaseNamU);
- }
- }
-
- if (BaseName[0])
- {
- if (output_mode == NEW || (output_mode == PRAGMA && (PowerUP == TRUE || MorphOS == TRUE)))
- {
- fprintf(outfile,
- "#ifndef %s_BASE_NAME\n"
- "#define %s_BASE_NAME %s\n"
- "#endif /* !%s_BASE_NAME */\n\n",
- BaseNamU, BaseNamU, BaseName, BaseNamU);
- }
- else
- {
- fprintf(outfile,
- "#ifndef BASE_EXT_DECL\n"
- "#define BASE_EXT_DECL\n"
- "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
- "#endif /* !BASE_EXT_DECL */\n"
- "#ifndef BASE_PAR_DECL\n"
- "#define BASE_PAR_DECL\n"
- "#define BASE_PAR_DECL0 void\n"
- "#endif /* !BASE_PAR_DECL */\n"
- "#ifndef BASE_NAME\n"
- "#define BASE_NAME %s\n"
- "#endif /* !BASE_NAME */\n\n"
- "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
- }
- }
-
- for (count = 0; count < FDS && arrdefs[count]; count++)
- {
- DBP(fprintf(stderr, "outputting %ld...\n", count));
-
- fD_write(outfile, arrdefs[count]);
- fD_dtor(arrdefs[count]);
- arrdefs[count] = NULL;
- }
-
- if (output_mode == OLD || output_mode == STUBS)
- {
- if (BaseName[0])
- {
- fprintf(outfile,
- "#undef BASE_EXT_DECL\n"
- "#undef BASE_EXT_DECL0\n"
- "#undef BASE_PAR_DECL\n"
- "#undef BASE_PAR_DECL0\n"
- "#undef BASE_NAME\n\n");
- }
-
- if (PowerUP || MorphOS)
- {
- fprintf(outfile, "#endif /* !_PPCINLINE_%s_H */\n", BaseNamU);
- }
- else
- {
- fprintf(outfile, "#endif /* !_INLINE_%s_H */\n", BaseNamU);
- }
- }
- else if (output_mode == PRAGMA)
- {
- fprintf(outfile, "#endif /* SASC Pragmas */\n");
- if (PowerUP || MorphOS)
- {
- fprintf(outfile, "#endif /* !_PPCPRAGMA_%s_H */\n", BaseNamU);
- }
- else
- {
- fprintf(outfile, "#endif /* !_PRAGMA_%s_H */\n", BaseNamU);
- }
- }
- else if (output_mode == NEW)
- {
- if (PowerUP || MorphOS)
- {
- fprintf(outfile, "#endif /* !_PPCINLINE_%s_H */\n", BaseNamU);
- }
- else
- {
- fprintf(outfile, "#endif /* !_INLINE_%s_H */\n", BaseNamU);
- }
- }
-
- }
-
- free(arrdefs);
- if (closeoutfile)
- {
- fclose(outfile);
- }
- return EXIT_SUCCESS;
- }
-