# HG changeset patch # User Eris Caffee # Date 1439925972 18000 # Node ID 5b67bf33fcccef03dd2ddb0063960287f47a8e87 # Parent b8cfd6af18b3de60e762b0c8e71072f969afe47b Added comments. Broke out file read toa function slurp_file(). diff -r b8cfd6af18b3 -r 5b67bf33fccc string_search/kmp.c --- a/string_search/kmp.c Tue Aug 18 12:22:22 2015 -0500 +++ b/string_search/kmp.c Tue Aug 18 14:26:12 2015 -0500 @@ -17,7 +17,7 @@ /* Knuth-Morris-Pratt algorithm * * As described on Wikipedia - * https://duckduckgo.com/l/?kh=-1&uddg=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FKnuth-Morris-Pratt_algorithm + * https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm */ size_t kmp_search( char *haystack, char *needle ) { @@ -94,6 +94,12 @@ } /******************************************************************************/ +/* Calculate the difference between two struct timeval's. + * + * OUT: struct timeval *elapsed The calculated difference. + * IN: struct timeval *start The starting time; + * IN: struct timeval *end The ending time; + */ void timevaldiff( struct timeval *elapsed, struct timeval *start, struct timeval *end ) { time_t sec; @@ -112,6 +118,54 @@ } /******************************************************************************/ +/* Read the entire contents of a file into memory. + * + * IN: char *filename The name of the file to read. It will be open in "rb" + * mode. + * IN: char **buffer The address of a char * which will be set to the start + * of the memory buffer containing the contents of the + * file. You should call free() on this when you are done. + * + * Return value: The amount of data read. Note that the data in the + * buffer will be null terminated, but this may be + * meaningless if the file is a binary file, so you should + * use the return value when iterating through the data. + */ + +size_t slurp_file( char *filename, char **buffer ) { + + FILE * file; + char temp[65536]; + size_t bytes_read; + size_t buffer_top = 0; + size_t buffer_max = 1; + + *buffer = malloc( sizeof( char ) ); + + file = fopen( filename, "rb" ); + while ( bytes_read = fread( temp, sizeof( char ), sizeof( temp ), file ) ) { + while ( buffer_max - buffer_top < bytes_read ) { + size_t new_buffer_max = 2 * buffer_max; + char * new_buffer = malloc( new_buffer_max ); + for ( size_t i = 0; i < buffer_max; i++ ) { + new_buffer[i] = (*buffer)[i]; + } + free( *buffer ); + *buffer = new_buffer; + buffer_max = new_buffer_max; + } + memcpy( &(*buffer)[ buffer_top ], temp, bytes_read ); + buffer_top += bytes_read; + } + + (*buffer)[ buffer_top + 1 ] = 0; + + fclose( file ); + + return buffer_top; + } + +/******************************************************************************/ int main( int argc, char **argv ) { char *def_needle = "ABCDABD"; @@ -121,8 +175,6 @@ char * haystack; size_t haystack_max; size_t haystack_top = 0; - haystack = malloc( sizeof( char ) ); - haystack_max = 1; if ( argc >= 2 ) { needle = argv[1]; @@ -131,33 +183,15 @@ needle = def_needle; } + size_t filesize; if ( argc >= 3 ) { - FILE * file; - char buffer[65536]; - size_t bytes_read; - - file = fopen( argv[2], "r" ); - while ( bytes_read = fread( buffer, sizeof( char ), sizeof( buffer ), file ) ) { - while ( haystack_max - haystack_top < bytes_read ) { - size_t new_haystack_max = 2 * haystack_max; - char * new_haystack = malloc( new_haystack_max ); - for ( size_t i = 0; i < haystack_max; i++ ) { - new_haystack[i] = haystack[i]; - } - free( haystack ); - haystack = new_haystack; - haystack_max = new_haystack_max; - } - memcpy( &haystack[ haystack_top ], buffer, bytes_read ); - } - - fclose( file ); + filesize = slurp_file( argv[2], &haystack ); } else { - haystack = def_haystack; + haystack = strdup( def_haystack ); + filesize = strlen( def_haystack ); } - struct timeval start; struct timeval end; struct timeval elapsed; @@ -185,5 +219,7 @@ printf( "found >%s<\n", found ); printf( "brute force found in %d.%06d seconds\n", elapsed.tv_sec, elapsed.tv_usec ); + free(haystack); + exit( EXIT_SUCCESS ); }