states.man: Escape backslashes in namerules and startrules examples.
[enscript.git] / src / gsint.h
1 /*
2  * Internal header file.
3  * Copyright (c) 1995-2000 Markku Rossi.
4  *
5  * Author: Markku Rossi <mtr@iki.fi>
6  */
7
8 /*
9  * This file is part of GNU Enscript.
10  *
11  * Enscript is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * Enscript is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
23  */
24
25 #ifndef GSINT_H
26 #define GSINT_H
27
28 /*
29  * Config stuffs.
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include <stdio.h>
37
38 #include <sys/types.h>
39 #include <sys/stat.h>
40
41 #ifndef ___P
42 #if PROTOTYPES
43 #define ___P(protos) protos
44 #else /* no PROTOTYPES */
45 #define ___P(protos) ()
46 #endif /* no PROTOTYPES */
47 #endif
48
49 #if STDC_HEADERS
50
51 #include <stdlib.h>
52 #include <string.h>
53
54 #else /* no STDC_HEADERS */
55
56 #if HAVE_STDLIB_H
57 #include <stdlib.h>
58 #endif
59
60 #if HAVE_STRING_H
61 #include <string.h>
62 #endif
63
64 #ifndef HAVE_STRCHR
65 #define strchr index
66 #define strrchr rindex
67 #endif
68 char *strchr ();
69 char *strrchr ();
70
71 #ifndef HAVE_STRERROR
72 extern char *strerror ___P ((int));
73 #endif
74
75 #ifndef HAVE_MEMMOVE
76 extern void *memmove ___P ((void *, void *, size_t));
77 #endif
78
79 #ifndef HAVE_MEMCPY
80 extern void *memcpy ___P ((void *, void *, size_t));
81 #endif
82
83 #endif /* no STDC_HEADERS */
84
85 #if HAVE_UNISTD_H
86 #include <unistd.h>
87 #endif
88
89 #if HAVE_MATH_H
90 #include <math.h>
91 #else
92 extern double atan2 ___P ((double, double));
93 #endif
94
95 #include <errno.h>
96 #include <time.h>
97 #include <assert.h>
98 #include <ctype.h>
99
100 #if HAVE_PWD_H
101 #include <pwd.h>
102 #else
103 #include "dummypwd.h"
104 #endif
105
106 #if ENABLE_NLS
107 #include <libintl.h>
108 #define _(String) gettext (String)
109 #else
110 #define _(String) String
111 #endif
112
113 #if HAVE_LC_MESSAGES
114 #include <locale.h>
115 #endif
116
117 #ifndef HAVE_GETCWD
118 #if HAVE_GETWD
119 #define getcwd(buf, len) getwd(buf)
120 #endif /* HAVE_GETWD */
121 #endif /* not HAVE_GETCWD */
122
123 #include "afm.h"
124 #include "strhash.h"
125 #include "xalloc.h"
126
127 /*
128  * Types and definitions.
129  */
130
131 #define MATCH(a, b) (strcmp (a, b) == 0)
132
133 #define ISNUMBERDIGIT(ch) \
134   (('0' <= (ch) && (ch) <= '9') || (ch) == '.' || (ch) == '-' || (ch) == '+')
135
136 /* Return the width of the character <ch> */
137 #define CHAR_WIDTH(ch) (font_widths[(unsigned char) (ch)])
138
139 /* Current point y movement from line to line. */
140 #define LINESKIP (Fpt.h + baselineskip)
141
142
143 /* Constants for output files. */
144 #define OUTPUT_FILE_NONE   NULL
145 #define OUTPUT_FILE_STDOUT ((char *) 1)
146
147 /* Underlay styles. */
148 #define UL_STYLE_OUTLINE        0
149 #define UL_STYLE_FILLED         1
150
151 struct media_entry_st
152 {
153   struct media_entry_st *next;
154   char *name;
155   int w;
156   int h;
157   int llx;
158   int lly;
159   int urx;
160   int ury;
161 };
162
163 typedef struct media_entry_st MediaEntry;
164
165 typedef enum
166 {
167   HDR_NONE,
168   HDR_SIMPLE,
169   HDR_FANCY
170 } HeaderType;
171
172
173 typedef enum
174 {
175   ENC_ISO_8859_1,
176   ENC_ISO_8859_2,
177   ENC_ISO_8859_3,
178   ENC_ISO_8859_4,
179   ENC_ISO_8859_5,
180   ENC_ISO_8859_7,
181   ENC_ISO_8859_9,
182   ENC_ISO_8859_10,
183   ENC_ASCII,
184   ENC_ASCII_FISE,
185   ENC_ASCII_DKNO,
186   ENC_IBMPC,
187   ENC_MAC,
188   ENC_VMS,
189   ENC_HP8,
190   ENC_KOI8,
191   ENC_PS
192 } InputEncoding;
193
194 struct encoding_registry_st
195 {
196   char *names[3];
197   InputEncoding encoding;
198   int nl;
199   int bs;
200 };
201
202 typedef struct encoding_registry_st EncodingRegistry;
203
204 typedef enum
205 {
206   LABEL_SHORT,
207   LABEL_LONG
208 } PageLabelFormat;
209
210 typedef enum
211 {
212   MWLS_NONE     = 0,
213   MWLS_PLUS     = 1,
214   MWLS_BOX      = 2,
215   MWLS_ARROW    = 3
216 } MarkWrappedLinesStyle;
217
218 typedef enum
219 {
220   NPF_SPACE,
221   NPF_QUESTIONMARK,
222   NPF_CARET,
223   NPF_OCTAL
224 } NonPrintableFormat;
225
226 typedef enum
227 {
228   FORMFEED_COLUMN,
229   FORMFEED_PAGE,
230   FORMFEED_HCOLUMN
231 } FormFeedType;
232
233 typedef enum
234 {
235   LE_TRUNCATE,
236   LE_CHAR_WRAP,
237   LE_WORD_WRAP
238 } LineEndType;
239
240 struct buffer_st
241 {
242   char *data;
243   size_t allocated;
244   size_t len;
245 };
246
247 typedef struct buffer_st Buffer;
248
249 struct file_lookup_ctx_st
250 {
251   /* The name of the file to lookup. */
252   char *name;
253
254   /* The suffix of the file.  This string is appended to <name>. */
255   char *suffix;
256
257   /* Buffer to which the name of the file is constructed.  If the
258      file_lookup() returns 1, the name of the file is here.  The
259      caller of the file_lookup() must allocate this buffer. */
260   Buffer *fullname;
261 };
262
263 typedef struct file_lookup_ctx_st FileLookupCtx;
264
265 typedef int (*PathWalkProc) ___P ((char *path, void *context));
266
267
268 struct input_stream_st
269 {
270   int is_pipe;                  /* Is <fp> opened to pipe? */
271   FILE *fp;
272   unsigned char buf[4096];
273   unsigned int data_in_buf;
274   unsigned int bufpos;
275   unsigned int nreads;
276   unsigned char *unget_ch;
277   unsigned int unget_pos;
278   unsigned int unget_alloc;
279 };
280
281 typedef struct input_stream_st InputStream;
282
283
284 struct page_range_st
285 {
286   struct page_range_st *next;
287   int odd;
288   int even;
289   unsigned int start;
290   unsigned int end;
291 };
292
293 typedef struct page_range_st PageRange;
294
295 struct font_point_st
296 {
297   double w;                     /* width */
298   double h;                     /* height */
299 };
300
301 typedef struct font_point_st FontPoint;
302
303 struct color_st
304 {
305   float r;
306   float g;
307   float b;
308 };
309
310 typedef struct color_st Color;
311
312 struct cached_font_info_st
313 {
314   double font_widths[256];
315   char font_ctype[256];
316   AFMBoolean font_is_fixed;
317   AFMNumber font_bbox_lly;
318 };
319
320 typedef struct cached_font_info_st CachedFontInfo;
321
322
323 /*
324  * Global variables.
325  */
326
327 extern char *program;
328 extern FILE *ofp;
329 extern char *version_string;
330 extern char *ps_version_string;
331 extern char *date_string;
332 extern struct tm run_tm;
333 extern struct tm mod_tm;
334 extern struct passwd *passwd;
335 extern char *libpath;
336 extern char *afm_path;
337 extern MediaEntry *media_names;
338 extern MediaEntry *media;
339 extern char *no_job_header_switch;
340 extern char *output_first_line;
341 extern char *queue_param;
342 extern char *spooler_command;
343 extern int nl;
344 extern int bs;
345 extern unsigned int current_pagenum;
346 extern unsigned int input_filenum;
347 extern unsigned int current_file_linenum;
348 extern char *fname;
349
350 /* Statistics. */
351 extern int total_pages;
352 extern int num_truncated_lines;
353 extern int num_missing_chars;
354 extern int missing_chars[];
355 extern int num_non_printable_chars;
356 extern int non_printable_chars[];
357
358 /* Dimensions that are used during PostScript generation. */
359 extern int d_page_w;
360 extern int d_page_h;
361 extern int d_header_w;
362 extern int d_header_h;
363 extern int d_footer_h;
364 extern int d_output_w;
365 extern int d_output_h;
366 extern int d_output_x_margin;
367 extern int d_output_y_margin;
368 extern unsigned int nup_xpad;
369 extern unsigned int nup_ypad;
370
371 /* Document needed resources. */
372 extern StringHashPtr res_fonts;
373
374 /* Fonts to download. */
375 extern StringHashPtr download_fonts;
376
377 /* Additional key-value pairs, passed to the generated PostScript code. */
378 extern StringHashPtr pagedevice;
379 extern StringHashPtr statusdict;
380
381 /* User defined strings. */
382 extern StringHashPtr user_strings;
383
384 /* Cache for AFM files. */
385 extern StringHashPtr afm_cache;
386 extern StringHashPtr afm_info_cache;
387
388 /* AFM library handle. */
389 extern AFMHandle afm;
390
391 /* Fonts. */
392 extern char *HFname;
393 extern FontPoint HFpt;
394 extern char *Fname;
395 extern FontPoint Fpt;
396 extern FontPoint default_Fpt;
397 extern char *default_Fname;
398 extern InputEncoding default_Fencoding;
399
400 extern double font_widths[];
401 extern char font_ctype[];
402 extern int font_is_fixed;
403 extern double font_bbox_lly;
404
405 /* Known input encodings. */
406 extern EncodingRegistry encodings[];
407
408 /* Options. */
409
410 extern char *printer;
411 extern int verbose;
412 extern int num_copies;
413 extern char *title;
414 extern int num_columns;
415 extern LineEndType line_end;
416 extern int quiet;
417 extern int landscape;
418 extern HeaderType header;
419 extern char *fancy_header_name;
420 extern char *fancy_header_default;
421 extern double line_indent;
422 extern char *page_header;
423 extern char *page_footer;
424 extern char *output_file;
425 extern unsigned int lines_per_page;
426 extern InputEncoding encoding;
427 extern char *media_name;
428 extern char *encoding_name;
429 extern int special_escapes;
430 extern int escape_char;
431 extern int default_escape_char;
432 extern int tabsize;
433 extern double baselineskip;
434 extern FontPoint ul_ptsize;
435 extern double ul_gray;
436 extern char *ul_font;
437 extern char *underlay;
438 extern char *ul_position;
439 extern double ul_x;
440 extern double ul_y;
441 extern double ul_angle;
442 extern unsigned int ul_style;
443 extern char *ul_style_str;
444 extern int ul_position_p;
445 extern int ul_angle_p;
446 extern PageLabelFormat page_label;
447 extern char *page_label_format;
448 extern int pass_through;
449 extern int line_numbers;
450 extern unsigned int start_line_number;
451 extern int interpret_formfeed;
452 extern NonPrintableFormat non_printable_format;
453 extern MarkWrappedLinesStyle mark_wrapped_lines_style;
454 extern char *mark_wrapped_lines_style_name;
455 extern char *npf_name;
456 extern int clean_7bit;
457 extern int append_ctrl_D;
458 extern unsigned int highlight_bars;
459 extern double highlight_bar_gray;
460 extern int page_prefeed;
461 extern PageRange *page_ranges;
462 extern int borders;
463 extern double line_highlight_gray;
464 extern double bggray;
465 extern int accept_composites;
466 extern FormFeedType formfeed_type;
467 extern char *input_filter_stdin;
468 extern int toc;
469 extern FILE *toc_fp;
470 extern char *toc_fmt_string;
471 extern unsigned int file_align;
472 extern int slicing;
473 extern unsigned int slice;
474
475 extern char *states_binary;
476 extern int states_color;
477 extern char *states_config_file;
478 extern char *states_highlight_style;
479 extern char *states_path;
480
481 extern unsigned int nup;
482 extern unsigned int nup_rows;
483 extern unsigned int nup_columns;
484 extern int nup_landscape;
485 extern unsigned int nup_width;
486 extern unsigned int nup_height;
487 extern double nup_scale;
488 extern int nup_columnwise;
489 extern char *output_language;
490 extern int output_language_pass_through;
491 extern int generate_PageSize;
492 extern double horizontal_column_height;
493 extern unsigned int pslevel;
494 extern int rotate_even_pages;
495 extern int swap_even_page_margins;
496 extern int continuous_page_numbers;
497
498 \f
499 /*
500  * Prototypes for global functions.
501  */
502
503 /* Print message if <verbose> is >= <verbose_level>. */
504 #define MESSAGE(verbose_level, body)            \
505   do {                                          \
506     if (!quiet && verbose >= (verbose_level))   \
507       fprintf body;                             \
508   } while (0)
509
510 /* Report continuable error. */
511 #define ERROR(body)                     \
512   do {                                  \
513     fprintf (stderr, "%s: ", program);  \
514     fprintf body;                       \
515     fprintf (stderr, "\n");             \
516     fflush (stderr);                    \
517   } while (0)
518
519 /* Report fatal error and exit with status 1.  Function never returns. */
520 #define FATAL(body)                     \
521   do {                                  \
522     fprintf (stderr, "%s: ", program);  \
523     fprintf body;                       \
524     fprintf (stderr, "\n");             \
525     fflush (stderr);                    \
526     exit (1);                           \
527   } while (0)
528
529 /*
530  * Read config file <path, name>.  Returns bool.  If function fails, error
531  * is found from errno.
532  */
533 int read_config ___P ((char *path, char *name));
534
535 /* Print PostScript header to our output stream. */
536 void dump_ps_header ___P ((void));
537
538 /* Print PostScript trailer to our output stream. */
539 void dump_ps_trailer ___P ((void));
540
541 /*
542  * Open InputStream to <fp> or <fname>.  If <input_filter> is given
543  * it is used to pre-filter the incoming data stream.  Function returns
544  * 1 if stream could be opened or 0 otherwise.
545  */
546 int is_open ___P ((InputStream *is, FILE *fp, char *fname,
547                    char *input_filter));
548
549 /* Close InputStream <is>. */
550 void is_close ___P ((InputStream *is));
551
552 /*
553  * Read next character from the InputStream <is>.  Returns EOF if
554  * EOF was reached.
555  */
556 int is_getc ___P ((InputStream *is));
557
558 /*
559  * Put character <ch> back to the InputStream <is>.  Function returns EOF
560  * if character couldn't be unget.
561  */
562 int is_ungetc ___P ((int ch, InputStream *is));
563
564
565 void buffer_init ___P ((Buffer *buffer));
566
567 void buffer_uninit ___P ((Buffer *buffer));
568
569 Buffer *buffer_alloc ();
570
571 void buffer_free ___P ((Buffer *buffer));
572
573 void buffer_append ___P ((Buffer *buffer, const char *data));
574
575 void buffer_append_len ___P ((Buffer *buffer, const char *data, size_t len));
576
577 char *buffer_copy ___P ((Buffer *buffer));
578
579 void buffer_clear ___P ((Buffer *buffer));
580
581 char *buffer_ptr ___P ((Buffer *buffer));
582
583 size_t buffer_len ___P ((Buffer *buffer));
584
585
586 /*
587  * Process single input file <fp>.  File's name is given in <fname> and
588  * it is used to print headers.  The argument <is_toc> specifies whether
589  * the file is a table of contents file or not.
590  */
591 void process_file ___P ((char *fname, InputStream *fp, int is_toc));
592
593 /* Add a new media to the list of known media. */
594 void add_media ___P ((char *name, int w, int h, int llx, int lly, int urx,
595                       int ury));
596
597 /* Print a listing of missing characters. */
598 void do_list_missing_characters ___P ((int *array));
599
600 /*
601  * Check if file <name, suffix> exists.  Returns bool.  If function fails
602  * error can be found from errno.
603  */
604 int file_existsp ___P ((char *name, char *suffix));
605
606 /*
607  * Paste file <name, suffix> to output stream.  Returns bool. If
608  * function fails, error can be found from errno.
609  */
610 int paste_file ___P ((char *name, char *suffix));
611
612 /*
613  * Do tilde substitution for filename <fname>.  The function returns a
614  * xmalloc()ated result that must be freed by the caller.
615  */
616 char *tilde_subst ___P ((char *fname));
617
618 /*
619  * Parse one float dimension from string <string>.  If <units> is true,
620  * then number can be followed by an optional unit specifier.  If
621  * <horizontal> is true, then dimension is horizontal, otherwise it
622  * is vertical.
623  */
624 double parse_float ___P ((char *string, int units, int horizontal));
625
626 /*
627  * Parse font spec <spec> and return font's name, size, and encoding
628  * in variables <name_return>, <size_return>, and <encoding_return>.
629  * Returns 1 if <spec> was a valid font spec or 0 otherwise.  Returned
630  * name <name_return> is allocated with xcalloc() and must be freed by
631  * caller.
632  */
633 int parse_font_spec ___P ((char *spec, char **name_return,
634                            FontPoint *size_return,
635                            InputEncoding *encoding_return));
636
637 /*
638  * Read body font's character widths and character codes from AFM files.
639  */
640 void read_font_info ___P ((void));
641
642 /*
643  * Try to download font <name>.
644  */
645 void download_font ___P ((char *name));
646
647 /*
648  * Escape all PostScript string's special characters from string <string>.
649  * Returns a xmalloc()ated result.
650  */
651 char *escape_string ___P ((char *string));
652
653 /*
654  * Expand user escapes from string <string>.  Returns a xmalloc()ated
655  * result.
656  */
657 char *format_user_string ___P ((char *context_name, char *string));
658
659 /*
660  * Parses key-value pair <kv> and inserts/deletes key from <set>.
661  */
662 void parse_key_value_pair ___P ((StringHashPtr set, char *kv));
663
664 /*
665  * Count how many non-empty items there are in the key-value set <set>.
666  */
667 int count_key_value_set ___P ((StringHashPtr set));
668
669 /*
670  * Walk through path <path> and call <proc> once for each of its
671  * components.  Function returns 0 if all components were accessed.
672  * Callback <proc> can interrupt walking by returning a non zero
673  * return value.  In that case value is returned as the return value
674  * of the pathwalk().
675  */
676 int pathwalk ___P ((char *path, PathWalkProc proc, void *context));
677
678 /* Lookup file from path.  <context> must point to FileLookupCtx. */
679 int file_lookup ___P ((char *path, void *context));
680
681
682 /*
683  * Portable printer interface.
684  */
685
686 /*
687  * Open and initialize printer <cmd>, <options>, <queue_param> and
688  * <printer_name>.  Function returns a FILE pointer to which enscript
689  * can generate its PostScript output or NULL if printer
690  * initialization failed.  Command can store its context information
691  * to variable <context_return> wich is passed as an argument to the
692  * printer_close() function.
693  */
694 FILE *printer_open ___P ((char *cmd, char *options, char *queue_param,
695                           char *printer_name, void **context_return));
696
697 /*
698  * Flush all pending output to printer <context> and close it.
699  */
700 void printer_close ___P ((void *context));
701
702 /*
703  * Escape filenames for shell usage
704  */
705 char *shell_escape ___P ((const char *fn));
706
707 #endif /* not GSINT_H */