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 >
Wrap
C/C++ Source or Header
|
1994-03-12
|
26KB
|
1,122 lines
/*
fd2pragma.c
This is a small little hack which converts fd-files to either
pragmas readable by a C-Compiler of LVO files readable by an
assembler. Use it as you want, but WITHOUT ANY WARRANTY!
V1.2: Added pragmas for the Dice compiler. Available via switch "Dice".
Added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
turn on the default (except that Maxon expects pragma files to be
called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
Dice, except that SAS supports the pragma tagcall.
V2.0: Added support for tag functions. See the docs for details.
Computer: Amiga 1200 Compiler: Aztec-C V5.0a
Dice 2.07.54 (3.0)
Author: Jochen Wiedmann
Am Eisteich 9
72555 Metzingen (Germany)
Tel. 07123 / 14881
Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
*/
/*
Include files
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#ifdef AZTEC_C
#include <pragmas/exec_lib.h>
#include <pragmas/dos_lib.h>
#endif
#if defined(_DCC) || defined(__SASC) || defined(__MAXON)
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#endif
#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/dos.h>
#endif
/*
Constants
*/
#define MAXNAMELEN 128
const UBYTE VERSION[] = "$VER: fd2pragma 2.0 (11.03.94) by Jochen Wiedmann";
const UBYTE TEMPLATE[] =
"FDFILE/A,AZTEC/K,AS/K,SAS/K,DICE/K,MAXON/K,TAGDIR/K,HELP/S";
const STRPTR RegNames[16] =
{ (STRPTR) "d0", (STRPTR) "d1", (STRPTR) "d2", (STRPTR) "d3",
(STRPTR) "d4", (STRPTR) "d5", (STRPTR) "d6", (STRPTR) "d7",
(STRPTR) "a0", (STRPTR) "a1", (STRPTR) "a2", (STRPTR) "a3",
(STRPTR) "a4", (STRPTR) "a5", (STRPTR) "a6", (STRPTR) "a7"
};
const UBYTE HexDigits[16] = "0123456789ABCDEF";
/*
This structure is used to represent the pragmas that are read.
*/
struct AmiPragma
{ struct MinNode Node;
LONG Bias;
LONG Public;
STRPTR FuncName;
STRPTR TagName;
ULONG NumArgs;
struct
{ STRPTR ArgName;
ULONG ArgReg;
} Args[14]; /* a6 and a7 must not be used for function arguments */
};
/*
Global variables
*/
struct MinList AmiPragmaList;
STRPTR BaseName;
STRPTR ShortBaseName;
/*
This function works similar to strdup, but doesn't duplicate the
whole string.
Inputs: Str - the string to be duplicated
Len - the number of bytes to be duplicated
Result: Pointer to the copy of the string or NULL.
*/
STRPTR strndup(const STRPTR Str, ULONG Len)
{ STRPTR result;
if ((result = malloc(Len+1)))
{ memcpy(result, Str, Len);
result[Len] = '\0';
}
return(result);
}
/*
This function prints help information.
*/
void Usage(void)
{ fprintf(stderr, "\nUsage: fd2pragma %s\n\n", TEMPLATE);
fprintf(stderr, "This program reads the given FDFILE and converts it ");
fprintf(stderr, "into pragmas for\n");
fprintf(stderr, "a C-Compiler (SAS, Dice, Aztec or Maxon) or LVO files ");
fprintf(stderr, "for an\n");
fprintf(stderr, "Assembler (Aztec-As).\n\n");
fprintf(stderr, "TAGDIR is the name of a directory where to store stub ");
fprintf(stderr, "routines for\n");
fprintf(stderr, "pragma functions, if any are found. \"\" is the current ");
fprintf(stderr, "directory.\n\n\n");
fprintf(stderr, "%s\n\n", VERSION+6);
fprintf(stderr,
"This is public domain, use it as you want, but WITHOUT ANY WARRANTY!\n");
fprintf(stderr,
"Bugs and suggestions to wiedmann@mailserv.zdv.uni-tuebingen.de.\n\n");
exit (1);
}
/*
This function is used to skip over blanks.
Inputs: OldPtr - pointer to the beginning of a string.
Result: Pointer to the first nonblank character of the string.
*/
STRPTR SkipBlanks(const STRPTR OldPtr)
{ STRPTR oldptr = OldPtr;
while (*oldptr == ' ' || *oldptr == '\t')
{ ++oldptr;
}
return(oldptr);
}
/*
This function is used to skip over vvariable names.
Inputs: OldPtr - pointer to the beginning of a string.
Result: Pointer to the first character of the string, that is not one
of a-z, A-Z, 0-9 or the underscore.
*/
STRPTR SkipName(const STRPTR OldPtr)
{ STRPTR oldptr;
UBYTE c;
oldptr = OldPtr;
while((c = *oldptr) == '_' ||
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z'))
{ ++oldptr;
}
return(oldptr);
}
/*
This function tells, that we ran out of memory.
*/
void MemError(void)
{ fprintf(stderr, "Fatal: Out of memory!\n");
}
/*
This function is called to scan the FD file.
Inputs: FDFile - the name of the file to scan
Result: TRUE, if successful, FALSE otherwise
*/
ULONG ScanFDFile(const STRPTR FDFile)
{ FILE *fp;
ULONG public = TRUE;
ULONG bias = -1;
ULONG linenum = 0;
ULONG result = FALSE;
UBYTE line[512];
if (!(fp = fopen((char *) FDFile, "r")))
{ fprintf(stderr, "Fatal: Cannot open FD file %s.\n", FDFile);
return(FALSE);
}
NewList((struct List *) &AmiPragmaList);
while(fgets((char *) line, sizeof(line), fp) != NULL)
{ ULONG len;
++linenum;
for (len = 0; len < sizeof(line); ++len)
{ if (line[len] == '\n')
{ break;
}
}
if (len == sizeof(line))
{ int c;
fprintf(stderr, "Error: Line %ld too long.\n", linenum);
while((c = getc(fp)) != EOF && c != '\n')
{
}
continue;
}
line[len] = '\0'; /* Remove Line Feed */
if (line[0] == '*')
{ /* Comment */
STRPTR ptr;
ptr = SkipBlanks(line+1);
if(strnicmp((char *) ptr, "tagcall", 7) == 0) /* Tag to create? */
{ struct AmiPragma *prevpragma;
ptr = SkipBlanks(ptr+7);
prevpragma = (struct AmiPragma *) AmiPragmaList.mlh_TailPred;
if (!prevpragma->Node.mln_Pred)
{ fprintf(stderr,
"Line %ld, Error: Tag definition without preceding Pragma.\n",
linenum);
continue;
}
if (prevpragma->TagName)
{ fprintf(stderr, "Line %ld, Error: Tag function declared twice.\n",
linenum);
continue;
}
if (!prevpragma->NumArgs)
{ fprintf(stderr,
"Line %ld, Error: Tag function must have arguments.\n",
linenum);
}
/*
Get the tag functions name.
*/
len = strlen((char *) prevpragma->FuncName)+strlen((char *) ptr)+1;
if (!(prevpragma->TagName = strndup(prevpragma->FuncName, len)))
{ MemError();
goto exit_ScanFDFile;
}
if (!*ptr)
{ len = strlen((char *) prevpragma->TagName);
if (prevpragma->TagName[len-1] == 'A')
{ prevpragma->TagName[len-1] = '\0';
}
}
else
{ STRPTR nextptr;
if (*ptr == '-')
{ STRPTR removeptr;
ptr = SkipBlanks(ptr+1);
nextptr = SkipName(ptr);
if ((len = nextptr-ptr))
{ removeptr = prevpragma->TagName+strlen((char *) prevpragma->TagName)-len;
if (!strncmp((char *) removeptr, (char *) ptr, len))
{ fprintf(stderr,
"Line %ld, Error: Cannot convert pragma name into tag name.\n",
linenum);
continue;
}
*removeptr = '\0';
}
ptr = SkipBlanks(nextptr);
}
if (*ptr == '+')
{ ptr = SkipBlanks(ptr+1);
}
else
{ *ptr = toupper((int) *ptr);
}
nextptr = SkipName(ptr);
len = nextptr-ptr;
if (len)
{ strncat((char *) prevpragma->TagName, (char *) ptr, len);
ptr += len;
}
if (*SkipBlanks(nextptr))
{ fprintf(stderr, "Line %ld, warning: Extra characters\n", linenum);
}
}
}
}
else if (strnicmp((char *) line, "##base", 6) == 0)
{ STRPTR ptr, nextptr;
LONG len;
if (BaseName)
{ fprintf(stderr, "Line %ld, Error: Basename declared twice.\n",
linenum);
}
ptr = SkipBlanks(line+6);
if (*ptr != '_')
{ fprintf(stderr, "Line %ld, Warning: Expected preceding _ in Basename.\n",
linenum);
}
else
{ ++ptr;
}
nextptr = SkipName(ptr);
if ((len = nextptr-ptr))
{ if (!(BaseName = strndup(ptr, len)))
{ MemError();
goto exit_ScanFDFile;
}
ptr = FilePart(FDFile);
len = strlen((char *) ptr)-7;
if (len >= 0 && stricmp((char *) ptr+len, "_lib.fd