home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / System / MorphOS / Developer / emultools / fd2inline / fd2inline.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-02  |  72.3 KB  |  3,253 lines

  1. /******************************************************************************
  2.  *
  3.  * fd2inline
  4.  *
  5.  * Should be able to parse CBM fd files and generate vanilla inline calls
  6.  * for gcc. Works as a filter.
  7.  *
  8.  * by Wolfgang Baron, all rights reserved.
  9.  *
  10.  * improved, updated, simply made workable by Rainer F. Trunz 1/95
  11.  *
  12.  * Completely reworked Version, cleaned up and removed a whole lot of bugs
  13.  * found by Kamil Iskra.
  14.  *
  15.  * Expect miracles now (hopefully...). Ok, I am just kidding :)
  16.  *
  17.  * Version 0.99a by Rainer F. Trunz 6/95
  18.  *
  19.  * Version 0.99b and later by Kamil Iskra.
  20.  *
  21.  * Version 1.12 by Ralph Schmidt
  22.  *              PowerUP GCC/SAS extensions
  23.  *              I hope Kamil Iskra integrates that
  24.  *              in the official ADE version.
  25.  *
  26.  * Version 2.00 by Ralph Schmidt and Emmanuel Leseur
  27.  *              Adding MorphOS support and a variety of new options
  28.  ******************************************************************************/
  29.  
  30. /*
  31.  * My whole ixemul includes are messed up * so this is hacky fix 
  32.  */
  33.  
  34. #include <ctype.h>
  35. #include <stddef.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39.  
  40. /******************************************************************************
  41.  * The program has a few sort of class definitions, which are the result of
  42.  * object oriented thinking, to be imlemented in plain C. I just haven't
  43.  * had the time to learn C++ or install the compiler. The design does however
  44.  * improve robustness, which allows the source to be used over and over again.
  45.  * if you use this code, please leave a little origin note.
  46.  ******************************************************************************/
  47.  
  48. const static char version_str[] = "$VER: fd2inline " VERSION " (12.12.97)";
  49.  
  50. /******************************************************************************
  51.  * These are general definitions including types for defining registers etc.
  52.  ******************************************************************************/
  53.  
  54. #ifdef DEBUG
  55. #define DBP(a) a
  56. #else  /*
  57.         * !DEBUG 
  58.         */
  59. #define DBP(a)
  60. #endif /*
  61.         * !DEBUG 
  62.         */
  63.  
  64. #if (defined(__GNUC__) || defined(__SASC)) && 0
  65. #define INLINE __inline                            /*
  66.                                         * Gives 20% *larger* executable with GCC?! 
  67.                                         */
  68. #else
  69. #define INLINE
  70. #endif
  71.  
  72. #define REGS 16                                            /*
  73.                                         * d0=0,...,a7=15 
  74.                                         */
  75. #define FDS 1000
  76.  
  77. typedef enum
  78. {
  79.     d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
  80. }
  81. regs;
  82.  
  83. typedef unsigned char uchar, shortcard;
  84. typedef unsigned long ulong;
  85.  
  86. #ifndef  FALSE
  87. #define  FALSE 0
  88. #endif
  89. #ifndef  TRUE
  90. #define  TRUE  1
  91. #endif
  92.  
  93. typedef enum
  94. {
  95.     false, nodef, real_error
  96. }
  97. Error;
  98.  
  99. enum
  100. {
  101.     NEW, OLD, STUBS, PROTO, PRAGMA, GATESTUBS
  102. }
  103. output_mode = NEW;
  104.  
  105. int DirectVarargsCalls = 0;
  106. int PowerUP = 0, MorphOS = 0;
  107. int RegLibFlag = 0;
  108. int PreLibFlag = 0;
  109. int PostLibFlag = 0;
  110. int LocalFlag = 0;
  111. char *prefixname = "";
  112. char *subprefixname = "";
  113. char *premacro = "";
  114.  
  115. char BaseName[32 + 32], BaseNamU[32 + 32], BaseNamL[32 + 32];
  116. char    Buffer[512];
  117.  
  118. const static char *LibExcTable[] =
  119. {
  120.     "BattClockBase", "Node",
  121.     "BattMemBase", "Node",
  122.     "ConsoleDevice", "Device",
  123.     "DiskBase", "DiskResource",
  124.     "DOSBase", "DosLibrary",
  125.     "SysBase", "ExecBase",
  126.     "ExpansionBase", "ExpansionBase",
  127.     "GfxBase", "GfxBase",
  128.     "InputBase", "Device",
  129.     "IntuitionBase", "IntuitionBase",
  130.     "LocaleBase", "LocaleBase",
  131.     "MathIeeeDoubBasBase", "MathIEEEBase",
  132.     "MathIeeeDoubTransBase", "MathIEEEBase",
  133.     "MathIeeeSingBasBase", "MathIEEEBase",
  134.     "MathIeeeSingTransBase", "MathIEEEBase",
  135.     "MiscBase", "Node",
  136.     "PotgoBase", "Node",
  137.     "RamdriveDevice", "Device",
  138.     "RealTimeBase", "RealTimeBase",
  139.     "RexxSysBase", "RxsLib",
  140.     "TimerBase", "Device",
  141.     "UtilityBase", "UtilityBase"
  142. };
  143. const char *StdLib;                                        /*
  144.  
  145.                                         * global lib-name ptr 
  146.                                         */
  147.  
  148. /*******************************************
  149.  * just some support functions, no checking
  150.  *******************************************/
  151.  
  152. char *
  153. NewString(char **new, const char *old)
  154. {
  155.     const char *high;
  156.     ulong len;
  157.  
  158.     while (*old && (*old == ' ' || *old == '\t'))
  159.         old++;
  160.     len = strlen(old);
  161.     for (high = old + len - 1; high >= old && (*high == ' ' || *high == '\t'); high--) ;
  162.     high++;
  163.     len = high - old;
  164.     *new = malloc(1 + len);
  165.     if (*new)
  166.     {
  167.         strncpy(*new, old, len);
  168.         (*new)[len] = '\0';
  169.     }
  170.     else
  171.         fprintf(stderr, "no mem for string\n");
  172.     return *new;
  173. }
  174.  
  175. static INLINE void
  176. illparams(const char *funcname)
  177. {
  178.     fprintf(stderr, "%s: illegal Parameters\n", funcname);
  179. }
  180.  
  181. static INLINE const char *
  182. RegStr(regs reg)
  183. {
  184.     const static char *myregs[] =
  185.     {
  186.         "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  187.         "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
  188.     };
  189.  
  190.     if (reg > illegal)
  191.         reg = illegal;
  192.     if (reg < d0)
  193.         reg = d0;
  194.     return myregs[reg];
  195. }
  196.  
  197. static INLINE const char *
  198. RegStrU(regs reg)
  199. {
  200.     const static char *myregs[] =
  201.     {
  202.         "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
  203.         "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
  204.     };
  205.  
  206.     if (reg > illegal)
  207.         reg = illegal;
  208.     if (reg < d0)
  209.         reg = d0;
  210.     return myregs[reg];
  211. }
  212.  
  213. /******************************************************************************
  214.  *    StrNRBrk
  215.  *
  216.  * searches string in from position at downwards, as long as in does not
  217.  * contain any character in not.
  218.  *
  219.  ******************************************************************************/
  220.  
  221. const char *
  222. StrNRBrk(const char *in, const char *not, const char *at)
  223. {
  224.     const char *chcheck;
  225.     Error ready;
  226.  
  227.     chcheck = "";                                      /*
  228.                                         * if at<in, the result will be NULL 
  229.                                         */
  230.     for (ready = false; ready == false && at >= in;)
  231.     {
  232.         for (chcheck = not; *chcheck && *chcheck != *at; chcheck++) ;
  233.         if (*chcheck)
  234.             ready = real_error;
  235.         else
  236.             at--;
  237.     }
  238.     DBP(fprintf(stderr, "{%c}", *chcheck));
  239.     return *chcheck ? at : NULL;
  240. }
  241.  
  242. /*
  243.  * Our own "strupr", since it is a non-standard function. 
  244.  */
  245. void
  246. StrUpr(char *str)
  247. {
  248.     while (*str)
  249.     {
  250.         *str = toupper(*str);
  251.         str++;
  252.     }
  253. }
  254.  
  255. /******************************************************************************
  256.  *    CLASS fdFile
  257.  *
  258.  * stores a file with a temporary buffer (static length, sorry), a line number,
  259.  * an offset (used for library offsets and an error field.
  260.  * When there's no error, line will contain line #lineno and offset will be
  261.  * the last offset set by the interpretation of the last line. If there's been
  262.  * no ##bias line, this field assumes a bias of 30, which is the standard bias.
  263.  * It is assumed offsets are always negative.
  264.  ******************************************************************************/
  265.  
  266. #define fF_BUFSIZE 1024
  267.  
  268. /*
  269.  * all you need to know about an fdFile you parse 
  270.  */
  271.  
  272. typedef struct
  273. {
  274.     FILE *file;                                                /*
  275.                                         * the file we're reading from      
  276.                                         */
  277.     char line[fF_BUFSIZE];                     /*
  278.                                         * the current line                 
  279.                                         */
  280.     ulong lineno;                                      /*
  281.                                         * current line number              
  282.                                         */
  283.     long offset;                                       /*
  284.                                         * current fd offset (-bias)        
  285.                                         */
  286.     Error error;                                       /*
  287.                                         * is everything o.k.               
  288.                                         */
  289.     char private;                                      /*
  290.                                         * are we in ##public or ##private  
  291.                                         */
  292. }
  293. fdFile;
  294.  
  295. fdFile *
  296.  fF_ctor(const char *fname);
  297. static void
  298.  fF_dtor(fdFile * obj);
  299. static void
  300.  fF_SetError(fdFile * obj, Error error);
  301. static void
  302.  fF_SetOffset(fdFile * obj, long at);
  303.  
  304. Error
  305. fF_readln(fdFile * obj);
  306. static Error
  307.  fF_GetError(const fdFile * obj);
  308. static long
  309.  fF_GetOffset(const fdFile * obj);
  310. char *
  311.  fF_FuncName(fdFile * obj);                        /*
  312.  
  313.                                         * return name or null 
  314.                                         */
  315. static void
  316.  fF_SetPrivate(fdFile * obj, char priv);
  317. static char
  318.  fF_GetPrivate(const fdFile * obj);
  319.  
  320. static INLINE void
  321. fF_dtor(fdFile * obj)
  322. {
  323.     fclose(obj->file);
  324.     free(obj);
  325. }
  326.  
  327. static INLINE void
  328. fF_SetError(fdFile * obj, Error error)
  329. {
  330.     if (obj)
  331.         obj->error = error;
  332.     else
  333.         illparams("fF_SetError");
  334. }
  335.  
  336. static INLINE void
  337. fF_SetOffset(fdFile * obj, long at)
  338. {
  339.     if (obj)
  340.         obj->offset = at;
  341.     else
  342.         illparams("fFSetOffset");
  343. }
  344.  
  345. static INLINE void
  346. fF_SetPrivate(fdFile * obj, char priv)
  347. {
  348.     if (obj)
  349.         obj->private = priv;
  350.     else
  351.         illparams("fF_SetPrivate");
  352. }
  353.  
  354. fdFile *
  355. fF_ctor(const char *fname)
  356. {
  357.     fdFile *result;
  358.  
  359.     if (fname)
  360.     {
  361.         result = malloc(sizeof(fdFile));
  362.         if (result)
  363.         {
  364.             result->file = fopen(fname, "r");
  365.             if (result->file)
  366.             {
  367.                 result->lineno = 0;
  368.                 fF_SetOffset(result, -30);
  369.                 fF_SetError(result, false);
  370.                 fF_SetPrivate(result, 0);
  371.                 result->line[0] = '\0';
  372.             }
  373.             else
  374.             {
  375.                 free(result);
  376.                 result = NULL;
  377.             }
  378.         }
  379.     }
  380.     else
  381.     {
  382.         result = NULL;
  383.         illparams("fF_ctor");
  384.     }
  385.     return result;
  386. }
  387.  
  388. Error
  389. fF_readln(fdFile * obj)
  390. {
  391.     char *low, *bpoint;
  392.     long glen,                                                 /*
  393.                                         * the length we read until now 
  394.                                         */
  395.      len;                                                      /*
  396.  
  397.                                         * the length of the last segment 
  398.                                         */
  399.  
  400.     if (obj)
  401.     {
  402.         low = obj->line;
  403.         glen = 0;
  404.  
  405.         for (;;)
  406.         {
  407.             obj->lineno++;
  408.             if (!fgets(low, fF_BUFSIZE - 1 - glen, obj->file))
  409.             {
  410.                 fF_SetError(obj, real_error);
  411.                 obj->line[0] = '\0';
  412.                 return real_error;
  413.             }
  414.             if (low == strpbrk(low, "*#/"))
  415.             {
  416.                 DBP(fprintf(stderr, "in# %s\n", obj->line));
  417.                 return false;
  418.             }
  419.             len = strlen(low);
  420.             bpoint = low + len - 1;
  421.             while (len && isspace(*bpoint))
  422.             {
  423.                 bpoint--;
  424.                 len--;
  425.             }
  426.             if (*bpoint == ';' || *bpoint == ')')
  427.             {
  428.                 DBP(fprintf(stderr, "\nin: %s\n", obj->line));
  429.                 return false;
  430.             }
  431.             glen += len;
  432.             low += len;
  433.             if (glen >= fF_BUFSIZE - 10)    /*
  434.                                              * somewhat pessimistic? 
  435.                                              */
  436.             {
  437.                 fF_SetError(obj, real_error);
  438.                 fprintf(stderr, "line %lu too long.\n", obj->lineno);
  439.                 return real_error;
  440.             }
  441.             DBP(fprintf(stderr, "+"));
  442.         }
  443.     }
  444.     illparams("fF_readln");
  445.     return real_error;
  446. }
  447.  
  448. static INLINE Error
  449. fF_GetError(const fdFile * obj)
  450. {
  451.     if (obj)
  452.         return obj->error;
  453.     illparams("fF_GetError");
  454.     return real_error;
  455. }
  456.  
  457. static INLINE long
  458. fF_GetOffset(const fdFile * obj)
  459. {
  460.     if (obj)
  461.         return obj->offset;
  462.     illparams("fF_GetOffset");
  463.     return -1;
  464. }
  465.  
  466. /******************************************************************************
  467.  * fF_FuncName
  468.  *
  469.  * checks if it can find a function-name and return it's address, or NULL
  470.  * if the current line does not seem to contain one. The return value will
  471.  * be a pointer into a malloced buffer, thus the caller will have to free().
  472.  ******************************************************************************/
  473.  
  474. char *
  475. fF_FuncName(fdFile * obj)
  476. {
  477.     const char *lower;
  478.     const char *upper;
  479.     char *buf;
  480.     long obraces;                                      /*
  481.  
  482.                                         * count of open braces 
  483.                                         */
  484.     Error ready;                                       /*
  485.  
  486.                                         * ready with searching 
  487.                                         */
  488.  
  489.     if (!obj || fF_GetError(obj) == real_error)
  490.     {
  491.         illparams("fF_FuncName");
  492.         return NULL;
  493.     }
  494.  
  495.     lower = obj->line;
  496.     while (*lower && (*lower == ' ' || *lower == '\t'))
  497.         lower++;
  498.  
  499.     if (!*lower || (!isalpha(*lower) && *lower != '_'))
  500.     {
  501.         fF_SetError(obj, nodef);
  502.         return NULL;
  503.     }
  504.  
  505.     while (*lower)
  506.     {
  507.         if (!isalnum(*lower) && !isspace(*lower) && *lower != '*' && *lower != ','
  508.             && *lower != '.' && *lower != ';' && *lower != '(' && *lower != ')' &&
  509.             *lower != '[' && *lower != ']' && *lower != '_' && *lower != '\\')
  510.         {
  511.             fF_SetError(obj, nodef);
  512.             return NULL;
  513.         }
  514.         lower++;
  515.     }
  516.  
  517.     lower = NULL;
  518.     buf = NULL;
  519.  
  520.     if (obj && fF_GetError(obj) == false)
  521.     {
  522.         if ((upper = strrchr(obj->line, ')')) != 0)
  523.         {
  524.             DBP(fprintf(stderr, "end:%s:", upper));
  525.  
  526.             for (obraces = 1, ready = false; ready == false; upper = lower)
  527.             {
  528.                 lower = StrNRBrk(obj->line, "()", --upper);
  529.                 if (lower)
  530.                 {
  531.                     switch (*lower)
  532.                      {
  533.                      case ')':
  534.                          obraces++;
  535.                          DBP(fprintf(stderr, " )%ld%s", obraces, lower));
  536.                          break;
  537.                      case '(':
  538.                          obraces--;
  539.                          DBP(fprintf(stderr, " (%ld%s", obraces, lower));
  540.                          if (!obraces)
  541.                              ready = nodef;
  542.                          break;
  543.                      default:
  544.                          fprintf(stderr, "faulty StrNRBrk\n");
  545.                      }
  546.                 }
  547.                 else
  548.                 {
  549.                     fprintf(stderr, "'(' or ')' expected in line %lu.\n",
  550.                             obj->lineno);
  551.                     ready = real_error;
  552.                 }
  553.             }
  554.             if (ready == nodef)                /*
  555.                                         * we found the matching '(' 
  556.                                         */
  557.             {
  558.                 long newlen;
  559.                 const char *name;
  560.  
  561.                 upper--;
  562.  
  563.                 while (upper >= obj->line && (*upper == ' ' || *upper == '\t'))
  564.                     upper--;
  565.  
  566.                 lower = StrNRBrk(obj->line, " \t*)", upper);
  567.  
  568.                 if (!lower)
  569.                     lower = obj->line;
  570.                 else
  571.                     lower++;
  572.  
  573.                 for (name = lower; name <= upper; name++)
  574.                     if (!isalnum(*name) && *name != '_')
  575.                     {
  576.                         fF_SetError(obj, nodef);
  577.                         return NULL;
  578.                     }
  579.  
  580.                 newlen = upper - lower + 1;
  581.                 buf = malloc(newlen + 1);
  582.  
  583.                 if (buf)
  584.                 {
  585.                     strncpy(buf, lower, newlen);
  586.                     buf[newlen] = '\0';
  587.                 }
  588.                 else
  589.                     fprintf(stderr, "no mem for fF_FuncName");
  590.             }
  591.         }
  592.     }
  593.     else
  594.         illparams("fF_FuncName");
  595.     return buf;
  596. }
  597.  
  598. static INLINE char
  599. fF_GetPrivate(const fdFile * obj)
  600. {
  601.     if (obj)
  602.         return obj->private;
  603.     illparams("fF_GetPrivate");
  604.     return 0;
  605. }
  606.  
  607. /*********************
  608.  *    CLASS fdDef    *
  609.  *********************/
  610.  
  611. typedef struct
  612. {
  613.     char *name;
  614.     char *type;
  615.     long offset;
  616.     regs reg[REGS];
  617.     char *param[REGS];
  618.     char *proto[REGS];
  619.     regs funcpar;                                      /*
  620.                                         * number of argument that has type "pointer to function" 
  621.                                         */
  622. }
  623. fdDef;
  624.  
  625. fdDef *
  626.  fD_ctor(void);
  627. void
  628.  fD_dtor(fdDef * obj);
  629. static void
  630.  fD_NewName(fdDef * obj, const char *newname);
  631. void
  632.  fD_NewParam(fdDef * obj, shortcard at, const char *newstr);
  633. void
  634.  fD_NewProto(fdDef * obj, shortcard at, char *newstr);
  635. static void
  636.  fD_NewReg(fdDef * obj, shortcard at, regs reg);
  637. static void
  638.  fD_NewType(fdDef * obj, const char *newstr);
  639. static void
  640.  fD_SetOffset(fdDef * obj, long off);
  641.  
  642. Error
  643. fD_parsefd(fdDef * obj, fdFile * infile);
  644. Error
  645. fD_parsepr(fdDef * obj, fdFile * infile);
  646. static const char *
  647.  fD_GetName(const fdDef * obj);
  648. static long
  649.  fD_GetOffset(const fdDef * obj);
  650. static const char *
  651.  fD_GetParam(const fdDef * obj, shortcard at);
  652. static regs
  653.  fD_GetReg(const fdDef * obj, shortcard at);
  654. static const char *
  655.  fD_GetRegStr(const fdDef * obj, shortcard at);
  656. static const char *
  657.  fD_GetType(const fdDef * obj);
  658. static shortcard
  659.  fD_ParamNum(const fdDef * obj);
  660. static shortcard
  661.  fD_ProtoNum(const fdDef * obj);
  662. static shortcard
  663.  fD_RegNum(const fdDef * obj);
  664. int
  665.  fD_cmpName(const void *big, const void *small);
  666. void
  667.  fD_write(FILE * outfile, const fdDef * obj);
  668. static shortcard
  669.  fD_GetFuncParNum(const fdDef * obj);
  670. static void
  671.  fD_SetFuncParNum(fdDef * obj, shortcard at);
  672. static void
  673.  fD_adjustargnames(fdDef * obj);
  674.  
  675. fdDef **arrdefs;
  676. long fds;
  677.  
  678. char *fD_nostring = "";
  679.  
  680. fdDef *
  681. fD_ctor(void)
  682. {
  683.     fdDef *result;
  684.     regs count;
  685.  
  686.     result = malloc(sizeof(fdDef));
  687.  
  688.     if (result)
  689.     {
  690.         result->name = fD_nostring;
  691.         result->type = fD_nostring;
  692.         result->funcpar = illegal;
  693.  
  694.         for (count = d0; count < illegal; count++)
  695.         {
  696.             result->reg[count] = illegal;
  697.             result->param[count] = fD_nostring;             /*
  698.                                                      * if (!strlen) dont't free() 
  699.                                                      */
  700.             result->proto[count] = fD_nostring;
  701.         }
  702.     }
  703.     return result;
  704. }
  705.  
  706. /*
  707.  * free all resources and make the object as illegal as possible 
  708.  */
  709.  
  710. void
  711. fD_dtor(fdDef * obj)
  712. {
  713.     regs count;
  714.  
  715.     if (obj)
  716.     {
  717.         if (!obj->name)
  718.             fprintf(stderr, "fD_dtor: null name");
  719.         else if (obj->name != fD_nostring)
  720.             free(obj->name);
  721.  
  722.         if (!obj->type)
  723.             fprintf(stderr, "fD_dtor: null type");
  724.         else if (obj->type != fD_nostring)
  725.             free(obj->type);
  726.  
  727.         obj->name = obj->type = NULL;
  728.  
  729.         for (count = d0; count < illegal; count++)
  730.         {
  731.             obj->reg[count] = illegal;
  732.  
  733.             if (!obj->param[count])
  734.                 fprintf(stderr, "fD_dtor: null param");
  735.             else if (obj->param[count] != fD_nostring)
  736.                 free(obj->param[count]);
  737.  
  738.             if (!obj->proto[count])
  739.                 fprintf(stderr, "fD_dtor: null proto");
  740.             else if (obj->proto[count] != fD_nostring)
  741.                 free(obj->proto[count]);
  742.  
  743.             obj->param[count] = obj->proto[count] = NULL;
  744.         }
  745.  
  746.         free(obj);
  747.     }
  748.     else
  749.         fprintf(stderr, "fd_dtor(NULL)\n");
  750. }
  751.  
  752. static INLINE void
  753. fD_NewName(fdDef * obj, const char *newname)
  754. {
  755.     if (obj && newname)
  756.     {
  757.         if (obj->name && obj->name != fD_nostring)
  758.             free(obj->name);
  759.         if (!NewString(&obj->name, newname))
  760.             obj->name = fD_nostring;
  761.     }
  762.     else
  763.         illparams("fD_NewName");
  764. }
  765.  
  766. void
  767. fD_NewParam(fdDef * obj, shortcard at, const char *newstr)
  768. {
  769.     char *pa;
  770.  
  771.     if (newstr && obj && at < illegal)
  772.     {
  773.         pa = obj->param[at];
  774.  
  775.         if (pa && pa != fD_nostring)
  776.             free(pa);
  777.  
  778.         while (*newstr == ' ' || *newstr == '\t')
  779.             newstr++;
  780.  
  781.         if (NewString(&pa, newstr))
  782.             obj->param[at] = pa;
  783.         else
  784.             obj->param[at] = fD_nostring;
  785.     }
  786.     else
  787.         illparams("fD_NewParam");
  788. }
  789.  
  790. /*
  791.  * get first free *reg or illegal 
  792.  */
  793.  
  794. static INLINE shortcard
  795. fD_RegNum(const fdDef * obj)
  796. {
  797.     shortcard count;
  798.  
  799.     if (obj)
  800.     {
  801.         for (count = d0; count < illegal && obj->reg[count] != illegal; count++) ;
  802.         DBP(fprintf(stderr, "< )0> RegNum=%ld",count));
  803.         return count;
  804.     }
  805.     else
  806.     {
  807.         illparams("fD_RegNum");
  808.         DBP(fprintf(stderr, "< )0> RegNum illegal"));
  809.         return illegal;
  810.     }
  811. }
  812.  
  813. static INLINE void
  814. fD_NewReg(fdDef * obj, shortcard at, regs reg)
  815. {
  816.     if (obj && at < illegal && reg >= d0 && reg <= illegal)
  817.         obj->reg[at] = reg;
  818.     else
  819.         illparams("fD_NewReg");
  820. }
  821.  
  822. static INLINE regs
  823. fD_GetReg(const fdDef * obj, shortcard at)
  824. {
  825.     if (obj && at < illegal)
  826.         return obj->reg[at];
  827.     else
  828.     {
  829.         illparams("fD_GetReg");
  830.         return illegal;
  831.     }
  832. }
  833.  
  834. static INLINE shortcard
  835. fD_GetFuncParNum(const fdDef * obj)
  836. {
  837.     if (obj)
  838.         return (shortcard) obj->funcpar;
  839.     else
  840.     {
  841.         illparams("fD_GetFuncParNum");
  842.         return illegal;
  843.     }
  844. }
  845.  
  846. static INLINE void
  847. fD_SetFuncParNum(fdDef * obj, shortcard at)
  848. {
  849.     if (obj && at < illegal)
  850.         obj->funcpar = at;
  851.     else
  852.         illparams("fD_SetFuncParNum");
  853. }
  854.  
  855. void
  856. fD_NewProto(fdDef * obj, shortcard at, char *newstr)
  857. {
  858.     char *pr;
  859.  
  860.     if (newstr && obj && at < illegal)
  861.     {
  862.         char *t, arr[200];                         /*
  863.  
  864.                                         * I hope 200 will be enough... 
  865.                                         */
  866.         int numwords = 1;
  867.  
  868.         pr = obj->proto[at];
  869.  
  870.         if (pr && pr != fD_nostring)
  871.             free(pr);
  872.  
  873.         while (*newstr == ' ' || *newstr == '\t')
  874.             newstr++;                                  /*
  875.                                         * Skip leading spaces 
  876.                                         */
  877.  
  878.         t = arr;
  879.         while ((*t++ = *newstr) != 0)
  880.         {
  881.           /*
  882.            * Copy the rest, counting number of words 
  883.            */
  884.             if ((*newstr == ' ' || *newstr == '\t') && newstr[1] && newstr[1] != ' ' &&
  885.                 newstr[1] != '\t')
  886.                 numwords++;
  887.             newstr++;
  888.         }
  889.  
  890.         t = arr + strlen(arr) - 1;
  891.         while (*t == ' ' || *t == '\t')
  892.             t--;
  893.         t[1] = '\0';                               /*
  894.                                         * Get rid of tailing spaces 
  895.                                         */
  896.         if (at != fD_GetFuncParNum(obj))
  897.         {
  898.             if (numwords > 1)                  /*
  899.                                         * One word - must be type 
  900.                                         */
  901.                 if (*t != '*')
  902.                 {
  903.                   /*
  904.                    * '*' on the end - no parameter name used 
  905.                    */
  906.                     while (*t != ' ' && *t != '\t' && *t != '*')
  907.                         t--;
  908.                     t++;
  909.                     if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
  910.                         && strcmp(t, "long"))
  911.                     {
  912.                       /*
  913.                        * Not one of applicable keywords - must be parameter name.
  914.                        * Get rid of it. 
  915.                        */
  916.                         t--;
  917.                         while (*t == ' ' || *t == '\t')
  918.                             t--;
  919.                         t[1] = '\0';
  920.                     }
  921.                 }
  922.         }
  923.         else
  924.         {
  925.           /*
  926.            * Parameter of type "pointer to function". 
  927.            */
  928.             char *end;
  929.  
  930.             t = strchr(arr, '(');
  931.             while (*t++ != '*') ;
  932.             end = strchr(t, ')');
  933.             memmove(t + 2, end, strlen(end) + 1);
  934.             *t = '%';
  935.             t[1] = 's';
  936.         }
  937.  
  938.         if (NewString(&pr, arr))
  939.         {
  940.             obj->proto[at] = pr;
  941.             while (*pr == ' ' || *pr == '\t')
  942.                 pr++;
  943.             if (!stricmp(pr, "double"))
  944.             {
  945.               /*
  946.                * "double" needs two data registers 
  947.                */
  948.                 int count, regs = fD_RegNum(obj);
  949.  
  950.                 for (count = at + 1; count < regs; count++)
  951.                     fD_NewReg(obj, count, fD_GetReg(obj, count + 1));
  952.             }
  953.         }
  954.         else
  955.             obj->proto[at] = fD_nostring;
  956.     }
  957.     else
  958.         illparams("fD_NewProto");
  959. }
  960.  
  961. static INLINE void
  962. fD_NewType(fdDef * obj, const char *newtype)
  963. {
  964.     if (obj && newtype)
  965.     {
  966.         if (obj->type && obj->type != fD_nostring)
  967.             free(obj->type);
  968.         if (!NewString(&obj->type, newtype))
  969.             obj->type = fD_nostring;
  970.     }
  971.     else
  972.         illparams("fD_NewType");
  973. }
  974.  
  975. static INLINE void
  976. fD_SetOffset(fdDef * obj, long off)
  977. {
  978.     if (obj)
  979.         obj->offset = off;
  980.     else
  981.         illparams("fD_SetOffset");
  982. }
  983.  
  984. static INLINE const char *
  985. fD_GetName(const fdDef * obj)
  986. {
  987.     if (obj && obj->name)
  988.         return obj->name;
  989.     else
  990.     {
  991.         illparams("fD_GetName");
  992.         return fD_nostring;
  993.     }
  994. }
  995.  
  996. static INLINE long
  997. fD_GetOffset(const fdDef * obj)
  998. {
  999.     if (obj)
  1000.         return obj->offset;
  1001.     else
  1002.     {
  1003.         illparams("fD_GetOffset");
  1004.         return 0;
  1005.     }
  1006. }
  1007.  
  1008. static INLINE const char *
  1009. fD_GetProto(const fdDef * obj, shortcard at)
  1010. {
  1011.     if (obj && at < illegal && obj->proto[at])
  1012.         return obj->proto[at];
  1013.     else
  1014.     {
  1015.         illparams("fD_GetProto");
  1016.         return fD_nostring;
  1017.     }
  1018. }
  1019.  
  1020. static INLINE const char *
  1021. fD_GetParam(const fdDef * obj, shortcard at)
  1022. {
  1023.     if (obj && at < illegal && obj->param[at])
  1024.         return obj->param[at];
  1025.     else
  1026.     {
  1027.         illparams("fD_GetParam");
  1028.         return fD_nostring;
  1029.     }
  1030. }
  1031.  
  1032. static INLINE const char *
  1033. fD_GetRegStr(const fdDef * obj, shortcard at)
  1034. {
  1035.     if (obj && at < illegal)
  1036.         return RegStr(obj->reg[at]);
  1037.     else
  1038.     {
  1039.         illparams("fD_GetReg");
  1040.         return RegStr(illegal);
  1041.     }
  1042. }
  1043.  
  1044. static INLINE const char *
  1045. fD_GetRegStrU(const fdDef * obj, shortcard at)
  1046. {
  1047.     if (obj && at < illegal)
  1048.         return RegStrU(obj->reg[at]);
  1049.     else
  1050.     {
  1051.         illparams("fD_GetReg");
  1052.         return RegStrU(illegal);
  1053.     }
  1054. }
  1055.  
  1056. static INLINE const char *
  1057. fD_GetType(const fdDef * obj)
  1058. {
  1059.     if (obj && obj->type)
  1060.         return obj->type;
  1061.     else
  1062.     {
  1063.         illparams("fD_GetType");
  1064.         return fD_nostring;
  1065.     }
  1066. }
  1067.  
  1068. /*
  1069.  * get first free param or illegal 
  1070.  */
  1071.  
  1072. static INLINE shortcard
  1073. fD_ParamNum(const fdDef * obj)
  1074. {
  1075.     shortcard count;
  1076.  
  1077.     if (obj)
  1078.     {
  1079.         for (count = d0; count < illegal && obj->param[count] != fD_nostring;
  1080.              count++) ;
  1081.         return count;
  1082.     }
  1083.     else
  1084.     {
  1085.         illparams("fD_ParamNum");
  1086.         return illegal;
  1087.     }
  1088. }
  1089.  
  1090. static INLINE shortcard
  1091. fD_ProtoNum(const fdDef * obj)
  1092. {
  1093.     shortcard count;
  1094.  
  1095.     if (obj)
  1096.     {
  1097.         for (count = d0; count < illegal && obj->proto[count] != fD_nostring;
  1098.              count++) ;
  1099.         return count;
  1100.     }
  1101.     else
  1102.     {
  1103.         illparams("fD_ProtoNum");
  1104.         return illegal;
  1105.     }
  1106. }
  1107.  
  1108. /******************************************************************************
  1109.  *    fD_parsefd
  1110.  *
  1111.  *  parse the current line. Needs to copy input, in order to insert \0's
  1112.  *  RETURN
  1113.  *    fF_GetError(infile):
  1114.  * false = read a definition.
  1115.  * nodef = not a definition on line (so try again)
  1116.  * error = real error
  1117.  ******************************************************************************/
  1118.  
  1119. Error
  1120. fD_parsefd(fdDef * obj, fdFile * infile)
  1121. {
  1122.     enum parse_info
  1123.     {
  1124.         name, params, regs, ready
  1125.     }
  1126.     parsing;
  1127.     char *buf, *bpoint, *bnext;
  1128.     ulong index;
  1129.  
  1130.     if (obj && infile && fF_GetError(infile) == false)
  1131.     {
  1132.         parsing = name;
  1133.  
  1134.         if (!NewString(&buf, infile->line))
  1135.         {
  1136.             fprintf(stderr, "no mem for line %lu\n", infile->lineno);
  1137.             fF_SetError(infile, real_error);
  1138.         }
  1139.         bpoint = buf;                              /*
  1140.                                         * so -Wall keeps quiet 
  1141.                                         */
  1142.  
  1143.       /*
  1144.        * try to parse the line until there's an error or we are done 
  1145.        */
  1146.  
  1147.         while (parsing != ready && fF_GetError(infile) == false)
  1148.         {
  1149.             switch (parsing)
  1150.              {
  1151.              case name:
  1152.                  switch (buf[0])
  1153.                   {
  1154.                   case '#':
  1155.                       if (strncmp("##base", buf, 6) == 0)
  1156.                       {
  1157.                           bnext = buf + 6;
  1158.                           while (*bnext == ' ' || *bnext == '\t' || *bnext == '_')
  1159.                               bnext++;
  1160.                           strcpy(BaseName, bnext);
  1161.                           BaseName[strlen(BaseName) - 1] = '\0';
  1162.                       }
  1163.                       else if (strncmp("##bias", buf, 6) == 0)
  1164.                       {
  1165.                           if (!sscanf(buf + 6, "%ld", &infile->offset))
  1166.                           {
  1167.                               fprintf(stderr, "illegal ##bias in line %lu: %s\n",
  1168.                                       infile->lineno, infile->line);
  1169.                               fF_SetError(infile, real_error);
  1170.                               break;   /*
  1171.                                         * avoid nodef 
  1172.                                         */
  1173.                           }
  1174.                           else
  1175.                           {
  1176.                               if (fF_GetOffset(infile) > 0)
  1177.                                   fF_SetOffset(infile, -fF_GetOffset(infile));
  1178.                               DBP(fprintf(stderr, "set offset to %ld\n",
  1179.                                           fF_GetOffset(infile)));
  1180.                           }
  1181.                       }
  1182.                       else
  1183.                       {
  1184.                           if (strncmp("##private", buf, 9) == 0)
  1185.                               fF_SetPrivate(infile, 1);
  1186.                           else if (strncmp("##public", buf, 8) == 0)
  1187.                               fF_SetPrivate(infile, 0);
  1188.                       }
  1189.                     /*
  1190.                      * drop through for error comment 
  1191.                      */
  1192.  
  1193.                   case '*':
  1194.                     /*
  1195.                      * try again somewhere else 
  1196.                      */
  1197.                       fF_SetError(infile, nodef);
  1198.                       break;
  1199.  
  1200.                   default:
  1201.                     /*
  1202.                      * assume a regular line here 
  1203.                      */
  1204.                       if (fF_GetPrivate(infile))
  1205.                       {
  1206.                         /*
  1207.                          * don't store names of privates 
  1208.                          */
  1209.                           fF_SetError(infile, nodef);
  1210.                           fF_SetOffset(infile, fF_GetOffset(infile) - 6);
  1211.                           break;
  1212.                       }
  1213.                       parsing = name;  /*
  1214.                                         * switch (parsing) 
  1215.                                         */
  1216.                       for (index = 0; buf[index] && buf[index] != '('; index++) ;
  1217.  
  1218.                       if (!buf[index])
  1219.                       {
  1220.                         /*
  1221.                          * oops, no fd ? 
  1222.                          */
  1223.                           fprintf(stderr, "not an fd, line %lu: %s\n",
  1224.                                   infile->lineno, buf   /*
  1225.                                                          * infile->line 
  1226.                                                          */ );
  1227.                           fF_SetError(infile, nodef);
  1228.                       }                                /*
  1229.                                         * maybe next time 
  1230.                                         */
  1231.                       else
  1232.                       {
  1233.                           buf[index] = 0;
  1234.  
  1235.                           fD_NewName(obj, buf);
  1236.                           fD_SetOffset(obj, fF_GetOffset(infile));
  1237.  
  1238.                           bpoint = buf + index + 1;
  1239.                           parsing = params;             /*
  1240.                                                  * continue the loop 
  1241.                                                  */
  1242.                       }
  1243.                   }
  1244.                  break;
  1245.  
  1246.              case params:
  1247.                  {
  1248.                      char *bptmp;      /*
  1249.  
  1250.                                         * needed for fD_NewParam 
  1251.                                         */
  1252.  
  1253.                    /*
  1254.                     * look for parameters now 
  1255.                     */
  1256.  
  1257.                      for (bnext = bpoint; *bnext && *bnext != ',' && *bnext != ')';
  1258.                           bnext++) ;
  1259.  
  1260.                      if (*bnext)
  1261.                      {
  1262.                          bptmp = bpoint;
  1263.  
  1264.                          if (*bnext == ')')
  1265.                          {
  1266.                              if (bnext[1] != '(')
  1267.                              {
  1268.                                  fprintf(stderr, "registers expected in line %lu: %s\n",
  1269.                                          infile->lineno, infile->line);
  1270.                                  fF_SetError(infile, nodef);
  1271.                              }
  1272.                              else
  1273.                              {
  1274.                                  parsing = regs;
  1275.                                  bpoint = bnext + 2;
  1276.                              }
  1277.                          }
  1278.                          else
  1279.                              bpoint = bnext + 1;
  1280.  
  1281.                        /*
  1282.                         * terminate string and advance to next item 
  1283.                         */
  1284.  
  1285.                          *bnext = '\0';
  1286.                          fD_NewParam(obj, fD_ParamNum(obj), bptmp);
  1287.                      }
  1288.                      else
  1289.                      {
  1290.                          fF_SetError(infile, nodef);
  1291.                          fprintf(stderr, "param expected in line %lu: %s\n",
  1292.                                  infile->lineno, infile->line);
  1293.                      }
  1294.                      break;                    /*
  1295.                                         * switch parsing 
  1296.                                         */
  1297.                  }
  1298.  
  1299.              case regs:
  1300.                /*
  1301.                 * look for parameters now 
  1302.                 */
  1303.  
  1304.                  for (bnext = bpoint; *bnext && *bnext != '/' && *bnext != ',' &&
  1305.                       *bnext != ')'; bnext++) ;
  1306.  
  1307.                  if (*bnext)
  1308.                  {
  1309.                      if (')' == *bnext)
  1310.                      {
  1311.                        /*
  1312.                         * wow, we've finished 
  1313.                         */
  1314.                          fF_SetOffset(infile, fF_GetOffset(infile) - 6);
  1315.                          parsing = ready;
  1316.                      }
  1317.                      *bnext = '\0';
  1318.  
  1319.                      bpoint[0] = tolower(bpoint[0]);
  1320.  
  1321.                      if ((bpoint[0] == 'd' || bpoint[0] == 'a') && bpoint[1] >= '0' &&
  1322.                          bpoint[1] <= '8' && bnext == bpoint + 2)
  1323.                          fD_NewReg(obj, fD_RegNum(obj),
  1324.                                    bpoint[1] - '0' + (bpoint[0] == 'a' ? 8 : 0));
  1325.                      else if (bnext != bpoint)
  1326.                      {
  1327.                        /*
  1328.                         * it is when our function is void 
  1329.                         */
  1330.                          fprintf(stderr, "illegal register %s in line %ld\n",
  1331.                                  bpoint, infile->lineno);
  1332.                          fF_SetError(infile, nodef);
  1333.                      }
  1334.                      bpoint = bnext + 1;
  1335.                  }
  1336.                  else
  1337.                  {
  1338.                      fF_SetError(infile, nodef);
  1339.                      fprintf(stderr, "reg expected in line %lu\n",
  1340.                              infile->lineno);
  1341.                  }
  1342.                  break;                            /*
  1343.                                         * switch parsing 
  1344.                                         */
  1345.  
  1346.              case ready:
  1347.                  fprintf(stderr, "internal error, use another compiler.\n");
  1348.                  break;
  1349.              }
  1350.         }
  1351.  
  1352.         free(buf);
  1353.         return fF_GetError(infile);
  1354.     }
  1355.     else
  1356.     {
  1357.         illparams("fD_parsefd");
  1358.         return real_error;
  1359.     }
  1360. }
  1361.  
  1362. static void
  1363. fD_adjustargnames(fdDef * obj)
  1364. {
  1365.     int parnum;
  1366.  
  1367.     if (output_mode == NEW)
  1368.     {
  1369.  
  1370.       /*
  1371.        * For #define-base output mode, we have to check if argument names are not
  1372.        * the same as some words in type names. We check from the first argument
  1373.        * to the last, resolving conflicts by changing argument names, if
  1374.        * necessary. 
  1375.        */
  1376.  
  1377.         for (parnum = 0; parnum < fD_ParamNum(obj); parnum++)
  1378.         {
  1379.             const char *parname = fD_GetParam(obj, parnum);
  1380.             int finished;
  1381.  
  1382.             DBP(fprintf(stderr, "ParNum %ld ParName %s\n",parnum,parname));
  1383.             do
  1384.             {
  1385.                 int num;
  1386.                 const char *type = fD_GetType(obj);
  1387.                 char *str;
  1388.  
  1389.                 finished = 1;
  1390.  
  1391.                 DBP(fprintf(stderr, "DoLoop\n"));
  1392.                 if ((str = strstr(type, parname)) != 0 &&
  1393.                      (str == type || (!isalnum(str[-1]) && str[-1] != '_')) &&
  1394.                     (!*(str += strlen(parname)) || (!isalnum(*str) && *str != '_')))
  1395.                 {
  1396.                     char buf[300];     /*
  1397.                                 * Hope will be enough... 
  1398.                                 */
  1399.  
  1400.                     DBP(fprintf(stderr, "str1 %s\n",str));
  1401.                     strcpy(buf, parname);
  1402.                     strcat(buf, "_");
  1403.                     DBP(fprintf(stderr, "NewParam1 ParNum %ld Buf %s\n",parnum,buf));
  1404.                     fD_NewParam(obj, parnum, buf);
  1405.                     finished = 0;
  1406.                 }
  1407.                 else
  1408.                 {
  1409.                     DBP(fprintf(stderr, "str2 %s\n",str));
  1410.                     for (num = 0; num < fD_ParamNum(obj); num++)
  1411.                     {
  1412.                         const char *name = fD_GetParam(obj, num);
  1413.                         const char *proto = fD_GetProto(obj, num);
  1414.  
  1415.                         DBP(fprintf(stderr, "num %ld name %s proto %s\n",num,name,proto));
  1416.  
  1417.                         if ((num < parnum && strcmp(name, parname) == 0) ||
  1418.                             ((str = strstr(proto, parname)) != 0 &&
  1419.                             (str == proto ||  (!isalnum(str[-1]) && str[-1] != '_')) &&
  1420.                              (!*(str += strlen(parname)) || (!isalnum(*str) && *str != '_'))))
  1421.                         {
  1422.                             char buf[300];  /*
  1423.                                      * Hope will be enough... 
  1424.                                      */
  1425.                             strcpy(buf, parname);
  1426.                             strcat(buf, "_");
  1427.                             DBP(fprintf(stderr, "NewParam2 ParNum %ld Buf %s\n",parnum,buf));
  1428.                             fD_NewParam(obj, parnum, buf);
  1429.                             //finished = 0;
  1430.                             break;
  1431.                         }
  1432.                     }
  1433.                 }
  1434.             }
  1435.             while (!finished);
  1436.         }
  1437.     }
  1438. }
  1439.  
  1440. Error
  1441. fD_parsepr(fdDef * obj, fdFile * infile)
  1442. {
  1443. char *buf;                                                 /*
  1444.                                     * a copy of infile->line                    
  1445.                                     */
  1446. char *bpoint,                                      /*
  1447.                                     * cursor in buf                             
  1448.                                     */
  1449. *bnext,                                                    /*
  1450.                                     * looking for the end                       
  1451.                                     */
  1452. *lowarg;                                                   /*
  1453.                                     * beginning of this argument                
  1454.                                     */
  1455. long obraces;                                      /*
  1456.                                     * count of open braces                      
  1457.                                     */
  1458. regs count,                                                /*
  1459.                                     * count parameter number                    
  1460.                                     */
  1461. args;                                                      /*
  1462.                                     * the number of arguments for this function 
  1463.                                     */
  1464.  
  1465.     if (!(obj && infile && fF_GetError(infile) == false))
  1466.     {
  1467.         illparams("fD_parsepr");
  1468.         fF_SetError(infile, real_error);
  1469.         return real_error;
  1470.     }
  1471.     if (!NewString(&buf, infile->line))
  1472.     {
  1473.         fprintf(stderr, "no mem for fD_parsepr\n");
  1474.         fF_SetError(infile, real_error);
  1475.         return real_error;
  1476.     }
  1477.     fF_SetError(infile, false);
  1478.  
  1479.  
  1480.     DBP(fprintf(stderr,"buf %s",buf));
  1481.     bpoint = strchr(buf, '(');
  1482.     while (--bpoint >= buf && strstr(bpoint, fD_GetName(obj)) != bpoint) ;
  1483.  
  1484.     if (bpoint >= buf)
  1485.     {
  1486.         while (--bpoint >= buf && (*bpoint == ' ' || *bpoint == '\t')) ;
  1487.         *++bpoint = '\0';
  1488.  
  1489.         fD_NewType(obj, buf);
  1490.  
  1491.         while (bpoint && *bpoint++ != '(') ;    /* one beyond '(' */
  1492.  
  1493.         lowarg = bpoint;
  1494.         obraces = 0;
  1495.  
  1496.         for (count = 0, args = fD_RegNum(obj); count < args; bpoint = bnext + 1)
  1497.         {
  1498.             while (*bpoint && (*bpoint == ' ' || *bpoint == '\t'))
  1499.                 bpoint++;
  1500.  
  1501.             DBP(fprintf(stderr,"count %ld args %ld",count,args));
  1502.             DBP(fprintf(stderr,"bpoint %s",bpoint));
  1503.             bnext = strpbrk(bpoint, "(),");
  1504.             DBP(fprintf(stderr,"bnext %s",bnext));
  1505.  
  1506.             if (bnext)
  1507.             {
  1508.                 switch (*bnext)
  1509.                 {
  1510.                  case '(':
  1511.                      if (!obraces)
  1512.                      {
  1513.                         if ((PowerUP==0) && (MorphOS==0))
  1514.                         {
  1515.                             if (fD_GetFuncParNum(obj) != illegal &&
  1516.                                  fD_GetFuncParNum(obj) != count)
  1517.                                  fprintf(stderr, "Warning: two parameters of type "
  1518.                                          "pointer to function are used.\nThis is not "
  1519.                                          "supported!\n");
  1520.                         }
  1521.                          fD_SetFuncParNum(obj, count);
  1522.                      }
  1523.                      obraces++;
  1524.                      DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
  1525.                      break;
  1526.  
  1527.                  case ')':
  1528.                      if (obraces)
  1529.                      {
  1530.                          DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
  1531.                          obraces--;
  1532.                      }
  1533.                      else
  1534.                      {
  1535.                          *bnext = '\0';
  1536.                          DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
  1537.                          fD_NewProto(obj, count, lowarg);
  1538.                          lowarg = bnext + 1;
  1539.  
  1540.                          if (count != args - 1)
  1541.                          {
  1542.                              DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
  1543.                                          fD_GetName(obj), args, count + 1));
  1544.                              fF_SetError(infile, nodef);
  1545.                          }
  1546.                          count++;
  1547.                      }
  1548.                      break;
  1549.  
  1550.                  case ',':
  1551.                      if (!obraces)
  1552.                      {
  1553.                          *bnext = '\0';
  1554.                          DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
  1555.                          fD_NewProto(obj, count, lowarg);
  1556.                          lowarg = bnext + 1;
  1557.                          count++;
  1558.                      }
  1559.                      break;
  1560.  
  1561.                  default:
  1562.                      fprintf(stderr, "faulty strpbrk in line %lu.\n",
  1563.                              infile->lineno);
  1564.                  }
  1565.             }
  1566.             else
  1567.             {
  1568.                 DBP(fprintf(stderr, "faulty argument %u in line %lu.\n", count + 1,
  1569.                             infile->lineno));
  1570.                 count = args;              /*
  1571.                                         * this will effectively quit the for loop 
  1572.                                         */
  1573.                 fF_SetError(infile, nodef);
  1574.             }
  1575.         }
  1576.         if (fD_ProtoNum(obj) != fD_RegNum(obj))
  1577.             fF_SetError(infile, nodef);
  1578.     }
  1579.     else
  1580.     {
  1581.         fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
  1582.         fprintf(stderr, "function , definition %s.\n",
  1583.       /*
  1584.        * fD_GetName(obj),
  1585.        */ infile->line);
  1586.         fF_SetError(infile, nodef);
  1587.     }
  1588.  
  1589.     free(buf);
  1590.  
  1591.     fD_adjustargnames(obj);
  1592.  
  1593.     return fF_GetError(infile);
  1594. }
  1595.  
  1596. int
  1597. fD_cmpName(const void *big, const void *small)  /*
  1598.                                                  * for qsort and bsearch 
  1599.                                                  */
  1600. {
  1601.     return strcmp(fD_GetName(*(fdDef **) big), fD_GetName(*(fdDef **) small));
  1602. }
  1603.  
  1604. const static char *TagExcTable[] =
  1605. {
  1606.     "BuildEasyRequestArgs", "BuildEasyRequest",
  1607.     "DoDTMethodA", "DoDTMethod",
  1608.     "DoGadgetMethodA", "DoGadgetMethod",
  1609.     "EasyRequestArgs", "EasyRequest",
  1610.     "MUI_MakeObjectA", "MUI_MakeObject",
  1611.     "MUI_RequestA", "MUI_Request",
  1612.     "PrintDTObjectA", "PrintDTObject",
  1613.     "RefreshDTObjectA", "RefreshDTObjects",
  1614.     "UMSVLog", "UMSLog",
  1615.     "VFWritef", "FWritef",
  1616.     "VFPrintf", "FPrintf",
  1617.     "VPrintf", "Printf",
  1618. };
  1619.  
  1620. const char *
  1621. taggedfunction(const fdDef * obj)
  1622. {
  1623.     shortcard numregs = fD_RegNum(obj);
  1624.     unsigned int count;
  1625.     const char *name = fD_GetName(obj);
  1626.     static char newname[200];                  /*
  1627.  
  1628.                                         * Hope will be enough... static because used
  1629.                                         * out of the function. 
  1630.                                         */
  1631.     const char *lastarg;
  1632.     const static char *TagExcTable2[] =
  1633.     {
  1634.         "ApplyTagChanges",
  1635.         "CloneTagItems",
  1636.         "FindTagItem",
  1637.         "FreeTagItems",
  1638.         "GetTagData",
  1639.         "PackBoolTags",
  1640.         "PackStructureTags",
  1641.         "RefreshTagItemClones",
  1642.         "UnpackStructureTags",
  1643.     };
  1644.  
  1645.     if (!numregs)
  1646.         return NULL;
  1647.  
  1648.     for (count = 0; count < sizeof TagExcTable / sizeof TagExcTable[0]; count += 2)
  1649.         if (strcmp(name, TagExcTable[count]) == 0)
  1650.             return TagExcTable[count + 1];
  1651.  
  1652.     for (count = 0; count < sizeof TagExcTable2 / sizeof TagExcTable2[0]; count++)
  1653.         if (strcmp(name, TagExcTable2[count]) == 0)
  1654.             return NULL;
  1655.  
  1656.     lastarg = fD_GetProto(obj, numregs - 1);
  1657.     if (strncmp(lastarg, "struct", 6))
  1658.         return NULL;
  1659.     lastarg += 6;
  1660.     while (*lastarg == ' ' || *lastarg == '\t')
  1661.         lastarg++;
  1662.     if (strncmp(lastarg, "TagItem", 7))
  1663.         return NULL;
  1664.     lastarg += 7;
  1665.     while (*lastarg == ' ' || *lastarg == '\t')
  1666.         lastarg++;
  1667.     if (strcmp(lastarg, "*"))
  1668.         return NULL;
  1669.  
  1670.     strcpy(newname, name);
  1671.     if (newname[strlen(newname) - 1] == 'A')
  1672.         newname[strlen(newname) - 1] = '\0';
  1673.     else if (strlen(newname) > 7 && !strcmp(newname + strlen(newname) - 7, "TagList"))
  1674.         strcpy(newname + strlen(newname) - 4, "s");
  1675.     else
  1676.         strcat(newname, "Tags");
  1677.     return newname;
  1678. }
  1679.  
  1680. const char *
  1681. aliasfunction(const char *name)
  1682. {
  1683.     const static char *AliasTable[] =
  1684.     {
  1685.         "AllocDosObject", "AllocDosObjectTagList",
  1686.         "CreateNewProc", "CreateNewProcTagList",
  1687.         "NewLoadSeg", "NewLoadSegTagList",
  1688.         "System", "SystemTagList",
  1689.     };
  1690.     unsigned int count;
  1691.  
  1692.     for (count = 0; count < sizeof AliasTable / sizeof AliasTable[0]; count++)
  1693.         if (strcmp(name, AliasTable[count]) == 0)
  1694.             return AliasTable[count + (count % 2 ? -1 : 1)];
  1695.     return NULL;
  1696. }
  1697.  
  1698. void
  1699. fD_write(FILE * outfile, const fdDef * obj)
  1700. {
  1701.     shortcard count, numregs;
  1702.     const char *chtmp, *tagname, *name, *rettype;
  1703.     int vd = 0, a45 = 0, d7 = 0;
  1704.  
  1705.     DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
  1706.  
  1707.     numregs = fD_RegNum(obj);
  1708.  
  1709.     if ((rettype = fD_GetType(obj)) == fD_nostring)
  1710.     {
  1711.         fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
  1712.         return;
  1713.     }
  1714.     if (!stricmp(rettype, "void"))
  1715.     {
  1716.         vd = 1;         /*
  1717.                  * set flag 
  1718.                  */
  1719.     }
  1720.     for (count = d0; count < numregs; count++)
  1721.     {
  1722.         const char *reg = fD_GetRegStr(obj, count);
  1723.  
  1724.         if (!((output_mode == NEW) && (PowerUP == TRUE)))
  1725.         {
  1726.             if (strcmp(reg, "a4") == 0 || strcmp(reg, "a5") == 0)
  1727.             {
  1728.                 if (!a45)
  1729.                     a45 = (strcmp(reg, "a4") ? 5 : 4);      /*
  1730.                                                          * set flag 
  1731.                                                          */
  1732.                 else                               /*
  1733.                                         * Security check 
  1734.                                         */
  1735.                     fprintf(stderr, "Warning: both a4 and a5 are used. This is not "
  1736.                             "supported!\n");
  1737.             }
  1738.             if (strcmp(reg, "d7") == 0)             /*
  1739.                                              * Used only when a45!=0 
  1740.                                              */
  1741.             {
  1742.                 d7 = 1;
  1743.             }
  1744.         }
  1745.     }
  1746.  
  1747.     if (!((output_mode == NEW) && (PowerUP == TRUE)))
  1748.     {
  1749.         if (a45 && d7)                             /*
  1750.                                         * Security check 
  1751.                                         */
  1752.             fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
  1753.                     "supported!\n");
  1754.     }
  1755.  
  1756.     name = fD_GetName(obj);
  1757.  
  1758.     if (fD_ProtoNum(obj) != numregs)
  1759.     {
  1760.         fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
  1761.                 fD_ProtoNum(obj), fD_ProtoNum(obj) != 1 ? "s" : "");
  1762.         return;
  1763.     }
  1764.  
  1765.     if ((output_mode == NEW) && (PowerUP == FALSE) && (MorphOS == FALSE))
  1766.     {
  1767.         fprintf(outfile, "#define %s(", name);
  1768.  
  1769.         if (numregs > 0)
  1770.         {
  1771.             for (count = d0; count < numregs - 1; count++)
  1772.                 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
  1773.             fprintf(outfile, "%s", fD_GetParam(obj, count));
  1774.         }
  1775.  
  1776.         fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
  1777.                 (vd ? "NR" : ""), (a45 ? (a45 == 4 ? "A4" : "A5") : ""),
  1778.                 (BaseName[0] ? "" : "UB"),
  1779.                 (fD_GetFuncParNum(obj) == illegal ? "" : "FP"), -fD_GetOffset(obj));
  1780.         if (!vd)
  1781.         {
  1782.             fprintf(outfile, "%s, ", rettype);
  1783.         }
  1784.         fprintf(outfile, "%s, ", name);
  1785.  
  1786.         for (count = d0; count < numregs; count++)
  1787.         {
  1788.             chtmp = fD_GetRegStr(obj, count);
  1789.             if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
  1790.                 chtmp = "d7";
  1791.             fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj) == count ?
  1792.                                               "__fpt" : fD_GetProto(obj, count)), fD_GetParam(obj, count),
  1793.                     chtmp, (count == numregs - 1 && !BaseName[0] ? "" : ", "));
  1794.         }
  1795.  
  1796.         if (BaseName[0])                           /*
  1797.                                         * was "##base" used? 
  1798.                                         */
  1799.             fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
  1800.         if (fD_GetFuncParNum(obj) != illegal)
  1801.         {
  1802.             fprintf(outfile, ", ");
  1803.             fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
  1804.         }
  1805.         fprintf(outfile, ")\n\n");
  1806.     }
  1807.     else if ((output_mode == NEW) && (PowerUP == TRUE || MorphOS == TRUE))
  1808.     {
  1809.         fprintf(outfile, "#define %s(", name);
  1810.  
  1811.         if (numregs > 0)
  1812.         {
  1813.             for (count = d0; count < numregs - 1; count++)
  1814.                 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
  1815.  
  1816.             fprintf(outfile, "%s", fD_GetParam(obj, count));
  1817.         }
  1818.  
  1819. #if 1
  1820.         fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
  1821.                 numregs,
  1822.                 (vd ? "NR" : ""),
  1823.                 (BaseName[0] ? "" : "UB"),
  1824.                 -fD_GetOffset(obj));
  1825. #else
  1826.         fprintf(outfile, ") \\\n\tLP%d%s%s%s(0x%lx, ",
  1827.                 numregs,
  1828.                 (vd ? "NR" : ""),
  1829.                 (BaseName[0] ? "" : "UB"),
  1830.                 (fD_GetFuncParNum(obj) == illegal ? "" : "FP"), -fD_GetOffset(obj));
  1831. #endif
  1832.         if (!vd)
  1833.         {
  1834.             fprintf(outfile, "%s, ", rettype);
  1835.         }
  1836.  
  1837.         fprintf(outfile, "%s, ", name);
  1838.  
  1839.         for (count = d0; count < numregs; count++)
  1840.         {
  1841.             chtmp = fD_GetRegStr(obj, count);
  1842.  
  1843.             if (strchr(fD_GetProto(obj, count),'%'))
  1844.             {
  1845.                 sprintf(Buffer,
  1846.                     fD_GetProto(obj, count),
  1847.                     "");
  1848.  
  1849.                 fprintf(outfile, "%s, %s, %s%s",
  1850.                         Buffer,
  1851.                         fD_GetParam(obj, count),
  1852.                         chtmp,
  1853.                         (count == numregs - 1 && !BaseName[0] ? "" : ", "));
  1854.             }
  1855.             else
  1856.             {
  1857.                 fprintf(outfile, "%s, %s, %s%s",
  1858.                         fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProto(obj, count)),
  1859.                         fD_GetParam(obj, count),
  1860.                         chtmp,
  1861.                         (count == numregs - 1 && !BaseName[0] ? "" : ", "));
  1862.             }
  1863.         }
  1864.  
  1865.         if (BaseName[0])
  1866.         {
  1867.             fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
  1868.         }
  1869. #if 0
  1870.         if (fD_GetFuncParNum(obj) != illegal)
  1871.         {
  1872.             fprintf(outfile, ", ");
  1873.             fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
  1874.         }
  1875. #endif
  1876. /*
  1877.  * Here it would make sense to create a database file to integrate optimizations * automaticly into every new 
  1878.  * build. * Not every function needs a complete flush. For example functions with no parameter * wouldn`t
  1879.  * need a PPC flush normally. * Or Read(File,Addr,Size); would only need a flush for Addr with the Size 
  1880.  */
  1881.         fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
  1882.         fprintf(outfile, ")\n\n");
  1883.  
  1884.     }
  1885.     else if (output_mode == PRAGMA)
  1886.     {
  1887.         if (PowerUP == TRUE || MorphOS == TRUE)
  1888.         {
  1889.  
  1890.             fprintf(outfile, "#define\t%s",
  1891.                     name);
  1892.  
  1893.             if (numregs)
  1894.             {
  1895.                 fprintf(outfile, "(");
  1896.  
  1897.                 if (numregs > 0)
  1898.                 {
  1899.                     for (count = d0; count < numregs - 1; count++)
  1900.                     {
  1901.                         fprintf(outfile, "%s, ", fD_GetParam(obj, count));
  1902.                     }
  1903.                     fprintf(outfile, "%s", fD_GetParam(obj, count));
  1904.                 }
  1905.  
  1906.                 fprintf(outfile, ")");
  1907.  
  1908.                 if (BaseName[0])           /*
  1909.                                         * was "##base" used? 
  1910.                                         */
  1911.                 {
  1912.                     fprintf(outfile, "\t_%s(%s_BASE_NAME%s",
  1913.                             name,
  1914.                             BaseNamU,
  1915.                             numregs ? ", " : "");
  1916.                 }
  1917.                 else
  1918.                 {
  1919.                     fprintf(outfile, "\t_%s(",
  1920.                             name);
  1921.                 }
  1922.  
  1923.                 if (numregs > 0)
  1924.                 {
  1925.                     for (count = d0; count < numregs - 1; count++)
  1926.                     {
  1927.                         fprintf(outfile, "%s, ", fD_GetParam(obj, count));
  1928.                     }
  1929.                     fprintf(outfile, "%s", fD_GetParam(obj, count));
  1930.                 }
  1931.  
  1932.                 fprintf(outfile, ")\n\n");
  1933.             }
  1934.             else
  1935.             {
  1936.                 if (BaseName[0])           /*
  1937.                                         * was "##base" used? 
  1938.                                         */
  1939.                 {
  1940.                     fprintf(outfile, "()\t_%s(%s_BASE_NAME)\n\n",
  1941.                             name,
  1942.                             BaseNamU);
  1943.                 }
  1944.                 else
  1945.                 {
  1946.                     fprintf(outfile, "()\t_%s()\n\n",
  1947.                             name);
  1948.                 }
  1949.             }
  1950.  
  1951.             fprintf(outfile, "static __inline %s\n_%s(%s%s%s",
  1952.                     rettype,
  1953.                     name,
  1954.                     BaseName[0] ? "void *" : "",
  1955.                     BaseName[0] ? BaseName : "",
  1956.                     (BaseName[0] ? (numregs ? ", " : "") : ""));
  1957.  
  1958.             for (count = d0; count < numregs; count++)
  1959.             {
  1960.                 chtmp = fD_GetProto(obj, count);
  1961.                 if (fD_GetFuncParNum(obj) == count)
  1962.                 {
  1963.                     fprintf(outfile, chtmp, fD_GetParam(obj, count));
  1964.                 }
  1965.                 else
  1966.                 {
  1967.                     fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
  1968.                                                        "" : " "), fD_GetParam(obj, count));
  1969.                 }
  1970.                 if (count < numregs - 1)
  1971.                 {
  1972.                     fprintf(outfile, ", ");
  1973.                 }
  1974.             }
  1975.  
  1976.             fprintf(outfile, ")\n");
  1977.             fprintf(outfile, "{\n");
  1978.             fprintf(outfile, "struct Caos\tMyCaos;\n");
  1979.             fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\n");
  1980.             fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\n");
  1981.             fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\n");
  1982.             fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\n");
  1983.             fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\n");
  1984.             fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\n");
  1985.  
  1986.             if (numregs > 0)
  1987.             {
  1988.                 for (count = d0; count < numregs; count++)
  1989.                 {
  1990.                     fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\n",
  1991.                             fD_GetRegStr(obj, count),
  1992.                             fD_GetParam(obj, count));
  1993.                 }
  1994.             }
  1995.  
  1996.             fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\n",
  1997.                     fD_GetOffset(obj));
  1998.  
  1999.             if (BaseName[0])                   /*
  2000.                                         * was "##base" used? 
  2001.                                         */
  2002.             {
  2003.                 fprintf(outfile, "\tMyCaos.a6\t\t=(ULONG) %s;\t\n",
  2004.                         BaseName);
  2005.             }
  2006.             if (vd)
  2007.             {
  2008.                 fprintf(outfile, "\tPPCCallOS(&MyCaos);\n}\n\n");
  2009.             }
  2010.             else
  2011.             {
  2012.                 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
  2013.                         rettype);
  2014. /*
  2015.  * fprintf(outfile, "\treturn((%s)MyCaos.d0);\n}\n\n", rettype); 
  2016.  */
  2017.             }
  2018.  
  2019.         }
  2020.         else
  2021.         {
  2022.           /*
  2023.            * No M68k support yet 
  2024.            */
  2025.         }
  2026.     }
  2027.     else if (output_mode == GATESTUBS)
  2028.     {
  2029.         fprintf(outfile, "%s %s%s(void)\n{\n",
  2030.                 rettype,
  2031.                 prefixname,
  2032.                 name);
  2033.  
  2034.         if (numregs > 0)
  2035.         {
  2036.             for (count = d0; count < numregs; count++)
  2037.             {
  2038.                 if (strchr(fD_GetProto(obj, count),'%'))
  2039.                 {
  2040.                     /* Function parameter */
  2041.                     fprintf(outfile, "\t");
  2042.  
  2043.                     sprintf(Buffer,
  2044.                         fD_GetProto(obj, count),
  2045.                         fD_GetParam(obj, count));
  2046.                     fprintf(outfile, Buffer);
  2047.  
  2048.                     fprintf(outfile, "\t=(");
  2049.  
  2050.                     sprintf(Buffer,
  2051.                         fD_GetProto(obj, count),
  2052.                         "");
  2053.                     fprintf(outfile, Buffer);
  2054.  
  2055.                     fprintf(outfile, ") REG_%s;\n",
  2056.                             fD_GetRegStrU(obj, count));
  2057.                 }
  2058.                 else
  2059.                 {
  2060.                     fprintf(outfile, "\t%s %s\t=(%s) REG_%s;\n",
  2061.                             fD_GetProto(obj, count),
  2062.                             fD_GetParam(obj, count),
  2063.                             fD_GetProto(obj, count),
  2064.                             fD_GetRegStrU(obj, count));
  2065.                 }
  2066.             }
  2067.             if (PreLibFlag || PostLibFlag)
  2068.             {
  2069.                 if (RegLibFlag)
  2070.                 {
  2071.                     fprintf(outfile, "\tvoid *___RegBase\t=(void*) REG_A6;\n");
  2072.                 }
  2073.             }
  2074.  
  2075.         }
  2076.         if (vd)
  2077.         {
  2078.             fprintf(outfile, "\t(%s%s(",
  2079.                     subprefixname,
  2080.                     name);
  2081.         }
  2082.         else
  2083.         {
  2084.             fprintf(outfile, "\treturn(%s%s(",
  2085.                     subprefixname,
  2086.                     name);
  2087.         }
  2088.         if (numregs > 0)
  2089.         {
  2090.             if (PreLibFlag)
  2091.             {
  2092.                 if (RegLibFlag)
  2093.                 {
  2094.                     fprintf(outfile, "___RegBase,");
  2095.                 }
  2096.                 else
  2097.                 {
  2098.                     fprintf(outfile, "BASE_NAME,");
  2099.                 }
  2100.             }
  2101.  
  2102.             for (count = d0; count < numregs; count++)
  2103.             {
  2104.                 if (count >= numregs - 1)
  2105.                 {
  2106.                     if (PostLibFlag)
  2107.                     {
  2108.                         if (RegLibFlag)
  2109.                         {
  2110.                             fprintf(outfile, "%s,___RegBase));\n}\n",
  2111.                                 fD_GetParam(obj, count));
  2112.                         }
  2113.                         else
  2114.                         {
  2115.                             fprintf(outfile, "%s,BASE_NAME));\n}\n",
  2116.                                 fD_GetParam(obj, count));
  2117.                         }
  2118.                     }
  2119.                     else
  2120.                     {
  2121.                         fprintf(outfile, "%s));\n}\n",
  2122.                             fD_GetParam(obj, count));
  2123.                     }
  2124.                 }
  2125.                 else
  2126.                 {
  2127.                     fprintf(outfile, "%s,",
  2128.                             fD_GetParam(obj, count));
  2129.                 }
  2130.             }
  2131.         }
  2132.         else
  2133.         {
  2134.             if (PreLibFlag || PostLibFlag)
  2135.             {
  2136.                 if (RegLibFlag)
  2137.                 {
  2138.                     fprintf(outfile, "___RegBase));\n}\n");
  2139.                 }
  2140.                 else
  2141.                 {
  2142.                     fprintf(outfile, "BASE_NAME));\n}\n");
  2143.                 }
  2144.             }
  2145.             else
  2146.             {
  2147.                 fprintf(outfile, "));\n}\n");
  2148.             }
  2149.         }
  2150.  
  2151.     }
  2152.     else
  2153.     {
  2154.         if (PowerUP == TRUE)
  2155.         {
  2156.             fprintf(outfile, "%sstatic __inline %s\n%s(%s",
  2157.                     (output_mode == STUBS ? "" : "extern "), rettype, name,
  2158.                     (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
  2159.  
  2160.             for (count = d0; count < numregs; count++)
  2161.             {
  2162.                 chtmp = fD_GetProto(obj, count);
  2163.                 if (fD_GetFuncParNum(obj) == count)
  2164.                     fprintf(outfile, chtmp, fD_GetParam(obj, count));
  2165.                 else
  2166.                     fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
  2167.                                                        "" : " "), fD_GetParam(obj, count));
  2168.                 if (count < numregs - 1)
  2169.                     fprintf(outfile, ", ");
  2170.             }
  2171.  
  2172.             fprintf(outfile, ")\t\n");
  2173.             fprintf(outfile, "{\t\n");
  2174.             fprintf(outfile, "struct Caos\tMyCaos;\n");
  2175.             fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
  2176.             fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
  2177.             fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
  2178.             fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
  2179.             fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
  2180.             fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
  2181.  
  2182.             if (numregs > 0)
  2183.             {
  2184.                 for (count = d0; count < numregs; count++)
  2185.                 {
  2186.                     fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
  2187.                             fD_GetRegStr(obj, count),
  2188.                             fD_GetParam(obj, count));
  2189.                 }
  2190.             }
  2191.  
  2192.             fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
  2193.             if (BaseName[0])                   /*
  2194.                                         * was "##base" used? 
  2195.                                         */
  2196.             {
  2197.                 fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) %s_BASE_NAME;\t\n",
  2198.                         BaseNamU);
  2199.             }
  2200.             if (vd)
  2201.             {
  2202.                 fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
  2203.             }
  2204.             else
  2205.             {
  2206.                 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
  2207.                         rettype);
  2208. /*
  2209.  * fprintf(outfile, "\treturn((%s)MyCaos.d0);\t\n}\n\n", rettype); 
  2210.  */
  2211.             }
  2212.         }
  2213.         else if (MorphOS == TRUE)
  2214.         {
  2215.             fprintf(outfile, "%s%s\n%s(%s",
  2216.                     (output_mode == STUBS ? "" : "static __inline "), rettype, name,
  2217.                     (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
  2218.  
  2219.             for (count = d0; count < numregs; count++)
  2220.             {
  2221.                 chtmp = fD_GetProto(obj, count);
  2222.                 if (fD_GetFuncParNum(obj) == count)
  2223.                     fprintf(outfile, chtmp, fD_GetParam(obj, count));
  2224.                 else
  2225.                     fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
  2226.                                                        "" : " "), fD_GetParam(obj, count));
  2227.                 if (count < numregs - 1)
  2228.                     fprintf(outfile, ", ");
  2229.             }
  2230.  
  2231.             fprintf(outfile, ")\t\n");
  2232.             fprintf(outfile, "{\t\n");
  2233.             fprintf(outfile, "struct EmulCaos\tMyCaos;\n");
  2234.  
  2235.             if (numregs > 0)
  2236.             {
  2237.                 for (count = d0; count < numregs; count++)
  2238.                 {
  2239.                     fprintf(outfile, "\tMyCaos.reg_%s\t\t=\t(ULONG) %s;\n",
  2240.                             fD_GetRegStr(obj, count), fD_GetParam(obj, count));
  2241.                 }
  2242.             }
  2243.  
  2244.             fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\n", fD_GetOffset(obj));
  2245.             if (BaseName[0])                   /*
  2246.                                         * was "##base" used? 
  2247.                                         */
  2248.             {
  2249.                 fprintf(outfile, "\tMyCaos.reg_a6\t\t=\t(ULONG) BASE_NAME;\n");
  2250.             }
  2251.             if (vd)
  2252.             {
  2253.                 fprintf(outfile, "\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
  2254.             }
  2255.             else
  2256.             {
  2257.                 fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n",
  2258.                         rettype);
  2259. /*
  2260.  * fprintf(outfile, "\treturn((%s)MyCaos.d0);\t\n}\n\n", rettype); 
  2261.  */
  2262.             }
  2263.         }
  2264.         else
  2265.         {
  2266.             fprintf(outfile, "%s__inline %s\n%s(%s",
  2267.                     (output_mode == STUBS ? "" : "extern "), rettype, name,
  2268.                     (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
  2269.  
  2270.             for (count = d0; count < numregs; count++)
  2271.             {
  2272.                 chtmp = fD_GetProto(obj, count);
  2273.                 if (fD_GetFuncParNum(obj) == count)
  2274.                     fprintf(outfile, chtmp, fD_GetParam(obj, count));
  2275.                 else
  2276.                     fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
  2277.                                                        "" : " "), fD_GetParam(obj, count));
  2278.                 if (count < numregs - 1)
  2279.                     fprintf(outfile, ", ");
  2280.             }
  2281.             fprintf(outfile, ")\n{\n%s", (BaseName[0] ? "   BASE_EXT_DECL\n" : ""));
  2282.             if (!vd)
  2283.                 fprintf(outfile, "   register %s%sres __asm(\"d0\");\n", rettype,
  2284.                         (*(rettype + strlen(rettype) - 1) == '*' ? "" : " "));
  2285.  
  2286.             if (BaseName[0])
  2287.                 fprintf(outfile, "   register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
  2288.                         StdLib);
  2289.  
  2290.             for (count = d0; count < numregs; count++)
  2291.             {
  2292.                 chtmp = fD_GetRegStr(obj, count);
  2293.                 if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
  2294.                     chtmp = "d7";
  2295.                 if (fD_GetFuncParNum(obj) == count)
  2296.                 {
  2297.                     fprintf(outfile, "   register ");
  2298.                     fprintf(outfile, fD_GetProto(obj, count), chtmp);
  2299.                     fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
  2300.                                                                                   count));
  2301.                 }
  2302.                 else
  2303.                 {
  2304.                     const char *proto = fD_GetProto(obj, count);
  2305.  
  2306.                     fprintf(outfile, "   register %s%s%s __asm(\"%s\") = %s;\n",
  2307.                             proto, (*(proto + strlen(proto) - 1) == '*' ? "" : " "), chtmp,
  2308.                             chtmp, fD_GetParam(obj, count));
  2309.                 }
  2310.             }
  2311.             if (a45)
  2312.                 fprintf(outfile, "   __asm volatile (\"exg d7,%s\\n\\t"
  2313.                         "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45 == 4 ? "a4" : "a5"),
  2314.                         -fD_GetOffset(obj), (a45 == 4 ? "a4" : "a5"));
  2315.             else
  2316.                 fprintf(outfile, "   __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
  2317.                         -fD_GetOffset(obj));
  2318.  
  2319.             fprintf(outfile, (vd ? "   : /* No Output */\n" : "   : \"=r\" (res)\n"));
  2320.  
  2321.             fprintf(outfile, "   : ");
  2322.             if (BaseName[0])
  2323.                 fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", " : ""));
  2324.  
  2325.             for (count = d0; count < numregs; count++)
  2326.             {
  2327.                 chtmp = fD_GetRegStr(obj, count);
  2328.                 if (a45 && (strcmp(chtmp, "a4") == 0 || strcmp(chtmp, "a5") == 0))
  2329.                     chtmp = "d7";
  2330.                 fprintf(outfile, "\"r\" (%s)%s", chtmp, (count < numregs - 1 ? ", " : ""));
  2331.             }
  2332.             fprintf(outfile, "\n   : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
  2333.  
  2334.             if (vd)
  2335.                 fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n");      /*
  2336.                                                                      * { 
  2337.                                                                      */
  2338.             else
  2339.                 fprintf(outfile, ", \"cc\", \"memory\");\n   return res;\n}\n\n");
  2340.         }
  2341.     }
  2342.  
  2343.     if ((tagname = aliasfunction(fD_GetName(obj))) != 0)
  2344.     {
  2345.         fprintf(outfile, "#define %s(", tagname);
  2346.         for (count = d0; count < numregs - 1; count++)
  2347.             fprintf(outfile, "a%d, ", count);
  2348.  
  2349.         fprintf(outfile, "a%d) %s (", count, name);
  2350.  
  2351.         for (count = d0; count < numregs - 1; count++)
  2352.             fprintf(outfile, "(a%d), ", count);
  2353.  
  2354.         fprintf(outfile, "(a%d))\n\n", count);
  2355.     }
  2356.  
  2357.     if ((tagname = taggedfunction(obj)) != 0)
  2358.     {
  2359.         if (output_mode != STUBS)
  2360.         {
  2361.             if (PowerUP || MorphOS)
  2362.             {
  2363.                 fprintf(outfile, "#ifndef NO_PPCINLINE_STDARG\n#define %s(", tagname);
  2364.             }
  2365.             else
  2366.             {
  2367.                 fprintf(outfile, "#ifndef NO_INLINE_STDARG\n#define %s(", tagname);
  2368.             }
  2369.  
  2370.             for (count = d0; count < numregs - 1; count++)
  2371.                 fprintf(outfile, "a%d, ", count);
  2372.  
  2373.             fprintf(outfile, "tags...) \\\n\t({ULONG _tags[] = { tags }; %s(",
  2374.                     name);
  2375.  
  2376.             for (count = d0; count < numregs - 1; count++)
  2377.                 fprintf(outfile, "(a%d), ", count);
  2378.  
  2379.             if (PowerUP || MorphOS)
  2380.             {
  2381.                 fprintf(outfile, "(%s)_tags);})\n#endif /* !NO_PPCINLINE_STDARG */\n\n",
  2382.                         fD_GetProto(obj, fD_RegNum(obj) - 1));
  2383.             }
  2384.             else
  2385.             {
  2386.                 fprintf(outfile, "(%s)_tags);})\n#endif /* !NO_INLINE_STDARG */\n\n",
  2387.                         fD_GetProto(obj, fD_RegNum(obj) - 1));
  2388.             }
  2389.         }
  2390.         else
  2391.         {
  2392.             if (MorphOS)
  2393.             {
  2394.                 int n = 9 - numregs;
  2395.                 int d = n & 1 ? 4 : 0;
  2396.                 int taglist = 8 + (DirectVarargsCalls ? 0 : 64);
  2397.                 int local = (n * 4 + d + 8 + 15) & ~15;   /* size of the stack frame */
  2398.  
  2399.               /*
  2400.                *  Stack frame:
  2401.                *
  2402.                *   0 -  3: next frame ptr
  2403.                *   4 -  7: save lr
  2404.                *   8 - 71: struct Caos
  2405.                *  72 - 72+n*4+d+8-1: tag list start
  2406.                *   ? - local-1: padding
  2407.                */
  2408.  
  2409.                 fprintf(outfile,
  2410.                     "asm(\"\n"
  2411.                     " .align  2         \n"
  2412.                     " .globl  %s        \n"
  2413.                     " .type   %s,@function\n"
  2414.                     "%s:                \n"
  2415.                     " stwu    1,-%d(1)  \n" /* create stack frame */
  2416.                     " mflr    0         \n"
  2417.                     " stw     0,%d(1)   \n",
  2418.                     tagname, tagname, tagname, local, local + 4);
  2419.  
  2420.               /*
  2421.                * If n is odd, one tag is split between regs and stack.
  2422.                * Copy its ti_Data together with the ti_Tag.
  2423.                */
  2424.                 if (d)
  2425.                     fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
  2426.  
  2427.               /*
  2428.                * Save the registers 
  2429.                */
  2430.                 for (count = numregs; count <= 8; count++)
  2431.                     fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
  2432.  
  2433.                 if (d)
  2434.                     fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
  2435.  
  2436.               /*
  2437.                * Add TAG_MORE
  2438.                */
  2439.                 fprintf(outfile, " li   0,2       \n"
  2440.                          " stw  0,%d(1)   \n" /* add TAG_MORE */
  2441.  
  2442.                          " addi 0,1,%d    \n"
  2443.                          " stw  0,%d(1)   \n", /* ti_Data = &stack_params */
  2444.                     taglist + n * 4 + d,
  2445.                     local + 8 + d, taglist + n * 4 + d + 4);
  2446.  
  2447.  
  2448.                 if (DirectVarargsCalls)
  2449.                 {
  2450.                     fprintf(outfile,
  2451.                         " addi %d,1,%d \n" /* vararg_reg = &saved regs */
  2452.                         " bl   %s      \n",
  2453.                         numregs + 2, taglist, name);
  2454.  
  2455.                 }
  2456.                 else
  2457.                 {
  2458.                    /*
  2459.                     * Caos.Offset = -fD_GetOffset(obj)
  2460.                     */
  2461.                     fprintf(outfile,
  2462.                         " li  0,%ld  \n"
  2463.                         " stw 0,8(1) \n",
  2464.                         fD_GetOffset(obj));
  2465.  
  2466.                    /*
  2467.                     * Save the non-varargs registers in the Caos struct.
  2468.                     */
  2469.                     for (count = 0; count < numregs - 1; count++)
  2470.                     {
  2471.                         int r = fD_GetReg(obj, count);
  2472.  
  2473.                         fprintf(outfile, "stw %d,%d(1)\n", count + 3, 8 + 4 + r * 4);
  2474.                     }
  2475.  
  2476.                     fprintf(outfile,
  2477.                         " addi 0,1,%d    \n"
  2478.                         " lis  3,%s@ha   \n"
  2479.                         " stw  0,%d(1)   \n" /* Caos.reg_?? = taglist */
  2480.                         " lwz  12,%s@l(3)\n"
  2481.                         " lwz  11,88(2)  \n"
  2482.                         " stw  12,68(1)  \n" /* Caos.reg_a6 = libbase */
  2483.                         " mtctr 11       \n"
  2484.                         " addi 3,1,8     \n"
  2485.                         " bctrl          \n", /* EmulCallOS() */
  2486.                         taglist, BaseName, 12 + 4 * fD_GetReg(obj, numregs - 1), BaseName);
  2487.                 }
  2488.  
  2489.                 fprintf(outfile," lwz  0,%d(1)   \n" /* clear stack frame & return */
  2490.                         " mtlr 0         \n"
  2491.                         " addi 1,1,%d    \n"
  2492.                         " blr            \n"
  2493.                         ".L%se1:         \n"
  2494.                         " .size\t%s,.L%se1-%s\n"
  2495.                         "\");\n\n",
  2496.                         local + 4, local,
  2497.                         tagname, tagname, tagname, tagname);
  2498.             }
  2499.             else
  2500.             {
  2501.                 fprintf(outfile, "%s %s(", rettype, tagname);
  2502.  
  2503.                 for (count = d0; count < numregs - 1; count++)
  2504.                 {
  2505.                     chtmp = fD_GetProto(obj, count);
  2506.                     if (count == fD_GetFuncParNum(obj))
  2507.                         fprintf(outfile, chtmp, fD_GetParam(obj, count));
  2508.                     else
  2509.                         fprintf(outfile, "%s%s%s", chtmp,
  2510.                                 (*(chtmp + strlen(chtmp) - 1) == '*' ? "" : " "),
  2511.                                 fD_GetParam(obj, count));
  2512.                     fprintf(outfile, ", ");
  2513.                 }
  2514.  
  2515.                 fprintf(outfile, "int tag, ...)\n{\n   ");
  2516.                 if (!vd)
  2517.                     fprintf(outfile, "return ");
  2518.  
  2519.                 fprintf(outfile, "%s(", name);
  2520.                 for (count = d0; count < numregs - 1; count++)
  2521.                     fprintf(outfile, "%s, ", fD_GetParam(obj, count));
  2522.  
  2523.                 fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj) - 1));
  2524.             }
  2525.         }
  2526.     }
  2527.  
  2528.     if (strcmp(name, "DoPkt") == 0)
  2529.     {
  2530.         fdDef *objnc = (fdDef *) obj;
  2531.         char newname[7] = "DoPkt0";
  2532.  
  2533.         objnc->name = newname;
  2534.         for (count = 2; count < 7; count++)
  2535.         {
  2536.             regs reg = objnc->reg[count];
  2537.             char *proto = objnc->proto[count];
  2538.  
  2539.             objnc->reg[count] = illegal;
  2540.             objnc->proto[count] = fD_nostring;
  2541.             fD_write(outfile, objnc);
  2542.             objnc->reg[count] = reg;
  2543.             objnc->proto[count] = proto;
  2544.             newname[5]++;
  2545.         }
  2546.         objnc->name = (char *)name;
  2547.     }
  2548. }
  2549.  
  2550. int
  2551. varargsfunction(const char *proto, const char *funcname)
  2552. {
  2553.     const char *end = proto + strlen(proto) - 1;
  2554.  
  2555.     while (isspace(*end))
  2556.         end--;
  2557.     if (*end-- == ';')
  2558.     {
  2559.         while (isspace(*end))
  2560.             end--;
  2561.         if (*end-- == ')')
  2562.         {
  2563.             while (isspace(*end))
  2564.                 end--;
  2565.             if (!strncmp(end - 2, "...", 3))
  2566.             {
  2567.               /*
  2568.                * Seems to be a varargs function. Check if it will be recognized
  2569.                * as "tagged". 
  2570.                */
  2571.                 unsigned int count;
  2572.                 char fixedname[200];   /*
  2573.  
  2574.                                         * Hope will be enough... 
  2575.                                         */
  2576.                 fdDef *tmpdef;
  2577.  
  2578.                 for (count = 0; count < sizeof TagExcTable / sizeof TagExcTable[0];
  2579.                      count += 2)
  2580.                     if (strcmp(funcname, TagExcTable[count + 1]) == 0)
  2581.                         return 1;
  2582.  
  2583.                 if (!(tmpdef = fD_ctor()))
  2584.                 {
  2585.                     fprintf(stderr, "No mem for FDs\n");
  2586.                     exit(EXIT_FAILURE);
  2587.                 }
  2588.  
  2589.                 strcpy(fixedname, funcname);
  2590.                 if (strlen(funcname) > 4 &&
  2591.                     !strcmp(funcname + strlen(funcname) - 4, "Tags"))
  2592.                 {
  2593.                   /*
  2594.                    * Might be either nothing or "TagList". 
  2595.                    */
  2596.                     fixedname[strlen(fixedname) - 4] = '\0';
  2597.                     fD_NewName(tmpdef, fixedname);
  2598.                     if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
  2599.                                 fD_cmpName))
  2600.                         return 1;
  2601.  
  2602.                     strcat(fixedname, "TagList");
  2603.                     fD_NewName(tmpdef, fixedname);
  2604.                     if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
  2605.                                 fD_cmpName))
  2606.                         return 1;
  2607.                 }
  2608.                 else
  2609.                 {
  2610.                     strcat(fixedname, "A");
  2611.                     fD_NewName(tmpdef, fixedname);
  2612.                     if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
  2613.                                 fD_cmpName))
  2614.                         return 1;
  2615.                 }
  2616.             }
  2617.         }
  2618.     }
  2619.     return 0;
  2620. }
  2621.  
  2622. int
  2623. ishandleddifferently(const char *proto, const char *funcname)
  2624. {
  2625.   /*
  2626.    * First check if this is a vararg call? 
  2627.    */
  2628.     if (varargsfunction(proto, funcname))
  2629.         return 1;
  2630.  
  2631.   /*
  2632.    * It might be a dos.library "alias" name. 
  2633.    */
  2634.     if (aliasfunction(funcname))
  2635.         return 1;
  2636.  
  2637.   /*
  2638.    * It might be one from dos.library/DoPkt() family. 
  2639.    */
  2640.     if (strlen(funcname) == 6 && !strncmp(funcname, "DoPkt", 5) &&
  2641.         funcname[5] >= '0' && funcname[6] <= '4')
  2642.         return 1;
  2643.  
  2644.   /*
  2645.    * Finally, it can be intuition.library/ReportMouse1(). 
  2646.    */
  2647.     return !strcmp(funcname, "ReportMouse1");
  2648. }
  2649.  
  2650. void 
  2651. output_proto(FILE * outfile)
  2652. {
  2653.     if (PowerUP || MorphOS)
  2654.     {
  2655.         fprintf(outfile,
  2656.                 "/* Automatically generated header! Do not edit! */\n\n"
  2657.                 "#ifndef PROTO_%s_H\n"
  2658.                 "#define PROTO_%s_H\n\n"
  2659.                 "#include <clib/%s_protos.h>\n\n"
  2660.                 "#ifdef __GNUC__\n"
  2661.                 "#ifdef __PPC__\n"
  2662.                 "#include <ppcinline/%s.h>\n"
  2663.                 "#else\n"
  2664.                 "#include <inline/%s.h>\n"
  2665.                 "#endif /* __PPC__ */\n"
  2666.                 "#else\n"
  2667.                 "#include <pragmas/%s_pragmas.h>\n"
  2668.                 "#endif /* __GNUC__ */\n\n",
  2669.                 BaseNamU, BaseNamU, BaseNamL, BaseNamL, BaseNamL, BaseNamL);
  2670.     }
  2671.     else
  2672.     {
  2673.         fprintf(outfile,
  2674.                 "/* Automatically generated header! Do not edit! */\n\n"
  2675.                 "#ifndef PROTO_%s_H\n"
  2676.                 "#define PROTO_%s_H\n\n"
  2677.                 "#include <clib/%s_protos.h>\n\n"
  2678.                 "#ifdef __GNUC__\n"
  2679.                 "#include <inline/%s.h>\n"
  2680.                 "#endif /* __GNUC__ */\n\n",
  2681.                 BaseNamU, BaseNamU, BaseNamL, BaseNamL);
  2682.     }
  2683.     if (BaseName[0])
  2684.         fprintf(outfile,
  2685.                 "#ifndef __NOLIBBASE__\n"
  2686.                 "extern struct %s *\n"
  2687.                 "#ifdef __CONSTLIBBASEDECL__\n"
  2688.                 "__CONSTLIBBASEDECL__\n"
  2689.                 "#endif /* __CONSTLIBBASEDECL__ */\n"
  2690.                 "%s;\n"
  2691.                 "#endif /* !__NOLIBBASE__ */\n\n",
  2692.                 StdLib, BaseName);
  2693.  
  2694.     if (PowerUP || MorphOS)
  2695.     {
  2696.         fprintf(outfile,
  2697.                 "#endif /* !PPCPROTO_%s_H */\n", BaseNamU);
  2698.     }
  2699.     else
  2700.     {
  2701.         fprintf(outfile,
  2702.                 "#endif /* !PROTO_%s_H */\n", BaseNamU);
  2703.     }
  2704. }
  2705.  
  2706. /******************************************************************************/
  2707.  
  2708. void 
  2709. printusage(const char *exename)
  2710. {
  2711.     fprintf(stderr,
  2712.             "Usage: %s [options] [--prefix name] [--subprefix name] [--premacro name] fd-file clib-file [[-o] output-file]\n"
  2713.             "Options:\n"
  2714.             "--new\t\t\tpreprocessor based (default)\n"
  2715.             "--old\t\t\tinline based\n"
  2716.             "--stubs\t\t\tlibrary stubs\n"
  2717.             "--proto\t\t\tbuild proto files (no clib-file required)\n"
  2718.             "--pragma\t\tbuild pragma file\n"
  2719.             "--powerup\t\tpowerup flag\n"
  2720.             "--morphos\t\tmorphos flag\n"
  2721.             "--gatestubs\t\tlibrary stubs\n"
  2722.             "--prelib\t\tgatestub pre library arg\n"
  2723.             "--postlib\t\tgatestub pre library arg\n"
  2724.             "--reglib\t\tgatestub uses REG_A6 arg for pre/postlib argument\n"
  2725.             "--direct-varargs-calls\n"
  2726.             "--local\t\tlocal includes\n"
  2727.             "--version\t\tprint version number and exit\n", exename);
  2728. }
  2729.  
  2730. int 
  2731. main(int argc, char **argv)
  2732. {
  2733.     fdDef *tmpdef,                                     /*
  2734.                                         * a dummy to contain the name to look for 
  2735.                                         */
  2736.     *founddef;                                                 /*
  2737.  
  2738.                                         * the fdDef for which we found a prototype 
  2739.                                         */
  2740.     fdFile *myfile;
  2741.     char *tmpstr;
  2742.     FILE *outfile;
  2743.     int    closeoutfile=FALSE;
  2744.     char *fdfilename = 0, *clibfilename = 0, *outfilename = 0;
  2745.  
  2746.     int count;
  2747.     Error lerror;
  2748.  
  2749.     for (count = 1; count < argc; count++)
  2750.     {
  2751.         char *option = argv[count];
  2752.  
  2753.         if (*option == '-')
  2754.         {
  2755.             option++;
  2756.             if (strcmp(option, "o") == 0)
  2757.             {
  2758.                 if (count == argc - 1 || outfilename)
  2759.                 {
  2760.                     printusage(argv[0]);
  2761.                     return EXIT_FAILURE;
  2762.                 }
  2763.                 if (strcmp(argv[++count], "-"))
  2764.                     outfilename = argv[count];
  2765.             }
  2766.             else
  2767.             {
  2768.                 if (*option == '-')        /*
  2769.                                 * Accept GNU-style '--' options 
  2770.                                 */
  2771.                     option++;
  2772.                 if (strcmp(option, "new") == 0)
  2773.                     output_mode = NEW;
  2774.                 else if (strcmp(option, "old") == 0)
  2775.                     output_mode = OLD;
  2776.                 else if (strcmp(option, "stubs") == 0)
  2777.                     output_mode = STUBS;
  2778.                 else if (strcmp(option, "proto") == 0)
  2779.                     output_mode = PROTO;
  2780.                 else if (strcmp(option, "pragma") == 0)
  2781.                     output_mode = PRAGMA;
  2782.                 else if (strcmp(option, "gatestubs")==0)
  2783.                     output_mode=GATESTUBS;
  2784.                 else if (strcmp(option, "powerup") == 0)
  2785.                     PowerUP = TRUE;
  2786.                 else if (strcmp(option, "morphos") == 0)
  2787.                     MorphOS = TRUE;
  2788.                 else if (strcmp(option, "reglib") == 0)
  2789.                     RegLibFlag = TRUE;
  2790.                 else if (strcmp(option, "prelib") == 0)
  2791.                 {
  2792.                     if (PostLibFlag)
  2793.                     {
  2794.                         printusage(argv[0]);
  2795.                         return EXIT_FAILURE;
  2796.                     }
  2797.                     PreLibFlag = TRUE;
  2798.                 }
  2799.                 else if (strcmp(option, "postlib") == 0)
  2800.                 {
  2801.                     if (PreLibFlag)
  2802.                     {
  2803.                         printusage(argv[0]);
  2804.                         return EXIT_FAILURE;
  2805.                     }
  2806.                     PostLibFlag = TRUE;
  2807.                 }
  2808.                 else if (strcmp(option, "local") == 0)
  2809.                 {
  2810.                     LocalFlag = TRUE;
  2811.                 }
  2812.                 else if (strcmp(option, "prefix") == 0)
  2813.                 {
  2814.  
  2815.                     if (count == argc - 1 || outfilename)
  2816.                     {
  2817.                         printusage(argv[0]);
  2818.                         return EXIT_FAILURE;
  2819.                     }
  2820.                     if (strcmp(argv[++count], "-"))
  2821.                     {
  2822.                         prefixname = argv[count];
  2823.                     }
  2824.                 }
  2825.                 else if (strcmp(option, "subprefix") == 0)
  2826.                 {
  2827.  
  2828.                     if (count == argc - 1 || outfilename)
  2829.                     {
  2830.                         printusage(argv[0]);
  2831.                         return EXIT_FAILURE;
  2832.                     }
  2833.                     if (strcmp(argv[++count], "-"))
  2834.                     {
  2835.                         subprefixname = argv[count];
  2836.                     }
  2837.                 }
  2838.                 else if (strcmp(option, "premacro") == 0)
  2839.                 {
  2840.  
  2841.                     if (count == argc - 1 || outfilename)
  2842.                     {
  2843.                         printusage(argv[0]);
  2844.                         return EXIT_FAILURE;
  2845.                     }
  2846.                     if (strcmp(argv[++count], "-"))
  2847.                     {
  2848.                         premacro = argv[count];
  2849.                     }
  2850.                 }
  2851.                 else if (strcmp(option, "direct-varargs-calls") == 0)
  2852.                     DirectVarargsCalls = TRUE;
  2853.                 else if (strcmp(option, "version") == 0)
  2854.                 {
  2855.                     fprintf(stderr, "fd2inline version " VERSION "\n");
  2856.                     return EXIT_SUCCESS;
  2857.                 }
  2858.                 else
  2859.                 {
  2860.                     printusage(argv[0]);
  2861.                     return EXIT_FAILURE;
  2862.                 }
  2863.             }
  2864.         }
  2865.         else
  2866.         {
  2867.           /*
  2868.            * One of the filenames 
  2869.            */
  2870.             if (!fdfilename)
  2871.                 fdfilename = option;
  2872.             else if (!clibfilename)
  2873.                 clibfilename = option;
  2874.             else if (!outfilename)
  2875.                 outfilename = option;
  2876.             else
  2877.             {
  2878.                 printusage(argv[0]);
  2879.                 return EXIT_FAILURE;
  2880.             }
  2881.         }
  2882.     }
  2883.  
  2884.     if (!fdfilename || (!clibfilename && output_mode != PROTO))
  2885.     {
  2886.         printusage(argv[0]);
  2887.         return EXIT_FAILURE;
  2888.     }
  2889.  
  2890.     if (!(arrdefs = malloc(FDS * sizeof(fdDef *))))
  2891.     {
  2892.         fprintf(stderr, "No mem for FDs\n");
  2893.         return EXIT_FAILURE;
  2894.     }
  2895.     for (count = 0; count < FDS; count++)
  2896.         arrdefs[count] = NULL;
  2897.  
  2898.     if (!(myfile = fF_ctor(fdfilename)))
  2899.     {
  2900.         fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
  2901.         return EXIT_FAILURE;
  2902.     }
  2903.  
  2904.     lerror = false;
  2905.  
  2906.     for (count = 0; count < FDS && lerror == false; count++)
  2907.     {
  2908.         if (!(arrdefs[count] = fD_ctor()))
  2909.         {
  2910.             fprintf(stderr, "No mem for FDs\n");
  2911.             return EXIT_FAILURE;
  2912.         }
  2913.         do
  2914.         {
  2915.             if ((lerror = fF_readln(myfile)) == false)
  2916.             {
  2917.                 fF_SetError(myfile, false);
  2918.                 lerror = fD_parsefd(arrdefs[count], myfile);
  2919.             }
  2920.         }
  2921.         while (lerror == nodef);
  2922.     }
  2923.     if (count < FDS)
  2924.     {
  2925.         count--;
  2926.         fD_dtor(arrdefs[count]);
  2927.         arrdefs[count] = NULL;
  2928.     }
  2929.     fds = count;
  2930.  
  2931.     qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
  2932.  
  2933.     if (output_mode != NEW)
  2934.     {
  2935.         unsigned int count2;
  2936.  
  2937.         StdLib = "Library";
  2938.  
  2939.         for (count2 = 0; count2 < sizeof LibExcTable / sizeof LibExcTable[0]; count2 += 2)
  2940.             if (strcmp(BaseName, LibExcTable[count2]) == 0)
  2941.             {
  2942.                 StdLib = LibExcTable[count2 + 1];
  2943.                 break;
  2944.             }
  2945.     }
  2946.  
  2947.     fF_dtor(myfile);
  2948.  
  2949.     if (output_mode != PROTO)
  2950.     {
  2951.         if (!(myfile = fF_ctor(clibfilename)))
  2952.         {
  2953.             fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
  2954.             return EXIT_FAILURE;
  2955.         }
  2956.  
  2957.         if (!(tmpdef = fD_ctor()))
  2958.         {
  2959.             fprintf(stderr, "No mem for FDs\n");
  2960.             return EXIT_FAILURE;
  2961.         }
  2962.  
  2963.         for (lerror = false; lerror == false || lerror == nodef;)
  2964.             if ((lerror = fF_readln(myfile)) == false)
  2965.             {
  2966.                 fF_SetError(myfile, false);             /*
  2967.                                                  * continue even on errors 
  2968.                                                  */
  2969.                 tmpstr = fF_FuncName(myfile);
  2970.  
  2971.                 if (tmpstr)
  2972.                 {
  2973.                     fdDef **res;
  2974.  
  2975.                     fD_NewName(tmpdef, tmpstr);
  2976.                     res = (fdDef **) bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
  2977.                                              fD_cmpName);
  2978.  
  2979.                     if (res)
  2980.                     {
  2981.                         founddef = *res;
  2982.                         DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
  2983.                         fF_SetError(myfile, false);
  2984.                         lerror = fD_parsepr(founddef, myfile);
  2985.                     }
  2986.                     else if (!ishandleddifferently(myfile->line, tmpstr))
  2987.                         fprintf(stderr, "don't know what to do with <%s> in line %lu.\n",
  2988.                                 tmpstr, myfile->lineno);
  2989.                     free(tmpstr);
  2990.                 }
  2991.             }
  2992.  
  2993.         fD_dtor(tmpdef);
  2994.  
  2995.         fF_dtor(myfile);
  2996.     }
  2997.  
  2998.     if (strlen(fdfilename) > 7 &&
  2999.         !strcmp(fdfilename + strlen(fdfilename) - 7, "_lib.fd"))
  3000.     {
  3001.         char *str = fdfilename + strlen(fdfilename) - 8;
  3002.  
  3003.         while (str != fdfilename && str[-1] != '/' && str[-1] != ':')
  3004.             str--;
  3005.         strncpy(BaseNamL, str, strlen(str) - 7);
  3006.         strncpy(BaseNamU, str, strlen(str) - 7);
  3007.         BaseNamU[strlen(str) - 7] = '\0';
  3008.     }
  3009.     else
  3010.     {
  3011.       /*
  3012.        * Shouldn't really happen, but... 
  3013.        */
  3014.         strcpy(BaseNamU, BaseName);
  3015.         if (strlen(BaseNamU) > 4 && strcmp(BaseNamU + strlen(BaseNamU) - 4, "Base") == 0)
  3016.             BaseNamU[strlen(BaseNamU) - 4] = '\0';
  3017.     }
  3018.     StrUpr(BaseNamU);
  3019.  
  3020.     if (outfilename)
  3021.     {
  3022.         if (!(outfile = fopen(outfilename, "w")))
  3023.         {
  3024.             fprintf(stderr, "Couldn't open output file.\n");
  3025.             return EXIT_FAILURE;
  3026.         }
  3027.         else
  3028.         {
  3029.             closeoutfile=TRUE;
  3030.         }
  3031.     }
  3032.     else
  3033.     {
  3034.         outfile = stdout;
  3035.     }
  3036.  
  3037.     if (output_mode == PROTO)
  3038.     {
  3039.         output_proto(outfile);
  3040.     }
  3041.     else
  3042.     {
  3043.         if (output_mode == NEW)
  3044.         {
  3045.             if (PowerUP || MorphOS)
  3046.             {
  3047.                 fprintf(outfile,
  3048.                         "/* Automatically generated header! Do not edit! */\n\n"
  3049.                         "#ifndef _PPCINLINE_%s_H\n"
  3050.                         "#define _PPCINLINE_%s_H\n\n"
  3051.                         "#ifndef __PPCINLINE_MACROS_H\n"
  3052.                         "#include <ppcinline/macros.h>\n"
  3053.                         "#endif /* !__PPCINLINE_MACROS_H */\n\n",
  3054.                         BaseNamU,
  3055.                         BaseNamU);
  3056.             }
  3057.             else
  3058.             {
  3059.                 fprintf(outfile,
  3060.                         "/* Automatically generated header! Do not edit! */\n\n"
  3061.                         "#ifndef _INLINE_%s_H\n"
  3062.                         "#define _INLINE_%s_H\n\n"
  3063.                         "#ifndef __INLINE_MACROS_H\n"
  3064.                         "#include <inline/macros.h>\n"
  3065.                         "#endif /* !__INLINE_MACROS_H */\n\n",
  3066.                         BaseNamU,
  3067.                         BaseNamU);
  3068.             }
  3069.         }
  3070.         else if (output_mode == PRAGMA)
  3071.         {
  3072.             if (PowerUP || MorphOS)
  3073.             {
  3074.                 fprintf(outfile,
  3075.                     "/* Automatically generated header! Do not edit! */\n\n"
  3076.                     "#ifndef _PPCPRAGMA_%s_H\n"
  3077.                     "#define _PPCPRAGMA_%s_H\n"
  3078.                     "#ifdef __GNUC__\n"
  3079.                     "#ifndef _PPCINLINE__%s_H\n"
  3080.                     "#include <ppcinline/%s.h>\n"
  3081.                     "#endif\n"
  3082.                     "#else\n\n"
  3083.                     "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
  3084.                     "#include <ppclib/interface.h>\n"
  3085.                     "#endif\n\n"
  3086.                     "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
  3087.                     "#include <gcclib/powerup_protos.h>\n"
  3088.                     "#endif\n\n"
  3089.                     "#ifndef NO_PPCINLINE_STDARG\n"
  3090.                     "#define NO_PPCINLINE_STDARG\n"
  3091.                     "#endif"
  3092.                     "/* SAS C PPC inlines */\n\n",
  3093.                     BaseNamU,
  3094.                     BaseNamU,
  3095.                     BaseNamU,
  3096.                     BaseNamL);
  3097.             }
  3098.             else
  3099.             {
  3100.                 fprintf(outfile,
  3101.                         "/* Automatically generated header! Do not edit! */\n\n"
  3102.                         "#ifndef _INLINE__%s_H\n"
  3103.                         "#include <inline/%s.h>\n\n",
  3104.                         BaseNamU,
  3105.                         BaseNamL);
  3106.             }
  3107.  
  3108.         }
  3109.         else if (output_mode == GATESTUBS)
  3110.         {
  3111.             if (LocalFlag)
  3112.             {
  3113.                 fprintf(outfile,
  3114.                     "/* Automatically generated gate stubs */\n\n"
  3115.                     "%s\n"
  3116.                     "#include \"%s_protos.h\"\n\n"
  3117.                     "#include <emul/emulregs.h>\n",
  3118.                     premacro,
  3119.                     BaseNamL);
  3120.             }
  3121.             else
  3122.             {
  3123.                 fprintf(outfile,
  3124.                     "/* Automatically generated gate stubs */\n\n"
  3125.                     "%s\n"
  3126.                     "#include <clib/%s_protos.h>\n\n"
  3127.                     "#include <emul/emulregs.h>\n",
  3128.                     premacro,
  3129.                     BaseNamL);
  3130.             }
  3131.         }
  3132.         else
  3133.         {
  3134.             if (PowerUP || MorphOS)
  3135.             {
  3136.                 fprintf(outfile,
  3137.                     "/* Automatically generated header! Do not edit! */\n\n"
  3138.                     "#ifndef _PPCINLINE_%s_H\n"
  3139.                     "#define _PPCINLINE_%s_H\n\n"
  3140.                     "#ifndef __PPCINLINE_STUB_H\n"
  3141.                     "#include <ppcinline/stubs.h>\n"
  3142.                     "#endif /* !__PPCINLINE_STUB_H */\n\n",
  3143.                     BaseNamU,
  3144.                     BaseNamU);
  3145.                 if (MorphOS)
  3146.                     fprintf(outfile, "#include <emul/emulregs.h>\n");
  3147.             }
  3148.             else
  3149.             {
  3150.                 fprintf(outfile,
  3151.                     "/* Automatically generated header! Do not edit! */\n\n"
  3152.                     "#ifndef _INLINE_%s_H\n"
  3153.                     "#define _INLINE_%s_H\n\n"
  3154.                     "#ifndef __INLINE_STUB_H\n"
  3155.                     "#include <inline/stubs.h>\n"
  3156.                     "#endif /* !__INLINE_STUB_H */\n\n",
  3157.                     BaseNamU,
  3158.                     BaseNamU);
  3159.             }
  3160.         }
  3161.  
  3162.         if (BaseName[0])
  3163.         {
  3164.             if (output_mode == NEW || (output_mode == PRAGMA && (PowerUP == TRUE || MorphOS == TRUE)))
  3165.             {
  3166.                 fprintf(outfile,
  3167.                         "#ifndef %s_BASE_NAME\n"
  3168.                         "#define %s_BASE_NAME %s\n"
  3169.                         "#endif /* !%s_BASE_NAME */\n\n",
  3170.                         BaseNamU, BaseNamU, BaseName, BaseNamU);
  3171.             }
  3172.             else
  3173.             {
  3174.                 fprintf(outfile,
  3175.                         "#ifndef BASE_EXT_DECL\n"
  3176.                         "#define BASE_EXT_DECL\n"
  3177.                         "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
  3178.                         "#endif /* !BASE_EXT_DECL */\n"
  3179.                         "#ifndef BASE_PAR_DECL\n"
  3180.                         "#define BASE_PAR_DECL\n"
  3181.                         "#define BASE_PAR_DECL0 void\n"
  3182.                         "#endif /* !BASE_PAR_DECL */\n"
  3183.                         "#ifndef BASE_NAME\n"
  3184.                         "#define BASE_NAME %s\n"
  3185.                         "#endif /* !BASE_NAME */\n\n"
  3186.                         "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
  3187.             }
  3188.         }
  3189.  
  3190.         for (count = 0; count < FDS && arrdefs[count]; count++)
  3191.         {
  3192.             DBP(fprintf(stderr, "outputting %ld...\n", count));
  3193.  
  3194.             fD_write(outfile, arrdefs[count]);
  3195.             fD_dtor(arrdefs[count]);
  3196.             arrdefs[count] = NULL;
  3197.         }
  3198.  
  3199.         if (output_mode == OLD || output_mode == STUBS)
  3200.         {
  3201.             if (BaseName[0])
  3202.             {
  3203.                 fprintf(outfile,
  3204.                         "#undef BASE_EXT_DECL\n"
  3205.                         "#undef BASE_EXT_DECL0\n"
  3206.                         "#undef BASE_PAR_DECL\n"
  3207.                         "#undef BASE_PAR_DECL0\n"
  3208.                         "#undef BASE_NAME\n\n");
  3209.             }
  3210.  
  3211.             if (PowerUP || MorphOS)
  3212.             {
  3213.                 fprintf(outfile, "#endif /* !_PPCINLINE_%s_H */\n", BaseNamU);
  3214.             }
  3215.             else
  3216.             {
  3217.                 fprintf(outfile, "#endif /* !_INLINE_%s_H */\n", BaseNamU);
  3218.             }
  3219.         }
  3220.         else if (output_mode == PRAGMA)
  3221.         {
  3222.             fprintf(outfile, "#endif /* SASC Pragmas */\n");
  3223.             if (PowerUP || MorphOS)
  3224.             {
  3225.                 fprintf(outfile, "#endif /* !_PPCPRAGMA_%s_H */\n", BaseNamU);
  3226.             }
  3227.             else
  3228.             {
  3229.                 fprintf(outfile, "#endif /* !_PRAGMA_%s_H */\n", BaseNamU);
  3230.             }
  3231.         }
  3232.         else if (output_mode == NEW)
  3233.         {
  3234.             if (PowerUP || MorphOS)
  3235.             {
  3236.                 fprintf(outfile, "#endif /* !_PPCINLINE_%s_H */\n", BaseNamU);
  3237.             }
  3238.             else
  3239.             {
  3240.                 fprintf(outfile, "#endif /* !_INLINE_%s_H */\n", BaseNamU);
  3241.             }
  3242.         }
  3243.  
  3244.     }
  3245.  
  3246.     free(arrdefs);
  3247.     if (closeoutfile)
  3248.     {
  3249.         fclose(outfile);
  3250.     }
  3251.     return EXIT_SUCCESS;
  3252. }
  3253.