Combined tool to find and fix MS-DOS line endings.
Alex Cherepanov <[email protected]> Mon, 20 Sep 2004 15:27:57 -0400
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Organization | Coscript Software |
| Message-ID | <[email protected]> |
Per Igor's request here's a combined program to find and fix MS-DOS line endings. The program is formatted according to GNU format style: indent fix_cr.c _______________________________________________ gs-code-review mailing list [email protected] http://www.ghostscript.com/mailman/listinfo/gs-code-review
fix_cr.c
(text/plain, 4.6 KB)
/*
* Copyright 2004 Alex Cherepanov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Search and delete '\r' characters from the files in place.
* The file is modified only when it has '\r' characters and
* --not-fix is not set. Binary files are not modified except
* in the forced mode.
*
* This program was written to normalize line endings in MS-DOS
* and Mac files before submitting them to the UNIX-compatible project.
* The program loads the whole file to core, converts '\r\n' to '\n'
* and single '\r' to '\n', and writes the file back when needed.
*/
char version[] = "$Id: $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _MSC_VER
# define lseek _lseek
# define fileno _fileno
# define stat _stat
# define S_ISDIR(s) (s & _S_IFDIR)
#endif
#define STR2MEM0(s) s,sizeof(s)
static void
error (char *fmt, ...)
{
va_list v;
va_start (v, fmt);
vfprintf (stderr, fmt, v);
perror ("strerror");
va_end (v);
}
static int
is_binary (char *p, int len)
{
int i, rc = 0, cnt[256];
memset (cnt, 0, sizeof (cnt));
for (i = 0; i < len; i++)
cnt[p[i] & 0xFF] = 1;
cnt['\r'] = cnt['\n'] = cnt['\t'] = cnt['\f'] = 0;
for (i = 0; i < 32; i++)
rc |= cnt[i];
return rc;
}
int
main (int argc, char **argv)
{
int i;
int force = 0;
int not_fix = 0;
int max_opt = argc < 3 ? argc : 3;
if (argc == 2)
{
if (!strncmp (argv[1], STR2MEM0 ("--help")))
{
printf
("Search and delete '\\r' characters from the files in place.\n");
printf
("The file is modified only when it has '\\r' characters and --not-fix\n");
printf
("flag is not set. Binary files are ignored unless forced.\n\n");
printf ("Usage:\tfix_cr --help\n");
printf ("\tfix_cr --version\n");
printf
("\tfix_cr [ -f | --force] [ -n | --not-fix ] FILE1 FILE2 FILE3 ...\n");
exit (0);
}
if (!strncmp (argv[1], STR2MEM0 ("--version")))
{
printf ("%s\n", version);
exit (0);
}
}
for (i = 1; i < max_opt; i++)
{
if (!strncmp (argv[i], STR2MEM0 ("-fn"))
|| !strncmp (argv[i], STR2MEM0 ("-nf")))
{
force = not_fix = 1;
continue;
}
if (!strncmp (argv[i], STR2MEM0 ("-f"))
|| !strncmp (argv[i], STR2MEM0 ("--force")))
{
force = 1;
continue;
}
if (!strncmp (argv[i], STR2MEM0 ("-n"))
|| !strncmp (argv[i], STR2MEM0 ("--not-fix")))
{
not_fix = 1;
continue;
}
break;
}
for (; i < argc; i++)
{
long len;
char *buf;
struct stat st;
FILE *f;
if (stat (argv[i], &st) == EOF)
{
error ("Cannot get status on %s\n", argv[i]);
exit (1);
}
if (S_ISDIR (st.st_mode))
continue;
len = st.st_size;
f = fopen (argv[i], "rb");
if (f == 0)
{
error ("Cannot open %s for reading\n", argv[i]);
exit (2);
}
buf = malloc (len + 1);
if (buf == 0)
{
error ("Cannot allocate %d bytes\n", len + 1);
fclose (f);
exit (4);
}
buf[len] = 0;
fseek (f, 0, SEEK_SET);
if (fread (buf, 1, len, f) != len)
{
error ("Error reading %s\n", argv[i]);
free (buf);
fclose (f);
exit (5);
}
fclose (f);
if (memchr (buf, '\r', len))
{
long j;
if (!force && is_binary (buf, len))
{
fprintf (stderr, "Skipping binary file %s\n", argv[i]);
}
else
{
printf ("%s\n", argv[i]);
if (!not_fix)
{
f = fopen (argv[i], "wb");
if (!f)
{
error ("Cannot open %s for writing\n", argv[i]);
free (buf);
exit (6);
}
for (j = 0; j < len; j++)
{
char c = buf[j];
if (c == '\r')
{
if (buf[j + 1] == '\n')
continue;
c = '\n';
}
if (putc (c, f) == EOF)
{
error ("Error writing %s\n", argv[i]);
free (buf);
exit (7);
}
}
fclose (f);
}
}
}
free (buf);
}
return 0;
}