home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <exec/types.h>
-
- /*
- * Lit Text Utility - Filter a file to stdout showing all characters in
- * an unambiguous format. See Lit Text Utility Manual for specification.
- *
- * Version 2.0 - 11/16/86, Unpublished (C) 1986 Donald J Irving
- *
- * Author: Donald J. Irving
- * 9812 Gardenwood Way
- * Sacramento, CA 96827
- * (916) 366-3225
- * CIS: 73547,1335
- * PLINK: ops158
- *
- * Lit may be freely distributed for personal use.
- * Lit may not be sold or placed on a disk offered for sale without written
- * permission from the author. Written permission will normally be granted
- * at no charge for inclusion on so called "public domain disks" which are
- * sold for nominal medium and handling fees. Lit may be modified for
- * personal use, and trivial modifications such as changing defaults or
- * specifying include files may be made for distribution, but lit is not to
- * be modified substantially for distribution without written consent of the
- * author. The lit.c source, lit manual file , and this copyright notice must
- * be included on all distributions.
- *
- * Here is the overall algorithm, minus some of the details:
- *
- * if unable to interpret command line arguments
- * print an error message and a Usage line;
- * else
- * set options and open files;
- * if line specified to start on is not the first line
- * throw out input file lines until the line specified;
- * while read next char from input file
- * if the char is printable
- * print it;
- * else
- * represent it in a special format;
- * if the char is a line feed
- * output a linefeed;
- * if there was a number of lines to print specified
- * and ++line count equals that number
- * return;
- *
- * Functions not returning values are not typed. Functions returning values
- * are explicitly typed.
- *
- */
-
- /* The four possible settings for representation mode. */
- #define BSLASH 1 /* use backslash rep else numeric */
- #define CONTROL 2 /* use control char reps else numeric */
- #define ALLREPS 3 /* use backslash else control else numeric */
- #define NUMERIC 4 /* use numeric value reps only */
-
- /* The three possible settings for numeric number base */
- #define OCT 1 /* use octal representations as in \033 */
- #define HEX 2 /* use hex representations as in \1B */
- #define DEC 3 /* use decimal representations as in \027 */
-
- /* The most likely setting for how many lines to print */
- #define ALL_LINES 32767 /* print all the lines in the file */
-
- /*
- * Here are the default option settings. If you don't like them, please
- * change them here. The comments on the define lines show the the default
- * settings chosen by the author and upon which the manual is based. Please
- * leave the comments as they are.
- */
- /* original */
- #define DEFAULT_START 1 /* 1 */
- #define DEFAULT_PRINT ALL_LINES /* ALL_LINES */
- #define DEFAULT_OUTMODE BSLASH /* BSLASH */
- #define DEFAULT_BASE OCT /* OCT */
-
- /* Non-printing characters which require special handling in the code */
- #define DEL '\177'
-
- struct opt {
- short start;
- short print;
- short outmode;
- short base;
- };
-
- typedef struct opt opt_t;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *ifp = NULL;
- register short c;
- static opt_t opt = {
- DEFAULT_START,
- DEFAULT_PRINT,
- DEFAULT_OUTMODE,
- DEFAULT_BASE
- };
-
- if (! process_args(argc, argv, &ifp, &opt))
- printf("Usage: lit [<filename>] [-s<n>] [-p<n>] [-[bcan][ohd]]\n");
- else {
- if (opt.start != 1 && ! find_start_line(ifp, opt.start))
- return;
- while ((c = getc(ifp)) != EOF) {
- if (! print_char(c, opt.outmode))
- represent_char(c, opt.outmode, opt.base);
- if (c == '\n') {
- putchar('\n');
- if (opt.print != ALL_LINES && last_line(opt.print))
- break;
- }
- }
- if (c != '\n')
- putchar('\n');
- }
- }
-
-
- /*
- * process_args -- Process all the command line arguments. Each argument is
- * expected to be either a minus sign option or an input file name. If an
- * input file is already open, a subsequent input file name argument is an
- * error.
- */
-
- BOOL process_args(argc, argv, ifp, opt)
- int argc;
- char *argv[];
- FILE **ifp;
- opt_t *opt;
- {
- register short i;
-
- for (i = 1; i < argc; i++) {
- if (*argv[i] == '-') {
- if (! process_opt(argv[i]+1, opt))
- return (FALSE);
- }
- else if (*ifp != NULL) {
- printf("Invalid argument %s, Input file already specified\n",
- argv[i]);
- return (FALSE);
- }
- else if ((*ifp = fopen(argv[i], "r")) == NULL) {
- printf("Unable to open input file %s\n", argv[i]);
- return (FALSE);
- }
- }
-
- if (*ifp == NULL)
- *ifp = stdin;
- return (TRUE);
- }
-
-
- /*
- * process_opt -- Process a minus-sign command line argument. The options
- * s<linenum> and p<numlines> must stand alone with their own minus signs;
- * The options b,c,a,n,o,h,d may be stacked after a single minus sign.
- */
-
- BOOL process_opt(arg, opt)
- char *arg;
- opt_t *opt;
- {
- switch (*arg) {
- case 's':
- opt->start = atoi(arg+1); /* set starting linenum */
- break;
- case 'p':
- opt->print = atoi(arg+1); /* set linenums to print */
- break;
- default:
- for (; *arg; arg++) {
- switch (*arg) {
- case 'b':
- opt->outmode = BSLASH; /* use backslash rep else */
- break; /* numeric rep */
- case 'c':
- opt->outmode = CONTROL; /* use control char rep */
- break; /* else numeric rep */
- case 'a':
- opt->outmode = ALLREPS; /* use backslash else */
- break; /* control else numeric */
- case 'n':
- opt->outmode = NUMERIC; /* use numeric rep only */
- break;
- case 'o':
- opt->base = OCT; /* numeric rep base is octal */
- break;
- case 'h':
- opt->base = HEX; /* numeric rep base is hex */
- break;
- case 'd':
- opt->base = DEC; /* numeric rep base is decimal */
- break;
- default:
- printf("Unknown option: %c\n", *arg);
- return (FALSE);
- }
- }
- }
- return (TRUE);
- }
-
-
- /*
- * find_start_line -- Find the first line to start printing on, throwing
- * out all the lines along the way.
- */
-
- BOOL find_start_line(ifp, start)
- FILE *ifp;
- short start;
- {
- register short c, lineno = 1;
-
- while (lineno < start) {
- while ((c = getc(ifp)) != EOF && c != '\n')
- ;
- if (c == EOF)
- return (FALSE);
- lineno++;
- }
- return (TRUE);
- }
-
-
- /*
- * last_line -- Return true if the line just printed was the last line
- * to print.
- */
-
- BOOL last_line(print)
- short print;
- {
- static short printed = 0;
-
- if (++printed == print)
- return (TRUE);
- return (FALSE);
- }
-
-
- /*
- * print_char -- Print a printable character. If it's a \, or if
- * it's a ^ and control codes are enabled, then preface it with a \.
- */
-
- BOOL print_char(c, outmode)
- short c, outmode;
- {
- if (c < ' ' || c > '~')
- return (FALSE);
-
- if (c == '\\'
- || (c == '^' && (outmode == CONTROL || outmode == ALLREPS)))
- putchar('\\');
-
- putchar(c);
- return (TRUE);
- }
-
-
- /*
- * represent_char -- Represent a non-printable character using whichever
- * representation format is appropriate for the outmode selected. The
- * rep_xxx functions called try to represent the char in a particular
- * format, and return false if the the character is not applicable.
- */
-
- represent_char(c, outmode, base)
- short c, outmode, base;
- {
- switch (outmode) {
- case BSLASH:
- if (rep_bslash(c))
- return;
- break;
- case CONTROL:
- if (rep_control(c))
- return;
- break;
- case ALLREPS:
- if (rep_bslash(c) || rep_control(c))
- return;
- break;
- case NUMERIC:
- break;
- }
- rep_numeric(c, base);
- }
-
-
- /*
- * rep_bslash - Represent a non-printable char if possible using its
- * C Language backslash construct, else return false. '\0' is not included.
- */
-
- BOOL rep_bslash(c)
- short c;
- {
- switch (c) {
- case '\n': putchar('\\'); putchar('n'); break;
- case '\t': putchar('\\'); putchar('t'); break;
- case '\b': putchar('\\'); putchar('b'); break;
- case '\r': putchar('\\'); putchar('r'); break;
- case '\f': putchar('\\'); putchar('f'); break;
- default :
- return (FALSE);
- }
- return (TRUE);
- }
-
-
- /*
- * rep_control -- represent a non-printable char if possible using its
- * control character representation, else return false. All non-printing
- * ascii chars are representable as control chars (with DEL arbitrarily
- * assigned the representation ^?). Characters rejected are those outside
- * the range of ascii (ie, left most bit on).
- */
-
- BOOL rep_control(c)
- short c;
- {
- if (c < '\0' || c > '\177')
- return (FALSE);
-
- putchar('^');
-
- switch (c) {
- case DEL:
- putchar('?');
- break;
- default:
- putchar(c | 0x40);
- break;
- }
- return (TRUE);
- }
-
-
- /*
- * rep_numeric - Unconditionally represent a character as a numeric value
- * using the number base specified.
- */
-
- rep_numeric(c, base)
- short c, base;
- {
- char buf[4];
-
- switch (base) {
- case OCT:
- printf("\\%03o", c);
- break;
- case HEX:
- sprintf(buf, "\\%02x\0", c); /* make it upper case, %X */
- if (buf[1] >= 'a') /* doesn't seem to work on */
- buf[1] &= 0x5F; /* my compiler. */
- if (buf[2] >= 'a')
- buf[2] &= 0x5F;
- printf("%s", buf);
- break;
- case DEC:
- printf("\\%03d", c);
- break;
- }
- }
-
-