Here's the updated code, major new bits in red.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FILENAME "/Users/toddburch/Desktop/sql.txt"
int possibleOverrun(const char * s1, const char * s2, const int size) {
if (strlen(s1) + strlen(s2) > size) {
fprintf(stderr, "Overrun avoided - SQL statement ignored\n") ;
return 1 ;
}
return 0 ; // no overrun
}
char * readSQL(FILE * fp, char * buffer, const int size ) { // File is already open
char line[81] = {0} ; // fgets buffer
char * ptr ;
char * end_of_line ;
buffer[0] = 0 ; // Set to empty
// Read data from the input file until a semicolon is found or end of file is hit
while (fgets(line, sizeof(line), fp) ) {
if ( strncmp(line, "--", 2) == 0 ) continue ; // skip comments
ptr = line ;
end_of_line = ptr + strlen(ptr)-1 ; // position to last character
while (*end_of_line == ' ' || *end_of_line == '\n' || *end_of_line == '\r')
{
*end_of_line-- = 0 ; // back up to last non-blank
if (end_of_line < ptr) break; /* maybe we get to the beginning of the line? */
}
while (*ptr == ' ') ptr++ ; // index past leading blanks
if (strlen(ptr) == 0) continue ;
// look for trailing semi colon - that terminates a statement
if (*end_of_line == ';') {
if (possibleOverrun(buffer, ptr, size)) return NULL ;
strcat(buffer, ptr) ; // append to buffer
break ;
}
else {
if (possibleOverrun(buffer, ptr, size-1 )) return NULL ; // allow for blank
strcat(buffer, ptr) ; // append to buffer
strcat(buffer, " ") ; // separate it
}
}
if ( strlen(buffer) == 0 ) return NULL ;
return buffer ;
}
int strnicmp(const char * s1, const char * s2, const size_t length) {
// Return 0 if the strings match
// Return i of s1 != s2, where i is the differing character relative to 1.
int i ;
char c1, c2 ;
for (i = 0 ; i < length ; i++) {
c1 = toupper(s1[i]) ;
c2 = toupper(s2[i]) ;
if ( c1==0 && c2==0) return 0 ; // match
else if (c1==0 || c2==0) return 1 ; // no match
else if ( c1 == c2 ) continue ; // so far, so good
else return i+1 ; // Return position of the first non-matching char
}
return 0 ; // match
}
int isSelect(const char * sql) { // Determine if this is a SELECT statement
static const char keyword[] = "SELECT " ;
return !strnicmp(sql, keyword, strlen(keyword) ) ;
}
int main (int argc, const char * argv[]) {
FILE * fp ;
char * sql ;
char * buffer ;
int sqlcount = 0 ;
static const int bufsize = 32768 ;
if (( buffer = malloc(bufsize) ) == NULL) {
fprintf(stderr, "Cannnot get buffer for SQL. Exiting.\n") ;
return -1 ;
}
fp = fopen(FILENAME , "r") ;
if (!fp) {
fprintf(stderr, "Cannot open input file " FILENAME "\n") ;
return -1 ;
}
while (1) {
sql = readSQL(fp, buffer, bufsize ) ;
if (!sql) break ;
sqlcount++ ; // Bump count of SQL statements processed
if (isSelect(sql)) printf("Select Statement!\n") ;
else printf("Not a select Statement!\n") ;
printf("SQL = >%s<\n\n", sql) ;
}
printf("%d SQL statements processed.\n", sqlcount) ;
free(buffer) ;
fclose(fp) ;
return 0;
}