From: "Juan Manuel Guerrero" Organization: Darmstadt University of Technology To: djgpp-workers AT delorie DOT com Date: Thu, 21 Dec 2000 21:02:04 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Patch #4 for dtou and utod X-mailer: Pegasus Mail for Windows (v2.54DE) Message-ID: <39A514185@HRZ1.hrz.tu-darmstadt.de> Reply-To: djgpp-workers AT delorie DOT com On Sat, 25 Nov 2000, Eli Zaretskii wrote: [snip] > How about adding all the new switches, except -r and -s, to utod? > They seem all relevant. [snip] On Mon, 27 Nov 2000, Andris Pavenis wrote: [snip] > Below is patch against current CVS version of dtou.c > > - change to use getopt(). Some targets may not have getopt() in > libc (for example MINGW doesn't have it). But it's in > libiberty.a. > > - change to use verbosity level instead of 2 variables (verbose > and vverbose) > > - fix for broken detection when file are changed. Previous updates > often errorously misdetected file as changed. Try: > utod foo.txt > dtou -vv foo.txt foo.txt > for some file (replace foo.txt with name of file) > > - I removed notice about myself in copyright notes as I don't > think it's reasonable to keep it now > > - I added removal of old backup file (if one exist) before > renaming [snip] Well, I have added the following switches to utod: -b: backup -h/-?: help text -t: timestamp -v: verbose output -vv/ -v -v: very verbose output I have added to dtou and utod: - removal of old backup file before renaming as contributed by Andris Pavenis. - fix for broken detection when file are changed as contributed by Andris Pavenis. - change to use verbosity level instead of 2 variables as suggested by Andris Pavenis. - some other minor changes not worth to be enumerated. I do not know if the getopt() usage discussion has produced a usefull result at all, so I am sending two versions of this patch. This mail includes the first part of the patch that does **not** use getopt(), the next mails will contain the second part of this version and of the version that **uses** getopt(). I have no preference for any of the two versions and there is **no** functional difference between the two patches, except for getopt() usage, of course. May be that this days with less traffic than usual are optimal to finish this minor (dtou and utod) issue once and for all. Patch based on current CVS. Regards, Guerrero, Juan Manuel Patch 1/2 for version ***not*** using getopt(). diff -acprNC5 djgpp.orig/src/utils/dtou.c djgpp/src/utils/dtou.c *** djgpp.orig/src/utils/dtou.c Mon Nov 27 13:44:58 2000 --- djgpp/src/utils/dtou.c Thu Dec 21 20:24:38 2000 *************** *** 9,64 **** #include #include #include #ifndef O_BINARY ! #define O_BINARY 0 #endif #if defined(MSDOS) || defined(_Windows) ! #define IS_DIR_SEPARATOR(path) ((path) == '/' || (path) == '\\' || (path) == ':') #else ! #define IS_DIR_SEPARATOR(path) ((path) == '/') #endif #define IS_LAST_CR_IN_BUF (i == l - 1) #define IS_LAST_CR_IN_FILE (position + i + 1 == st.st_size) #define SET_FLAG(flag) \ do { \ if ((flag) == 0) (flag) = 1; \ } while (0) #define BUF_SIZE 16384 ! /* Control characters. */ #define LF 0x0A #define CR 0x0D #define CntlZ 0x1A /* Exit codes. */ #define NO_ERROR 0x00 #define IO_ERROR 0x01 /* Some I/O error occurred. */ static char * ! BaseName (char * name) { ! char * bn, *w; for (bn = w = name; *w; w++) if (IS_DIR_SEPARATOR (*w)) ! bn = w+1; return bn; } - static int ! dtou(char *fname, int make_backup, int repair_mode, int strip_mode, int verbose, int vverbose, int preserve_timestamp) { int i, k, sf, df, l, l2 = 0, is_CR = 0, is_nCR = 0, is_CR_sequence = 0; int CntlZ_flag = 0, CR_flag = 0, nCR_flag = 0, LF_flag = 0, exit_status = NO_ERROR; int buf_counter, nbufs, LF_counter, must_rewind, position, offset, whence; char buf[BUF_SIZE]; ! char bfname[FILENAME_MAX], tfname[FILENAME_MAX], *bn; struct stat st; struct utimbuf tim1; sf = open (fname, O_RDONLY|O_BINARY); if (sf < 1) --- 9,64 ---- #include #include #include #ifndef O_BINARY ! # define O_BINARY 0 #endif #if defined(MSDOS) || defined(_Windows) ! # define IS_DIR_SEPARATOR(path) ((path) == '/' || (path) == '\\' || (path) == ':') #else ! # define IS_DIR_SEPARATOR(path) ((path) == '/') #endif #define IS_LAST_CR_IN_BUF (i == l - 1) #define IS_LAST_CR_IN_FILE (position + i + 1 == st.st_size) #define SET_FLAG(flag) \ do { \ if ((flag) == 0) (flag) = 1; \ } while (0) #define BUF_SIZE 16384 ! /* Control characters. */ #define LF 0x0A #define CR 0x0D #define CntlZ 0x1A /* Exit codes. */ #define NO_ERROR 0x00 #define IO_ERROR 0x01 /* Some I/O error occurred. */ static char * ! BaseName (char *name) { ! char *bn, *w; for (bn = w = name; *w; w++) if (IS_DIR_SEPARATOR (*w)) ! bn = w + 1; return bn; } static int ! dtou (char *fname, int make_backup, int repair_mode, int strip_mode, int verbosity, int preserve_timestamp) { int i, k, sf, df, l, l2 = 0, is_CR = 0, is_nCR = 0, is_CR_sequence = 0; int CntlZ_flag = 0, CR_flag = 0, nCR_flag = 0, LF_flag = 0, exit_status = NO_ERROR; + int bytes_in = 0, bytes_out = 0; int buf_counter, nbufs, LF_counter, must_rewind, position, offset, whence; char buf[BUF_SIZE]; ! char backup_fname[FILENAME_MAX], temp_fname[FILENAME_MAX], *bn; struct stat st; struct utimbuf tim1; sf = open (fname, O_RDONLY|O_BINARY); if (sf < 1) *************** dtou(char *fname, int make_backup, int r *** 70,100 **** fstat (sf,&st); tim1.actime = st.st_atime; tim1.modtime = st.st_mtime; nbufs = st.st_size / BUF_SIZE; ! strcpy (tfname, fname); ! bn=BaseName(tfname); ! *bn=0; ! strcat (tfname,"dtou.tm$"); if (make_backup) { ! strcpy (bfname, fname); ! if (pathconf ((fname), _PC_NAME_MAX) <= 12) ! for (i = strlen (bfname); i > -1; i--) ! if (bfname[i] == '.') { ! bfname[i] = '\0'; break; } ! strcat (bfname,".d2u"); } ! ! df = open (tfname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); if (df < 1) { ! perror (tfname); close (sf); return IO_ERROR; } buf_counter = LF_counter = must_rewind = position = 0; --- 70,100 ---- fstat (sf,&st); tim1.actime = st.st_atime; tim1.modtime = st.st_mtime; nbufs = st.st_size / BUF_SIZE; ! strcpy (temp_fname, fname); ! bn = BaseName (temp_fname); ! *bn = 0; ! strcat (temp_fname,"dtou.tm$"); if (make_backup) { ! strcpy (backup_fname, fname); ! if (pathconf ((backup_fname), _PC_NAME_MAX) <= 12) ! for (i = strlen (backup_fname); i > -1; i--) ! if (backup_fname[i] == '.') { ! backup_fname[i] = '\0'; break; } ! strcat (backup_fname, ".d2u"); } ! ! df = open (temp_fname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); if (df < 1) { ! perror (temp_fname); close (sf); return IO_ERROR; } buf_counter = LF_counter = must_rewind = position = 0; *************** dtou(char *fname, int make_backup, int r *** 107,118 **** { offset = -1; whence = SEEK_CUR; } while ((l = read (sf, buf, BUF_SIZE)) > 0) ! { ! for (i = k = 0; i < l; i++) { if (strip_mode) { if (buf[i] == LF) { --- 107,119 ---- { offset = -1; whence = SEEK_CUR; } while ((l = read (sf, buf, BUF_SIZE)) > 0) ! { ! bytes_in += l; ! for (i = k = 0; i < l; i++) { if (strip_mode) { if (buf[i] == LF) { *************** dtou(char *fname, int make_backup, int r *** 186,305 **** position = lseek (sf, offset, whence); must_rewind = 0; } l2 = (k > 0 ? write (df, buf, k) : 0); if (l2 < 0 || CntlZ_flag) break; if (l2 != k) { exit_status = IO_ERROR; break; } } if (l < 0) perror (fname); ! if (l2 < 0) perror (tfname); if (exit_status != NO_ERROR) fprintf (stderr,"Cannot process file %s\n",fname); close (sf); close (df); if (l >= 0 && l2 >= 0 && exit_status == NO_ERROR) { ! int file_has_changed = CR_flag || nCR_flag || CntlZ_flag || LF_flag; ! if (verbose) printf ("File: %s successfully processed.\n",fname); ! if (vverbose) printf ("File: %s\n",fname); ! if (CR_flag && vverbose) printf ("At least one CR/LF to LF transformation occurred.\n"); ! if (nCR_flag && vverbose) printf ("Warning: At least one CR sequence stripped from a LF.\n"); ! if (CntlZ_flag && vverbose) printf ("Warning: At least one Cntl-Z has been found. File truncated at line %i.\n", LF_counter); ! if (LF_flag && vverbose) printf ("Warning: At least one LF without a preceeding CR has been found.\n"); ! if (vverbose && !file_has_changed) printf ("File unchanged.\n"); if (make_backup && file_has_changed) ! rename (fname, bfname); else remove (fname); ! rename (tfname, fname); chown (fname, st.st_uid, st.st_gid); chmod (fname, st.st_mode); if (preserve_timestamp || !file_has_changed) utime (fname, &tim1); } else { ! remove (tfname); ! if (verbose || vverbose) printf ("File: %s. An I/O error occurred\n",fname); } return exit_status; } static void ! usage(char *progname) { ! printf ("Usage: %s [-b] [-h] [-r] [-s] [-t] [-v] [-vv] files...\n\n", progname); printf ("Options are:\n"); printf (" -b: A backup of the original file is made using `.d2u' as backup\n"); printf (" extension, if the file has been modified.\n"); ! printf (" -h: Display this help and exit.\n"); printf (" -r: Transform MSDOS-style EOF (CRLF) into UNIX-style EOL (LF).\n"); printf (" Cntl-Z are ignored and will not truncate the file and\n"); printf (" CR sequences in front of LF will be left unchanged.\n"); printf (" -s: Transform MSDOS-style EOF (CRLF) into UNIX-style EOL (LF)\n"); printf (" and strip a CR sequence of arbitrary length from the file,\n"); printf (" if and only if the sequence is followed by LF. CR sequences\n"); printf (" that are not followed by LF are always left unchanged.\n"); printf (" -t: The timestamp of the modified file will not be preserved.\n"); printf (" -v: Show if file processing has been successful or not.\n"); ! printf (" -vv: Show the kind of modifications that have been done to the file.\n"); printf ("The program is backward compatible with previous program versions if no options\n"); printf ("are given at all. In this case, an occurrence of Cntl-Z will truncate the file,\n"); printf ("MSDOS-style EOL (CRLF) are transformed into UNIX-style EOL (LF) and CR sequence\n"); printf ("stripping will not happen at all. Also the timestamp will not be alterated and\n"); ! printf ("no backup of the original file will be done.%s", ! #if defined(__MSDOS__) || defined(_WIN32) ! "" ! #else ! "\n" ! #endif ! ); } int ! main(int argc, char **argv) { int exit_status = NO_ERROR, i, make_backup, repair_mode; ! int strip_mode, verbose, vverbose, preserve_timestamp; ! char* progname = BaseName(argv[0]); if (argc < 2) { usage (progname); exit(NO_ERROR); } /* Default for backward compatibility. */ ! make_backup = repair_mode = strip_mode = verbose = vverbose = 0; preserve_timestamp = 1; i = 1; while ((argc > i) && (argv[i][0] == '-') && argv[i][1]) { switch (argv[i][1]) { case 'b': make_backup = 1; break; ! case 'h': usage (progname); exit(NO_ERROR); break; case 'r': repair_mode = 1; --- 187,304 ---- position = lseek (sf, offset, whence); must_rewind = 0; } l2 = (k > 0 ? write (df, buf, k) : 0); + bytes_out += k; if (l2 < 0 || CntlZ_flag) break; if (l2 != k) { exit_status = IO_ERROR; break; } } if (l < 0) perror (fname); ! if (l2 < 0) perror (temp_fname); if (exit_status != NO_ERROR) fprintf (stderr,"Cannot process file %s\n",fname); close (sf); close (df); if (l >= 0 && l2 >= 0 && exit_status == NO_ERROR) { ! int file_has_changed = (bytes_in != bytes_out) || CntlZ_flag; ! if (verbosity == 1) printf ("File: %s successfully processed.\n",fname); ! if (verbosity == 2) printf ("File: %s\n",fname); ! if (CR_flag && (verbosity == 2)) printf ("At least one CR/LF to LF transformation occurred.\n"); ! if (nCR_flag && (verbosity == 2)) printf ("Warning: At least one CR sequence stripped from a LF.\n"); ! if (CntlZ_flag && (verbosity == 2)) printf ("Warning: At least one Cntl-Z has been found. File truncated at line %i.\n", LF_counter); ! if (LF_flag && (verbosity == 2)) printf ("Warning: At least one LF without a preceeding CR has been found.\n"); ! if ((verbosity == 2) && !file_has_changed) printf ("File unchanged.\n"); if (make_backup && file_has_changed) ! { ! remove (backup_fname); ! rename (fname, backup_fname); ! } else remove (fname); ! rename (temp_fname, fname); chown (fname, st.st_uid, st.st_gid); chmod (fname, st.st_mode); if (preserve_timestamp || !file_has_changed) utime (fname, &tim1); } else { ! remove (temp_fname); ! if (verbosity) printf ("File: %s. An I/O error occurred\n",fname); } return exit_status; } static void ! usage (char *progname) { ! printf ("Usage: %s [options] files...\n\n", progname); printf ("Options are:\n"); printf (" -b: A backup of the original file is made using `.d2u' as backup\n"); printf (" extension, if the file has been modified.\n"); ! printf (" -h or -?: Display this help and exit.\n"); printf (" -r: Transform MSDOS-style EOF (CRLF) into UNIX-style EOL (LF).\n"); printf (" Cntl-Z are ignored and will not truncate the file and\n"); printf (" CR sequences in front of LF will be left unchanged.\n"); printf (" -s: Transform MSDOS-style EOF (CRLF) into UNIX-style EOL (LF)\n"); printf (" and strip a CR sequence of arbitrary length from the file,\n"); printf (" if and only if the sequence is followed by LF. CR sequences\n"); printf (" that are not followed by LF are always left unchanged.\n"); printf (" -t: The timestamp of the modified file will not be preserved.\n"); printf (" -v: Show if file processing has been successful or not.\n"); ! printf (" -v -v or -vv: Show the kind of modifications that have been done to the file.\n"); printf ("The program is backward compatible with previous program versions if no options\n"); printf ("are given at all. In this case, an occurrence of Cntl-Z will truncate the file,\n"); printf ("MSDOS-style EOL (CRLF) are transformed into UNIX-style EOL (LF) and CR sequence\n"); printf ("stripping will not happen at all. Also the timestamp will not be alterated and\n"); ! printf ("no backup file of the original file will be created.\n"); } int ! main (int argc, char **argv) { int exit_status = NO_ERROR, i, make_backup, repair_mode; ! int strip_mode, verbosity, preserve_timestamp; ! char* progname = BaseName (argv[0]); if (argc < 2) { usage (progname); exit(NO_ERROR); } /* Default for backward compatibility. */ ! make_backup = repair_mode = strip_mode = verbosity = 0; preserve_timestamp = 1; i = 1; while ((argc > i) && (argv[i][0] == '-') && argv[i][1]) { switch (argv[i][1]) { case 'b': make_backup = 1; break; ! case 'h': case '?': usage (progname); exit(NO_ERROR); break; case 'r': repair_mode = 1; *************** main(int argc, char **argv) *** 311,330 **** break; case 't': preserve_timestamp = 0; break; case 'v': ! if (argv[i][2] == 'v') ! { ! vverbose = 1; ! verbose = 0; ! } else ! { ! verbose = 1; ! vverbose = 0; ! } break; default: fprintf (stderr, "%s: invalid option -- %s\n", progname, &argv[i][1]); fprintf (stderr, "Try `%s -h' for more information.\n", progname); exit (IO_ERROR); --- 310,325 ---- break; case 't': preserve_timestamp = 0; break; case 'v': ! if (verbosity == 1) ! verbosity++; ! else if (argv[i][2] == 'v') ! verbosity++; else ! verbosity = 1; break; default: fprintf (stderr, "%s: invalid option -- %s\n", progname, &argv[i][1]); fprintf (stderr, "Try `%s -h' for more information.\n", progname); exit (IO_ERROR); *************** main(int argc, char **argv) *** 332,339 **** } i++; } for (; i < argc; i++) ! exit_status += dtou (argv[i], make_backup, repair_mode, strip_mode, verbose, vverbose, preserve_timestamp); return exit_status; } --- 327,334 ---- } i++; } for (; i < argc; i++) ! exit_status += dtou (argv[i], make_backup, repair_mode, strip_mode, verbosity, preserve_timestamp); return exit_status; }