/* PROGRAM RGrow : grow (or shrink) the record size of a fixed size record file. * These are not the old and new sizes of the file, but of the fixed length records * in the file. If you increase the record size, each record will be padded * with nulls. The entire file will grow as a result. * * * usage : RGrow Myfile.SEQ 512 1024 * filename oldrecsize newrecsize * Version 1.3 * Compiled as a Windows console App, without precompiled headers. * For Visual C++ Express options see http://mindprod.com/jgloss/cpp.html#COMPILING * ==================================== */ /* Roedy Green Canadian Mind Products #101 - 2536 Wark Street Victoria, BC Canada V8T 4G8 tel:(250) 361-9093 mailto:roedyg@mindprod.com http://mindprod.com Version History: 1.0 2004-03-10 Roedy Green in Microsoft Visual C 8 1.1 2008-01-03 add pad, icon, use safe char library, POSIX compliance. 1.2 2008-01-03 display banner on any error. Correct temp file placement. 1.3 2009-03-11 add ANT build script */ #include /* exit, putenv, _splitpath */ #include /* isUpper isLower toUpper */ #include /* fclose, fgetc, printf, remove, rename, setvbuf */ #include #include /* getch, putch */ #include /* P R O T O T Y P E S */ int main ( int argc, char *argv[] ); void Banner(void); void bldAName ( void ); void die ( void ); void honk ( void ); void safeFilename ( void ); /* ==================================== */ #define Esc '\x1B' /* use all global variables and no parameter passing for simplicity. */ FILE *before; /* input file */ FILE *after; /* output file with comments converted */ /* Before name of file we will convert */ char *bFilename; /* pointer to string name of file */ /* After name of the temporary output file */ char *aFilename; /* ==================================== */ void safeFilename() { /* Ensure appropriate file name extensions. good = done without prompt bad = abort warning = others */ static const char * GoodExtensions [] = { ".SEQ", ".BLK", ".DAT", 0}; /* 0 is just end marker */ static const char * BadExtensions [] = { ".C", ".CMD", ".COM", ".CPP", ".CSV", ".CTL", ".DLL", ".EXE", ".H", ".HPP", ".HTM", ".IH", ".INI", ".KEY", ".LST", ".MAC", ".OBJ", ".PAS", ".RH", ".SQL", ".USE", 0}; int Response; /* Y or N, yes Virginia, int, C is weird */ char Extension[_MAX_EXT]; int i; /* local loop counter */ _splitpath_s(bFilename, NULL /* drive */, 0, NULL /* dir */, 0, NULL /* name */, 0, Extension, _MAX_EXT) ; _strupr_s(Extension, _MAX_EXT); /* convert to upper case for compare */ for ( i=0 ; GoodExtensions[i]; i++ ) { if ( strcmp(Extension,GoodExtensions[i])==0 ) { /* match, it is Good */ return; } } for ( i=0 ; BadExtensions[i] ; i++ ) { if ( strcmp(Extension,BadExtensions[i])==0 ) { /* match, it is bad */ Banner(); printf("Oops! RGrow cannot be used on EXE COM or OBJ files " "such as %s\n", bFilename); die(); } } /* just give a warning */ printf("Warning!\n" /* new line to give room for long filename */ "RGrow is not usually used on %s files such as %s\n", Extension,bFilename); printf("Do you want to continue and process anyway?" " (Y)es (N)o "); while ( 1 ) { /* loop forever till user enters Y or N */ honk(); Response = _getch(); /* not echoed because user might hit tab or Enter */ /* and mess up the screen */ Response = toupper(Response); /* toupper is a macro, so needs simple argument */ switch ( Response ) { case 'Y': return; case 'N': case Esc : printf("\nRGrow aborted\n"); die(); /* others, keep looping */ } } } /* safeFilename */ /* ==================================== */ void bldAName(void) { /* create temp file in same directory as bFilename */ char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char name[_MAX_FNAME]; char ext[_MAX_EXT]; char filepath[_MAX_DRIVE + _MAX_DIR]; _splitpath_s(bFilename, drive, _MAX_DRIVE, dir,_MAX_DIR, name, _MAX_FNAME, ext, _MAX_EXT); strcpy_s(filepath, _MAX_DRIVE + _MAX_DIR, drive); strcat_s(filepath, _MAX_DRIVE + _MAX_DIR, dir); /* Force to current directory if empty */ if ( strcmp(filepath, "") == 0 ) { strcpy_s(filepath, _MAX_DRIVE + _MAX_DIR, "."); } else { filepath[strlen(filepath) - 1] = 0; } _putenv("TMP="); /* Sets TMP just for this and any "children" */ /* processes -- doesn't change parents TMP */ if ( (aFilename = _tempnam(filepath, "")) == NULL ) { Banner(); printf("Oops! Cannot create the temporary work file\n\a"); exit(1); } } /* ==================================== */ int main(int argc, char *argv[]) /* main RGrow */ { int oldRecSize = 512; int newRecSize = 1024; char* oldRec; // buffer for old record char* newRec; // buffor for expanded record int copyBytes; // how many bytes to copy from old to new int i; // loop counter. if ( argc != 4 /* 0=RGrow.Exe 1=MyFile.SEQ 2=oldRecSize 3=newRecSize */ ) { Banner(); printf("Oops! usage: RGrow Myfile.seq 512 1024\n\a"); exit(1); } bFilename = argv[1]; oldRecSize = atoi(argv[2]); newRecSize = atoi(argv[3]); safeFilename(); bldAName(); if ( fopen_s(&before, bFilename, "rb") ) { Banner(); printf("Oops! Cannot open file %s\n\a", bFilename); exit(1); } if ( fopen_s(&after, aFilename, "wb") ) { Banner(); printf("Oops! Cannot open work file %s\n\a", aFilename); exit(1); } setvbuf(before, NULL, _IOFBF, 8192); setvbuf(after, NULL, _IOFBF, 8192); // Allocate buffers oldRec = (char *) malloc( oldRecSize ); newRec = (char *) malloc( newRecSize ); // calc bytes to copy over from old buffer. copyBytes = oldRecSize; if ( newRecSize < copyBytes ) { copyBytes = newRecSize; } // clear tail of new buffer for ( i=0; i