#include #define UNIX_BREAKS 1 #define PC_BREAKS 2 #define MAC_BREAKS 3 #define DEFAULT_BREAKS PC_BREAKS /* Define WRITE_MODE as "wb" on PCs */ #define WRITE_MODE "w" #define READ_LENGTH 4096; #define CR 015 #define LF 012 #define HT 011 #define FF 014 /* extern int getopt (int argc, char **argv, char *optstring); */ int main (argc, argv) int argc; char **argv; { int usage (char *, char *); int getopt (int, char **, char*); int lookahead (FILE *f); char *infn, *outfn; FILE *infile, *outfile; char *progname; int breaks = DEFAULT_BREAKS; int verify = 0; int quiet = 0; int ch; char *brname[4] = { "ERROR", "UNIX", "PC", "Mac" }; unsigned char *inbuf, *outbuf; int inbuflen, outbuflen; int datalen, inplace, outplace; extern char *optarg; extern int optind; progname = (char *) malloc (strlen(argv[0])+1); strcpy(progname, argv[0]); while ((ch = getopt(argc, argv, "upmvqhH")) != -1) { switch (ch) { case 'u': breaks = UNIX_BREAKS; break; case 'p': breaks = PC_BREAKS; break; case 'm': breaks = MAC_BREAKS; break; case 'v': verify = 1; break; case 'q': quiet = 1; break; case 'h': case 'H': usage(progname, NULL); break; default: usage(progname, "unexpected option"); } } if (optind < argc) { infn = argv[optind++]; if (strcmp(infn, "-") == 0) { infile = stdin; } else { infile = fopen(infn,"r"); if (infile == NULL) usage(progname, "error opening input file"); } } else { infn = "-"; infile = stdin; } inbuflen = READ_LENGTH; outbuflen = 2*inbuflen; inbuf = (char *) malloc(inbuflen); outbuf = (char *) malloc(outbuflen); if (verify) { datalen = fread(inbuf, 1, inbuflen, infile); ch = 0; for (inplace = 0; inplace < datalen; inplace++) { if ((inbuf[inplace] < 32) && (inbuf[inplace] != CR) && (inbuf[inplace] != LF) && (inbuf[inplace] != HT) && (inbuf[inplace] != FF)) { ch = 1; break; } } if (ch) { fprintf (stderr, "%s: %s does not appear to be a text file (%d).\n", progname, infn, inplace); exit (2); } fseek(infile, 0, 0); } if (optind < argc) { outfn = argv[optind++]; if (strcmp(outfn, "-") == 0) { outfile = stdout; } else { outfile = fopen(outfn,WRITE_MODE); if (outfile == NULL) usage(progname, "error opening output file"); } } else { outfn = "-"; outfile = stdout; } if (!quiet) fprintf (stderr, "Converting %s to %s with %s line breaks.\n", infn, outfn, brname[breaks]); if (strcmp(infn, "-") == 0) { /* It's not possible to do random access on a stream, so we have * to go slowly through the file. Another possibility would be creating * a temporary file, but how to do that in a system-independent manner? */ int lookch; while ((ch = fgetc(infile)) >= 0) { /* If this CR is the start of a CR/LF pair, skip it */ if (ch == CR) { lookch = fgetc(infile); ungetc(lookch, infile); if (lookch == LF) continue; } if ((ch == CR) || (ch == LF)) { if (breaks == UNIX_BREAKS) fputc(LF, outfile); else fputc(CR, outfile); if (breaks == PC_BREAKS) fputc(LF, outfile); } else { fputc(ch, outfile); } } } else { while ((datalen = fread(inbuf, 1, inbuflen, infile)) > 0) { outplace = 0; for (inplace = 0; inplace < datalen; inplace++) { /* If this CR is the start of a CR/LF pair, skip it */ if (inbuf[inplace] == CR) { if (inplace+1 == datalen) { if (lookahead(infile) == LF) continue; } else { if (inbuf[inplace+1] == LF) continue; } } if ((inbuf[inplace] == CR) || (inbuf[inplace] == LF)) { if (breaks == UNIX_BREAKS) outbuf[outplace++] = LF; else outbuf[outplace++] = CR; if (breaks == PC_BREAKS) outbuf[outplace++] = LF; } else { outbuf[outplace++] = inbuf[inplace]; } } datalen = fwrite(outbuf, 1, outplace, outfile); if (datalen != outplace) exit(1); } } fclose (infile); fclose (outfile); exit (0); } int usage (progname, msg) char *progname; char *msg; { if (msg) fprintf (stderr, "Error: %s\n", msg); fprintf (stderr, "Usage: %s infile [outfile]\n", progname); fprintf (stderr, "Where: infile = name of input file\n"); fprintf (stderr, " outfile = name of output file\n"); fprintf (stderr, " Use '-' for stdin or stdout, respectively.\n"); exit (1); } int lookahead (f) FILE *f; { int pos = ftell(f); int ch = fgetc(f); fseek(f, pos, 0); return ch; }