home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
dev
/
misc
/
p2c
/
src
/
makeproto.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-21
|
16KB
|
509 lines
/* "makeproto" Copyright 1989, 1990, 1991 Free Software Foundation */
/* Program to scan old-style source files and make prototypes */
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#ifdef FILE /* a #define in BSD, a typedef in SYSV (hp-ux, at least) */
# ifndef BSD
# define BSD 1
# endif
#endif
#ifdef BSD
# include <strings.h>
#else
# include <string.h>
#endif
#define isidchar(x) (isalnum(x) || (x) == '_')
#define dprintf if (!debug) ; else printf
#define MAXARGS 16
int verbose, debug, incomment;
struct warnstruct {
char *bad, *good;
} warntypes[] = {
{ "char", "int" },
{ "signed char", "int" },
{ "unsigned char", "int" },
{ "short", "int" },
{ "signed short", "int" },
{ "unsigned short", "int" },
{ "boolean", "int" },
{ "Boolean", "int" },
{ "float", "double" },
{ NULL, NULL }
} ;
int readline(buf, inf)
char *buf;
FILE *inf;
{
char *cp, *cp2;
int spflag;
for (;;) {
if (fgets(buf, 1000, inf)) {
cp = buf;
cp2 = buf;
spflag = 0;
while (*cp) {
if (incomment) {
if (cp[0] == '*' && cp[1] == '/') {
incomment = 0;
cp += 2;
} else
cp++;
spflag = 1;
} else {
if (cp[0] == '/' && cp[1] == '*') {
incomment = 1;
cp += 2;
} else if (isspace(*cp)) {
spflag = 1;
cp++;
} else {
if (spflag)
*cp2++ = ' ';
*cp2++ = *cp++;
spflag = 0;
}
}
}
*cp2 = 0;
if (!*buf)
continue;
if (verbose)
printf("\217%s\210\n", buf);
return 1;
} else
strcpy(buf, "\001");
return 0;
}
}
int strbeginsword(s1, s2)
register char *s1, *s2;
{
while (*s2 && *s1 == *s2)
s1++, s2++;
return (!*s2 && !isidchar(*s1));
}
void usage()
{
fprintf(stderr, "usage: makeproto [options] [infile ...] [-o outfile]]\n");
fprintf(stderr, " -tnnn Tab to nnn after type name [default 15]\n");
fprintf(stderr, " -annn Tab to nnn before arguments [default 30]\n");
fprintf(stderr, " -s0 Omit functions declared static\n");
fprintf(stderr, " -s1 Omit functions not declared static\n");
fprintf(stderr, " -x Add \"extern\" keyword (-X => \"Extern\")\n");
fprintf(stderr, " -n Include argument names in prototypes\n");
fprintf(stderr, " -m Use PP/PV macro notation\n");
#ifdef MCH_AMIGA
exit(20);
#else
exit(1);
#endif
}
#define bounce(msg) do { if (verbose) printf("Bounced: %s\n", msg); if (stupid) goto Lbounce; } while (0)
main(argc, argv)
int argc;
char **argv;
{
FILE *inf, *outf;
char outfname[256];
char buf[1000], ifdefname[256];
char ftype[256], fname[80], dtype[256], decl[256], dname[80], temp[256];
char argdecls[MAXARGS][256], argnames[MAXARGS][80];
char *cp, *cp2, *cp3;
int i, j, pos, len, thistab, numstars, whichf, nargs, incomment, errors = 0;
long li;
int typetab = 15, argtab = 30, width = 80, usenames = 0, usemacros = 0;
int useextern = 0, staticness = -1, hasheader = 0, useifdefs = 0;
int stupid = 1, firstdecl;
errors = 0;
verbose = 0;
debug = 0;
*outfname = 0;
while (argc > 1 && argv[1][0] == '-') {
if (argv[1][1] == 't') {
typetab = atoi(argv[1] + 2);
} else if (argv[1][1] == 'a') {
argtab = atoi(argv[1] + 2);
} else if (argv[1][1] == 'w') {
width = atoi(argv[1] + 2);
} else if (argv[1][1] == 's') {
staticness = atoi(argv[1] + 2);
} else if (argv[1][1] == 'v') {
verbose = 1;
} else if (argv[1][1] == 'D') {
debug = 1;
} else if (argv[1][1] == 'x') {
useextern = 1;
} else if (argv[1][1] == 'X') {
useextern = 2;
} else if (argv[1][1] == 'n') {
usenames = 1;
} else if (argv[1][1] == 'm') {
usemacros = 1;
} else if (argv[1][1] == 'h') {
hasheader = 1;
} else if (argv[1][1] == 'i') {
useifdefs = 1;
} else if (argv[1][1] == 'o' && argc > 2) {
strcpy(outfname, argv[2]);
argc--, argv++;
} else {
usage();
}
argc--, argv++;
}
if (argc > 2 && !strcmp(argv[argc-2], "-o")) {
strcpy(outfname, argv[argc-1]);
argc -= 2;
}
if (*outfname) {
outf = fopen(outfname, "w");
if (!outf) {
perror(outfname);
#ifdef MCH_AMIGA
exit(20);
#else
exit(1);
#endif
}
} else
outf = stdout;
if (hasheader) {
time(&li);
cp = ctime(&li);
cp[24] = 0;
fprintf(outf, "\n/* Declarations created by \"makeproto\" on %s */\n", cp);
fprintf(outf, "\n\n");
}
incomment = 0;
for (whichf = 1; whichf < argc + (argc < 2); whichf++) {
if (whichf >= argc || !strcmp(argv[whichf], "-")) {
inf = stdin;
} else {
inf = fopen(argv[whichf], "r");
if (!inf) {
perror(argv[whichf]);
fprintf(outf, "\n/* Unable to open file %s */\n", argv[whichf]);
errors++;
continue;
}
}
firstdecl = 1;
while (readline(buf, inf)) {
if (!isidchar(*buf))
continue;
cp = buf;
cp2 = ftype;
numstars = 0;
while (isspace(*cp) || isidchar(*cp))
*cp2++ = *cp++;
if (*cp == '*') {
while (*cp == '*' || isspace(*cp)) {
if (*cp == '*')
numstars++;
cp++;
}
} else {
while (cp > buf && isspace(cp[-1])) cp--, cp2--;
while (cp > buf && isidchar(cp[-1])) cp--, cp2--;
}
while (cp2 > ftype && isspace(cp2[-1])) cp2--;
*cp2 = 0;
if (!*ftype)
strcpy(ftype, "int");
dprintf("numstars is %d\n", numstars); /***/
dprintf("ftype is %s\n", ftype); /***/
dprintf("cp after ftype is %s\n", cp); /***/
if (strbeginsword(ftype, "static") || strbeginsword(ftype, "Static")) {
if (staticness == 0)
bounce("Function is static");
} else {
if (staticness == 1)
bounce("Function is not static");
if (useextern &&
!strbeginsword(ftype, "extern") && !strbeginsword(ftype, "Extern")) {
sprintf(temp, useextern == 2 ? "Extern %s" : "extern %s", ftype);
strcpy(ftype, temp);
}
}
while (isspace(*cp)) cp++;
if (!*cp) {
readline(buf, inf);
cp = buf;
}
dprintf("cp before fname is %s\n", cp); /***/
if (!isidchar(*cp))
bounce("No function name");
cp2 = fname;
while (isidchar(*cp))
*cp2++= *cp++;
*cp2 = 0;
dprintf("fname is %s\n", fname); /***/
dprintf("cp after fname is %s\n", cp); /***/
while (isspace(*cp)) cp++;
if (*cp++ != '(')
bounce("No function '('");
nargs = 0;
if (!*cp) {
readline(buf, inf);
cp = buf;
}
while (isspace(*cp)) cp++;
while (*cp != ')') {
if (!isidchar(*cp))
bounce("Missing argument name");
if (nargs >= MAXARGS)
bounce("Too many arguments");
cp2 = argnames[nargs];
argdecls[nargs][0] = 0;
nargs++;
while (isidchar(*cp))
*cp2++ = *cp++;
*cp2 = 0;
dprintf("Argument %d is named %s\n", nargs-1, argnames[nargs-1]); /***/
while (isspace(*cp)) cp++;
if (*cp == ',') {
cp++;
if (!*cp) {
readline(buf, inf);
cp = buf;
}
while (isspace(*cp)) cp++;
} else if (*cp != ')')
bounce("Missing function ')'");
}
if (cp[1])
bounce("Characters after function ')'");
readline(buf, inf);
cp = buf;
for (;;) {
while (isspace(*cp)) cp++;
if (isidchar(*cp)) {
cp2 = dtype;
if (strbeginsword(cp, "register")) {
cp += 8;
while (isspace(*cp)) cp++;
}
while (isspace(*cp) || isidchar(*cp))
*cp2++ = *cp++;
if (*cp == ',' || *cp == ';' || *cp == '[') {
while (cp2 > dtype && isspace(cp2[-1])) cp--, cp2--;
while (cp2 > dtype && isidchar(cp2[-1])) cp--, cp2--;
} else if (*cp != '(' && *cp != '*')
bounce("Strange character in arg decl");
while (cp2 > dtype && isspace(cp2[-1])) cp2--;
*cp2 = 0;
if (!*dtype)
bounce("Empty argument type");
for (;;) {
cp2 = decl;
cp3 = dname;
while (*cp == '*' || *cp == '(' || isspace(*cp))
*cp2++ = *cp++;
if (!isidchar(*cp))
bounce("Missing arg decl name");
while (isidchar(*cp)) {
if (usenames)
*cp2++ = *cp;
*cp3++ = *cp++;
}
if (!usenames) {
while (cp2 > decl && isspace(cp2[-1])) cp2--;
while (isspace(*cp)) cp++;
}
i = 0;
while (*cp && *cp != ';' && (*cp != ',' || i > 0)) {
if (*cp == '(' || *cp == '[') i++;
if (*cp == ')' || *cp == ']') i--;
*cp2++ = *cp++;
}
*cp2 = 0;
*cp3 = 0;
dprintf("Argument %s is %s\n", dname, decl); /***/
if (i > 0)
bounce("Unbalanced parens in arg decl");
if (!*cp)
bounce("Missing ';' or ',' in arg decl");
for (i = 0; i < nargs && strcmp(argnames[i], dname); i++) ;
if (i >= nargs)
bounce("Arg decl name not in argument list");
if (*decl)
sprintf(argdecls[i], "%s %s", dtype, decl);
else
strcpy(argdecls[i], dtype);
if (*cp == ',') {
cp++;
if (!*cp) {
readline(buf, inf);
cp = buf;
}
while (isspace(*cp)) cp++;
} else
break;
}
cp++;
if (!*cp) {
readline(buf, inf);
cp = buf;
}
} else
break;
}
if (*cp != '{')
bounce("Missing function '{'");
if (firstdecl) {
firstdecl = 0;
if (argc > 2)
fprintf(outf, "\n/* Declarations from %s */\n", argv[whichf]);
if (useifdefs && inf != stdin) {
strcpy(ifdefname, argv[whichf]);
cp = ifdefname;
for (cp2 = ifdefname; *cp2; ) {
if (*cp2++ == '/')
cp = cp2;
}
for (cp2 = ifdefname; *cp; cp++, cp2++) {
if (islower(*cp))
*cp2 = toupper(*cp);
else if (isalnum(*cp))
*cp2 = *cp;
else
*cp2 = '_';
}
fprintf(outf, "#ifdef PROTO_%s\n", ifdefname);
}
}
for (i = 0; i < nargs; i++) {
if (!argdecls[i][0])
sprintf(argdecls[i], "int %s", argnames[i]);
for (j = 0; warntypes[j].bad &&
!strbeginsword(argdecls[i], warntypes[j].bad); j++) ;
if (warntypes[j].bad) {
cp = argdecls[i];
while (isspace(*cp) || isidchar(*cp)) cp++;
if (!*cp) { /* not, e.g., "char *" */
sprintf(temp, "%s%s", warntypes[j].good,
argdecls[i] + strlen(warntypes[j].bad));
strcpy(argdecls[i], temp);
fprintf(stderr, "Warning: Argument %s of %s has type %s\n",
argnames[i], fname, warntypes[j]);
}
}
}
if (verbose && outf != stdout)
printf("Found declaration for %s\n", fname);
fprintf(outf, "%s", ftype);
pos = strlen(ftype) + numstars;
do {
putc(' ', outf);
pos++;
} while (pos < typetab);
for (i = 1; i <= numstars; i++)
putc('*', outf);
fprintf(outf, "%s", fname);
pos += strlen(fname);
do {
putc(' ', outf);
pos++;
} while (pos < argtab);
if (nargs == 0) {
if (usemacros)
fprintf(outf, "PV();");
else
fprintf(outf, "(void);");
} else {
if (usemacros)
fprintf(outf, "PP( ("), pos += 5;
else
fprintf(outf, "("), pos++;
thistab = pos;
for (i = 0; i < nargs; i++) {
len = strlen(argdecls[i]);
if (i > 0) {
putc(',', outf);
pos++;
if (pos > thistab && pos + len >= width) {
putc('\n', outf);
for (j = 1; j <= thistab; j++)
putc(' ', outf);
pos = thistab;
} else {
putc(' ', outf);
pos++;
}
}
fprintf(outf, "%s", argdecls[i]);
pos += len;
}
if (usemacros)
fprintf(outf, ") );");
else
fprintf(outf, ");");
}
putc('\n', outf);
Lbounce: ;
}
if (inf != stdin) {
if (useifdefs && !firstdecl)
fprintf(outf, "#endif /*PROTO_%s*/\n", ifdefname);
fclose(inf);
}
}
if (hasheader) {
fprintf(outf, "\n\n/* End. */\n\n");
}
if (outf != stdout)
fclose(outf);
if (errors)
exit(1);
else
exit(0);
}
/* End. */