]> thyrsus.com Git - mstrans.git/commitdiff
Initial revision
authorEric S. Raymond <esr@thyrsus.com>
Tue, 25 Oct 1994 06:51:15 +0000 (06:51 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Tue, 25 Oct 1994 06:51:15 +0000 (06:51 +0000)
mstrans.c [new file with mode: 0644]

diff --git a/mstrans.c b/mstrans.c
new file mode 100644 (file)
index 0000000..4954f03
--- /dev/null
+++ b/mstrans.c
@@ -0,0 +1,176 @@
+/*****************************************************************************
+
+NAME
+    mstrans.c -- translate MS-DOS and Wordstar text files into pure ASCII
+
+SYNOPSIS
+    mstrans [-vwcr] [file...]
+
+DESCRIPTION
+    This program may be used to filter MS-DOS text files for UNIX and/or
+ASCII-ize WordStar document files
+    MS-DOS text files use an <CR><LF> terminator rather than UNIX's <LF>.
+They end with control-Z characters (hex 1A) filling out their last 128
+bytes. This filter squeezes out control-Z characters. The UNIX version of
+this program strips CRs by default; the MS-DOS version doesn't. The -c
+inverts the default.
+    WordStar text files use the meta bits of characters as formatting
+information; the -w option strips those off. It also turns WordStar hyphens
+into ASCII hyphens and discards the invisible hyphen-break marks left when
+hyphenation changes. These WordStar translations should be harmless to
+ordinary text and program files.
+    If called with no arguments, this tool will filter standard input to
+standard output. If given arguments, it assumes they are all-caps MS-DOS
+filenames and translates each into a UNIX equivalent in all small letters.
+It will not translate a file with a name that is already all smalls, and
+the UNIX version will not attempt to translate directory files. Thus, invoking
+
+    mstrans *
+
+in a directory containing MS-DOS files with all-caps names will do the
+right thing.
+   The -r option reverses these transformations,  turning <LF> into <LF><CR>.
+
+NOTE
+    On UNIX, compile with -DUNIX as an option. This will enable the skipping
+of directory files and make CR-stripping the default. On MS-DOS or CP/M, 
+compile without this option to make no CR stripping the default.
+
+HISTORY
+    Eric S. Raymond created 18 Oct 85
+
+****************************************************************************/
+
+#define UNIX
+
+#include <stdio.h>
+
+#ifdef UNIX
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#define PATHLEN            64
+#define TRUE       1
+#define FALSE      0
+
+/* characters to treat specially */
+#define LF     '\012'  /* ASCII line feed */
+#define        CR      '\015'  /* ASCII carriage return */
+#define        CTRLZ   '\032'  /* MS-DOS uses this to end text files */
+#define SOFTH  '\037'  /* WordStar visible soft hyphen */
+#define HMARK  '\036'  /* WordStar invisible hyphen break mark */
+
+/* option flags */
+int verbose = FALSE;   /* be chatty about skipped files */
+int wordstar = FALSE;  /* do WordStar translations */
+int reverse = FALSE;   /* reverse translation, UNIX to MS-DOS */
+#ifdef UNIX
+int stripcr = TRUE;    /* by default, strip carriage returns on UNIX */
+#else
+int stripcr = FALSE;   /* MS-DOS, CP/M etc use <CR><LF>; keep CRs */
+#endif /* UNIX */
+
+mstrans()
+{
+    register int    c;
+    
+    while ((c = getchar()) != EOF)
+    {
+       /* do to-MSDOS translations if enabled */
+       if (reverse && c == LF)
+       {
+           putchar(CR);
+           putchar(LF);
+           continue;
+       }
+
+       /* strip out MS-DOS end-of-file marks */
+       else if (c == CTRLZ  || (c == CR && stripcr))
+           continue;
+
+       /* do WordStar translations if enabled */
+       if (wordstar)
+       {
+           c &= 0x7F;                  /* strip off WordStar meta bits */
+           if (c == SOFTH)
+               c = '-';                /* change soft hyphens to real ones */
+           else if (c == HMARK)
+               continue;               /* discard hyphen break marks */
+       }
+
+       putchar(c);
+    }
+}
+
+main(argc, argv)
+/* process filename arguments */
+int    argc;
+char   *argv[];
+{
+    char           c, dst[PATHLEN];
+    register char   *sp, *tp;
+    extern int     optind;
+#ifdef UNIX
+    struct stat            fs;
+#endif
+
+    while ((c = getopt(argc, argv, "vcwr")) != EOF)
+       if (c == 'v')
+           verbose = TRUE;
+       else if (c == 'w')
+           wordstar = TRUE;
+       else if (c == 'r')
+           reverse = TRUE;
+       else if (c == 'c')
+           stripcr = !stripcr;
+
+    if (optind == argc)
+       mstrans();
+    else
+       for (; optind < argc; optind++)
+       {
+#ifdef UNIX
+           /* if the name is of anything but a file, skip it */
+           if (stat(argv[optind], &fs) || (fs.st_mode & S_IFMT) != S_IFREG)
+           {
+               if (verbose)
+                   fprintf(stderr,
+                       "mstrans: %s is a directory or special file\n",
+                       argv[optind]);
+               continue;
+           }
+#endif /* UNIX */
+
+           /* generate an all-smalls version of the all-caps MS-DOS name */
+           tp = dst;
+           for (sp = argv[optind]; *sp; sp++)
+               if (reverse)
+                   *tp++ = toupper(*sp);
+               else
+                   *tp++ = tolower(*sp);
+           *tp = 0;
+
+           /* if the name is already all-smalls, forget it */
+           if (strcmp(argv[optind], dst) == 0)
+           {
+               if (verbose)
+                   fprintf(stderr,
+                       "mstrans: skipping %s\n",
+                       argv[optind]);
+               continue;
+           }
+
+           /* if we can open both source and destination file, translate */
+           if (freopen(argv[optind], "r", stdin) && freopen(dst, "w",stdout))
+           {
+               if (verbose)
+                   fprintf(stderr,
+                       "mstrans: translating %s to %s\n",
+                       argv[optind],  dst);
+               mstrans();
+           }
+       }
+}
+
+/* mstrans.c ends here */