From owner-freebsd-stable Mon May 3 14:39: 5 1999 Delivered-To: freebsd-stable@freebsd.org Received: from bogslab.ucdavis.edu (bogslab.ucdavis.edu [169.237.68.34]) by hub.freebsd.org (Postfix) with ESMTP id 8E25114BE0 for ; Mon, 3 May 1999 14:39:00 -0700 (PDT) (envelope-from greg@bogslab.ucdavis.edu) Received: from deal1.bogs.org (deal1.bogs.org [198.137.203.51]) by bogslab.ucdavis.edu (8.9.3/8.9.3) with ESMTP id OAA20595 for ; Mon, 3 May 1999 14:38:49 -0700 (PDT) Received: from deal1.bogs.org (LOCALHOST [127.0.0.1]) by deal1.bogs.org (8.8.8/8.6.12) with ESMTP id OAA23272 for ; Mon, 3 May 1999 14:38:47 -0700 (PDT) Message-Id: <199905032138.OAA23272@deal1.bogs.org> X-To: chris@calldei.com X-To: Chris Costello To: stable@FreeBSD.ORG Subject: Re: Dos2unix In-reply-to: Your message of "Mon, 03 May 1999 14:52:25 CDT." <19990503145223.A8709@holly.dyndns.org> Reply-To: gkshenaut@ucdavis.edu Date: Mon, 03 May 1999 14:38:46 -0700 From: Greg Shenaut Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In message <19990503145223.A8709@holly.dyndns.org>, Chris Costello cleopede: >On Mon, May 3, 1999, Vince Vielhaber wrote: >> >> On 03-May-99 Chris Costello wrote: >> > On Mon, May 3, 1999, Michael C. Vergallen wrote: >> >> Here it is ... someone gave me this routine to use ... >> > >> > This code is both unnecessarily complex and it does not >> > function the same way the BSDI dos2bsd/bsd2dos tools work. If you want to see something which is seriously over-complex and works almost nothing like the bsdi tools, read on. If nothing else, it may be good for a laugh. . . . I used BSD/OS for several years before I came over to FreeBSD, and I disliked the BSDI utils enough that I wrote the following code several years ago. Its main advantages are that it can be compiled to run on *nix or msdos, it can handle *unix <--> msdos <--> mac, and, while it can be used as a filter, it is designed to convert multiple files *in place* (i.e., "fixnl *.[ch]" replaces all the *.[ch] files with versions containing only locally valid end-of-line characters). This is because 99 times out of 100, this is what you want to do. BTW, you have to use the -z flag to cause ^Z to signal EOF; the -Z flag will add a newline at the end of the file if it doesn't already end with one--this is handy sometimes; the -F flag is like the -Z flag, except that it won't add a newline if the file ends in \f (I don't remember why I needed this--if you don't like this option, don't use it). -Greg Shenaut (tabs set to 4 columns) ----------------- /* * take care of \r\n stuff in a sightly more intelligent way * we are concerned with both \n\r and \r\n * \n\r --> NL (nonstandard, but handled) * \r\n --> NL (DOS) * x\n --> xNL (UNIX) * \nx --> NLx (UNIX) * x\r --> xNL (MAC) * \rx --> NLx (MAC) * xEOF --> xNL (x is not \f--all) */ #include #include #include char Usage[] = "[ -n|-rn|-r|-z|-Z|-F ][ file ...]"; /* OS defaults */ char *nl = 0; #ifdef __MSDOS__ #define NL "\r\n" /* DOS */ #else dos #ifdef __MAC__ /* not sure this is the right constant. . . . */ #define NL "\r" /* Macintosh (anything to be different) */ #else mac #define NL "\n" /* UNIX newline */ #endif mac #endif dos FILE * efopen(char *s, char *m) { FILE *f = fopen(s, m); if (f == NULL) { fprintf(stderr, "Failed to open %s, mode %s\n", s, m); exit (1); } return(f); } void usage(char *s) { fprintf(stderr, "Usage: fixnl %s\n", s); exit(1); } char tmp[50]; void main(int argc, char **argv) { int i, c, lastc; int zflg = 0; int Zflg = 0; int Fflg = 0; FILE *in, *out, *efopen(); while (argc > 1 && *argv[1] == '-') { char *p; for (p = argv[1]+1; *p; p++) switch (*p) { default: usage(Usage); case 'z': zflg = 1; break; case 'F': Fflg = 1; /* fall thru */ case 'Z': Zflg = 1; break; case 'n': if (nl) usage(Usage); if (p[1] == 'r') usage(Usage); nl = "\n"; break; case 'r': if (nl) usage(Usage); if (p[1] == 'n') { nl = "\r\n"; p++; } else nl = "\r"; } argc--; argv++; } if (!nl) nl = NL; sprintf(tmp, "/tmp/fnl%04x.tmp", (short)getpid()); if (argc <= 1) { in = stdin; out = stdout; i = 0; goto cheat; } for (i = 1; i < argc; i++) { struct stat s; if (stat(argv[i], &s) || (s.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "%s is not a regular file -- skipped\n", argv[i]); continue; } out = efopen(tmp, "w+"); in = fopen(argv[i], "r+"); if (!in) { fprintf(stderr, "Failed to open %s -- skipped\n", argv[i]); continue; } cheat: lastc = EOF; while ((c = getc(in)) != EOF) { if (zflg != 0 && c == 032) { c = EOF; break; } /* handle ^Z as early EOF */ switch (c) { default: switch(lastc) { default: if (lastc != EOF) putc(lastc, out); break; case '\r': case '\n': fputs(nl, out); break; } break; case '\r': switch(lastc) { default: if (lastc != EOF) putc(lastc, out); break; case '\r': /* two in a row */ fputs(nl, out); break; case '\n': fputs(nl, out); c = EOF; break; } break; case '\n': switch(lastc) { default: if (lastc != EOF) putc(lastc, out); break; case '\n': /* two in a row */ fputs(nl, out); break; case '\r': fputs(nl, out); c = EOF; break; } break; } lastc = c; } switch(lastc) { default: putc(lastc, out); if (!Zflg && !Fflg) break; case '\n': case '\r': fputs(nl, out); case EOF: break; case '\f': putc(lastc, out); if (!Fflg && Zflg) fputs(nl, out); break; } if (in == stdin) break; /* now copy on top of the original file & unlink the tmp */ /* ... I hope this won't leave smegma behind at the end ... */ rewind(in); rewind(out); while ((c = getc(out)) != EOF) putc(c, in); fflush(in); write(fileno(in), NULL, 0); /* works in DOS, no effect in unix */ #ifdef __unix__ ftruncate(fileno(in), ftell(in)); #endif fclose(in); fclose(out); unlink(tmp); } exit(0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message