home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
fd2inline-1.0-src.tgz
/
tar.out
/
contrib
/
fd2inline
/
fd2inline.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
44KB
|
1,941 lines
/******************************************************************************
*
* fd2inline
*
* Should be able to parse AmigaOS fd files and generate vanilla inline calls
* for gcc. Works as a filter. This is a 0.9 evaluation version.
* Don't expect miracles (yet...).
*
* by Wolfgang Baron, all rights reserved.
*
* improved, updated, simply made workable by Rainer F. Trunz 1/95
*
* Completely reworked Version, cleaned up and removed a whole lot of bugs
* found by Kamil Iskra.
*
* Expect miracles now (hopefully...). Ok, I am just kidding :)
*
* Version 0.99a by Rainer F. Trunz 6/95
*
* Version 0.99b by Kamil Iskra 10/95 - removed all serious limitations,
* added support for new "inline" format.
*
* Version 0.99c by Kamil Iskra 11/95 - added support for "library stubs",
* slightly modified "old" output, fixed bug in DateStamp() parsing.
*
* Version 0.99d by Kamil Iskra 12/95 - changed output of "new" inlines to
* support their enhanced version.
*
******************************************************************************/
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/******************************************************************************
* The program has a few sort of class definitions, which are the result of
* object oriented thinking, to be imlemented in plain C. I just haven't
* had the time to learn C++ or install the compiler. The design does however
* improve robustness, which allows the source to be used over and over again.
* if you use this code, please leave a little origin note.
******************************************************************************/
const static char version_str[]="$VER: fd2inline " VERSION " (14.07.96)";
/******************************************************************************
* These are general definitions including types for defining registers etc.
******************************************************************************/
#ifdef DEBUG
#define DBP(a) a
#else /* !DEBUG */
#define DBP(a)
#endif /* !DEBUG */
#if (defined(__GNUC__) || defined(__SASC)) && 0
#define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
#else
#define INLINE
#endif
#define REGS 16 /* d0=0,...,a7=15 */
#define FDS 1000
typedef enum
{
d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
} regs;
typedef unsigned char uchar, shortcard;
typedef unsigned long ulong;
typedef enum { false, nodef, real_error } Error;
enum {NEW, OLD, STUBS} output_mode=NEW;
char BaseName[32];
char BaseNamU[32];
const static char *LibExcTable[]=
{
"BattClockBase", "Node",
"BattMemBase", "Node",
"ConsoleDevice", "Device",
"DiskBase", "DiskResource",
"DOSBase", "DosLibrary",
"SysBase", "ExecBase",
"ExpansionBase", "ExpansionBase",
"GfxBase", "GfxBase",
"InputBase", "Device",
"IntuitionBase", "IntuitionBase",
"LocaleBase", "LocaleBase",
"MathIeeeDoubBasBase", "MathIEEEBase",
"MathIeeeDoubTransBase","MathIEEEBase",
"MathIeeeSingBasBase", "MathIEEEBase",
"MathIeeeSingTransBase","MathIEEEBase",
"MiscBase", "Node",
"PotgoBase", "Node",
"RamdriveDevice", "Device",
"RealTimeBase", "RealTimeBase",
"RexxSysBase", "RxsLib",
"TimerBase", "Device",
"UtilityBase", "UtilityBase"
};
const char * StdLib; /* global lib-name ptr */
/*******************************************
* just some support functions, no checking
*******************************************/
char *
NewString(char **new, const char *old)
{
const char *high;
ulong len;
while (*old && (*old==' ' || *old=='\t'))
old++;
len=strlen(old);
for (high=old+len-1; high>=old && (*high==' ' || *high=='\t'); high--);
high++;
len=high-old;
*new=malloc(1+len);
if (*new)
{
strncpy(*new, old, len);
(*new)[len]='\0';
}
else
fprintf(stderr, "no mem for string\n");
return *new;
}
static INLINE void
illparams(const char *funcname)
{
fprintf(stderr, "%s: illegal Parameters\n", funcname);
}
static INLINE const char*
RegStr(regs reg)
{
const static char *myregs[]=
{
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
};
if (reg>illegal)
reg=illegal;
if (reg<d0)
reg=d0;
return myregs[reg];
}
/******************************************************************************
* StrNRBrk
*
* searches string in from position at downwards, as long as in does not
* contain any character in not.
*
******************************************************************************/
const char *
StrNRBrk(const char *in, const char *not, const char *at)
{
const char *chcheck;
Error ready;
chcheck=""; /* if at<in, the result will be NULL */
for (ready=false; ready==false && at>=in;)
{
for (chcheck=not; *chcheck && *chcheck != *at; chcheck++);
if (*chcheck)
ready=real_error;
else
at--;
}
DBP(fprintf(stderr, "{%c}", *chcheck));
return *chcheck ? at : NULL;
}
/*
Our own "strupr", since it is a non-standard function.
*/
void
StrUpr(char *str)
{
while (*str)
{
*str=toupper(*str);
str++;
}
}
/******************************************************************************
* binSearch
*
* A binary search routine, wich operates on an array like you would use
* for qsort. The prototype does not contain the (*) bug...
*
* returns the address of the (a?) fitting object, or NULL;
*
* the binary intersection is (low+high)/2, so the highest value will never
* be reached, but the lowest value will. In the while condition, the diff
* has to be called last in case we got an empty array.
*
******************************************************************************/
void*
binSearch(void ** array, size_t elements, const void *lookfor,
int cmpfunc(const void **, const void **))
{
size_t low, high, index;
int diff;
DBP(fprintf(stderr, "bs(%ld): ", (long)elements));
diff=1; /* this needs to be so in case we got an empty array... */
low=0;
high=elements; /* our algorithm never reaches elements */
while (index=(high+low)/2, /* somewhere inbetween */
high!=low && (diff=cmpfunc((const void **)array+index,
&lookfor)))
{
if (diff>0)
{
high=index; /* our value was too big, so grow downwards */
DBP(fprintf(stderr, "<"));
}
else
{
low=index+1; /* the low value will be reached */
DBP(fprintf(stderr, ">"));
}
DBP(fprintf(stderr, "%ld ", (long)index));
}
DBP(fprintf(stderr, "->%ld\n", diff ? -1L : (long)index));
return diff ? NULL : array[index]; /* bingo */
}
/******************************************************************************
* CLASS fdFile
*
* stores a file with a temporary buffer (static length, sorry), a line number,
* an offset (used for library offsets and an error field.
* When there's no error, line will contain line #lineno and offset will be
* the last offset set by the interpretation of the last line. If there's been
* no ##bias line, this field assumes a bias of 30, which is the standard bias.
* It is assumed offsets are always negative.
******************************************************************************/
#define fF_BUFSIZE 1024
/* all you need to know about an fdFile you parse */
typedef struct
{
FILE* file; /* the file we're reading from */
char line[fF_BUFSIZE]; /* the current line */
ulong lineno; /* current line number */
long offset; /* current fd offset (-bias) */
Error error; /* is everything o.k. */
char private; /* are we in ##public or ##private */
} fdFile;
fdFile* fF_ctor (const char *fname);
static
void fF_dtor (fdFile *obj);
static
void fF_SetError (fdFile *obj, Error error);
static
void fF_SetOffset (fdFile *obj, long at);
Error fF_readln (fdFile *obj);
static
Error fF_GetError (const fdFile *obj);
static
long fF_GetOffset (const fdFile *obj);
char* fF_FuncName (fdFile *obj); /* return name or null */
static
void fF_SetPrivate (fdFile *obj, char priv);
static
char fF_GetPrivate (const fdFile *obj);
static INLINE void
fF_dtor(fdFile *obj)
{
fclose(obj->file);
free(obj);
}
static INLINE void
fF_SetError(fdFile *obj, Error error)
{
if (obj)
obj->error=error;
else
illparams("fF_SetError");
}
static INLINE void
fF_SetOffset(fdFile *obj, long at)
{
if (obj)
obj->offset= at;
else
illparams("fFSetOffset");
}
static INLINE void
fF_SetPrivate(fdFile *obj, char priv)
{
if (obj)
obj->private=priv;
else
illparams("fF_SetPrivate");
}
fdFile *
fF_ctor(const char *fname)
{
fdFile *result;
if (fname)
{
result=malloc(sizeof(fdFile));
if (result)
{
result->file=fopen(fname, "r");
if (result->file)
{
result->lineno=0;
fF_SetOffset(result, -30);
fF_SetError(result, false);
fF_SetPrivate(result, 0);
result->line[0]='\0';
}
else
{
free(result);
result=NULL;
}
}
}
else
{
result=NULL;
illparams("fF_ctor");
}
return result;
}
Error
fF_readln(fdFile *obj)
{
char *low, *bpoint;
long glen, /* the length we read until now */
len; /* the length of the last segment */
if (obj)
{
low=obj->line;
glen=0;
for (;;)
{
obj->lineno++;
if (!fgets(low, fF_BUFSIZE-1-glen, obj->file))
{
fF_SetError(obj, real_error);
obj->line[0]='\0';
return real_error;
}
if (low==strpbrk(low, "*#/"))
{
DBP(fprintf(stderr, "in# %s\n", obj->line));
return false;
}
len=strlen(low);
bpoint=low+len-1;
while (len && isspace(*bpoint))
{
bpoint--;
len--;
}
if (*bpoint==';' || *bpoint==')')
{
DBP(fprintf(stderr, "\nin: %s\n", obj->line));
return false;
}
glen+=len;
low+=len;
if (glen>=fF_BUFSIZE-10) /* somewhat pessimistic? */
{
fF_SetError(obj, real_error);
fprintf(stderr, "line %lu too long.\n", obj->lineno);
return real_error;
}
DBP(fprintf(stderr, "+"));
}
}
illparams("fF_readln");
return real_error;
}
static INLINE Error
fF_GetError(const fdFile *obj)
{
if (obj)
return obj->error;
illparams("fF_GetError");
return real_error;
}
static INLINE long
fF_GetOffset(const fdFile *obj)
{
if (obj)
return obj->offset;
illparams("fF_GetOffset");
return -1;
}
/******************************************************************************
* fF_FuncName
*
* checks if it can find a function-name and return it's address, or NULL
* if the current line does not seem to contain one. The return value will
* be a pointer into a malloced buffer, thus the caller will have to free().
******************************************************************************/
char *
fF_FuncName(fdFile *obj)
{
const char *lower;
const char *upper;
char *buf;
long obraces; /* count of open braces */
Error ready; /* ready with searching */
if (!obj || fF_GetError(obj)==real_error)
{
illparams("fF_FuncName");
return NULL;
}
if (obj->line==strpbrk(obj->line, "#*/"))
{
fF_SetError(obj, nodef);
return NULL;
}
lower=NULL;
buf=NULL;
if (obj && fF_GetError(obj)==false)
{
if ((upper=strrchr(obj->line, ')'))!=0)
{
DBP(fprintf(stderr, "end:%s:", upper));
for (obraces=1, ready=false; ready==false; upper=lower)
{
lower=StrNRBrk(obj->line, "()", --upper);
if (lower)
{
switch (*lower)
{
case ')':
obraces++;
DBP(fprintf(stderr, " )%ld%s", obraces, lower));
break;
case '(':
obraces--;
DBP(fprintf(stderr, " (%ld%s", obraces, lower));
if (!obraces)
ready=nodef;
break;
default:
fprintf(stderr, "faulty StrNRBrk\n");
}
}
else
{
fprintf(stderr, "'(' or ')' expected in line %lu.\n",
obj->lineno);
ready=real_error;
}
}
if (ready==nodef) /* we found the matching '(' */
{
long newlen;
upper--;
while (upper>=obj->line && (*upper==' ' || *upper=='\t'))
upper--;
lower=StrNRBrk(obj->line, " \t*)", upper);
if (!lower)
lower=obj->line;
else
lower++;
newlen=upper-lower+2;
buf=malloc(newlen);
if (buf)
{
strncpy(buf, lower, --newlen);
buf[newlen]='\0';
}
else
fprintf(stderr, "no mem for fF_FuncName");
}
}
}
else
illparams("fF_FuncName");
return buf;
}
static INLINE char
fF_GetPrivate(const fdFile *obj)
{
if (obj)
return obj->private;
illparams("fF_GetPrivate");
return 0;
}
/*********************
* CLASS fdDef *
*********************/
typedef struct
{
char* name;
char* type;
long offset;
regs reg[REGS];
char* param[REGS];
char* proto[REGS];
regs funcpar; /* number of argument that has type "pointer to function" */
} fdDef;
fdDef* fD_ctor (void);
void fD_dtor (fdDef *obj);
static
void fD_NewName (fdDef *obj, const char *newname);
void fD_NewParam (fdDef *obj, shortcard at, const char *newstr);
void fD_NewProto (fdDef *obj, shortcard at, char *newstr);
static
void fD_NewReg (fdDef *obj, shortcard at, regs reg);
static
void fD_NewType (fdDef *obj, const char *newstr);
static
void fD_SetOffset (fdDef *obj, long off);
Error fD_parsefd (fdDef *obj, fdFile *infile);
Error fD_parsepr (fdDef *obj, fdFile *infile);
static
const char* fD_GetName (const fdDef *obj);
static
long fD_GetOffset (const fdDef *obj);
static
const char* fD_GetParam (const fdDef *obj, shortcard at);
static
regs fD_GetReg (const fdDef *obj, shortcard at);
static
const char* fD_GetRegStr (const fdDef *obj, shortcard at);
static
const char* fD_GetType (const fdDef *obj);
static
shortcard fD_ParamNum (const fdDef *obj);
static
shortcard fD_ProtoNum (const fdDef *obj);
static
shortcard fD_RegNum (const fdDef *obj);
int fD_cmpName (const fdDef **big, const fdDef **small);
void fD_write (FILE *outfile, const fdDef *obj);
static
shortcard fD_GetFuncParNum (const fdDef *obj);
static
void fD_SetFuncParNum (fdDef *obj, shortcard at);
char *fD_nostring = "";
fdDef*
fD_ctor(void)
{
fdDef *result;
regs count;
result=malloc(sizeof(fdDef));
if (result)
{
result->name=fD_nostring;
result->type=fD_nostring;
result->funcpar=illegal;
for (count=d0; count<illegal; count++ )
{
result->reg[count]=illegal;
result->param[count]=fD_nostring; /* if (!strlen) dont't free() */
result->proto[count]=fD_nostring;
}
}
return result;
}
/* free all resources and make the object as illegal as possible */
void
fD_dtor(fdDef *obj)
{
regs count;
if (obj)
{
if (!obj->name)
fprintf(stderr, "fD_dtor: null name");
else
if (obj->name!=fD_nostring)
free(obj->name);
if (!obj->type)
fprintf(stderr, "fD_dtor: null type");
else
if (obj->type!=fD_nostring)
free(obj->type);
obj->name=obj->type=NULL;
for (count=d0; count<illegal; count++)
{
obj->reg[count]=illegal;
if (!obj->param[count])
fprintf(stderr, "fD_dtor: null param");
else
if (obj->param[count]!=fD_nostring)
free(obj->param[count]);
if (!obj->proto[count])
fprintf(stderr, "fD_dtor: null proto");
else
if (obj->proto[count]!=fD_nostring)
free(obj->proto[count]);
obj->param[count]=obj->proto[count]=NULL;
}
free(obj);
}
else
fprintf(stderr, "fd_dtor(NULL)\n");
}
static INLINE void
fD_NewName(fdDef *obj, const char *newname)
{
if (obj && newname)
{
if (obj->name && obj->name!=fD_nostring)
free(obj->name);
if (!NewString(&obj->name, newname))
obj->name=fD_nostring;
}
else
illparams("fD_NewName");
}
void
fD_NewParam(fdDef *obj, shortcard at, const char *newstr)
{
char *pa;
if (newstr && obj && at<illegal)
{
pa=obj->param[at];
if (pa && pa!=fD_nostring)
free(pa);
while (*newstr==' ' || *newstr=='\t')
newstr++;
if (NewString(&pa, newstr))
obj->param[at]=pa;
else
obj->param[at]=fD_nostring;
}
else
illparams("fD_NewParam");
}
/* get first free *reg or illegal */
static INLINE shortcard
fD_RegNum(const fdDef *obj)
{
shortcard count;
if (obj)
{
for (count=d0; count<illegal && obj->reg[count]!=illegal; count++);
return count;
}
else
{
illparams("fD_RegNum");
return illegal;
}
}
static INLINE void
fD_NewReg(fdDef *obj, shortcard at, regs reg)
{
if (obj && at<illegal && reg>=d0 && reg<=illegal)
obj->reg[at]=reg;
else
illparams("fD_NewReg");
}
static INLINE regs
fD_GetReg(const fdDef *obj, shortcard at)
{
if (obj && at<illegal)
return obj->reg[at];
else
{
illparams("fD_GetReg");
return illegal;
}
}
static INLINE shortcard
fD_GetFuncParNum(const fdDef *obj)
{
if (obj)
return (shortcard)obj->funcpar;
else
{
illparams("fD_GetFuncParNum");
return illegal;
}
}
static INLINE void
fD_SetFuncParNum(fdDef *obj, shortcard at)
{
if (obj && at<illegal)
obj->funcpar=at;
else
illparams("fD_SetFuncParNum");
}
void
fD_NewProto(fdDef *obj, shortcard at, char *newstr)
{
char *pr;
if (newstr && obj && at<illegal)
{
char *t, arr[200]; /* I hope 200 will be enough... */
int numwords=1;
pr=obj->proto[at];
if (pr && pr!=fD_nostring)
free(pr);
while (*newstr==' ' || *newstr=='\t')
newstr++; /* Skip leading spaces */
t=arr;
while ((*t++=*newstr)!=0)
{
/* Copy the rest, counting number of words */
if ((*newstr==' ' || *newstr=='\t') && newstr[1] && newstr[1]!=' ' &&
newstr[1]!='\t')
numwords++;
newstr++;
}
t=arr+strlen(arr)-1;
while (*t==' ' || *t=='\t')
t--;
t[1]='\0'; /* Get rid of tailing spaces */
if (at!=fD_GetFuncParNum(obj))
{
if (numwords>1) /* One word - must be type */
if (*t!='*')
{
/* '*' on the end - no parameter name used */
while (*t!=' ' && *t!='\t' && *t!='*')
t--;
t++;
if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
&& strcmp(t, "long"))
{
/* Not one of applicable keywords - must be parameter name.
Get rid of it. */
t--;
while (*t==' ' || *t=='\t')
t--;
t[1]='\0';
}
}
}
else
{
/* Parameter of type "pointer to function". */
char *end;
t=strchr(arr, '(');
while (*t++!='*');
end=strchr(t, ')');
memmove(t+2, end, strlen(end)+1);
*t='%';
t[1]='s';
}
if (NewString(&pr, arr))
{
obj->proto[at]=pr;
while (*pr==' ' || *pr=='\t')
pr++;
if (!stricmp(pr, "double"))
{
/* "double" needs two data registers */
int count, regs=fD_RegNum(obj);
for (count=at+1; count<regs; count++)
fD_NewReg(obj, count, fD_GetReg(obj, count+1));
}
}
else
obj->proto[at]=fD_nostring;
}
else
illparams("fD_NewProto");
}
static INLINE void
fD_NewType(fdDef *obj, const char *newtype)
{
if (obj && newtype)
{
if (obj->type && obj->type!=fD_nostring)
free(obj->type);
if (!NewString(&obj->type, newtype))
obj->type=fD_nostring;
}
else
illparams("fD_NewType");
}
static INLINE void
fD_SetOffset(fdDef *obj, long off)
{
if (obj)
obj->offset=off;
else
illparams("fD_SetOffset");
}
static INLINE const char*
fD_GetName(const fdDef *obj)
{
if (obj && obj->name)
return obj->name;
else
{
illparams("fD_GetName");
return fD_nostring;
}
}
static INLINE long
fD_GetOffset(const fdDef *obj)
{
if (obj)
return obj->offset;
else
{
illparams("fD_GetOffset");
return 0;
}
}
static INLINE const char*
fD_GetProto(const fdDef *obj, shortcard at)
{
if (obj && at<illegal && obj->proto[at])
return obj->proto[at];
else
{
illparams("fD_GetProto");
return fD_nostring;
}
}
static INLINE const char*
fD_GetParam(const fdDef *obj, shortcard at)
{
if (obj && at<illegal && obj->param[at])
return obj->param[at];
else
{
illparams("fD_GetParam");
return fD_nostring;
}
}
static INLINE const char*
fD_GetRegStr(const fdDef *obj, shortcard at)
{
if (obj && at<illegal)
return RegStr(obj->reg[at]);
else
{
illparams("fD_GetReg");
return RegStr(illegal);
}
}
static INLINE const char*
fD_GetType(const fdDef *obj)
{
if (obj && obj->type)
return obj->type;
else
{
illparams("fD_GetType");
return fD_nostring;
}
}
/* get first free param or illegal */
static INLINE shortcard
fD_ParamNum(const fdDef *obj)
{
shortcard count;
if (obj)
{
for (count=d0; count<illegal && obj->param[count]!=fD_nostring;
count++);
return count;
}
else
{
illparams("fD_ParamNum");
return illegal;
}
}
static INLINE shortcard
fD_ProtoNum(const fdDef *obj)
{
shortcard count;
if (obj)
{
for (count=d0; count<illegal && obj->proto[count]!=fD_nostring;
count++);
return count;
}
else
{
illparams("fD_ProtoNum");
return illegal;
}
}
/******************************************************************************
* fD_parsefd
*
* parse the current line. Needs to copy input, in order to insert \0's
* RETURN
* fF_GetError(infile):
* false = read a definition.
* nodef = not a definition on line (so try again)
* error = real error
******************************************************************************/
Error
fD_parsefd(fdDef *obj, fdFile *infile)
{
enum parse_info { name, params, regs, ready } parsing;
char *buf, *bpoint, *bnext;
ulong index;
if (obj && infile && fF_GetError(infile)==false)
{
parsing=name;
if (!NewString(&buf, infile->line))
{
fprintf(stderr, "no mem for line %lu\n", infile->lineno);
fF_SetError(infile, real_error);
}
bpoint=buf; /* so -Wall keeps quiet */
/* try to parse the line until there's an error or we are done */
while (parsing!=ready && fF_GetError(infile)==false)
{
switch (parsing)
{
case name:
switch (buf[0])
{
case '#':
if (strncmp("##base", buf, 6)==0)
{
bnext=buf+6;
while (*bnext==' ' || *bnext=='\t' || *bnext=='_')
bnext++;
strcpy(BaseName, bnext);
BaseName[strlen(BaseName)-1]='\0';
}
else
if (strncmp("##bias", buf, 6)==0)
{
if (!sscanf(buf+6, "%ld", &infile->offset))
{
fprintf(stderr, "illegal ##bias in line %lu: %s\n",
infile->lineno, infile->line);
fF_SetError(infile, real_error);
break; /* avoid nodef */
}
else
{
if (fF_GetOffset(infile)>0)
fF_SetOffset(infile, -fF_GetOffset(infile));
DBP(fprintf(stderr, "set offset to %ld\n",
fFGetOffset(infile)));
}
}
else
{
if (strncmp("##private", buf, 9)==0)
fF_SetPrivate(infile, 1);
else
if (strncmp("##public", buf, 8)==0)
fF_SetPrivate(infile, 0);
}
/* drop through for error comment */
case '*':
/* try again somewhere else */
fF_SetError(infile, nodef);
break;
default:
/* assume a regular line here */
if (fF_GetPrivate(infile))
{
/* don't store names of privates */
fF_SetError(infile, nodef);
fF_SetOffset(infile, fF_GetOffset(infile)-6);
break;
}
parsing=name; /* switch (parsing) */
for (index=0; buf[index] && buf[index]!='('; index++);
if (!buf[index])
{
/* oops, no fd ? */
fprintf(stderr, "not an fd, line %lu: %s\n",
infile->lineno, buf /* infile->line */);
fF_SetError(infile, nodef);
} /* maybe next time */
else
{
buf[index]=0;
fD_NewName(obj, buf);
fD_SetOffset(obj, fF_GetOffset(infile));
bpoint=buf+index+1;
parsing=params; /* continue the loop */
}
}
break;
case params:
{
char *bptmp; /* needed for fD_NewParam */
/* look for parameters now */
for (bnext = bpoint; *bnext && *bnext!=',' && *bnext!=')';
bnext++);
if (*bnext)
{
bptmp=bpoint;
if (*bnext == ')')
{
if (bnext[1] != '(')
{
fprintf(stderr, "registers expected in line %lu: %s\n",
infile->lineno, infile->line);
fF_SetError(infile, nodef);
}
else
{
parsing=regs;
bpoint=bnext+2;
}
}
else
bpoint = bnext+1;
/* terminate string and advance to next item */
*bnext='\0';
fD_NewParam(obj, fD_ParamNum(obj), bptmp);
}
else
{
fF_SetError(infile, nodef);
fprintf(stderr, "param expected in line %lu: %s\n",
infile->lineno, infile->line);
}
break; /* switch parsing */
}
case regs:
/* look for parameters now */
for (bnext=bpoint; *bnext && *bnext!='/' && *bnext!=',' &&
*bnext!=')'; bnext++);
if (*bnext)
{
if (')'==*bnext)
{
/* wow, we've finished */
fF_SetOffset(infile, fF_GetOffset(infile)-6);
parsing=ready;
}
*bnext = '\0';
bpoint[0]=tolower(bpoint[0]);
if ((bpoint[0]=='d' || bpoint[0]=='a') && bpoint[1]>='0' &&
bpoint[1]<='8' && bnext==bpoint+2)
fD_NewReg(obj, fD_RegNum(obj),
bpoint[1]-'0'+(bpoint[0]=='a'? 8 : 0));
else
if (bnext!=bpoint)
{
/* it is when our function is void */
fprintf(stderr, "illegal register %s in line %ld\n",
bpoint, infile->lineno);
fF_SetError(infile, nodef);
}
bpoint = bnext+1;
}
else
{
fF_SetError(infile, nodef);
fprintf(stderr, "reg expected in line %lu\n",
infile->lineno);
}
break; /* switch parsing */
case ready:
fprintf(stderr, "internal error, use another compiler.\n");
break;
}
}
free(buf);
return fF_GetError(infile);
}
else
{
illparams("fD_parsefd");
return real_error;
}
}
Error
fD_parsepr(fdDef *obj, fdFile *infile)
{
char *buf; /* a copy of infile->line */
char *bpoint, /* cursor in buf */
*bnext, /* looking for the end */
*lowarg; /* beginning of this argument */
long obraces; /* count of open braces */
regs count, /* count parameter number */
args; /* the number of arguments for this function */
if (!(obj && infile && fF_GetError(infile)==false))
{
illparams("fD_parsepr");
fF_SetError(infile, real_error);
return real_error;
}
if (!NewString(&buf, infile->line))
{
fprintf(stderr, "no mem for fD_parsepr\n");
fF_SetError(infile, real_error);
return real_error;
}
fF_SetError(infile, false);
bpoint=strchr(buf, '(');
while (--bpoint>=buf && strstr(bpoint, fD_GetName(obj))!=bpoint);
if (bpoint>=buf)
{
while (--bpoint >= buf && (*bpoint==' ' || *bpoint=='\t'));
*++bpoint='\0';
fD_NewType(obj, buf);
while (bpoint && *bpoint++!='('); /* one beyond '(' */
lowarg=bpoint;
obraces=0;
for (count=0, args=fD_RegNum(obj); count<args; bpoint=bnext+1)
{
while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
bpoint++;
bnext=strpbrk(bpoint, "(),");
if (bnext)
{
switch (*bnext)
{
case '(':
if (!obraces)
{
if (fD_GetFuncParNum(obj)!=illegal &&
fD_GetFuncParNum(obj)!=count)
fprintf(stderr, "Warning: two parameters of type "
"pointer to function are used.\nThis is not "
"supported!\n");
fD_SetFuncParNum(obj, count);
}
obraces++;
DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
break;
case ')':
if (obraces)
{
DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
obraces--;
}
else
{
*bnext='\0';
DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
fD_NewProto(obj, count, lowarg);
lowarg=bnext+1;
if (count!=args-1)
{
DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
fD_GetName(obj), args, count+1));
fF_SetError(infile, nodef);
}
count++;
}
break;
case ',':
if (!obraces)
{
*bnext='\0';
DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
fD_NewProto(obj, count, lowarg);
lowarg=bnext+1;
count++;
}
break;
default:
fprintf(stderr, "faulty strpbrk in line %lu.\n",
infile->lineno);
}
}
else
{
DBP(fprintf(stderr, "faulty argument %u in line %lu.\n", count+1,
infile->lineno));
count=args; /* this will effectively quit the for loop */
fF_SetError(infile, nodef);
}
}
if (fD_ProtoNum(obj)!=fD_RegNum(obj))
fF_SetError(infile, nodef);
}
else
{
fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
fprintf(stderr, "function , definition %s.\n",
/* fD_GetName(obj),*/ infile->line);
fF_SetError(infile, nodef);
}
free(buf);
return fF_GetError(infile);
}
int
fD_cmpName(const fdDef **big, const fdDef **small) /* for qsort */
{
return strcmp(fD_GetName(*big), fD_GetName(*small));
}
const char*
taggedfunction(const fdDef *obj)
{
shortcard numregs=fD_RegNum(obj);
int count;
const char *name=fD_GetName(obj);
static char newname[200]; /* Hope will be enough... static because used
out of the function. */
const char *lastarg;
const static char *FuncExcTable[]=
{
"BuildEasyRequestArgs", "BuildEasyRequest",
"DoDTMethodA", "DoDTMethod",
"DoGadgetMethodA", "DoGadgetMethod",
"EasyRequestArgs", "EasyRequest",
"PrintDTObjectA", "PrintDTObject",
"VFWritef", "FWritef",
"VFPrintf", "FPrintf",
"VPrintf", "Printf",
"MUI_MakeObjectA", "MUI_MakeObject",
"MUI_RequestA", "MUI_Request",
},
*FuncExcTable2[]=
{
"ApplyTagChanges",
"CloneTagItems",
"FindTagItem",
"FreeTagItems",
"GetTagData",
"PackBoolTags",
"PackStructureTags",
"RefreshTagItemClones",
"UnpackStructureTags",
};
if (!numregs)
return NULL;
for (count=0; count<sizeof FuncExcTable/sizeof(char*); count+=2)
if (strcmp(name, FuncExcTable[count])==0)
return FuncExcTable[count+1];
for (count=0; count<sizeof FuncExcTable2/sizeof(char*); count++)
if (strcmp(name, FuncExcTable2[count])==0)
return NULL;
lastarg=fD_GetProto(obj, numregs-1);
if (strncmp(lastarg, "struct", 6))
return NULL;
lastarg+=6;
while (*lastarg==' ' || *lastarg=='\t')
lastarg++;
if (strncmp(lastarg, "TagItem", 7))
return NULL;
lastarg+=7;
while (*lastarg==' ' || *lastarg=='\t')
lastarg++;
if (strcmp(lastarg, "*"))
return NULL;
strcpy(newname, name);
if (newname[strlen(newname)-1]=='A')
newname[strlen(newname)-1]='\0';
else
if (strlen(newname)>7 && !strcmp(newname+strlen(newname)-7, "TagList"))
strcpy(newname+strlen(newname)-4, "s");
else
strcat(newname, "Tags");
return newname;
}
const char*
aliasfunction(const char *name)
{
const static char *AliasTable[]=
{
"AllocDosObject", "AllocDosObjectTagList",
"CreateNewProc", "CreateNewProcTagList",
"NewLoadSeg", "NewLoadSegTagList",
"System", "SystemTagList",
};
int count;
for (count=0; count<sizeof AliasTable/sizeof(char*); count++)
if (strcmp(name, AliasTable[count])==0)
return AliasTable[count+(count%2 ? -1 : 1)];
return NULL;
}
void
fD_write(FILE *outfile, const fdDef *obj)
{
shortcard count, numregs;
const char *chtmp, *tagname, *name, *rettype;
int vd=0, a45=0, d7=0;
DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
numregs=fD_RegNum(obj);
if ((rettype=fD_GetType(obj))==fD_nostring)
{
fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
return;
}
if (!stricmp(rettype, "void"))
vd = 1; /* set flag */
for (count=d0; count<numregs; count++)
{
const char *reg=fD_GetRegStr(obj, count);
if (strcmp(reg, "a4")==0 || strcmp(reg, "a5")==0)
if (!a45)
a45=(strcmp(reg, "a4") ? 5 : 4); /* set flag */
else /* Security check */
fprintf(stderr, "Warning: both a4 and a5 are used. This is not "
"supported!\n");
if (strcmp(reg, "d7")==0) /* Used only when a45!=0 */
d7=1;
}
if (a45 && d7) /* Security check */
fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
"supported!\n");
name=fD_GetName(obj);
if (fD_ProtoNum(obj)!=numregs)
{
fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
fD_ProtoNum(obj), fD_ProtoNum(obj)!= 1 ? "s" : "");
return;
}
if (output_mode==NEW)
{
fprintf(outfile, "#define %s(", name);
if (numregs>0)
{
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "%s, ", fD_GetParam(obj, count));
fprintf(outfile, "%s", fD_GetParam(obj, count));
}
fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
(vd ? "NR" : ""), (a45 ? (a45==4 ? "A4" : "A5") : ""),
(BaseName[0] ? "" : "UB"),
(fD_GetFuncParNum(obj)==illegal ? "" : "FP"), -fD_GetOffset(obj));
if (!vd)
fprintf(outfile, "%s, ", rettype);
fprintf(outfile, "%s, ", name);
for (count=d0; count<numregs; count++)
{
chtmp=fD_GetRegStr(obj, count);
if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
chtmp="d7";
fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj)==count ?
"__fpt" : fD_GetProto(obj, count)), fD_GetParam(obj, count),
chtmp, (count==numregs-1 && !BaseName[0] ? "" : ", "));
}
if (BaseName[0]) /* was "##base" used? */
fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
if (fD_GetFuncParNum(obj)!=illegal)
{
fprintf(outfile, ", ");
fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
}
fprintf(outfile, ")\n\n");
}
else
{
fprintf(outfile, "%s__inline %s\n%s(%s",
(output_mode==STUBS ? "" : "extern "), rettype, name,
(BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
for (count=d0; count<numregs; count++)
{
chtmp=fD_GetProto(obj, count);
if (fD_GetFuncParNum(obj)==count)
fprintf(outfile, chtmp, fD_GetParam(obj, count));
else
fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
"" : " "), fD_GetParam(obj, count));
if (count<numregs-1)
fprintf(outfile, ", ");
}
fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
if (!vd)
fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
(*(rettype+strlen(rettype)-1)=='*' ? "" : " "));
if (BaseName[0])
fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
StdLib);
for (count=d0; count<numregs; count++)
{
chtmp=fD_GetRegStr(obj, count);
if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
chtmp="d7";
if (fD_GetFuncParNum(obj)==count)
{
fprintf(outfile, " register ");
fprintf(outfile, fD_GetProto(obj, count), chtmp);
fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
count));
}
else
{
const char *proto=fD_GetProto(obj, count);
fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
proto, (*(proto+strlen(proto)-1)=='*' ? "" : " "), chtmp,
chtmp, fD_GetParam(obj, count));
}
}
if (a45)
fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
"jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45==4 ? "a4" : "a5"),
-fD_GetOffset(obj), (a45==4 ? "a4" : "a5"));
else
fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
-fD_GetOffset(obj));
fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
fprintf(outfile, " : ");
if (BaseName[0])
fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", ": ""));
for (count=d0; count<numregs; count++)
{
chtmp=fD_GetRegStr(obj, count);
if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
chtmp="d7";
fprintf(outfile, "\"r\" (%s)%s", chtmp, (count<numregs-1 ? ", " : ""));
}
fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\"");
if (vd)
fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n");
else
fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
}
if ((tagname=aliasfunction(fD_GetName(obj)))!=0)
{
fprintf(outfile, "#define %s(", tagname);
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "a%d, ", count);
fprintf(outfile, "a%d) %s (", count, name);
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "(a%d), ", count);
fprintf(outfile, "(a%d))\n\n", count);
}
if ((tagname=taggedfunction(obj))!=0)
{
if (output_mode!=STUBS)
{
fprintf(outfile, "#ifndef NO_INLINE_STDARG\n#define %s(", tagname);
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "a%d, ", count);
fprintf(outfile, "tags...) \\\n\t({ULONG _tags[] = { tags }; %s(",
name);
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "(a%d), ", count);
fprintf(outfile, "(%s)_tags);})\n#endif /* !NO_INLINE_STDARG */\n\n",
fD_GetProto(obj, fD_RegNum(obj)-1));
}
else
{
fprintf(outfile, "%s %s(", rettype, tagname);
for (count=d0; count<numregs-1; count++)
{
chtmp=fD_GetProto(obj, count);
if (count==fD_GetFuncParNum(obj))
fprintf(outfile, chtmp, fD_GetParam(obj, count));
else
fprintf(outfile, "%s%s%s", chtmp,
(*(chtmp+strlen(chtmp)-1)=='*' ? "" : " "),
fD_GetParam(obj, count));
fprintf(outfile, ", ");
}
fprintf(outfile, "int tag, ...)\n{\n ");
if (!vd)
fprintf(outfile, "return ");
fprintf(outfile, "%s(", name);
for (count=d0; count<numregs-1; count++)
fprintf(outfile, "%s, ", fD_GetParam(obj, count));
fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj)-1));
}
}
if (strcmp(name, "DoPkt")==0)
{
fdDef *objnc=(fdDef*)obj;
char newname[7]="DoPkt0";
objnc->name=newname;
for (count=2; count<7; count++)
{
regs reg=objnc->reg[count];
char *proto=objnc->proto[count];
objnc->reg[count]=illegal;
objnc->proto[count]=fD_nostring;
fD_write(outfile, objnc);
objnc->reg[count]=reg;
objnc->proto[count]=proto;
newname[5]++;
}
objnc->name=(char*)name;
}
}
int
ishandleddifferently(const char *proto, const char *funcname)
{
/* First check if this is a vararg call? */
const char *end=proto+strlen(proto)-1;
while (isspace(*end))
end--;
if (*end--==';')
{
while (isspace(*end))
end--;
if (*end--==')')
{
while (isspace(*end))
end--;
if (!strncmp(end-2, "...", 3))
return 1;
}
}
/* It might be a dos.library "alias" name. */
if (aliasfunction(funcname))
return 1;
/* It might be one from dos.library/DoPkt() family. */
if (strlen(funcname)==6 && !strncmp(funcname, "DoPkt", 5) &&
funcname[5]>='0' && funcname[6]<='4')
return 1;
/* Finally, it can be intuition.library/ReportMouse1(). */
return !strcmp(funcname, "ReportMouse1");
}
void
printusage(const char* exename)
{
fprintf(stderr,
"Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
"Options:\n"
"--new\t\tpreprocessor based (default)\n"
"--old\t\tinline based\n"
"--stubs\t\tlibrary stubs\n", exename);
}
/******************************************************************************/
int
main(int argc, char **argv)
{
fdDef **mydef;
fdDef *tmpdef, /* a dummy to contain the name to look for */
*founddef; /* the fdDef for which we found a prototype */
fdFile *myfile;
char *tmpstr;
FILE *outfile;
char *fdfilename=0, *protofilename=0, *outfilename=0;
long count, fds;
Error lerror;
for (count=1; count<argc; count++)
{
char *option=argv[count];
if (*option=='-')
{
option++;
if (strcmp(option, "o")==0)
{
if (count==argc-1 || outfilename)
{
printusage(argv[0]);
return EXIT_FAILURE;
}
if (strcmp(argv[++count], "-"))
outfilename=argv[count];
}
else
{
if (*option=='-') /* Accept GNU-style '--' options */
option++;
if (strcmp(option, "new")==0)
output_mode=NEW;
else if (strcmp(option, "old")==0)
output_mode=OLD;
else if (strcmp(option, "stubs")==0)
output_mode=STUBS;
else
{
printusage(argv[0]);
return EXIT_FAILURE;
}
}
}
else
{
/* One of the filenames */
if (!fdfilename)
fdfilename=option;
else if (!protofilename)
protofilename=option;
else if (!outfilename)
outfilename=option;
else
{
printusage(argv[0]);
return EXIT_FAILURE;
}
}
}
if (!fdfilename || !protofilename)
{
printusage(argv[0]);
return EXIT_FAILURE;
}
if (!(mydef=malloc(FDS*sizeof(fdDef*))))
{
fprintf(stderr, "No mem for FDs\n");
return EXIT_FAILURE;
}
for (count=0; count<FDS; count++)
mydef[count]=NULL;
if (!(myfile=fF_ctor(fdfilename)))
{
fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
return EXIT_FAILURE;
}
lerror=false;
for (count=0; count<FDS && lerror==false; count++)
{
if (!(mydef[count]=fD_ctor()))
{
fprintf(stderr, "No mem for FDs\n" );
return EXIT_FAILURE;
}
do
{
if ((lerror=fF_readln(myfile))==false)
{
fF_SetError(myfile, false);
lerror=fD_parsefd(mydef[count], myfile);
}
}
while (lerror==nodef);
}
if (count<FDS)
{
count--;
fD_dtor(mydef[count]);
mydef[count]=NULL;
}
fds=count;
/* the gnu stdlib.h seems to have a bug for qsort: int (*)(etc.) */
qsort(mydef, count, sizeof(fdDef*), (void*)fD_cmpName);
if (output_mode==OLD || output_mode==STUBS)
{
StdLib="Library";
for (count=0; count<(sizeof LibExcTable)/sizeof(char*); count+=2)
if (strcmp(BaseName, LibExcTable[count])==0)
{
StdLib=LibExcTable[count+1];
break;
}
}
fF_dtor(myfile);
if (!(myfile=fF_ctor(protofilename)))
{
fprintf(stderr, "Couldn't open file '%s'.\n", protofilename);
return EXIT_FAILURE;
}
if (!(tmpdef=fD_ctor()))
{
fprintf(stderr, "No mem for FDs\n");
return EXIT_FAILURE;
}
for (lerror=false; lerror==false || lerror==nodef;)
if ((lerror=fF_readln(myfile))==false)
{
fF_SetError(myfile, false); /* continue even on errors */
tmpstr=fF_FuncName(myfile);
if (tmpstr)
{
fD_NewName(tmpdef, tmpstr);
founddef=binSearch((void**)mydef, fds, tmpdef, (void*)fD_cmpName);
if (founddef)
{
DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
fF_SetError(myfile, false);
lerror=fD_parsepr(founddef, myfile);
}
else
if (!ishandleddifferently(myfile->line, tmpstr))
fprintf(stderr, "did not find <%s> in line %lu.\n",
tmpstr, myfile->lineno);
free(tmpstr);
}
}
fD_dtor(tmpdef);
fF_dtor(myfile);
if (strlen(fdfilename)>7 &&
!strcmp(fdfilename+strlen(fdfilename)-7, "_lib.fd"))
{
char *str=fdfilename+strlen(fdfilename)-8;
while (str!=fdfilename && str[-1]!='/' && str[-1]!=':')
str--;
strncpy(BaseNamU, str, strlen(str)-7);
BaseNamU[strlen(str)-7]='\0';
}
else
{
/* Shouldn't really happen, but... */
strcpy(BaseNamU, BaseName);
if (strlen(BaseNamU)>4 && strcmp(BaseNamU+strlen(BaseNamU)-4, "Base")==0)
BaseNamU[strlen(BaseNamU)-4]='\0';
}
StrUpr(BaseNamU);
if (outfilename)
{
if (!(outfile=fopen(outfilename, "w")))
{
fprintf(stderr, "Couldn't open output file.\n");
return EXIT_FAILURE;
}
}
else
outfile=stdout;
fprintf(outfile,
"#ifndef _INLINE_%s_H\n"
"#define _INLINE_%s_H\n\n"
"%s\n"
"#endif\n\n", BaseNamU, BaseNamU, (output_mode==NEW ?
"#ifndef __INLINE_MACROS_H\n"
"#include <inline/macros.h>" :
"#ifndef __INLINE_STUB_H\n"
"#include <inline/stubs.h>"));
if (BaseName[0])
{
if (output_mode==NEW)
fprintf(outfile,
"#ifndef %s_BASE_NAME\n"
"#define %s_BASE_NAME %s\n"
"#endif\n\n", BaseNamU, BaseNamU, BaseName);
else
fprintf(outfile,
"#ifndef BASE_EXT_DECL\n"
"#define BASE_EXT_DECL\n"
"#define BASE_EXT_DECL0 extern struct %s *%s;\n"
"#endif\n"
"#ifndef BASE_PAR_DECL\n"
"#define BASE_PAR_DECL\n"
"#define BASE_PAR_DECL0 void\n"
"#endif\n"
"#ifndef BASE_NAME\n"
"#define BASE_NAME %s\n"
"#endif\n\n"
"BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
}
for (count=0; count<FDS && mydef[count]; count++)
{
DBP(fprintf(stderr, "outputting %ld...\n", count));
fD_write(outfile, mydef[count]);
fD_dtor(mydef[count]);
mydef[count]=NULL;
}
if (output_mode==OLD || output_mode==STUBS)
if (BaseName[0])
fprintf(outfile,
"#undef BASE_EXT_DECL\n"
"#undef BASE_EXT_DECL0\n"
"#undef BASE_PAR_DECL\n"
"#undef BASE_PAR_DECL0\n"
"#undef BASE_NAME\n\n");
fprintf(outfile, "#endif /* _INLINE_%s_H */\n", BaseNamU);
free(mydef);
return EXIT_SUCCESS;
}