AROS-v0/scripts/cint2.awk

504 lines
11 KiB
Awk
Raw Permalink Blame History

# Creates C files with function prototypes from FD and clib/*_proto.h files.
# Example usage:
#
# Required directory structure:
# amiga/include/fd/mylib_lib.fd
# amiga/include/clib/mylib_protos.h
# Usage: awk -f cint2.awk mylib
# Result:
# mylib/func1.c
# mylib/func2.c
# ...
BEGIN {
date="27-11-96";
RTYPES["long"]="LONG";
RTYPES["unsigned long"]="ULONG";
RTYPES["short"]="WORD";
RTYPES["unsigned short"]="UWORD";
RTYPES["char"]="BYTE";
RTYPES["unsigned char"]="UBYTE";
TYPES["ULONG"]=1;
TYPES["LONG"]=1;
TYPES["UBYTE"]=1;
TYPES["BYTE"]=1;
TYPES["UWORD"]=1;
TYPES["WORD"]=1;
TYPES["APTR"]=1;
TYPES["BPTR"]=1;
TYPES["STRPTR"]=1;
TYPES["BSTR"]=1;
TYPES["BOOL"]=1;
TYPES["Tag"]=1;
TYPES["FLOAT"]=1;
TYPES["DOUBLE"]=1;
TYPES[""]=1;
TYPES[""]=1;
# 1- types
# 2- commands
KEYWORDS["struct"]=2;
KEYWORDS["int"]=1;
KEYWORDS["char"]=1;
KEYWORDS["double"]=1;
KEYWORDS["float"]=1;
KEYWORDS["for"]=10;
KEYWORDS["if"]=10;
KEYWORDS["else"]=10;
KEYWORDS["do"]=10;
KEYWORDS["while"]=10;
KEYWORDS["switch"]=10;
KEYWORDS["case"]=10;
KEYWORDS["break"]=10;
KEYWORDS["continue"]=10;
KEYWORDS["goto"]=10;
KEYWORDS["union"]=2;
KEYWORDS["enum"]=2;
KEYWORDS["typedef"]=1;
KEYWORDS["void"]=1;
KEYWORDS["unsigned"]=3;
KEYWORDS["signed"]=3;
KEYWORDS["const"]=3;
KEYWORDS["long"]=3;
KEYWORDS["short"]=3;
KEYWORDS[""]=0;
KEYWORDS[""]=0;
SpecialStructs["exec"]="ExecBase";
SpecialStructs["graphics"]="GfxBase";
SpecialStructs["dos"]="DosLibrary";
SpecialStructs["intuition"]="IntuitionBase";
spaces=" ";
for (t=0; t<10; t++)
spaces=spaces spaces;
for (arg=1; arg<ARGC; arg++)
{
part_name=ARGV[arg];
Part_name=toupper(substr(part_name,1,1)) substr(part_name,2);
if (part_name in SpecialStructs)
struct_name=SpecialStructs[part_name];
else
struct_name="Library";
print "Working on " part_name "..."
dir="amiga/" part_name;
system("mkdir " dir);
print dir;
dir=dir"/";
INPUT="amiga/include/fd/" part_name "_lib.fd"
print INPUT
# Read LVO
delete LVO
while ((getline line < INPUT) > 0)
{
if (substr(line,1,6) == "##bias")
offset = int(substr(line,7))/6;
else if (substr(line,1,6) == "##base")
{
match(line,"[A-Za-z_][A-Za-z0-9_]*$");
Base = substr(line,RSTART+1,RLENGTH-1);
}
else if (!match (line,/[*#]/))
{
match(line,"[A-Za-z_][A-Za-z0-9_]*");
fname=substr(line,RSTART,RLENGTH);
line=substr(line,RSTART+RLENGTH);
if (match(line,"[(][^)]*[)]"))
{
if (RLENGTH!=2)
fargs=substr(line,RSTART+1,RLENGTH-2);
else
fargs="";
}
else
fargs="";
line=substr(line,RSTART+RLENGTH);
if (match(line,"[(][^)]*[)]"))
{
if (RLENGTH!=2)
fregs=substr(line,RSTART+1,RLENGTH-2);
else
fregs="";
}
else
fregs="";
#print fname " (" fargs ") (" fregs ") " offset
LVO[fname] = offset;
offset ++;
LVO_regs[fname] = toupper(fregs);
}
}
INPUT="amiga/include/clib/" part_name "_protos.h"
#print INPUT
getline line < INPUT
yyinit(line);
rt_type="";
#if (!match(FILENAME,"\/.*_"))
#{
# print "Can't find libname"
# exit (10);
#}
#dir=substr(FILENAME,RSTART+1,RLENGTH-2);
#
#if (dir!="")
#{
# system("mkdir " dir);
# part_name=dir;
# dir=dir "/";
#}
while ((token=yylex()) != "EOF")
{
#print "0 -" token "-" yyval "-"
if ((token=="keyword" && KEYWORDS[yyval]<10) || token=="typedef")
{
plevel=0;
token=read_type(token);
fname = yyval;
token=yylex();
if (token=="(")
{
plevel ++;
token=yylex();
if (rt_ptr!="")
ret=rt_type " " rt_ptr;
else
ret=rt_type;
if (token==")")
{
npar=1;
par_type[1]="void";
par_ptr[1]="";
par_name[1]="";
}
else
{
npar=0;
while (token!=")")
{
#print 1
if (token==",")
token=yylex();
token=read_type(token);
if (token=="ident")
{
name=yyval;
token=yylex();
}
else
name="";
# if (plevel != 1)
# {
# plevel --;
# name=name ") "
# while((token==yylex())!=")" || plevel!=1)
# {
#print 2
# if (token=="(")
# plevel ++;
# else if (token==")")
# plevel --;
# name=name " " yyval;
# }
# }
npar++;
par_type[npar]=rt_type;
par_ptr[npar]=rt_ptr;
par_name[npar]=name;
#print "npar " npar "-" rt_type "-" rt_ptr "-" name
}
}
print "Processing "fname"..."
#file="/dev/stdout"
file=dir tolower(fname) ".c"
if (fname in LVO)
{
offset=LVO[fname];
regs=LVO_regs[fname];
}
else
{
offset=-1;
regs="";
}
printf ("/*\n") > file;
print " Copyright <20> 2010, The AROS Development Team. All rights reserved." >> file
printf (" %sId$\n", "$") >> file;
printf ("\n") >> file;
printf (" Desc:\n") >> file;
printf (" Lang: english\n") >> file;
printf ("*/\n") >> file;
printf ("#include \"%s_intern.h\"\n\n", part_name) >> file;
print "/*****************************************************************************\n" >> file
print " NAME */" >>file
print "#include <proto/" part_name ".h>\n">>file
if (offset!=-1)
{
if (npar==1 && par_type[1]=="void" && par_ptr[1] == "" &&
par_name[1]=="")
print "\tAROS_LH0("ret", "fname",\n" >>file
else
print "\tAROS_LH"npar"("ret", "fname",\n" >>file
print "/* SYNOPSIS */" >>file
if (npar==1 && par_type[1]=="void" && par_ptr[1] == "" &&
par_name[1]=="")
{
print "\t/* void */" >>file
}
else
{
maxlen=0;
for (t=1; t<=npar; t++)
{
#print 3
len=length(par_type[t]);
len2=length(par_ptr[t]);
len+=len2 ? len2+1 : 0;
if (len > maxlen)
maxlen = len;
}
for (t=1; t<=npar; t++)
{
#print 4
len=length(par_type[t]);
len2=length(par_ptr[t]);
printf("\tAROS_LHA(%s", par_type[t])>>file;
printf("%s", substr(spaces,1,maxlen-len-len2))>>file;
printf("%s, %s, %s),\n",par_ptr[t],par_name[t],
substr(regs,1,2))>>file;
if (regs!="")
{
regs=substr(regs,4);
}
}
}
print "\n/* LOCATION */\n\tstruct "struct_name" *, "Base", "offset", "Part_name")">>file
}
else
{
print "\t"ret" "fname" (\n" >>file
print "/* SYNOPSIS */" >>file
if (npar==1 && par_type[1]=="void" && par_ptr[1] == "" &&
par_name[1]=="")
{
print "\tvoid)" >>file
}
else
{
maxlen=0;
for (t=1; t<=npar; t++)
{
#print 3
len=length(par_type[t]);
len2=length(par_ptr[t]);
len+=len2 ? len2+1 : 0;
if (len > maxlen)
maxlen = len;
}
for (t=1; t<=npar; t++)
{
#print 4
len=length(par_type[t]);
len2=length(par_ptr[t]);
printf("\t%s", par_type[t])>>file;
printf("%s", substr(spaces,1,maxlen-len-len2))>>file;
printf("%s %s",par_ptr[t],par_name[t])>>file;
if (t==npar)
printf(")\n")>>file;
else
printf(",\n")>>file;
}
}
}
print "\n/* FUNCTION\n\n INPUTS\n\n RESULT\n\n NOTES\n">>file
print " EXAMPLE\n\n BUGS\n\n SEE ALSO\n\n INTERNALS\n">>file
print " HISTORY\n\n">>file;
print "*****************************************************************************/" > file
print "{">>file;
print " AROS_LIBFUNC_INIT\n">>file;
print " extern void aros_print_not_implemented (char *);">>file;
print " aros_print_not_implemented (\"" fname "\");\n">>file;
print " AROS_LIBFUNC_EXIT">>file;
print "} /* " fname " */">>file;
fclose (file);
} # found "("
} # found keyword
} # while token != EOF
} # for all args
} # BEGIN
function read_type(pretoken ,token) {
token=pretoken;
#print "token3 " token "-" yyval
rt_type="";
while ((token=="keyword" && KEYWORDS[yyval]<10) || token=="typedef" ||
token=="...")
{
#print 5
rt_type=rt_type " " yyval;
if (KEYWORDS[yyval]==2)
{
token=yylex();
rt_type=rt_type " " yyval;
}
token=yylex();
#print "token2 " token
}
rt_type=substr(rt_type,2);
#print "type " rt_type
if (rt_type in RTYPES)
rt_type = RTYPES[rt_type];
rt_ptr="";
while (token=="*" || token=="(")
{
#print 6
rt_ptr=rt_ptr yyval;
if (token=="(")
plevel++;
token=yylex();
#print "token1 " token
}
#print "ptr " rt_ptr
return token;
}
function yyinit(str) {
yyrest=str;
}
function yylex() {
#print yylex
for (yyagain=1; yyagain; )
{
yyagain=0;
if (yyrest=="" || match(yyrest,/^[ \t\014\r]+/))
{
while (1)
{
while (yyrest=="")
{
if ((getline yyrest < INPUT) != 1)
return "EOF";
#print "1 -" yyrest "-"
if (substr(yyrest,1,1) == "#")
yyrest="";
}
if (!match(yyrest,"^[ \t\014\r]+"))
break;
yyrest=substr(yyrest,RSTART+RLENGTH);
}
}
if (match(yyrest,/^\/\*/))
{
yyrest=substr(yyrest,3);
while (!match(yyrest,"\*\/"))
{
if ((getline yyrest < INPUT) != 1)
return "EOF";
#print "2 -" yyrest "-"
}
yyrest=substr(yyrest,RSTART+RLENGTH);
yyagain=1;
}
}
if (match(yyrest,"^[a-zA-Z_][a-zA-Z0-9_]*"))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
if (yyval in TYPES)
return "typedef";
else if (yyval in KEYWORDS)
return "keyword";
else
return "ident";
}
if (match(yyrest,"^0[xX][0-9a-f]+[lL]?"))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "int_const";
}
if (match(yyrest,/^([0-9]*\.[0-9]+|[0-9]+\.[0-9]*)([eE][0-9]+)?[fF]?/))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "float_const";
}
if (match(yyrest,"^0[0-7]+[lL]?"))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "int_const";
}
if (match(yyrest,"^[1-9][0-9]*[lL]?"))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "int_const";
}
if (match(yyrest,"^\""))
{
if (match(yyrest,"^\"(\\\"|[^\"])*\""))
{
yyval=substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "str_const";
}
else
{
yyval=substr(yyrest,1,length(yyrest)-1);
while (1)
{
if ((getline yyrest < INPUT) != 1)
return "EOF";
if (match(yyrest,"^(\\\"|[^\"])*\""))
break;
yyval=yyval substr(yyrest,1,length(yyrest)-1);
}
yyval=yyval substr(yyrest,RSTART,RLENGTH);
yyrest=substr(yyrest,RSTART+RLENGTH);
return "str_const";
}
}
if (substr(yyrest,1,3)=="...")
{
yyval="...";
yyrest=substr(yyrest,4);
return yyval;
}
yyval=substr(yyrest,1,1);
yyrest=substr(yyrest,2);
return yyval;
}