/* Source Code: argcheck.c Date: August of 2000 Programmer: Scott Wenger, Box 802, Stevens Point, WI 54481 USA panther@wctc.net Purpose: To perform argument checking in C source code. This program detects and reports mismatches between the number of conversion specifiers and the number of arguments in the following functions: printf, sprintf, and fprintf Double percent sign for percent symbol (%) is distinguished from conversion specifiers. This program is useful when using compilers and/or preprocessors that ignore argument checking. Enhancements and modifications of this program are left to the individual. */ #include #include #include #include #define BUFF_SIZE 1000 int open_file(); int study(char funcname[], char lbuffer[]); FILE *fp; char filename[75]; int ln = 1; // line number int total_errors = 0; // total number of errors main() { char lbuffer[BUFF_SIZE]; // line buffer open_file(); while (fgets(lbuffer, 1000, fp) != NULL) { printf("%3d: %s", ln, lbuffer); if (strstr(lbuffer, "sprintf") != NULL) study("sprintf", lbuffer); else if (strstr(lbuffer, "fprintf") != NULL) study("fprintf", lbuffer); else if (strstr(lbuffer, "printf") != NULL) study("printf", lbuffer); ln++; // increment line counter } fclose(fp); if (total_errors > 0) fprintf(stderr, "\n\nThere were a total of %d mismatches in this code.", total_errors); else fprintf(stderr, "\n\nCompleted argument check and no errors were found."); fprintf(stderr, "\nPress [Enter] to return to your operating system..."); fflush(stdout); getch(); exit(0); } /*-----------------------------------------------------------------------*/ int study(char funcname[], char lbuffer[]) { // this function looks for a match betwen // conversion specifiers and args (in number only) // 0 is returned if there is a mismatch // 1 is returned if there is match int match = 1; int i = 0; int cs = 0; // number of converion specifiers int ar = 0; // number of arguments char *ch, *start; char possible[20]; int pair = 0; // a flag for two %% in a row ch = strchr(lbuffer, funcname[0]); // start of possible function start = ch; for (i = 0; i < strlen(funcname); i++) { possible[i] = *ch; ch++; } possible[i] = '\0'; ch = start; while (*ch && *ch != '"') ch++; if (*ch) ch++; // skip opening quote while (*ch && *ch != '"') { // scan format string if (pair == 1) pair = 0; if (*ch == '%') { ch++; if (*ch && *ch == '%') pair = 1; else cs++; // count conversion specifiers } if (*ch) ch++; } if (*ch) ch++; // skip closing quote while (*ch && *ch != ')') { if (*ch == ',') ar++; // count arguments ch++; } if (cs != ar) { match = 0; total_errors++; // total number of mismatches printf("\nError in line %d: mismatch in %s", ln, funcname); printf("\nFound %d conversion specifier(s) and %d argument(s)", cs, ar); printf("\nPress [Enter] to continue checking...\n\n"); fflush(stdout); getch(); } return(match); } /*-----------------------------------------------------------------------*/ int open_file() { printf("\nC source file to check: "); scanf("%s", filename); if ( (fp = fopen(filename, "r")) == NULL) { printf("\nInput file could not be opened.\n"); printf("\nPress [Enter] to return to your operating system."); fflush(stdout); fclose(fp); getch(); exit(1); } return(1); } /*------------------------------- END -----------------------------------*/