home *** CD-ROM | disk | FTP | other *** search
- /*
- ** 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 By Mitchell Fisher\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);
- }
-