home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / dev / misc / fd2pragma.lha / fd2pragma / fd2pragma.c < prev    next >
C/C++ Source or Header  |  1994-03-12  |  26KB  |  1,122 lines

  1. /*
  2.     fd2pragma.c
  3.  
  4.     This is a small little hack which converts fd-files to either
  5.     pragmas readable by a C-Compiler of LVO files readable by an
  6.     assembler. Use it as you want, but WITHOUT ANY WARRANTY!
  7.  
  8.     V1.2:   Added pragmas for the Dice compiler. Available via switch "Dice".
  9.         Added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
  10.         turn on the default (except that Maxon expects pragma files to be
  11.         called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
  12.         Dice, except that SAS supports the pragma tagcall.
  13.  
  14.     V2.0:   Added support for tag functions. See the docs for details.
  15.  
  16.     Computer: Amiga 1200            Compiler: Aztec-C V5.0a
  17.                               Dice 2.07.54 (3.0)
  18.  
  19.     Author:    Jochen Wiedmann
  20.         Am Eisteich 9
  21.       72555 Metzingen (Germany)
  22.         Tel. 07123 / 14881
  23.         Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
  24. */
  25.  
  26.  
  27.  
  28.  
  29.  
  30. /*
  31.     Include files
  32. */
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include <exec/nodes.h>
  38. #include <exec/lists.h>
  39. #include <exec/libraries.h>
  40. #include <clib/exec_protos.h>
  41. #include <clib/alib_protos.h>
  42. #include <clib/dos_protos.h>
  43.  
  44. #ifdef AZTEC_C
  45. #include <pragmas/exec_lib.h>
  46. #include <pragmas/dos_lib.h>
  47. #endif
  48.  
  49. #if defined(_DCC)  ||  defined(__SASC)  ||  defined(__MAXON)
  50. #include <pragmas/exec_pragmas.h>
  51. #include <pragmas/dos_pragmas.h>
  52. #endif
  53.  
  54. #ifdef __GNUC__
  55. #include <inline/exec.h>
  56. #include <inline/dos.h>
  57. #endif
  58.  
  59.  
  60.  
  61.  
  62.  
  63. /*
  64.     Constants
  65. */
  66. #define MAXNAMELEN 128
  67.  
  68. const UBYTE VERSION[] = "$VER: fd2pragma 2.0 (11.03.94)   by  Jochen Wiedmann";
  69. const UBYTE TEMPLATE[] =
  70.     "FDFILE/A,AZTEC/K,AS/K,SAS/K,DICE/K,MAXON/K,TAGDIR/K,HELP/S";
  71.  
  72. const STRPTR RegNames[16] =
  73. { (STRPTR) "d0", (STRPTR) "d1", (STRPTR) "d2", (STRPTR) "d3",
  74.   (STRPTR) "d4", (STRPTR) "d5", (STRPTR) "d6", (STRPTR) "d7",
  75.   (STRPTR) "a0", (STRPTR) "a1", (STRPTR) "a2", (STRPTR) "a3",
  76.   (STRPTR) "a4", (STRPTR) "a5", (STRPTR) "a6", (STRPTR) "a7"
  77. };
  78.  
  79. const UBYTE HexDigits[16] = "0123456789ABCDEF";
  80.  
  81.  
  82.  
  83. /*
  84.     This structure is used to represent the pragmas that are read.
  85. */
  86. struct AmiPragma
  87. { struct MinNode Node;
  88.   LONG Bias;
  89.   LONG Public;
  90.   STRPTR FuncName;
  91.   STRPTR TagName;
  92.   ULONG NumArgs;
  93.   struct
  94.   { STRPTR ArgName;
  95.     ULONG ArgReg;
  96.   } Args[14];    /*  a6 and a7 must not be used for function arguments    */
  97. };
  98.  
  99.  
  100.  
  101.  
  102.  
  103. /*
  104.     Global variables
  105. */
  106. struct MinList AmiPragmaList;
  107. STRPTR BaseName;
  108. STRPTR ShortBaseName;
  109.  
  110.  
  111.  
  112.  
  113.  
  114. /*
  115.     This function works similar to strdup, but doesn't duplicate the
  116.     whole string.
  117.  
  118.     Inputs: Str - the string to be duplicated
  119.         Len - the number of bytes to be duplicated
  120.  
  121.     Result: Pointer to the copy of the string or NULL.
  122. */
  123. STRPTR strndup(const STRPTR Str, ULONG Len)
  124.  
  125. { STRPTR result;
  126.  
  127.   if ((result = malloc(Len+1)))
  128.   { memcpy(result, Str, Len);
  129.     result[Len] = '\0';
  130.   }
  131.   return(result);
  132. }
  133.  
  134.  
  135.  
  136.  
  137.  
  138. /*
  139.     This function prints help information.
  140. */
  141. void Usage(void)
  142.  
  143. { fprintf(stderr, "\nUsage: fd2pragma %s\n\n", TEMPLATE);
  144.  
  145.   fprintf(stderr, "This program reads the given FDFILE and converts it ");
  146.   fprintf(stderr, "into pragmas for\n");
  147.   fprintf(stderr, "a C-Compiler (SAS, Dice, Aztec or Maxon) or LVO files ");
  148.   fprintf(stderr, "for an\n");
  149.   fprintf(stderr, "Assembler (Aztec-As).\n\n");
  150.   fprintf(stderr, "TAGDIR is the name of a directory where to store stub ");
  151.   fprintf(stderr, "routines for\n");
  152.   fprintf(stderr, "pragma functions, if any are found. \"\" is the current ");
  153.   fprintf(stderr, "directory.\n\n\n");
  154.   fprintf(stderr, "%s\n\n", VERSION+6);
  155.   fprintf(stderr,
  156.       "This is public domain, use it as you want, but WITHOUT ANY WARRANTY!\n");
  157.   fprintf(stderr,
  158.       "Bugs and suggestions to wiedmann@mailserv.zdv.uni-tuebingen.de.\n\n");
  159.  
  160.   exit (1);
  161. }
  162.  
  163.  
  164.  
  165.  
  166.  
  167. /*
  168.     This function is used to skip over blanks.
  169.  
  170.     Inputs: OldPtr  - pointer to the beginning of a string.
  171.  
  172.     Result: Pointer to the first nonblank character of the string.
  173. */
  174. STRPTR SkipBlanks(const STRPTR OldPtr)
  175.  
  176. { STRPTR oldptr = OldPtr;
  177.  
  178.   while (*oldptr == ' '  ||  *oldptr == '\t')
  179.   { ++oldptr;
  180.   }
  181.   return(oldptr);
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*
  189.     This function is used to skip over vvariable names.
  190.  
  191.     Inputs: OldPtr  - pointer to the beginning of a string.
  192.  
  193.     Result: Pointer to the first character of the string, that is not one
  194.         of a-z, A-Z, 0-9 or the underscore.
  195. */
  196. STRPTR SkipName(const STRPTR OldPtr)
  197.  
  198. { STRPTR oldptr;
  199.   UBYTE c;
  200.  
  201.   oldptr = OldPtr;
  202.   while((c = *oldptr) == '_'  ||
  203.     (c >= '0'  &&  c <= '9')  ||
  204.     (c >= 'a'  &&  c <= 'z')  ||
  205.     (c >= 'A'  &&  c <= 'Z'))
  206.   { ++oldptr;
  207.   }
  208.   return(oldptr);
  209. }
  210.  
  211.  
  212.  
  213.  
  214.  
  215. /*
  216.     This function tells, that we ran out of memory.
  217. */
  218. void MemError(void)
  219.  
  220. { fprintf(stderr, "Fatal: Out of memory!\n");
  221. }
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228. /*
  229.     This function is called to scan the FD file.
  230.  
  231.     Inputs: FDFile  - the name of the file to scan
  232.  
  233.     Result: TRUE, if successful, FALSE otherwise
  234. */
  235. ULONG ScanFDFile(const STRPTR FDFile)
  236.  
  237. { FILE *fp;
  238.   ULONG public = TRUE;
  239.   ULONG bias = -1;
  240.   ULONG linenum = 0;
  241.   ULONG result = FALSE;
  242.   UBYTE line[512];
  243.  
  244.   if (!(fp = fopen((char *) FDFile, "r")))
  245.   { fprintf(stderr, "Fatal: Cannot open FD file %s.\n", FDFile);
  246.     return(FALSE);
  247.   }
  248.  
  249.   NewList((struct List *) &AmiPragmaList);
  250.  
  251.   while(fgets((char *) line, sizeof(line), fp)  !=  NULL)
  252.   { ULONG len;
  253.  
  254.     ++linenum;
  255.  
  256.     for (len = 0;  len < sizeof(line);  ++len)
  257.     { if (line[len] == '\n')
  258.       { break;
  259.       }
  260.     }
  261.     if (len == sizeof(line))
  262.     { int c;
  263.  
  264.       fprintf(stderr, "Error: Line %ld too long.\n", linenum);
  265.       while((c = getc(fp)) != EOF  &&  c != '\n')
  266.       {
  267.       }
  268.       continue;
  269.     }
  270.     line[len] = '\0';   /*  Remove Line Feed    */
  271.  
  272.     if (line[0] == '*')
  273.     { /*  Comment   */
  274.       STRPTR ptr;
  275.  
  276.       ptr = SkipBlanks(line+1);
  277.       if(strnicmp((char *) ptr, "tagcall", 7) == 0)  /*  Tag to create?  */
  278.       { struct AmiPragma *prevpragma;
  279.  
  280.     ptr = SkipBlanks(ptr+7);
  281.  
  282.     prevpragma = (struct AmiPragma *) AmiPragmaList.mlh_TailPred;
  283.     if (!prevpragma->Node.mln_Pred)
  284.     { fprintf(stderr,
  285.           "Line %ld, Error: Tag definition without preceding Pragma.\n",
  286.           linenum);
  287.       continue;
  288.     }
  289.  
  290.     if (prevpragma->TagName)
  291.     { fprintf(stderr, "Line %ld, Error: Tag function declared twice.\n",
  292.           linenum);
  293.       continue;
  294.     }
  295.  
  296.     if (!prevpragma->NumArgs)
  297.     { fprintf(stderr,
  298.           "Line %ld, Error: Tag function must have arguments.\n",
  299.           linenum);
  300.     }
  301.  
  302.     /*
  303.         Get the tag functions name.
  304.     */
  305.     len = strlen((char *) prevpragma->FuncName)+strlen((char *) ptr)+1;
  306.  
  307.     if (!(prevpragma->TagName = strndup(prevpragma->FuncName, len)))
  308.     { MemError();
  309.       goto exit_ScanFDFile;
  310.     }
  311.  
  312.     if (!*ptr)
  313.     { len = strlen((char *) prevpragma->TagName);
  314.       if (prevpragma->TagName[len-1] == 'A')
  315.       { prevpragma->TagName[len-1] = '\0';
  316.       }
  317.     }
  318.     else
  319.     { STRPTR nextptr;
  320.  
  321.       if (*ptr == '-')
  322.       { STRPTR removeptr;
  323.  
  324.         ptr = SkipBlanks(ptr+1);
  325.         nextptr = SkipName(ptr);
  326.         if ((len = nextptr-ptr))
  327.         { removeptr = prevpragma->TagName+strlen((char *) prevpragma->TagName)-len;
  328.           if (!strncmp((char *) removeptr, (char *) ptr, len))
  329.           { fprintf(stderr,
  330.             "Line %ld, Error: Cannot convert pragma name into tag name.\n",
  331.             linenum);
  332.         continue;
  333.           }
  334.           *removeptr = '\0';
  335.         }
  336.         ptr = SkipBlanks(nextptr);
  337.       }
  338.       if (*ptr == '+')
  339.       { ptr = SkipBlanks(ptr+1);
  340.       }
  341.       else
  342.       { *ptr = toupper((int) *ptr);
  343.       }
  344.  
  345.       nextptr = SkipName(ptr);
  346.       len = nextptr-ptr;
  347.       if (len)
  348.       { strncat((char *) prevpragma->TagName, (char *) ptr, len);
  349.         ptr += len;
  350.       }
  351.  
  352.       if (*SkipBlanks(nextptr))
  353.       { fprintf(stderr, "Line %ld, warning: Extra characters\n", linenum);
  354.       }
  355.     }
  356.       }
  357.     }
  358.     else if (strnicmp((char *) line, "##base", 6) == 0)
  359.     { STRPTR ptr, nextptr;
  360.       LONG len;
  361.  
  362.       if (BaseName)
  363.       { fprintf(stderr, "Line %ld, Error: Basename declared twice.\n",
  364.         linenum);
  365.       }
  366.  
  367.       ptr = SkipBlanks(line+6);
  368.       if (*ptr != '_')
  369.       { fprintf(stderr, "Line %ld, Warning: Expected preceding _ in Basename.\n",
  370.         linenum);
  371.       }
  372.       else
  373.       { ++ptr;
  374.       }
  375.       nextptr = SkipName(ptr);
  376.       if ((len = nextptr-ptr))
  377.       { if (!(BaseName = strndup(ptr, len)))
  378.     { MemError();
  379.       goto exit_ScanFDFile;
  380.     }
  381.  
  382.     ptr = FilePart(FDFile);
  383.     len = strlen((char *) ptr)-7;
  384.     if (len >= 0  &&  stricmp((char *) ptr+len, "_lib.fd