home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
PROTC12A.ZIP
/
PROTOC.C
< prev
next >
Wrap
Text File
|
1990-07-28
|
19KB
|
600 lines
/*
** PROTOC.C by: Mitch Fisher
**
** Options available are:
** O output to screen
**
** Update 07/24/90
** Update included correcting problem with comment on same line as a
** function.
** Error occurred if () were in a single line comment - corrected.
** Program is BOUND so it can run under OS/2 and DOS
**
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <process.h>
#include "protoc.h"
#define min(x,y) (x<y)?x:y
/*
Prototypes for Character functions in CHRFUNCS.OBJ
*/
int delchr(char *string, int loc);
int inschr(char *string, int size, char chr, int loc);
int poschr(char *string, char chr, int f1);
int utcharsb(int ctrl, char *string, char ch);
int cjust(char ch, char *s);
int rjsut(char ch, char *s);
int ljust(char ch, char *s);
int snlbntb(char ch, int *nlb, int *ntb, char *s);
/* Global variables */
char comment = 0, /* Comment level */
dquote = 0, /* Double Quote mode */
squote = 0, /* Single Quote mode */
funct = 0, /* function mode */
hpath[64]; /* Header Path */
unsigned functline = 0,
line = 0,
level = 0; /* The level of Begin's and End's */
/*
** Ensure_extension will make sure that 'string' has an appending 'ext'
** value if there only if there isn't one.
*/
void ensure_extension(string, ext)
char *string,
*ext;
{
char *last_slash,
*last_dot;
last_slash = strrchr(string, '\\');
last_dot = strrchr(string, '.');
if ( (last_dot < last_slash) || ( !last_dot ) )
strcat(string, ext);
}
/*
** This procedure will get the nesting of BEGIN's and END's. It will take
** account if the { or } is in a comment and it will also handle nested
** comments.
*/
void nesting(string) /* Find the nesting levels */
char *string; /* Pointer to the line of text from the file */
{
do
{
if ( !comment )
{
if ( ( *string == 0x22) && ( dquote == 1 ) )
dquote = 0;
else if ( *string == 0x22 )
dquote = 1;
if ( !dquote )
{
if ( ( *string == 0x27) && ( squote == 1 ) )
squote = 0;
else if ( *string == 0x27 )
squote = 1;
}
}
if ( (*string == '/') && (*(string + 1) == '*') ) /* Is it a begin comment ? */
comment++; /* If so increment the comment variable */
if ( (*string == '*') && (*(string + 1) == '/') ) /* Is it an end comment ? */
comment--; /* If so, decrement the comment variable */
if ( (!comment) && (!squote) && (!dquote) ) /* If the comment counter is 0 and quote modes are 0 */
{ /* Check for {'s and }'s */
if ( *string == '{' ) /* Is it a { ? */
level++; /* If so, add one to the value */
if ( *string == '}' ) /* Is it an } ? */
level--; /* If so, decrement the value */
}
} while ( *string++ ); /* Do..While there is still a string */
}
int iscomment(string)
char *string;
{
int first,
secnd,
comma,
semi,
paren;
first = poschr(string, '/', 0);
secnd = poschr(string, '*', 0);
semi = poschr(string, ';', 0);
comma = poschr(string, '.', 0);
paren = poschr(string, '(', 0);
if ( (!first) || (!secnd) )
return(0);
if ( first == (secnd - 1) )
{
if ( (paren) && ( paren > first ) )
return(1);
if ( (paren) && ( paren < first ) )
return(0);
if ( (semi) && ( semi > first ) )
return(1);
if ( (comma) && ( comma > first ) )
return(1);
if ( (semi) && ( semi < first ) )
return(0);
if ( (comma) && ( comma < first ) )
return(0);
return(1);
}
return(0);
}
int isfunct(string)
char *string;
{
int last;
char temp[256];
if ( (comment) || (squote) || (dquote) )
return(0);
if ( iscomment(string) )
return(0);
strcpy(temp, string);
utcharsb(3, temp, ' ');
if ( temp[0] == '#' )
return(0);
last = poschr(temp, ',', 1);
if ( last )
{
temp[last - 1] = 0;
if ( temp[strlen(temp) - 1] == ')' )
return(0);
}
if ( !poschr(string, ';', 0) && ( level == 0 ) )
{
if ( poschr(string, '(', 0 ) )
{
if ( poschr(string, ')', 0 ) )
return(1);
}
}
return(0);
}
void strip_array(string)
char *string;
{
char *ptr;
int first;
ptr = string;
if ( !poschr(ptr, '[', 0 ) )
return;
while(*ptr)
{
first = poschr(ptr, '[', 0);
if ( !first )
break;
ptr += first;
while( *ptr != ']' )
delchr(ptr, 1);
}
}
void strip_tab(string)
char *string;
{
while ( *string )
{
if ( *string == '\t' )
*string = ' ';
*string++;
}
}
/*
** This procedure will print the function name if the line scanned has
** two (2) parenthesis '()' and no semicolon ';'
*/
void function(string, fp, direction)
char *string;
FILE *fp,
*direction;
{
int first;
char temp[256],
original[256],
proto[256],
type[256],
*front,
hold,
*ptr;
int oldlevel = level,
count;
/*
** If currently in a comment, quote, double quote of function,
** return since a callable function may not be within any of the
** above.
*/
if ( (comment) || (squote) || (dquote) || (level) )
return;
if ( !isfunct(string) )
return;
count = 0;
strcpy(temp, string);
strip_tab(temp);
do
{
nesting(temp);
if (level != oldlevel)
break;
utcharsb(3, temp, '\n');
if ( temp[0] == 0 )
{
count++;
continue;
}
if ( funct )
{
utcharsb(3, temp, ' ');
if ( iscomment(temp) )
{
count++;
continue;
}
first = poschr(temp, ';', 1); /* end in ';' */
if ( first )
temp[first - 1] = 0;
else
{
first = poschr(temp, ',', 1); /* end in ',' */
temp[first - 1] = 0;
}
first = poschr(temp, ' ', 1);
ptr = &temp[first];
*ptr--;
while( isspace(*ptr) )
*ptr--;
ptr += 2;
utcharsb(3, ptr, ' ');
front = temp;
if ( poschr(temp, ' ', 0) )
{
*ptr--;
hold = *ptr;
*ptr = 0;
strcpy(type, front);
strcat(type, " ");
*ptr = hold;
*ptr++;
}
else
{
*ptr--;
strcat(type, temp);
strcpy(temp, type);
*ptr++;
}
utcharsb(3, temp, '\n');
utcharsb(3, temp, ',');
strcat(proto, temp);
strcat(proto, ", ");
}
if ( (isfunct(temp)) && (!funct) && ( level == 0 ) )
{
first = poschr(temp, '(', 0);
strcpy(original, temp);
temp[first] = '\0';
strcpy(proto, temp);
funct = 1;
}
count++;
} while ( fgets(temp, 132, fp) );
if ( count == 1 )
{
strcpy(proto, original);
if ( proto[strlen(proto) - 2] == '(' )
{
proto[strlen(proto) - 1] = 0;
strcat(proto, "void)");
}
}
else
{
utcharsb(3, proto, ' ');
utcharsb(3, proto, ',');
strcat(proto, ")");
}
/*
** Delete any contents in an array
*/
strip_array(proto);
fprintf(direction, "%s;\n", proto);
funct = 0;
}
/*
** The main program. The input line may contain additional arguments
** that being O and/or F.
*/
void main(int argc, char *argv[])
{
char string[256], /* Input string from the file */
header[14], /* Header file name */
*pram, /* Parameter */
*period, /* The address of the . in the filename */
pname[14],
argstr[256]; /* The name of the file to print */
int item = 1, /* Location within **ARGV */
first,
files = 0,
OutOnly = 0, /* Output to screen only flag */
options = 0, /* Number of options found */
errtype = 0; /* Type of error that occured */
FILE *stream, /* The file stream */
*project, /* The project stream */
*direction; /* The file direction stream */
puts("\n\n\nPROTOC Prototype Generator Version 1.2 (OS/2 Dual Mode)\n(C) Mitchell Fisher, 1990\n\n");
if ( argc == 1 ) /* If only one parameter error = 1 */
errtype = 1; /* Set errortype */
else /* Otherwise... */
if ( argv[1][0] == '-' ) /* Check to see if there is an option specified */
{
pram = strupr(argv[1]); /* Uppercase the first parameter */
item++;
if ( strlen(pram) > 3 ) /* If option length > 3, error! */
errtype = 2; /* Set errtype */
if ( strchr(pram, 'O') ) /* If 'O' option */
{
OutOnly = 1; /* Set OutOnly flag */
options++; /* Add one to options found */
}
if ( (options == 1) && (strlen(pram) == 3) ) /* If only one option found but pram has 2 parameters in it */
errtype = 2; /* Error! */
}
if ( errtype ) /* If an error has occured */
{
switch ( errtype )
{
case 1: puts("Usage: PROTOC [-O] Project Name[.PRJ]");
puts("Where O = output to screen only. Otherwise, output");
puts("is sent to .H file with project name.");
break;
case 2: puts("Error: Illegal Parameter.");
break;
case 3: puts("Error: Too many Parameters.");
}
exit(1); /* Exit the program */
}
strcpy(pname, strupr(argv[item]));
if ( !poschr(pname, '.', 0 ) )
{
if ( strlen(pname) < 9 )
strcat(pname, ".PRJ");
}
if ( !OutOnly )
{
/*
** strip any extension
*/
strcpy(argstr, pname);
options = poschr(argstr, '.', 0);
if ( !options )
options = strlen(argstr) + 1;
argstr[options - 1] = '\0';
strcpy(header, argstr);
strcpy(header, strupr(header));
strcat(header, ".H");
}
fprintf(stderr, "Creating Header file %s from project file %s\n", header, pname);
project = fopen(pname, "r"); /* Open the project file */
if ( !project )
{
fprintf(stderr, "File '%s' not found\n", pname);
exit(1);
}
if ( !OutOnly )
direction = fopen(header, "w"); /* If not to screen set direction file */
else
direction = stderr; /* Otherwise to console */
fprintf(direction, "%s\n", "/*");
fprintf(direction, "%s %s\n", "** Function Prototypes for ", pname);
fprintf(direction, "%s\n", "*/\n");
for(;;) /* While there are still files in **ARGV */
{
if ( (fgets(argstr, 132, project)) == NULL ) /* Read from the project file into argstr */
break; /* End the while if an EOF detected */
/*
** Delete any comilation conditions
*/
first = poschr(argstr, '(', 0);
if ( first )
argstr[first - 1] = 0;
utcharsb(3, argstr, '\n');
utcharsb(3, argstr, ' ');
strcpy(argstr, strupr(argstr)); /* Convert filename into uppercase */
/*
** Check filename to check to see if it an Object (.OBJ)
** or a library file (.LIB). If so, bypass the file
*/
period = strchr(argstr, '.');
if ( !strncmp(period, ".OBJ", 4) )
continue;
if ( !strncmp(period, ".LIB", 4) )
continue;
if ( (stream = fopen(argstr, "r")) == NULL) /* Open the file in ARGSTR */
{
printf("\nFile '%s' not found.\n", argstr); /* Print error if file not found */
item++;
continue; /* Continue with WHILE loop */
}
level = 0; /* Reset line number and level number */
if ( !OutOnly )
fprintf(stderr, " Processing %s\n", argstr);
files++;
/*
** Write header comments
*/
fprintf(direction, "\n%s\n", "/*");
fprintf(direction, "** File: %s\n", argstr);
fprintf(direction, "%s\n", "*/\n");
while ( fgets(string, 254, stream) ) /* Get a line in the file */
{
utcharsb(3, string, '\n');
nesting(string); /* Check '{' '}' nesting */
string[255] = 0;
if ( isfunct(string) )
function(string, stream, direction);
}
fclose(stream); /* Close the file */
if ( (comment) || (squote) || (dquote) )
{
fprintf(stderr, "Your source file %s has errors.\n");
if ( comment )
{
fprintf(stderr, " %d ", comment);
if ( comment > 1 )
fprintf(stderr, "comments were not ended.\n");
else
fprintf(stderr, "comment was not ended.\n");
}
if ( squote )
{
fprintf(stderr, " %d ", squote);
if ( squote > 1 )
fprintf(stderr, "single quotes are missing the ending quote.\n");
else
fprintf(stderr, "single quote is missing the ending quote.\n");
}
if ( dquote )
{
fprintf(stderr, " %d ", dquote);
if ( dquote > 1 )
fprintf(stderr, "double quotes are missing the ending quote.\n");
else
fprintf(stderr, "double quote is missing the ending quote.\n");
}
exit(1);
}
}
if ( !OutOnly ) /* If output == printer, close the direction file */
fclose(direction);
fclose(project); /* Close the project file */
fprintf(stderr, "\n\n%d file(s) processed.\n", files);
}