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