#include #include #include #include /* Program to walk a directory and convert each file it finds from DOS format to Unix format, Unix format to DOS format, Mac format to Unix format, or Unix format to Mac format. The various line-ending styles are: Mac: \r Unix: \n DOS: \r\n Author: Nick Gammon Date: 18th February 1998 Copyright 1998 Gammon Software Solutions. This program and source may be redistributed provided no charge is made for it, and credit given to the original author. Usage: unix2dos [, ... ] dos2unix [, ... ] mac2unix [, ... ] eg. unix2dos c:\source\mush\*.c dos2unix *.h *.c *.cpp mac2unix *.c All versions are in the same source file. Define: UNIX2DOS in "project settings" to make a unix2dos program DOS2UNIX in "project settings" to make a dos2unix program MAC2UNIX in "project settings" to make a mac2unix program UNIX2MAC in "project settings" to make a unix2mac program */ #ifdef UNIX2DOS #define PROGRAMNAME "unix2dos" #define RENAMESUFFIX ".unix" #define INPUTMODE "rb" #define OUTPUTMODE "w" #elif DOS2UNIX #define PROGRAMNAME "dos2unix" #define RENAMESUFFIX ".dos" #define INPUTMODE "r" #define OUTPUTMODE "wb" #elif MAC2UNIX #define PROGRAMNAME "mac2unix" #define RENAMESUFFIX ".mac" #define INPUTMODE "rb" #define OUTPUTMODE "wb" #define SEARCHFOR '\r' #define REPLACEWITH '\n' #elif UNIX2MAC #define PROGRAMNAME "unix2mac" #define RENAMESUFFIX ".unix" #define INPUTMODE "rb" #define OUTPUTMODE "wb" #define SEARCHFOR '\n' #define REPLACEWITH '\r' #else #error Please include a define for: UNIX2DOS, DOS2UNIX, MAC2UNIX, or UNIX2MAC #endif // helper define for appending an "s" to plural amounts #define PLURAL(arg) arg, arg == 1 ? "" : "s" #define BOOL int #define FALSE 0 #define TRUE 1 long nFiles = 0; long nErrors = 0; long nWarnings = 0; long nTotalLines = 0; void ProcessWildcard (char * sWildcard) { struct _finddata_t fileinfo; long nFindFileHandle; char sInputFileName [_MAX_PATH]; char sOutputFileName [_MAX_PATH]; char sBuff [5000]; FILE * fi; FILE * fo; char * p; BOOL bWriteError = FALSE; long nLines; int iRenameResult, iDeleteResult; printf ("Processing wildcard \"%s\"\n", sWildcard); nFindFileHandle = _findfirst (sWildcard, &fileinfo); if (nFindFileHandle == -1) { printf ("*** Unable to find any files matching sWildcard: %s\n", sWildcard); nWarnings++; return; } do { if ((fileinfo.attrib & _A_SUBDIR) == 0) { // display name of file we are processing printf ("%s \n",fileinfo.name); // calculate full pathnames strcpy (sOutputFileName, sWildcard); // strip off trailing filename sWildcard p = strrchr (sOutputFileName, '\\'); if (p) { *p = 0; // remove everything past the slash strcat (sOutputFileName, "\\"); } else strcpy (sOutputFileName, ""); // no directory, must be in current directory strcat (sOutputFileName, fileinfo.name); strcpy (sInputFileName, sOutputFileName); strcat (sInputFileName, RENAMESUFFIX); // rename input file with a different suffix iRenameResult = rename (sOutputFileName, sInputFileName); if (iRenameResult != 0) { perror( "Rename of input file failed" ); printf ("Could not rename \"%s\" to \"%s\".\n", sOutputFileName, sInputFileName); nErrors++; continue; // don't convert this one } // open input file fi = fopen (sInputFileName, INPUTMODE); if (fi == NULL) { perror( "Open of input file failed" ); printf ("File name: \"%s\".\n", sInputFileName); nErrors++; continue; } // open output file fo = fopen (sOutputFileName, OUTPUTMODE); if (fo == NULL) { fclose (fi); // close input file already opened perror( "Open of output file failed" ); printf ("File name: \"%s\".\n", sOutputFileName); nErrors++; continue; } nLines = 0; while (!feof (fi)) { // In the case of Mac input/output we simply want to change \n to \r or vice versa. // We may as well do this in chunks. #if defined (MAC2UNIX) || defined (UNIX2MAC) { size_t iNumRead; iNumRead = fread(sBuff, sizeof(char), sizeof (sBuff), fi); if (iNumRead == 0) break; // convert each carriage-return into a linefeed, thus going from Mac to Unix // or vice-versa while (p = strrchr (sBuff, SEARCHFOR)) { *p = REPLACEWITH; nLines++; nTotalLines++; } if (fwrite(sBuff, sizeof(char), iNumRead, fo) != iNumRead) { perror( "Error writing to output file" ); printf ("File name: \"%s\".\n", sOutputFileName); bWriteError = TRUE; nErrors++; break; } } #else // read line-by-line if (fgets(sBuff, sizeof (sBuff), fi) == NULL) break; nLines++; nTotalLines++; // strip trailing carriage return, if any p = strrchr (sBuff, '\r'); if (p) *p = 0; // make sure line ends with newline if (sBuff [strlen (sBuff) - 1] != '\n') strcat (sBuff, "\n"); if (fputs (sBuff, fo) == EOF) { perror( "Error writing to output file" ); printf ("File name: \"%s\".\n", sOutputFileName); bWriteError = TRUE; nErrors++; break; } #endif // not Mac-style read } // end of read loop fclose (fi); fclose (fo); // If no error, delete backup file if (bWriteError) printf ("Original file is now called \"%s\"\n", sInputFileName); else { iDeleteResult = remove (sInputFileName); if (iDeleteResult != 0) { perror( "Delete of original file failed" ); printf ("Could not delete \"%s\".\n", sInputFileName); nErrors++; } nFiles++; // count files successfully converted } } // end of not being a subdirectory } while (!bWriteError && _findnext (nFindFileHandle, &fileinfo) != -1); // end of file loop _findclose (nFindFileHandle); } // end of ProcessWildcard int main (int iArgumentCount, char * sArgument []) { int iArgument; if (iArgumentCount <= 1) { printf ("Usage: " PROGRAMNAME " [ ...]\n"); return 1; } printf (PROGRAMNAME " Version 1.01 (Gammon Software Solutions) 13-Mar-98\n"); // process each wildcard or filename supplied on the command line for (iArgument = 1; iArgument < iArgumentCount; iArgument++) ProcessWildcard (sArgument [iArgument]); // show file count printf ("%ld file%s converted.\n", PLURAL (nFiles)); // show line count printf ("%ld total line%s converted.\n", PLURAL (nTotalLines)); // show error and warning count printf ("%ld error%s.\n", PLURAL (nErrors)); printf ("%ld warning%s.\n", PLURAL (nWarnings)); return nErrors; // no errors will mean OK return } // end of main