home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: main.c,v 1.3 1992/10/07 22:06:08 craigs Exp $
- *
- * This code was written by Craig Southeren whilst under contract
- * to Computer Sciences of Australia, Systems Engineering Division.
- * It has been kindly released by CSA into the public domain.
- *
- * Neither CSA or me guarantee that this source code is fit for anything,
- * so use it at your peril. I don't even work for CSA any more, so
- * don't bother them about it. If you have any suggestions or comments
- * (or money, cheques, free trips =8^) !!!!! ) please contact me
- * care of geoffw@extro.ucc.oz.au
- *
- */
-
- #include "machdep.h"
- #include "defs.h"
-
- #include "version.h"
- #include "postscri.h"
- #include "print.h"
- #include "main.h"
- #include "paper.h"
-
- /********************************
- defines
- ********************************/
-
- /* environment variables */
- #define PRINTER "PRINTER" /* sets name of printer */
- #define NENSCRIPT "NENSCRIPT" /* contains options */
-
- /********************************
- exports
- ********************************/
- char *progname;
-
- /********************************
- usage
- ********************************/
-
- void usage ()
-
- {
- printf ("usage: %s -?12BGghlNnRrSsVWwZ -f font -F titlefont -b header -i filetitle -L lines -p filename -P printer -S classification -T papertype -t tabstop -# copies file...\n", progname);
- exit (0);
- }
-
- /*********************************
-
- variables set by options
-
- *********************************/
-
- static int landscape = False; /* True if in ladnscape mode, i.e. -r specified */
- static int columns = 1; /* number of columns to print with */
- static char *outputfilename = NULL; /* name of output file, if still NULL after parsing args then use lpr */
- static char *bodyfont = NULL; /* font to use for text */
- static char *titlefont = NULL; /* font to use for titles */
- static int wrap = True; /* True if to wrap long lines */
- static int titlesenabled = True; /* True if page titles enables */
- static char *title = NULL; /* set to title if specified */
- static int copies = 1; /* number of copies of each page */
- static int gaudy = False; /* enables gaudy mode */
- static int force_lines = 0; /* force number of lines per page */
- static char *classification = NULL; /* security classification */
- static int line_numbers = False; /* true if to display line numbers */
- static char *printername = DEF_PRINTER; /* name of printer to use when output goes to lpr */
- static int tabstop = 8; /* tab stops */
- static int passthroughflag = False; /* if True, then check for %! to allow passthrough of raw postscript */
- static char *filetitle = NULL; /* set file title */
-
- #ifdef US_VERSION
- static char *papertype = "US";
- #else
- static char *papertype = "A4";
- #endif
-
-
- /*
- * forward declarations if in ANSI mode
- */
-
- #ifdef __STDC__
- char * get_string (char **);
- void parse_options (int *, char ***);
- void parse_env (char *);
-
-
- #endif
-
-
- /********************************
- parse_options
- ********************************/
-
- #define ARGC (*argc)
- #define ARGV (*argv)
-
- void parse_options (argc, argv)
-
- int *argc;
- char ***argv;
-
- {
- char c;
- char *s;
- int i;
-
- /* parse the options */
-
- next_argv:
- while (--ARGC > 0 && (*++ARGV)[0] == '-')
- while (c = *++ARGV[0])
- switch (c) {
-
- /* -? : print help message */
- case '?' :
- case 'h' :
- usage ();
- break;
-
- /* -1 : single column mode */
- case '1' :
- columns = 1;
- break;
-
- /* -2 : double column mode */
- case '2' :
- columns = 2;
- break;
-
- /* -#: set number of copies */
- case '#' :
- if (*++ARGV[0])
- copies = atoi (ARGV[0]);
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -# option requires argument\n", progname);
- else {
- --ARGC;
- copies = atoi (*++ARGV);
- }
- }
- if (copies < 1) {
- fprintf (stderr, "%s: illegal number of copies specified - defaulting to one\n");
- copies = 1;
- }
- goto next_argv;
- break;
-
- /* -b: set page title */
- case 'b' :
- if (*++ARGV[0])
- title = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -b option requires argument\n", progname);
- else {
- --ARGC;
- title = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -f : set font to use for printing body */
- case 'f' :
- if (*++ARGV[0])
- bodyfont = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -f option requires argument\n", progname);
- else {
- --ARGC;
- bodyfont = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -N : display line numbers */
- case 'N' :
- line_numbers = True;
- break;
-
- /* -n : disable line numbers */
- case 'n' :
- line_numbers = False;
- break;
-
- /* -p: send to file rather than lpr */
- case 'p' :
- if (*++ARGV[0])
- outputfilename = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -p option requires argument\n", progname);
- else {
- --ARGC;
- outputfilename = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -r : landscape mode */
- case 'r' :
- landscape = True;
- break;
-
- /* -w : wrap mode */
- case 'w' :
- wrap = True;
- break;
-
- /* -Z : check for postscript passthrough mode */
- case 'Z' :
- passthroughflag = True;
- break;
-
- /* -B : disable page headings and disable gaudy mode */
- case 'B' :
- titlesenabled = False;
- break;
-
- /* -F : set font to use for printing titles */
- case 'F' :
- if (*++ARGV[0])
- titlefont = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -F option requires argument\n", progname);
- else {
- --ARGC;
- titlefont = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -g : disable gaudy mode */
- case 'g' :
- gaudy = False;
- break;
-
- /* -G : enable gaudy mode */
- case 'G' :
- gaudy = True;
- break;
-
- /* -i: set file title when inputting from stdin */
- case 'i' :
- if (*++ARGV[0])
- filetitle = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -i option requires argument\n", progname);
- else {
- --ARGC;
- filetitle = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -l : don't set number of lines of page, i.e. use maximum */
- case 'l' :
- force_lines = 0;
- break;
-
- /* -L : force number of lines per page */
- case 'L' :
- if (*++ARGV[0])
- force_lines = atoi(ARGV[0]);
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -x option requires argument\n", progname);
- else {
- --ARGC;
- force_lines = atoi (*++ARGV);
- }
- }
- if (force_lines <= 0) {
- fprintf (stderr, "%s: ignoring illegal arguement to -L option\n", progname);
- force_lines = 0;
- }
- goto next_argv;
- break;
-
- /* -P: set printer name - overrides PRINTER environment variables */
- case 'P' :
- if (*++ARGV[0])
- printername = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -P option requires argument\n", progname);
- else {
- --ARGC;
- printername = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -R : portrait mode */
- case 'R' :
- landscape = False;
- break;
-
- /* -S: set security classification */
- case 'S' :
- if (*++ARGV[0])
- classification = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -S option requires argument\n", progname);
- else {
- --ARGC;
- classification = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -s : disable security classification printing */
- case 's' :
- classification = NULL;
- break;
-
-
- /* -T: set paper size to either US or A4 */
- case 'T' :
- if (*++ARGV[0])
- papertype = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -T option requires argument\n", progname);
- else {
- --ARGC;
- papertype = *++ARGV;
- }
- }
- goto next_argv;
- break;
-
- /* -t: set tab stop size */
- case 't' :
- if (*++ARGV[0])
- s = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -t option requires argument\n", progname);
- else {
- --ARGC;
- s = *++ARGV;
- }
- }
- if ((i = atoi (s)) <= 0)
- fprintf (stderr, "%s: illegal tab setting %s ignored\n", progname, s);
- else
- tabstop = i;
- goto next_argv;
- break;
-
- /* -V : print version number */
- case 'V' :
- fputs (version_string, stderr);
- fputs ("\n", stderr);
- /* fputs (copyright_string, stderr); */
- exit (0);
- break;
-
- /* -W : turn off wrap mode */
- case 'W' :
- wrap = False;
- break;
-
- /* single char option */
- /* case 'x' :
- allow_checkouts = True;
- break;
- */
-
- /* option with string */
- /* case 'x' :
- if (*++ARGV[0])
- optionstring = ARGV[0];
- else {
- if (ARGC < 1)
- fprintf (stderr, "%s: -x option requires argument\n", progname);
- else {
- --ARGC;
- optionstring = *++ARGV;
- }
- }
- goto next_argv;
- break;
- */
- default :
- fprintf (stderr, "%s: unknown option %c\n", progname, c);
- ARGC = 0;
- break;
- }
- }
-
- /********************************
- get_string
- return the next string from the argument
- ********************************/
-
- char * get_string (str)
-
- char **str;
-
- #define STR (*str)
-
- {
- char *ret = NULL;
- int in_dquote, in_squote, in_bquote;
- int quote_count;
-
- /* skip leading whitespace */
- while (*STR == ' ' ||
- *STR == '\t')
- STR++;
-
- /* return if end of string */
- if (*STR == '\0')
- return NULL;
-
- /* collect characters until end of string or whitespace */
- in_dquote = -1;
- in_squote = -1;
- in_bquote = -1;
- quote_count = 0;
- ret = STR;
- while (*STR != '\0' &&
- (quote_count > 0 || (*STR != ' ' && *STR != '\t'))
- ) {
- switch (*STR) {
- case '"':
- in_dquote = -in_dquote;
- quote_count += in_dquote;
- break;
-
- case '\'':
- in_squote = -in_squote;
- quote_count += in_squote;
- break;
-
- case '`':
- in_bquote = -in_bquote;
- quote_count += in_bquote;
- break;
-
- case '\\':
- if (STR[1] != '\0')
- STR++;
- break;
- }
- STR++;
- }
- if (*STR != '\0') {
- *STR = '\0';
- STR++;
- }
-
- if (quote_count > 0)
- fprintf (stderr, "unmatched quote in %s environment variable\n", NENSCRIPT);
-
- return ret;
- }
-
-
- /********************************
- parse_env
- process the options specified in the supplied string
- ********************************/
-
- void parse_env (env)
-
- char *env;
-
- {
- int argc;
- char *s;
- char **argv;
- int i;
-
- if (env == NULL)
- return;
-
- /* insert a "fake" argv[0] which corresponds to the real
- argv[0] passed to main. The allows us to use same routine
- for handling the real arguments */
- argv = (char **)malloc (sizeof (char *));
- argc = 1;
- argv[0] = progname;
-
- /* split the single environment string into separate strings so we can pass
- them to parse_options */
- while ((s = get_string (&env)) != NULL) {
- argv = (char **)realloc ((void *)argv, (argc+1) * sizeof (char *));
- argv[argc] = s;
- argc++;
- }
-
- /* parse the options */
- parse_options (&argc, &argv);
- }
-
- /********************************
- passthrough
- ********************************/
-
- static void passthrough (input, output)
-
- FILE * input;
- FILE * output;
-
- {
- char buff [512];
- int len;
-
- while ((len = fread (buff, 1, 512, input)) > 0)
- fwrite (buff, 1, len, output);
- }
-
-
- /********************************
- main
- ********************************/
-
- int main (argc, argv)
-
- int argc;
- char *argv[];
-
- {
- char *env;
- char cmd[1024];
- struct PaperMetrics * papermetrics;
- int i;
- int ch1;
- int ch2;
-
-
- FILE *outputstream; /* opened output stream - either file or lpr */
- FILE *inputstream; /* opened input stream, 0 if max */
-
- /* extract the program name */
- if ((progname = strrchr (argv[0], '/')) == NULL)
- progname = argv[0];
- else
- progname++;
-
- /* get the printer environment variable */
- if ((env = getenv (PRINTER)) != NULL)
- printername = env;
-
- /* handle the NENSCRIPT environment variable */
- if ((env = getenv (NENSCRIPT)) != NULL)
- parse_env (STRDUP(env));
-
- /* parse arguments */
- parse_options (&argc, &argv);
-
- /* open either the output file or a pipe to lpr */
- if (outputfilename != NULL) {
- if (strcmp (outputfilename, "-") == 0)
- outputstream = stdout;
- else if ((outputstream = fopen (outputfilename, "w")) == NULL) {
- perror (outputfilename);
- exit (1);
- }
- } else {
- #ifdef MSDOS
- if ((outputstream = fopen (printername, "w")) == NULL) {
- perror (printername);
- exit (1);
- }
- #else
- sprintf (cmd, "%s %s", LPR, printername);
- if ((outputstream = popen (cmd, "w")) == NULL) {
- perror (LPR);
- exit (1);
- }
- #endif
- }
-
- /* can't be in passthrough mode with more than one argument */
- if (argc > 1 && passthroughflag) {
- fprintf (stderr, "%s: ignoring -Z flag as there is more than one argument", progname);
- passthroughflag = False;
- }
-
- /* if in passthrough mode, open the input stream and check for %! */
- if (passthroughflag) {
- if (argc < 1)
- inputstream = stdin;
- else if ((inputstream = fopen (*argv, "r")) == NULL) {
- perror (*argv);
- exit (1);
- }
- ch1 = fgetc (inputstream);
- ch2 = fgetc (inputstream);
- ungetc (ch2, inputstream);
- ungetc (ch1, inputstream);
- if (ch1 == '%' && ch2 == '!') {
- passthrough (inputstream, outputstream);
- exit (0);
- }
- } else
- inputstream = NULL;
-
- /* check the paper type and get ptr to record */
- papermetrics = NULL;
- for (i = 0; PaperTypes[i].Name != NULL; i++)
- if (STRICMP ((papermetrics = &PaperTypes[i])->Name, papertype) == 0)
- break;
-
- /* if the papermetric was not set, give error */
- if (PaperTypes[i].Name == NULL) {
- fprintf (stderr, "%s: paper type %s not known\n", progname, papertype);
- exit (1);
- }
-
- /* set up the fonts */
- if (bodyfont == NULL)
- bodyfont = (columns == 2 && landscape) ? papermetrics->LandscapeFont : papermetrics->PortraitFont;
-
- if (titlefont == NULL)
- titlefont = papermetrics->TitleFont;
-
- /* display the header */
- StartJob (outputstream,
- *argv,
- landscape,
- columns,
- bodyfont,
- titlefont,
- wrap,
- titlesenabled,
- title,
- copies,
- gaudy,
- force_lines,
- classification,
- papermetrics,
- tabstop);
-
- /* if no arguments, then accept stdin */
- if (argc < 1)
- print_file (stdin, outputstream, (filetitle ? filetitle : "stdin"), line_numbers);
- else for (;argc > 0;argc--) {
- if (inputstream == NULL && (inputstream = fopen (*argv, "r")) == NULL)
- perror (*argv);
- else {
- print_file (inputstream, outputstream, (filetitle ? filetitle : *argv), line_numbers);
- inputstream == NULL;
- }
- argv++;
- }
-
- /* output trailer */
- EndJob (outputstream);
-
- /* finished */
- return (0);
- }
-