#include "gsint.h"
#include "getopt.h"
static void open_output_file ();
static void close_output_file ();
static void handle_env_options ___P ((char *var));
static void handle_options ___P ((int argc, char *argv[]));
static void do_list_options ();
static void usage ();
static void version ();
char *program;
FILE *ofp = NULL;
void *printer_context;
char version_string[256];
char ps_version_string[20];
char date_string[256];
struct tm run_tm;
struct tm mod_tm;
struct passwd *passwd;
char *enscript_library = LIBRARY;
char libpath[1024];
char *afm_path = NULL;
char afm_path_buffer[1024];
MediaEntry *media_names = NULL;
MediaEntry *media = NULL;
int bs = 8;
int total_pages = 0;
int num_truncated_lines = 0;
int num_missing_chars = 0;
int missing_chars[256] = {0};
int num_non_printable_chars = 0;
int non_printable_chars[256] = {0};
int d_page_w = 0;
int d_page_h = 0;
int d_header_w = 0;
int d_header_h = 0;
int d_footer_h = 0;
int d_output_w = 0;
int d_output_h = 0;
int d_output_x_margin = 5;
int d_output_y_margin = 2;
StringHashPtr res_fonts;
StringHashPtr download_fonts;
StringHashPtr pagedevice;
StringHashPtr statusdict;
StringHashPtr user_strings;
StringHashPtr afm_cache = NULL;
StringHashPtr afm_info_cache = NULL;
AFMHandle afm = NULL;
int num_columns = 1;
PageRange *page_ranges = NULL;
unsigned int file_align = 1;
char *page_header = NULL;
LineEndType line_end = LE_CHAR_WRAP;
int line_numbers = 0;
unsigned int start_line_number = 1;
char *printer = NULL;
char printer_buf[256];
int special_escapes = 0;
int escape_char = '\0';
int default_escape_char;
int pretty_print = 0;
char *pp_start_state = NULL;
char pp_filter[4096];
char *Fname = "Courier";
FontPoint Fpt = {10.0, 10.0};
FontPoint default_Fpt;
char *default_Fname;
int user_body_font_defined = 0;
double font_widths[256];
char font_ctype[256];
int font_is_fixed;
double font_bbox_lly;
char *HFname = "Courier-Bold";
FontPoint HFpt = {10.0, 10.0};
HeaderType header = HDR_SIMPLE;
char *fancy_header_name = NULL;
char fancy_header_default[256];
static int no_job_header = 0;
unsigned int highlight_bars = 0;
double line_indent = 0.0;
char *line_indent_spec = "0";
char *input_filter = NULL;
int borders = 0;
int page_prefeed = 0;
unsigned int lines_per_page = (unsigned int) -1;
int mail = 0;
char *media_name = "A4";
char media_name_buffer[256];
int num_copies = 1;
int nl = -1;
char *output_file = OUTPUT_FILE_NONE;
int list_missing_characters = 0;
int quiet = 0;
int landscape = 0;
double baselineskip = 1.0;
char *title = "Enscript Output";
int title_given = 0;
int tabsize = 8;
double ul_gray = .8;
FontPoint ul_ptsize = {200.0, 200.0};
char *ul_font = "Times-Roman";
char *underlay = NULL;
char ul_position_buf[256];
char *ul_position = "+0-0";
double ul_x;
double ul_y;
double ul_angle;
unsigned int ul_style = UL_STYLE_OUTLINE;
char *ul_style_str = "outline";
char ul_style_str_buf[256];
int ul_position_p = 0;
int ul_angle_p = 0;
unsigned int nup = 1;
unsigned int nup_exp = 0;
unsigned int nup_rows = 1;
unsigned int nup_columns = 1;
int nup_landscape = 0;
unsigned int nup_width;
unsigned int nup_height;
double nup_scale;
int verbose = 0;
char *output_language = "PostScript";
int output_language_pass_through = 0;
InputEncoding encoding = ENC_ISO_8859_1;
char *encoding_name = "88591";
char encoding_name_buffer[256];
int interpret_formfeed = 1;
int pass_through = 0;
char *input_filter_stdin = "";
double horizontal_column_height = 283465.0;
int help_pretty_print = 0;
double highlight_bar_gray = .97;
int list_media = 0;
int list_options = 0;
char *margins_spec = NULL;
char mark_wrapped_lines_style_name[256] = {0};
MarkWrappedLinesStyle mark_wrapped_lines_style = MWLS_NONE;
char *npf_name = "octal";
char npf_name_buf[256];
NonPrintableFormat non_printable_format = NPF_OCTAL;
unsigned int nup_xpad = 10;
unsigned int nup_ypad = 10;
char *page_label_format = "short";
char page_label_format_buf[256];
PageLabelFormat page_label;
unsigned int pslevel = 2;
char *printer_options = NULL;
int rotate_even_pages = 0;
int slicing = 0;
unsigned int slice = 1;
int toc = 0;
char toc_fname[512];
FILE *toc_fp;
char *toc_fmt_string;
int accept_composites = 0;
int append_ctrl_D = 0;
int clean_7bit = 1;
FormFeedType formfeed_type = FORMFEED_COLUMN;
int generate_PageSize = 1;
char no_job_header_switch[16];
char output_first_line[256];
char queue_param[16];
char spooler_command[256];
char states_color_model[50];
char states_config_file[256];
char states_highlight_level[50];
char states_path[1024];
double line_highlight_gray = 1.0;
double bggray = 1.0;
static struct option long_options[] =
{
{"columns", required_argument, 0, 0},
{"pages", required_argument, 0, 'a'},
{"file-align", required_argument, 0, 'A'},
{"header", required_argument, 0, 'b'},
{"no-header", no_argument, 0, 'B'},
{"truncate-lines", no_argument, 0, 'c'},
{"line-numbers", optional_argument, 0, 'C'},
{"printer", required_argument, 0, 'd'},
{"setpagedevice", required_argument, 0, 'D'},
{"escapes", optional_argument, 0, 'e'},
{"pretty-print", optional_argument, 0, 'E'},
{"font", required_argument, 0, 'f'},
{"header-font", required_argument, 0, 'F'},
{"print-anyway", no_argument, 0, 'g'},
{"fancy-header", optional_argument, 0, 'G'},
{"no-job-header", no_argument, 0, 'h'},
{"highlight-bars", optional_argument, 0, 'H'},
{"indent", required_argument, 0, 'i'},
{"filter", required_argument, 0, 'I'},
{"borders", no_argument, 0, 'j'},
{"page-prefeed", no_argument, 0, 'k'},
{"no-page-prefeed", no_argument, 0, 'K'},
{"lineprinter", no_argument, 0, 'l'},
{"lines-per-page", required_argument, 0, 'L'},
{"mail", no_argument, 0, 'm'},
{"media", required_argument, 0, 'M'},
{"copies", required_argument, 0, 'n'},
{"newline", required_argument, 0, 'N'},
{"output", required_argument, 0, 'p'},
{"missing-characters", no_argument, 0, 'O'},
{"quiet", no_argument, 0, 'q'},
{"silent", no_argument, 0, 'q'},
{"landscape", no_argument, 0, 'r'},
{"portrait", no_argument, 0, 'R'},
{"baselineskip", required_argument, 0, 's'},
{"statusdict", required_argument, 0, 'S'},
{"title", required_argument, 0, 't'},
{"tabsize", required_argument, 0, 'T'},
{"underlay", optional_argument, 0, 'u'},
{"nup", required_argument, 0, 'U'},
{"verbose", optional_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"language", required_argument, 0, 'W'},
{"encoding", required_argument, 0, 'X'},
{"no-formfeed", no_argument, 0, 'z'},
{"pass-through", no_argument, 0, 'Z'},
{"color", optional_argument, 0, 142},
{"download-font", required_argument, 0, 131},
{"filter-stdin", required_argument, 0, 138},
{"h-column-height", required_argument, 0, 148},
{"help", no_argument, 0, 135},
{"help-pretty-print", no_argument, 0, 141},
{"highlight-bar-gray", required_argument, 0, 136},
{"list-media", no_argument, &list_media, 1},
{"list-options", no_argument, &list_options, 1},
{"margins", required_argument, 0, 144},
{"mark-wrapped-lines", optional_argument, 0, 143},
{"non-printable-format", required_argument, 0, 134},
{"nup-xpad", required_argument, 0, 145},
{"nup-ypad", required_argument, 0, 146},
{"page-label-format", required_argument, 0, 130},
{"ps-level", required_argument, 0, 149},
{"printer-options", required_argument, 0, 139},
{"rotate-even-pages", no_argument, 0, 150},
{"slice", required_argument, 0, 140},
{"toc", no_argument, &toc, 1},
{"word-wrap", no_argument, 0, 147},
{"ul-angle", required_argument, 0, 132},
{"ul-font", required_argument, 0, 128},
{"ul-gray", required_argument, 0, 129},
{"ul-position", required_argument, 0, 133},
{"ul-style", required_argument, 0, 137},
{NULL, 0, 0, 0},
};
static struct
{
char *names[3];
InputEncoding encoding;
int nl;
int bs;
} encodings[] =
{
{{"88591", "latin1", NULL}, ENC_ISO_8859_1, '\n', 8},
{{"88592", "latin2", NULL}, ENC_ISO_8859_2, '\n', 8},
{{"88593", "latin3", NULL}, ENC_ISO_8859_3, '\n', 8},
{{"88594", "latin4", NULL}, ENC_ISO_8859_4, '\n', 8},
{{"88595", "cyrillic", NULL}, ENC_ISO_8859_5, '\n', 8},
{{"88597", "greek", NULL}, ENC_ISO_8859_7, '\n', 8},
{{"ascii", NULL, NULL}, ENC_ASCII, '\n', 8},
{{"asciifise", "asciifi", "asciise"}, ENC_ASCII_FISE, '\n', 8},
{{"asciidkno", "asciidk", "asciino"}, ENC_ASCII_DKNO, '\n', 8},
{{"ibmpc", "pc", "dos"}, ENC_IBMPC, '\n', 8},
{{"mac", NULL, NULL}, ENC_MAC, '\r', 8},
{{"vms", NULL, NULL}, ENC_VMS, '\n', 8},
{{"hp8", NULL, NULL}, ENC_HP8, '\n', 8},
{{"koi8", NULL, NULL}, ENC_KOI8, '\n', 8},
{{"ps", "PS", NULL}, ENC_PS, '\n', 8},
{{"pslatin1", "ISOLatin1Encoding", NULL}, ENC_ISO_8859_1, '\n', 8},
{{NULL, NULL, NULL}, 0, 0, 0},
};
int
main (int argc, char *argv[])
{
InputStream is;
time_t tim;
struct tm *tm;
int i, j, found;
unsigned int ui;
MediaEntry *mentry;
AFMError afm_error;
char *cp, *cp2;
int retval = 0;
program = strrchr (argv[0], '/');
if (program == NULL)
program = argv[0];
else
program++;
argv[0] = program;
sprintf (version_string, "GNU %s %s", PACKAGE, VERSION);
strcpy (ps_version_string, VERSION);
cp = strrchr (ps_version_string, '.');
*cp = ' ';
toc_fmt_string = _("$3v $-40N $3% pages $4L lines $E $C");
#if HAVE_SETLOCALE
#if HAVE_LC_MESSAGES
setlocale (LC_MESSAGES, "");
#endif
#endif
#if ENABLE_NLS
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
tim = time (NULL);
tm = localtime (&tim);
memcpy (&run_tm, tm, sizeof (*tm));
sprintf (date_string, "%s", asctime (&run_tm));
i = strlen (date_string);
date_string[i - 1] = '\0';
passwd = getpwuid (getuid ());
if (passwd == NULL)
FATAL ((stderr, _("couldn't get passwd entry for uid=%d: %s"), getuid (),
strerror (errno)));
strcpy (spooler_command, "lpr");
strcpy (queue_param, "-P");
strcpy (no_job_header_switch, "-h");
strcpy (fancy_header_default, "enscript");
strcpy (output_first_line, "%!PS-Adobe-3.0");
cp = getenv ("ENSCRIPT_LIBRARY");
if (cp)
enscript_library = cp;
strcpy (states_color_model, "blackwhite");
sprintf (states_config_file, "%s/enscript.st", enscript_library);
strcpy (states_highlight_level, "heavy");
strcpy (states_path, "states");
sprintf (libpath, "%s%c%s/.enscript", enscript_library, PATH_SEPARATOR,
passwd->pw_dir);
res_fonts = strhash_init ();
download_fonts = strhash_init ();
pagedevice = strhash_init ();
statusdict = strhash_init ();
user_strings = strhash_init ();
#define CFG_FILE_NAME "enscript.cfg"
if (!read_config (SYSCONFDIR, CFG_FILE_NAME))
{
int saved_errno = errno;
if (!read_config (enscript_library, CFG_FILE_NAME))
{
if (!read_config ("../lib", CFG_FILE_NAME))
{
FATAL ((stderr, _("couldn't open config file \"%s/%s\": %s"),
enscript_library, CFG_FILE_NAME,
strerror (saved_errno)));
}
strcat (libpath, ":../lib");
}
}
(void) read_config (SYSCONFDIR, "enscriptsite.cfg");
(void) read_config (passwd->pw_dir, ".enscriptrc");
handle_env_options ("ENSCRIPT");
handle_env_options ("GENSCRIPT");
handle_options (argc, argv);
default_escape_char = escape_char;
found = 0;
for (i = 0; !found && encodings[i].names[0]; i++)
for (j = 0; j < 3; j++)
if (encodings[i].names[j] != NULL && MATCH (encodings[i].names[j],
encoding_name))
{
encoding = encodings[i].encoding;
encoding_name = encodings[i].names[0];
if (nl < 0)
nl = encodings[i].nl;
bs = encodings[i].bs;
found = 1;
break;
}
if (!found)
FATAL ((stderr, _("unknown encoding: %s"), encoding_name));
if (!user_body_font_defined && landscape && num_columns > 1)
Fpt.w = Fpt.h = 7.0;
afm_cache = strhash_init ();
afm_info_cache = strhash_init ();
afm_error = afm_create (afm_path, verbose, &afm);
if (afm_error != AFM_SUCCESS)
{
char buf[256];
afm_error_to_string (afm_error, buf);
FATAL ((stderr, _("couldn't open AFM library: %s"), buf));
}
default_Fpt.w = Fpt.w;
default_Fpt.h = Fpt.h;
default_Fname = Fname;
strhash_put (res_fonts, Fname, strlen (Fname) + 1, NULL, NULL);
strhash_put (res_fonts, HFname, strlen (HFname) + 1, NULL, NULL);
strhash_put (download_fonts, Fname, strlen (Fname) + 1, NULL, NULL);
strhash_put (download_fonts, HFname, strlen (HFname) + 1, NULL, NULL);
read_font_info ();
line_indent = parse_float (line_indent_spec, 1, 1);
if (list_media)
{
printf (_("known media:\n\
name width\theight\tllx\tlly\turx\tury\n\
------------------------------------------------------------\n"));
for (mentry = media_names; mentry; mentry = mentry->next)
printf ("%-16s %d\t%d\t%d\t%d\t%d\t%d\n",
mentry->name, mentry->w, mentry->h,
mentry->llx, mentry->lly, mentry->urx, mentry->ury);
exit (0);
}
for (mentry = media_names; mentry; mentry = mentry->next)
if (strcmp (media_name, mentry->name) == 0)
{
media = mentry;
break;
}
if (media == NULL)
FATAL ((stderr, _("do not know anything about media \"%s\""), media_name));
if (margins_spec)
{
for (i = 0; i < 4; i++)
{
if (*margins_spec == '\0')
break;
if (*margins_spec == ':')
{
margins_spec++;
continue;
}
j = atoi (margins_spec);
for (; *margins_spec != ':' && *margins_spec != '\0'; margins_spec++)
;
if (*margins_spec == ':')
margins_spec++;
switch (i)
{
case 0:
media->llx = j;
break;
case 1:
media->urx = media->w - j;
break;
case 2:
media->ury = media->h - j;
break;
case 3:
media->lly = j;
break;
}
}
MESSAGE (1,
(stderr,
_("set new marginals for media `%s' (%dx%d): llx=%d, lly=%d, urx=%d, ury=%d\n"),
media->name, media->w, media->h, media->llx, media->lly,
media->urx, media->ury));
}
if (MATCH (page_label_format, "short"))
page_label = LABEL_SHORT;
else if (MATCH (page_label_format, "long"))
page_label = LABEL_LONG;
else
FATAL ((stderr, _("illegal page label format \"%s\""), page_label_format));
if (MATCH (npf_name, "space"))
non_printable_format = NPF_SPACE;
else if (MATCH (npf_name, "questionmark"))
non_printable_format = NPF_QUESTIONMARK;
else if (MATCH (npf_name, "caret"))
non_printable_format = NPF_CARET;
else if (MATCH (npf_name, "octal"))
non_printable_format = NPF_OCTAL;
else
FATAL ((stderr, _("illegal non-printable format \"%s\""), npf_name));
if (mark_wrapped_lines_style_name[0])
{
if (MATCH (mark_wrapped_lines_style_name, "none"))
mark_wrapped_lines_style = MWLS_NONE;
else if (MATCH (mark_wrapped_lines_style_name, "plus"))
mark_wrapped_lines_style = MWLS_PLUS;
else if (MATCH (mark_wrapped_lines_style_name, "box"))
mark_wrapped_lines_style = MWLS_BOX;
else if (MATCH (mark_wrapped_lines_style_name, "arrow"))
mark_wrapped_lines_style = MWLS_ARROW;
else
FATAL ((stderr, _("illegal style for wrapped line marker: \"%s\""),
mark_wrapped_lines_style_name));
}
for (i = 0; ; i++)
{
ui = nup >> i;
if (ui == 0)
FATAL ((stderr, _("illegal N-up argument: %d"), nup));
if (ui & 0x1)
{
if (ui != 1)
FATAL ((stderr, _("N-up argument must be power of 2: %d"), nup));
nup_exp = i;
break;
}
}
nup_rows = nup_exp / 2 * 2;
if (nup_rows == 0)
nup_rows = 1;
nup_columns = (nup_exp + 1) / 2 * 2;
if (nup_columns == 0)
nup_columns = 1;
nup_landscape = nup_exp & 0x1;
if (landscape)
{
d_page_w = media->ury - media->lly;
d_page_h = media->urx - media->llx;
}
else
{
d_page_w = media->urx - media->llx;
d_page_h = media->ury - media->lly;
}
if (nup_landscape)
{
nup_width = media->ury - media->lly;
nup_height = media->urx - media->llx;
}
else
{
nup_width = media->urx - media->llx;
nup_height = media->ury - media->lly;
}
{
double w, h;
w = ((double) nup_width - (nup_columns - 1) * nup_xpad) / nup_columns;
h = ((double) nup_height - (nup_rows - 1) * nup_ypad) / nup_rows;
nup_width = w;
nup_height = h;
w = w / (media->urx - media->llx);
h = h / (media->ury - media->lly);
nup_scale = w < h ? w : h;
}
if (underlay != NULL)
{
strhash_put (res_fonts, ul_font, strlen (ul_font) + 1, NULL, NULL);
underlay = escape_string (underlay);
}
ul_x = strtod (ul_position, &cp);
if (cp == ul_position)
{
malformed_position:
FATAL ((stderr, _("malformed underlay position: %s"), ul_position));
}
if (ul_position[0] == '-')
ul_x += d_page_w;
ul_y = strtod (cp, &cp2);
if (cp2 == cp)
goto malformed_position;
if (cp[0] == '-')
ul_y += d_page_h;
if (!ul_angle_p)
ul_angle = (atan2 (-d_page_h, d_page_w) / 3.14159265 * 180);
if (strcmp (ul_style_str, "outline") == 0)
ul_style = UL_STYLE_OUTLINE;
else if (strcmp (ul_style_str, "filled") == 0)
ul_style = UL_STYLE_FILLED;
else
FATAL ((stderr, _("illegal underlay style: %s"), ul_style_str));
d_header_w = d_page_w;
switch (header)
{
case HDR_NONE:
d_header_h = 0;
break;
case HDR_SIMPLE:
d_header_h = HFpt.h * 1.5;
break;
case HDR_FANCY:
d_header_h = 36;
break;
}
if (help_pretty_print)
{
sprintf (pp_filter,
"%s -f \"%s\" -s describe_languages \"%s\"",
states_path, states_config_file, states_config_file);
system (pp_filter);
exit (0);
}
if (list_options)
{
do_list_options ();
exit (1);
}
if (output_language_pass_through)
{
char *start_state;
if (pp_start_state)
start_state = pp_start_state;
else if (pretty_print)
start_state = NULL;
else
start_state = "passthrough";
j = 0;
for (i = optind; i < argc; i++)
j += strlen (argv[i]) + 1;
j += 256;
cp = (char *) xmalloc (j);
sprintf (cp, "%s -f \"%s\" %s%s -Dcolormodel=%s -Dhl_level=%s -Dlanguage=%s -Dnum_input_files=%d -Ddocument_title=\"%s\" -Dtoc=%d",
states_path, states_config_file,
start_state ? "-s" : "",
start_state ? start_state : "",
states_color_model,
states_highlight_level,
output_language,
optind == argc ? 1 : argc - optind,
title,
toc);
for (i = optind; i < argc; i++)
{
strcat (cp, " ");
strcat (cp, argv[i]);
}
if (is_open (&is, stdin, NULL, cp))
{
open_output_file ();
process_file ("unused", &is);
is_close (&is);
}
}
else
{
if (pretty_print)
{
sprintf (pp_filter,
"%s -f \"%s\" %s%s -Dcolormodel=%s -Dhl_level=%s -Dfont_spec=%s@%g/%g \"%%s\"",
states_path,
states_config_file,
pp_start_state ? "-s " : "",
pp_start_state ? pp_start_state : "",
states_color_model,
states_highlight_level,
Fname, Fpt.w, Fpt.h);
input_filter = pp_filter;
input_filter_stdin = "-";
}
if (toc)
{
cp = tmpnam (toc_fname);
if (cp == NULL)
FATAL ((stderr, _("couldn't create toc file name: %s"),
strerror (errno)));
toc_fp = fopen (toc_fname, "w+b");
if (toc_fp == NULL)
FATAL ((stderr, _("couldn't create toc file \"%s\": %s"),
toc_fname, strerror (errno)));
if (remove (toc_fname) == 0)
toc_fname[0] = '\0';
}
if (optind == argc)
{
memcpy (&mod_tm, &run_tm, sizeof (run_tm));
if (is_open (&is, stdin, NULL, input_filter))
{
open_output_file ();
process_file (title_given ? title : "", &is);
is_close (&is);
}
}
else
{
for (; optind < argc; optind++)
{
if (is_open (&is, NULL, argv[optind], input_filter))
{
struct stat stat_st;
if (stat (argv[optind], &stat_st) == 0)
{
tim = stat_st.st_mtime;
tm = localtime (&tim);
memcpy (&mod_tm, tm, sizeof (*tm));
open_output_file ();
process_file (argv[optind], &is);
}
else
ERROR ((stderr, _("couldn't stat input file \"%s\": %s"),
argv[optind],
strerror (errno)));
is_close (&is);
}
}
}
if (toc)
{
toc = 0;
special_escapes = 1;
line_numbers = 0;
if (fseek (toc_fp, 0, SEEK_SET) != 0)
FATAL ((stderr, _("couldn't rewind toc file: %s"),
strerror (errno)));
memcpy (&mod_tm, &run_tm, sizeof (run_tm));
if (is_open (&is, toc_fp, NULL, NULL))
{
process_file (_("Table of Contents"), &is);
is_close (&is);
}
fclose (toc_fp);
if (toc_fname[0])
(void) remove (toc_fname);
}
dump_ps_trailer ();
if (ofp != NULL && append_ctrl_D)
fprintf (ofp, "\004\n");
}
close_output_file ();
if (ofp == NULL)
{
MESSAGE (0, (stderr, _("no output generated\n")));
}
else if (output_language_pass_through)
{
if (output_file == OUTPUT_FILE_NONE)
MESSAGE (0, (stderr, _("output sent to %s\n"),
printer ? printer : _("printer")));
else
MESSAGE (0, (stderr, _("output left in %s\n"),
output_file == OUTPUT_FILE_STDOUT ? "-" : output_file));
}
else
{
unsigned int real_total_pages;
if (nup > 1)
{
if (total_pages > 0)
real_total_pages = (total_pages - 1) / nup + 1;
else
real_total_pages = 0;
}
else
real_total_pages = total_pages;
MESSAGE (0, (stderr, _("[ %d pages * %d copy ]"), real_total_pages,
num_copies));
if (output_file == OUTPUT_FILE_NONE)
MESSAGE (0, (stderr, _(" sent to %s\n"),
printer ? printer : _("printer")));
else
MESSAGE (0, (stderr, _(" left in %s\n"),
output_file == OUTPUT_FILE_STDOUT ? "-" : output_file));
if (num_truncated_lines)
{
retval |= 2;
MESSAGE (0, (stderr, _("%d lines were %s\n"), num_truncated_lines,
line_end == LE_TRUNCATE
? _("truncated") : _("wrapped")));
}
if (num_missing_chars)
{
retval |= 4;
MESSAGE (0, (stderr, _("%d characters were missing\n"),
num_missing_chars));
if (list_missing_characters)
{
MESSAGE (0, (stderr, _("missing character codes (decimal):\n")));
do_list_missing_characters (missing_chars);
}
}
if (num_non_printable_chars)
{
retval |= 8;
MESSAGE (0, (stderr, _("%d non-printable characters\n"),
num_non_printable_chars));
if (list_missing_characters)
{
MESSAGE (0, (stderr,
_("non-printable character codes (decimal):\n")));
do_list_missing_characters (non_printable_chars);
}
}
}
return retval;
}
static void
open_output_file ()
{
if (ofp)
return;
if (output_file == OUTPUT_FILE_NONE)
{
char spooler_options[512];
spooler_options[0] = '\0';
if (mail)
strcat (spooler_options, "-m ");
if (no_job_header)
{
strcat (spooler_options, no_job_header_switch);
strcat (spooler_options, " ");
}
if (printer_options)
strcat (spooler_options, printer_options);
ofp = printer_open (spooler_command, spooler_options, queue_param,
printer, &printer_context);
if (ofp == NULL)
FATAL ((stderr, _("couldn't open printer `%s': %s"), printer,
strerror (errno)));
}
else if (output_file == OUTPUT_FILE_STDOUT)
ofp = stdout;
else
{
ofp = fopen (output_file, "w");
if (ofp == NULL)
FATAL ((stderr, _("couldn't create output file \"%s\": %s"),
output_file, strerror (errno)));
}
}
static void
close_output_file ()
{
if (ofp == NULL)
return;
if (output_file == OUTPUT_FILE_NONE)
printer_close (printer_context);
else if (output_file != OUTPUT_FILE_STDOUT)
fclose (ofp);
}
static void
handle_env_options (char *var)
{
int argc;
char **argv;
char *string;
char *str;
int i;
string = getenv (var);
if (string == NULL)
return;
MESSAGE (2, (stderr, "handle_env_options(): %s=\"%s\"\n", var, string));
str = xstrdup (string);
argc = (strlen (str) + 1) / 2 + 2;
argv = xcalloc (argc, sizeof (char *));
argc = 0;
argv[argc++] = program;
i = 0;
while (str[i])
{
for (; str[i] && isspace (str[i]); i++)
;
if (!str[i])
break;
if (str[i] == '"' || str[i] == '\'')
{
int endch = str[i++];
argv[argc++] = str + i;
for (; str[i] && str[i] != endch; i++)
;
if (!str[i])
FATAL ((stderr, _("syntax error in option string %s=\"%s\":\n\
missing end of quotation: %c"), var, string, endch));
str[i++] = '\0';
}
else
{
argv[argc++] = str + i;
for (; str[i] && !isspace (str[i]); i++)
;
if (str[i])
str[i++] = '\0';
}
}
argv[argc] = NULL;
MESSAGE (2, (stderr, "found following options (argc=%d):\n", argc));
for (i = 0; i < argc; i++)
MESSAGE (2, (stderr, "%3d = \"%s\"\n", i, argv[i]));
handle_options (argc, argv);
if (optind != argc)
{
MESSAGE (0,
(stderr,
_("warning: didn't process following options from \
environment variable %s:\n"),
var));
for (; optind < argc; optind++)
MESSAGE (0, (stderr, _(" option %d = \"%s\"\n"), optind,
argv[optind]));
}
xfree (argv);
}
static void
handle_options (int argc, char *argv[])
{
int c;
PageRange *prange;
optind = 0;
while (1)
{
int option_index = 0;
const char *cp;
c = getopt_long (argc, argv,
"#:12a:A:b:BcC::d:D:e::E::f:F:gGhH::i:I:jJ:kKlL:mM:n:N:o:Op:P:qrRs:S:t:T:u::U:vVW:X:zZ",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
cp = long_options[option_index].name;
if (strcmp (cp, "columns") == 0)
num_columns = atoi (optarg);
break;
case '1':
case '2':
num_columns = c - '0';
break;
case 'a':
prange = (PageRange *) xcalloc (1, sizeof (PageRange));
if (strcmp (optarg, "odd") == 0)
prange->odd = 1;
else if (strcmp (optarg, "even") == 0)
prange->even = 1;
else
{
cp = strchr (optarg, '-');
if (cp)
{
if (optarg[0] == '-')
prange->end = atoi (optarg + 1);
else if (cp[1] == '\0')
{
prange->start = atoi (optarg);
prange->end = (unsigned int) -1;
}
else
{
prange->start = atoi (optarg);
prange->end = atoi (cp + 1);
}
}
else
prange->start = prange->end = atoi (optarg);
}
prange->next = page_ranges;
page_ranges = prange;
break;
case 'A':
file_align = atoi (optarg);
if (file_align == 0)
FATAL ((stderr, _("file alignment must be larger than zero")));
break;
case 'b':
page_header = optarg;
break;
case 'B':
header = HDR_NONE;
break;
case 'c':
line_end = LE_TRUNCATE;
break;
case 'C':
line_numbers = 1;
if (optarg)
start_line_number = atoi (optarg);
break;
case 'd':
case 'P':
printer = optarg;
output_file = OUTPUT_FILE_NONE;
break;
case 'D':
parse_key_value_pair (pagedevice, optarg);
break;
case 'e':
special_escapes = 1;
if (optarg)
{
if (isdigit (optarg[0]))
escape_char = (int) strtoul (optarg, NULL, 0);
else
escape_char = ((unsigned char *) optarg)[0];
}
break;
case 'E':
pretty_print = 1;
special_escapes = 1;
escape_char = '\0';
pp_start_state = optarg;
break;
case 'f':
if (!parse_font_spec (optarg, &Fname, &Fpt))
FATAL ((stderr, _("malformed font spec: %s"), optarg));
user_body_font_defined = 1;
break;
case 'F':
if (!parse_font_spec (optarg, &HFname, &HFpt))
FATAL ((stderr, _("malformed font spec: %s"), optarg));
break;
case 'g':
break;
case 'G':
header = HDR_FANCY;
if (optarg)
fancy_header_name = optarg;
else
fancy_header_name = fancy_header_default;
if (!file_existsp (fancy_header_name, ".hdr"))
FATAL ((stderr,
_("couldn't find header definition file \"%s.hdr\""),
fancy_header_name));
break;
case 'h':
no_job_header = 1;
break;
case 'H':
if (optarg)
highlight_bars = atoi (optarg);
else
highlight_bars = 2;
break;
case 'i':
line_indent_spec = optarg;
break;
case 'I':
input_filter = optarg;
break;
case 'j':
borders = 1;
break;
case 'k':
page_prefeed = 1;
break;
case 'K':
page_prefeed = 0;
break;
case 'l':
lines_per_page = 66;
header = HDR_NONE;
break;
case 'L':
lines_per_page = atoi (optarg);
if (lines_per_page <= 0)
FATAL ((stderr,
_("must print at least one line per each page: %s"),
argv[optind]));
break;
case 'm':
mail = 1;
break;
case 'M':
media_name = optarg;
break;
case 'n':
case '#':
num_copies = atoi (optarg);
break;
case 'N':
if (!(optarg[0] == 'n' || optarg[0] == 'r') || optarg[1] != '\0')
{
fprintf (stderr, _("%s: illegal newline character specifier: \
'%s': expected 'n' or 'r'\n"),
program, optarg);
goto option_error;
}
if (optarg[0] == 'n')
nl = '\n';
else
nl = '\r';
break;
case 'o':
case 'p':
if (strcmp (optarg, "-") == 0)
output_file = OUTPUT_FILE_STDOUT;
else
output_file = optarg;
break;
case 'O':
list_missing_characters = 1;
break;
case 'q':
quiet = 1;
verbose = 0;
break;
case 'r':
landscape = 1;
break;
case 'R':
landscape = 0;
break;
case 's':
baselineskip = atof (optarg);
break;
case 'S':
parse_key_value_pair (statusdict, optarg);
break;
case 't':
case 'J':
title = optarg;
title_given = 1;
break;
case 'T':
tabsize = atoi (optarg);
if (tabsize <= 0)
tabsize = 1;
break;
case 'u':
underlay = optarg;
break;
case 'U':
nup = atoi (optarg);
break;
case 'v':
if (optarg)
verbose = atoi (optarg);
else
verbose++;
quiet = 0;
break;
case 'V':
version ();
exit (0);
break;
case 'W':
output_language = optarg;
if (strcmp (output_language, "PostScript") != 0)
output_language_pass_through = 1;
break;
case 'X':
encoding_name = optarg;
break;
case 'z':
interpret_formfeed = 0;
break;
case 'Z':
pass_through = 1;
break;
case 128:
if (!parse_font_spec (optarg, &ul_font, &ul_ptsize))
FATAL ((stderr, _("malformed font spec: %s"), optarg));
break;
case 129:
ul_gray = atof (optarg);
break;
case 130:
page_label_format = optarg;
break;
case 131:
strhash_put (download_fonts, optarg, strlen (optarg) + 1, NULL,
NULL);
break;
case 132:
ul_angle = atof (optarg);
ul_angle_p = 1;
break;
case 133:
ul_position = optarg;
ul_position_p = 1;
break;
case 134:
npf_name = optarg;
break;
case 135:
usage ();
exit (0);
break;
case 136:
highlight_bar_gray = atof (optarg);
break;
case 137:
ul_style_str = optarg;
break;
case 138:
input_filter_stdin = optarg;
break;
case 139:
printer_options = optarg;
break;
case 140:
slicing = 1;
slice = atoi (optarg);
if (slice <= 0)
FATAL ((stderr, _("slice must be greater than zero")));
break;
case 141:
help_pretty_print = 1;
break;
case 142:
if (optarg == NULL)
strcpy (states_color_model, "emacs");
else
strcpy (states_color_model, optarg);
break;
case 143:
if (optarg)
strcpy (mark_wrapped_lines_style_name, optarg);
else
mark_wrapped_lines_style = MWLS_BOX;
break;
case 144:
margins_spec = optarg;
break;
case 145:
nup_xpad = atoi (optarg);
break;
case 146:
nup_ypad = atoi (optarg);
break;
case 147:
line_end = LE_WORD_WRAP;
break;
case 148:
horizontal_column_height = atof (optarg);
formfeed_type = FORMFEED_HCOLUMN;
break;
case 149:
pslevel = atoi (optarg);
break;
case 150:
rotate_even_pages = 1;
break;
case '?':
option_error:
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program);
exit (1);
break;
default:
printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
FATAL ((stderr, "This is a bug!"));
break;
}
}
}
#define TF(val) ((val) ? 't' : 'f')
static void
do_list_options ()
{
int i, j;
char *cp, *cp2;
printf ("libpath=\"%s\"\n", libpath);
printf ("printer=\"%s\"\n", printer ? printer : "");
printf ("queue_param=\"%s\"\n", queue_param);
printf ("verbose=%d\n", verbose);
printf ("num_copies=%d\n", num_copies);
printf ("title=\"%s\"\n", title ? title : "");
printf ("columns=%d\n", num_columns);
printf ("line_numbers=#%c\n", TF (line_numbers));
printf ("mail=#%c\n", TF (mail));
printf ("quiet=#%c\n", TF (quiet));
printf ("landscape=#%c\n", TF (landscape));
printf ("header=");
switch (header)
{
case HDR_NONE:
printf ("none");
break;
case HDR_SIMPLE:
printf ("simple");
break;
case HDR_FANCY:
printf ("fancy (%s)", fancy_header_name);
break;
}
printf ("\n");
printf ("page_header=\"%s\"\n", page_header ? page_header : "");
printf ("font: name=%s size=%g/%gpt\n", Fname, Fpt.w, Fpt.h);
printf ("header font: name=%s size=%g/%gpt\n", HFname, HFpt.w, HFpt.h);
printf ("output_file=%s\n",
(output_file == OUTPUT_FILE_NONE
? "none"
: (output_file == OUTPUT_FILE_STDOUT
? "stdout"
: output_file)));
printf ("media=%s (w=%d, h=%d, llx=%d, lly=%d, urx=%d, ury=%d)\n",
media->name, media->w, media->h, media->llx, media->lly,
media->urx,media->ury);
printf ("encoding=%s\n", encoding_name);
printf ("interpret_formfeed=#%c\n", TF (interpret_formfeed));
printf ("pass_through=#%c\n", TF (pass_through));
printf ("spooler_command=\"%s\"\n", spooler_command);
printf ("special_escapes=#%c\n", TF (special_escapes));
printf ("tabsize=%d\n", tabsize);
printf ("baselineskip=%g\n", baselineskip);
printf ("statusdict: ");
for (i = strhash_get_first (statusdict, &cp, &j, (void **) &cp2); i;
i = strhash_get_next (statusdict, &cp, &j, (void **) &cp2))
printf ("%s %s ", cp2, cp);
printf ("\n");
printf ("setpagedevice: << ");
for (i = strhash_get_first (pagedevice, &cp, &j, (void **) &cp2); i;
i = strhash_get_next (pagedevice, &cp, &j, (void **) &cp2))
printf ("/%s %s ", cp, cp2);
printf (">>\n");
printf ("nl=%c\n", nl == '\n' ? 'n' : 'r');
printf ("AFM path=%s\n", afm_path ? afm_path : "(default)");
printf ("underlay=(%s)\n", underlay ? underlay : "");
printf ("ul_gray=%g\n", ul_gray);
printf ("ul_font=%s %g/%gpt\n", ul_font, ul_ptsize.w, ul_ptsize.h);
printf ("ul_position=%s (%g, %g)\n", ul_position, ul_x, ul_y);
printf ("ul_angle=%g\n", ul_angle);
printf ("download-fonts:");
for (i = strhash_get_first (download_fonts, &cp, &j, (void **) &cp2); i;
i = strhash_get_next (download_fonts, &cp, &j, (void **) &cp2))
printf (" %s", cp);
printf ("\n");
}
static void
usage ()
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
Mandatory arguments to long options are mandatory for short options too.\n\
-# an alias for option -n, --copies\n\
-1 same as --columns=1\n\
-2 same as --columns=2\n\
--columns=NUM specify the number of columns per page\n\
-a, --pages=PAGES specify which pages are printed\n\
-A, --file-align=ALIGN align separate input files to ALIGN\n\
-b, --header=HEADER set page header\n\
-B, --no-header no page headers\n\
-c, --truncate-lines cut long lines (default is to wrap)\n\
-C, --line-numbers[=START]\n\
precede each line with its line number\n\
-d an alias for option --printer\n\
-D, --setpagedevice=KEY[:VALUE]\n\
pass a page device definition to output\n\
-e, --escapes[=CHAR] enable special escape interpretation\n"),
program);
printf (_("\
-E, --pretty-print[=LANG] pretty-print source code\n"));
printf (_("\
-f, --font=NAME use font NAME for body text\n\
-F, --header-font=NAME use font NAME for header texts\n\
-g, --print-anyway nothing (compatibility option)\n\
-G same as --fancy-header\n\
--fancy-header[=NAME] select fancy page header\n\
-h, --no-job-header suppress the job header page\n\
-H, --highlight-bars=NUM specify how high highlight bars are\n\
-i, --indent=NUM set line indent to NUM characters\n\
-I, --filter=CMD read input files through input filter CMD\n\
-j, --borders print borders around columns\n\
-J, an alias for option --title\n\
-k, --page-prefeed enable page prefeed\n\
-K, --no-page-prefeed disable page prefeed\n\
-l, --lineprinter simulate lineprinter, this is an alias for:\n\
--lines-per-page=66, --no-header, --portrait,\n\
--columns=1\n"));
printf (_("\
-L, --lines-per-page=NUM specify how many lines are printed on each page\n\
-m, --mail send mail upon completion\n\
-M, --media=NAME use output media NAME\n\
-n, --copies=NUM print NUM copies of each page\n\
-N, --newline=NL select the newline character. Possible\n\
values for NL are: n (`\\n') and r (`\\r').\n\
-o an alias for option --output\n\
-O, --missing-characters list missing characters\n\
-p, --output=FILE leave output to file FILE. If FILE is `-',\n\
leave output to stdout.\n\
-P, --printer=NAME print output to printer NAME\n\
-q, --quiet, --silent be really quiet\n\
-r, --landscape print in landscape mode\n\
-R, --portrait print in portrait mode\n"));
printf (_("\
-s, --baselineskip=NUM set baselineskip to NUM\n\
-S, --statusdict=KEY[:VALUE]\n\
pass a statusdict definition to the output\n\
-t, --title=TITLE set banner page's job title to TITLE. Option\n\
sets also the name of the input file stdin.\n\
-T, --tabsize=NUM set tabulator size to NUM\n\
-u, --underlay[=TEXT] print TEXT under every page\n\
-U, --nup=NUM print NUM logical pages on each output page\n\
-v, --verbose tell what we are doing\n\
-V, --version print version number\n\
-W, --language=LANG set output language to LANG\n\
-X, --encoding=NAME use input encoding NAME\n\
-z, --no-formfeed do not interpret form feed characters\n\
-Z, --pass-through pass through PostScript and PCL files\n\
without any modifications\n"));
printf (_("Long-only options:\n\
--color[=COLOR] set output color model to COLOR\n\
--download-font=NAME download font NAME\n\
--filter-stdin=NAME specify how stdin is shown to the input filter\n\
--h-column-height=HEIGHT set the horizontal column height to HEIGHT\n\
--help print this help and exit\n\
--help-pretty-print describe all supported --pretty-print languages\n\
and file formats\n\
--highlight-bar-gray=NUM print highlight bars with gray NUM (0 - 1)\n\
--list-media list names of all known media\n\
--list-options list all options and their values\n\
--margins=LEFT:RIGHT:TOP:BOTTOM\n\
adjust page marginals\n\
--mark-wrapped-lines[STYLE]\n\
mark wrapped lines in the output with STYLE\n\
--non-printable-format=FMT specify how non-printable chars are printed\n"));
printf (_("\
--nup-xpad=NUM set the page x-padding of N-up printing to NUM\n\
--nup-ypad=NUM set the page y-padding of N-up printing to NUM\n\
--page-label-format=FMT set page label format to FMT\n\
--ps-level=LEVEL set the PostScript language level that enscript\n\
should use\n\
--printer-options=OPTIONS pass extra options to the printer command\n\
--rotate-even-pages rotate even-numbered pages 180 degrees\n"));
printf (_("\
--slice=NUM print vertical slice NUM\n\
--toc print table of contents\n\
--ul-angle=ANGLE set underlay text's angle to ANGLE\n\
--ul-font=NAME print underlays with font NAME\n\
--ul-gray=NUM print underlays with gray value NUM\n\
--ul-position=POS set underlay's starting position to POS\n\
--ul-style=STYLE print underlays with style STYLE\n\
--word-wrap wrap long lines from word boundaries\n\
"));
printf (_("\nReport bugs to mtr@iki.fi.\n"));
}
static void
version ()
{
printf ("%s\n\
Copyright (C) 1998 Markku Rossi.\n\
GNU enscript comes with NO WARRANTY, to the extent permitted by law.\n\
You may redistribute copies of GNU enscript under the terms of the GNU\n\
General Public License. For more information about these matters, see\n\
the files named COPYING.\n",
version_string);
}