#define _POSIX_C_SOURCE 201801 #include #include #include #include #include #include "array2d.h" #include "intHelper.h" static bool printElementArray(Array2d_value_t v) { printf("%ld ", (long int)v); return true; } static void dumpArray(Array2d a) { if ( a == NULL ) { printf("Array is null\n"); } else { printf("Array is %u x %u\n", Array2d_rows(a), Array2d_columns(a)); Array2d_map( a, printElementArray ); printf("\n"); } } // I'm using a preprocessor macro for this "function" just to // show you a preprocessor macro (and because it makes // sense in this case, more or less) #define cleanPointer(p) { \ if ( p ) free(p); \ p = NULL; \ } static void invalidCommand() { fprintf(stderr, "Invalid command\n"); } static void failedCommand() { fprintf(stderr, "Operation failed\n"); } //----------------------------------------------------------------------------------------------------- // main: // reads commands from a file whose name is given as the first argument //----------------------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { Array2d a = NULL; if ( argc != 2 ) { fprintf(stderr, "Usage: %s filename\n", argv[0]); exit(-1); } FILE* cmdFile = fopen(argv[1], "r"); if ( cmdFile == NULL ) { perror("Can't open command file"); exit(1); } // read command file line by line char *line = NULL; char *cmd = NULL; char *filename = NULL; char *dummy = NULL; for ( long int lineNumber = 0; ; lineNumber++ ) { cleanPointer( line ); cleanPointer( cmd ); cleanPointer( filename ); cleanPointer( dummy ); size_t buflen = 0; ssize_t getlineRcode = getline(&line, &buflen, cmdFile); if ( getlineRcode == -1 ) break; // probably EOF // print only lines that have something in them int n = sscanf(line, "%ms", &cmd); if ( n <= 0) continue; printf("\n[%ld] %s", lineNumber, line); // decode command switch (cmd[0]) { case 'd': //-------------------------------------------- // deserialize //-------------------------------------------- if ( !strcmp(cmd, "deserialize") ) { // deserialize filename n = sscanf(line, "%s %ms %ms", cmd, &filename, &dummy); if (n != 2) { invalidCommand(); continue; } FILE* in = fopen(filename, "r"); if ( in == NULL ) { fprintf(stderr, "Can't open %s\n", filename); continue; // it's unlikely anything good can happen, but we keep executing } a = Array2d_deserialize(in, intHelper_deserializeElement); if ( a == NULL ) failedCommand(); fclose(in); } //-------------------------------------------- // destroy //-------------------------------------------- else if ( !strcmp(cmd, "destroy") ) { if ( !Array2d_destroy(a, intHelper_destroyElement) ) failedCommand(); a = NULL; } else invalidCommand(); break; case 'p': //-------------------------------------------- // print //-------------------------------------------- if ( !strcmp(cmd, "print") ) dumpArray(a); else invalidCommand(); break; case 's': //-------------------------------------------- // serialize //-------------------------------------------- if ( !strcmp(cmd, "serialize") ) { // serialize filename n = sscanf(line, "%s %ms %ms", cmd, &filename, &dummy); if (n != 2) { invalidCommand(); continue; } FILE* out = fopen(filename, "w"); if ( out == NULL ) { fprintf(stderr, "Can't open %s for writing\n", filename); continue; } Array2d_serialize(a, out, intHelper_serializeElement); fclose(out); } //-------------------------------------------- // set //-------------------------------------------- else if ( !strcmp(cmd, "set") ) { // set i j value int i, j, value; int n = sscanf(line, "%s %i %i %i %ms", cmd, &i, &j, &value, &dummy); if ( n!=4 ) { invalidCommand(); continue; } if ( !Array2d_set( a, i, j, (Array2d_value_t)(intptr_t)value) ) failedCommand(); } //-------------------------------------------- // swap //-------------------------------------------- else if ( !strcmp(cmd, "swap") ) { // swap i j i j int i1, j1, i2, j2; int n = sscanf(line, "%s %i %i %i %i %ms", cmd, &i1, &j1, &i2, &j2, &dummy); if ( n != 5 ) { invalidCommand(); continue; } if ( !Array2d_swap( a, i1, j1, i2, j2) ) failedCommand(); } else invalidCommand(); break; default: invalidCommand(); break; } } cleanPointer( line ); cleanPointer( cmd ); cleanPointer( filename ); cleanPointer( dummy ); fclose(cmdFile); Array2d_destroy(a, intHelper_destroyElement); return EXIT_SUCCESS; }