/*** file = ipfe.c ********************************************/ /*** start of specifications ************************************ * * name = ipfe * descriptive name = interpress file editor * filename = ipfe.c * module type = main * subsystem name = interpress toolkit * copyright = (c) 1985, 1986, xerox corporation * author = mark l. rollins * date written = 10/oct/85 * * change activity = * 07/18/86 r1.05 mlr wrc: changed so Scale follows, rather than * precedes, Rotate, BindingOffset, XOffset, * and YOffset in output processing * 06/16/86 r1.04 mlr wrc: add Scale processing * 05/19/86 r1.03 mlr wrc: fixed bug in dsply of Y-offset values * 04/22/86 r1.02 mlr wrc: fixed bug in pagerange parsing that gave * error on terminating "]"; * add vers display * 03/14/86 r1.01 mlr wrc: major enhancements * 10/10/85 r1.00 mlr wrc: original date * * release = r1.05 * date = 18/jul/86 * * function = provide the following skeleton- and page-level functions * for editing interpress masters: * . concatenate masters * . merge pages from multiple masters into one master * . overlay selected pages as a single page (may be * combined with merge function) * . chapterize a master into multiple masters * . satisfy sequenceInsertFile & sequenceInsertMaster * references * . resolve alias and binding offset printing instructions * . return information about the properties of a set of * masters * * function description = * * Usage: ipfe [ options ] file [ pagerange] ... [ file [pagerange] ...] * Options: [-l logfile] [-dDiLqrRsS] [-a alias:actual [-a alias:actual] * ...] [-b offset:unit] [-c count:unit] [-o outfile] * [-p level:propfile] [-S factor] [-X offset:unit] * [-Y offset:unit] * * -a alias:actual * (alias). If the -s option is specified, * replace any SIF matching the string "alias" * with the string "actual" before attempting * to satisfy the SIF. If "actual" cannot be * opened or there is some error, the SIF * "alias" is preserved, unless the -r option * is also specified. * -b offset:unit (binding offset). Shift the image offset units * in the x-direction, where unit may be: none * (default centimeters), c (centimeters), i * (inches), p (points), P (Picas). If the -L * (Landscape) switch is set, the image offset * is in the y-direction. * -c count:unit (chapterize) every count units, where unit may * be p (pages), k (kilobytes), or m (megabytes). * -d (duplex). For resolving binding offset. * -D (Debug). If the -p option is specified, also * write to the properties file the offsets of * each skeleton-level token encountered. * -i (insert SIF for overlay). Insert (create) a * SIF for any unresolvable overlays. * -l logfile (log). Keep a running log. * -L (Landscape). Rotate every page 90 degrees * counterclockwise and preserve the upper left * corner. Intended for printing text in * landscape orientation. * -o outfile (output). Where the output goes. If there is * no -o and there is a -p, only the properties * are written, else if there is no -o * "infile.ip" is used if it doesn't already * exist, else "infileN.ip" is used, where N * is the lowest ordinal number such that * "infileN.ip" does not already exist. * -p level:propfile * (properties). Where the properties are * written. Increasing levels provide increasing * information details. * -q (quiet). Don't write info & error msgs (to * STDERR). * -r (remove SIFS). If -s is also specified, it * takes precedence and a SIF reference is * removed only if it is unresolved or there is * some other error. * -R (Rotate). Rotate every page 90 degrees * clockwise and preserve the center point. * Intended for rotating an image created for * a "landscape printer" to print in portrait * orientation. * -s (satisfy SIFS). Replace any SIF references * tokens found in the referenced file. If the * referenced file cannot be opened, the SIF * reference is preserved unless -r is also * specified. * -S factor (scale). Scale the image by factor. * -X offset:unit (X-imageShift). Shift the image offset units * in the x-direction, where unit may be: none * (default centimeters), c (centimeters), i * (inches), p (points), P (Picas). The shift * is independent of the -L and -R switches * (i.e., the x-direction is the same as the * unrotated image). * -Y offset:unit (Y-imageShift). Shift the image offset units * in the y-direction, where unit may be: none * (default centimeters), c (centimeters), i * (inches), p (points), P (Picas). The shift * is independent of the -L and -R switches * (i.e., the y-direction is the same as the * unrotated image). * infile [pagerange] * See the manual page for syntax details. * Example: * [1,4-6,9[pic1],10-11,12[pic2:2(2P,4P)][pic3(-4P,-2P)],15-] * include page 1. * skip pages 2-3. * include pages 4-6. * skip pages 7-8. * include page 9, overlaying it with pic1. * include pages 10-11. * include pages 12, overlaying it with page 2 of * pic2 at an offset of 2 Picas to the right * and 4 Picas up, and pic3 at an offset of * 4 Picas to the left and 2 Picas down. * skip pages 13-14. * include pages 15 thru the end of the master. * * linkage = * entry = exec ipfe * input = see cmd line options above * output = interpress master(s), STDERR, log file, property file * exit = exit(exit_status) * * publics = * * dependencies = * src = iptokens.h, ipnames.h * obj = * lnk = * * environment = * runtime = vax/masscomp unix/4.23bsd * development = vax unix/4.23bsd * processor = cc * code = unix c mnemonics & linkages * *** end of specifications **************************************/ #ifdef vax11c # include stdio # include setjmp # include ctype #else # include <stdio.h> /*** # include <sys/time.h> # include <sys/resource.h> ***/ # include <setjmp.h> # include <ctype.h> #endif #include "iptokens.h" #include "ipnames.h" #define IPFE_VERS "1.05" #define IPFE_DATE "18 JUL 86" #define FALSE 0 #define TRUE 1 #define FLAG_OFF 0 #define FLAG_ON 1 #define CR 13 #define BEL 07 #define BS 08 #define TAB 09 #define LF 10 #define FF 12 #define TOF 12 #define SPC 32 #define ESC 27 #define DEL 127 #define STDIN stdin #define STDOUT stdout #define STDERR stderr #define STDIN_DEV 0 #define STDOUT_DEV 1 #define STDERR_DEV 2 #define DEF_LOGFILENAME "ipfe.log" #define DEF_OUTFILENAME "ipfe.ip" #define DEF_PROPFILENAME "ipfe.prop" #define DEF_WORKFILENAME "ipfe.wrk" #define BUFSIZE 2048 #define OP_Mask 0xe0 #define OK 0 #define ERROR (-1) #define DONT_FORMAT 0 #define FORMAT 1 #define MX_NO_INFILES 64 #define MX_NO_OUTFILES 64 #define MX_NO_OVLY_FILES 64 #define IP_HDR_CHKLEN 17 #define IP_VERS_OFFSET 17 #define IP_HDR_MASTERLEN 21 #define MX_HDR_BUFLEN 255 #define MX_NO_ALIASES 128 #define MX_NO_MPG_ENTRIES 128 #define MX_BLOCK_DEPTH 8 #define MX_BODY_DEPTH 8 #define MX_BOP_DEPTH 16 /* max # of nested body_operators */ #define MX_SIF_DEPTH 8 /* max sif nesting depth */ #define INDENT_INCR 3 /* # cols to incr indent each nesting depth */ /* * defines for ipfe fn types */ #define CONCAT 0 #define CHAPTERIZE 1 #define SATISFY_SIFS 2 #define REMOVE_SIFS 3 #define PROPERTIES 4 #define INSERT_OVLY 5 #define DEBUG 6 #define PROC_LOG 7 #define FORCE_STDOUT 8 #define BINDING_OFFSET 9 #define DUPLEX 10 #define QUIET 11 #define LANDSCAPE 12 #define ROTATE 13 #define SCALE 14 #define X_OFFSET 15 #define Y_OFFSET 16 #define NUM_FNS 17 /* * defines for chapterization type */ #define CH_PAGES 1 #define CH_KBYTES 2 #define CH_MBYTES 3 #ifdef lcv2 /* if Lattice C vers 2.15 or earlier */ #define void int #endif /* * lattice C defines for fopen file types (binary & text) */ #define BINARY_FILE 0x8000 #define TEXT_FILE 0 FILE *input; FILE *output; FILE *workfile; /* work file for testing input file opens & storing hdr/preamble for chapterizing */ FILE *ovly_file; FILE *sif_file[MX_SIF_DEPTH]; FILE *siffile; FILE *logfile; FILE *propfile; jmp_buf next_file; extern int errno; int _fmode = TEXT_FILE; /* lattice C file_mode */ int abort_flag, debug_flag; int terrno; int exit_status; long pos, in_offset, out_offset; long out_beg_offset[MX_BLOCK_DEPTH], out_end_offset[MX_BLOCK_DEPTH]; long chap_val; long boff_num, boff_den; /* binding offset numerator, denominator */ long xoff_num, xoff_den; /* xOffset numerator, denominator */ long yoff_num, yoff_den; /* yOffset numerator, denominator */ long rxoff_num, rxoff_den, /* rotation xOffset numerator, denominator */ ryoff_num, ryoff_den; /* yOffset numerator, denominator */ long scale_num, scale_den; /* scale factor numerator, denominator */ long blk_num_bytes[MX_BLOCK_DEPTH]; long pg_num_bytes; int num_infiles, out_filnum; int input_indx, output_indx, sif_indx; int prop_level; int cur_indent, off_indent, cur_col; int ovly_flag; int proc_flag[NUM_FNS]; int chap_type; int ipwrite_flag; int rot_deg; /* rotation degrees */ int num_aliases; int alias_indx; int begBody_flag; int preamble_expected, endpreamble_expected, frstpg_flag, bop_preamble_expected[MX_BOP_DEPTH]; /* * MERGE & OVERLAY ARRAYS * There are 2 second order arrays, one for merge pages and one for * overlay files. The 1st order of both is indexed by input_indx, and * the 2nd order by merge_indx. For overlay files, there are 3 * additional arrays, one for an overlay pagenum, one for page offset * numerators, and one for page offset denominators. These 3 arrays * are indexed by ovly_indx (the 1st order indexing for the numerator * and denominator arrays is 0 for the x-offset and 1 for the y-offset). * * Each 2nd order vector of the merge_pg[][] array is initialized to * (-1),0,0,... which indicates to include all pages, and each vector * of the ovly_pg[][] array is initialized to (-1),(-1),(-1),... which * indicates no overlay files. * As IPFE scans the command line, an entry is put into the merge_pg[][] * array for each pageNum specified in a pagerange for an infile (the * value put into the entry is pageNum). If there is an overlay file * specified for pageNum, the (-1) in the ovly_pg[][merge_indx] entry * is replaced with the current value of ovly_indx and ovly_indx is * incremented. If there is another overlay file specified for pageNum, * the value pageNum is repeated in the next merge_pg[][] entry and the * incremented ovly_indx is placed in the next ovly_pg[][] entry. * Example: * ipfe infile "[2,4-6,9[ovly1],12[ovly2][ovly3],15-]" * will yield the following merge_pg[input_indx][] & * ovly_pg[input_indx][] vectors: * 0 1 2 3 4 5 6 7 8 9 10 * ----|----|----|----|----|----|----|----|----|----|---- * merge_pg: 2 , 4 ,(-1), 6 , 9 , 12 , 12 , 15 ,(-1), 0 , 0 ,... * ovly_pg: (-1),(-1),(-1),(-1), 0 , 1 , 2 ,(-1),(-1),(-1),(-1),... * * The algorithm used to decode the merge_pg vector for each infile is * as follows: * Initialize merge_indx to 0; * Loop: * Current_entry = merge_pg[input_indx][merge_indx]; * If Current_entry = 0, we're all done with this infile; * Else if Current_entry = (-1), look at next merge_indx entry; * Next_entry = merge_pg[input_indx][merge_indx+1]; * If Next_entry = 0, include all pages to the end of infile; * Else include all pages until the value of Next_entry is * reached in infile; when it is, increment merge_indx (making * Current_entry = Next_entry, and goto Loop; * Else exclude all pages until Current_entry is reached in infile * (it may already be reached); when it is, include that page and * check the ovly_pg[][] entry; * Ovly_entry = ovly_pg[input_indx][merge_indx]; * If Ovly_entry != (-1) do overlay processing; * Increment merge_indx, and goto Loop; */ int merge_indx, merge_pg[MX_NO_INFILES][MX_NO_MPG_ENTRIES]; int ovly_indx, ovly_pg[MX_NO_INFILES][MX_NO_MPG_ENTRIES]; int ovly_pgnum[MX_NO_OVLY_FILES]; long ovly_num[2][MX_NO_OVLY_FILES], ovly_den[2][MX_NO_OVLY_FILES]; int block_indx; int block_flag; int bproc_indx, bop_indx, bop_iindx[MX_BOP_DEPTH]; int bproc_flag, bop_flag; int num_blocks, num_pages, num_sifs, tnum_blocks, tnum_pages, tnum_sifs; int out_numpages; int infile_flag[MX_NO_INFILES]; int hdr_len; char hdr_buf[MX_HDR_BUFLEN+1], hdr_workbuf[MX_HDR_BUFLEN+1]; char input_name[MX_NO_INFILES][128], input_fnm[128], input_ext[128], output_name[128], output_fnm[128], output_ext[128], work_fname[128], sif_name[MX_SIF_DEPTH][128], prop_fname[128]; char ovly_fname[MX_NO_OVLY_FILES][128]; char alias_ref[MX_NO_ALIASES][128], alias_act[MX_NO_ALIASES][128]; char *inputname, *outputname, *sifname, *propfname; char *logfilename = "ipfe.log"; char *itostr(), lcase(), *op_name(), *strcat(), *strcpy(); /**************************************************************** * * main(argc, argv): ipfe mainline: * main: interpress file editor * ****************************************************************/ main(argc, argv) int argc; char *argv[]; { char msg[128]; (void)sprintf(msg, "\nIPFE Version %s, %s -- Interpress File Editor\n", IPFE_VERS, IPFE_DATE); pip_error(msg); pip_error("Copyright (c) 1985,1986 Xerox Corporation\n\n"); init_ipfe(); get_cmd_args(argc, argv); init1_ipfe(); /* initialization after getting cmd args */ for (input_indx=0; input_indx < num_infiles; input_indx++) { init_proc_file(); inputname = input_name[input_indx]; (void)sprintf(msg, "-- File: %s--\n", inputname); pip_error(msg); pip_prop(msg); _fmode = BINARY_FILE; input = fopen(inputname, "r"); if (input == NULL) { (void)sprintf(msg, "\nError opening input file: %s\n", inputname); pip_error(msg); pip_prop(msg); } else { proc_file(); /* do the real work */ (void)fclose(input); } } if ((abort_flag == FLAG_OFF) && (proc_flag[CONCAT] == FLAG_ON)) { ipwrite_flag = FLAG_ON; /* in case it was turned off by last file processed */ put_op(OP_endBlock); } cleanup(); exit(exit_status); } /**************************************************************** * * cleanup: housecleaning * ****************************************************************/ cleanup() { char msg[128]; if (proc_flag[CONCAT] == FLAG_ON) { (void)sprintf(msg, "\n--Total Number of Blocks:%4d\n", tnum_blocks); pip_prop(msg); (void)sprintf(msg, "--Total Number of Pages :%4d\n", tnum_pages); pip_prop(msg); (void)sprintf(msg, "--Total Number of SIFs :%4d\n", tnum_sifs); pip_prop(msg); } mputc_prop('\n'); (void)sprintf(msg, "\n-- Total Number of Input Pages :%4d\n", tnum_pages); pip_error(msg); if ((output != NULL) || (out_numpages > 0)) { (void)sprintf(msg, "-- Total Number of Output Pages:%4d\n", out_numpages); pip_error(msg); } pip_error("\n"); if (logfile != NULL) (void)fclose(logfile); if (propfile != NULL) (void)fclose(propfile); if (output != NULL) (void)fclose(output); } /**************************************************************** * * int count_int_bytes(val): * int count_int_bytes: return the number of bytes in the * specified int val * ****************************************************************/ int count_int_bytes(val) long val; { long mask; int i; if ((val == 0) || (val == (-1))) i = 1; /* avoid infinite looping */ else { if (val < 0) val = ~(val); /* same # of bytes as one's complement */ mask = 0xff800000; for (i=4; ((val & mask) == 0); i--) mask = mask >> 8; } return(i); } /**************************************************************** * * create_SIF(fname): * create_SIF: create a new SIF (for ovly handling) * ****************************************************************/ create_SIF(fname) char *fname; { int not_created_flag; char msg[128]; not_created_flag = FLAG_OFF; if (proc_flag[INSERT_OVLY] == FLAG_ON) { if (ovly_pgnum[ovly_indx] < 2) { (void)sprintf(msg, " --Creating SIF: %s\n", fname); pip_error(msg); put_seq_type_len(sequenceInsertFile, (long)strlen(fname)); ip_puts(fname); } else { pip_error( " --Cannot create SIF for overlay with pageNum > 1\n"); not_created_flag = FLAG_ON; } } else { pip_error( " -i switch (Insert SIF for overlay) not specified\n"); not_created_flag = FLAG_ON; } if (not_created_flag == FLAG_ON) { (void)sprintf(msg, " --SIF Not Created for: %s\n", fname); pip_error(msg); } } /**************************************************************** * * get_cmd_args(argc, argv): * get_cmd_args: get cmd_line arguments * gca: label for editing * ****************************************************************/ get_cmd_args(argc, argv) int argc; char *argv[]; { long val, val1, d; int arg, opt, opt_len, ch_ctr, neg_flag, sep_flag, retcd; int err_flag = FLAG_OFF; char ch, sep_char, msg[128]; for (arg=1; arg < argc; arg++) /* look for cmd_arguments */ { switch (argv[arg][0]) { case ('-'): opt_len = strlen(argv[arg]); /* because arg can be */ /* modified below */ for (opt=1; opt < opt_len; opt++) { switch (argv[arg][opt]) { case ('-'): opt = opt_len; /* to handle '--' switch */ break; case ('a'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } proc_alias(&(argv[arg][opt])); opt = opt_len; /* to get out of loop */ break; case ('b'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } /* * binding offset:unit */ val = val1 = d = ch_ctr = 0; neg_flag = FLAG_OFF; while (opt < opt_len) { ch = argv[arg][opt++]; if ((ch == '-') && (ch_ctr == 0)) neg_flag = FLAG_ON; else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; if (d == 0) val = (val * 10) + ch; else if (d <= 1000) /* prec = 10**(-3) truncated */ { val1 = (val1 * 10) + ch; d = d * 10; } } else if (ch == '.') d = 1; else { if ((ch == ':') && (opt < opt_len)) ch = argv[arg][opt++]; break; /* exit loop */ } ++ch_ctr; } /* end while (opt < opt_len) */ if (d == 0) d = 1; else val = (val * d) + val1; if (val != 0) { if (neg_flag == FLAG_ON) val = -(val); switch (ch) { case ('c'): d = d * 100; break; case ('i'): val = val * 254; d = d * 10000; break; case ('p'): val = val * 254; d = ((d * 720000) & 0x7fffffff); break; case ('P'): val = val * 254; d = ((d * 60000) & 0x7fffffff); break; default: d = d * 100; /* def=cm */ break; } /* end switch (ch) */ if (d != 0) /* last chk for div by 0 just in case of ovflw */ { boff_num = val; boff_den = d; proc_flag[BINDING_OFFSET] = FLAG_ON; } } else { (void)sprintf(msg, "--ipfe: No binding offset value specified in (%s)\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } --opt; /* to parse cur ch at cmd line */ break; case ('c'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } ch = val = 0; while (opt < opt_len) { ch = argv[arg][opt]; if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; val = (val * 10) + ch; ++opt; } else break; } if (val == 0) { (void)sprintf(msg, "--ipfe: No length specified for chapterize in %s\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } else { if ((ch == ':') && (opt < opt_len)) ch = argv[arg][++opt]; switch (ch) { case ('p'): proc_flag[CHAPTERIZE] = FLAG_ON; chap_type = CH_PAGES; chap_val = val; break; case ('k'): proc_flag[CHAPTERIZE] = FLAG_ON; chap_type = CH_KBYTES; chap_val = val * 1024; break; case ('m'): proc_flag[CHAPTERIZE] = FLAG_ON; chap_type = CH_MBYTES; chap_val = ((val * 1048576) & 0x7fffffff); break; default: (void)sprintf(msg, "--ipfe: No unit specified for chapterize in %s\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; --opt; /* parse opt again */ break; } } break; case ('d'): proc_flag[DUPLEX] = FLAG_ON; break; case ('D'): proc_flag[DEBUG] = FLAG_ON; break; case ('i'): proc_flag[INSERT_OVLY] = FLAG_ON; break; case ('l'): proc_flag[PROC_LOG] = FLAG_ON; if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } ch = argv[arg][opt]; if ((ch != ':') && (ch != '-')) { logfilename = &(argv[arg][opt]); opt = opt_len; /* to get out of lp */ } open_logfile(argc, argv); break; case ('L'): rot_deg = 90; rxoff_num = rxoff_den = 0; ryoff_num = -(2794); ryoff_den = 10000; proc_flag[LANDSCAPE] = FLAG_ON; break; case ('o'): if (strlen(&(argv[arg][opt])) > 1) outputname = &(argv[arg][opt+1]); else outputname = argv[++arg]; opt = opt_len; /* to get out of loop */ break; case ('p'): proc_flag[PROPERTIES] = FLAG_ON; if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } ch = argv[arg][opt]; if ((ch != ':') && (ch != '-')) { if ((ch >= '0') && (ch <= '9')) { prop_level = ch - '0'; ++opt; if (argv[arg][opt] == ':') ++opt; if (opt < opt_len) propfname = &(argv[arg][opt]); opt = opt_len; /* to exit loop */ } else { (void)sprintf(msg, "--ipfe: *** warning -- property level not specified in %s\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; propfname = &(argv[arg][opt]); opt = opt_len; /* to exit loop */ } } break; case ('q'): proc_flag[QUIET] = FLAG_ON; break; case ('r'): proc_flag[REMOVE_SIFS] = FLAG_ON; break; case ('R'): rot_deg = -(90); rxoff_num = -(2477); /* xOff = -(9 3/4") */ ryoff_num = -(318); /* yOff = -(1 1/4") */ rxoff_den = ryoff_den = 10000; proc_flag[ROTATE] = FLAG_ON; break; case ('s'): proc_flag[SATISFY_SIFS] = FLAG_ON; break; case ('S'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } /* * scale */ val = val1 = d = ch_ctr = 0; neg_flag = sep_flag = FLAG_OFF; while (opt < opt_len) { ch = argv[arg][opt++]; if ((ch == '-') && (ch_ctr == 0)) neg_flag = FLAG_ON; else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; if (d == 0) val = (val * 10) + ch; else if (d <= 1000) /* prec = 10**(-3) truncated */ { val1 = (val1 * 10) + ch; d = d * 10; } } else if ((ch == '.') || (ch == '/')) { if (sep_flag == FLAG_OFF) { d = 1; sep_char = ch; sep_flag = FLAG_ON; } else { (void)sprintf(msg, "--ipfe: Scale factor cannot have BOTH a '.' AND a '/' in (%s)\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; break; /* exit loop */ } } else { if ((ch == ':') && (opt < opt_len)) ch = argv[arg][opt++]; break; /* exit loop */ } ++ch_ctr; } /* end while (opt < opt_len) */ if (d == 0) d = 1; else if (sep_char == '/') d = val1; else val = (val * d) + val1; if ((val != 0) && (err_flag == FLAG_OFF)) { if (neg_flag == FLAG_ON) val = -(val); if (d != 0) /* last chk for div by 0 just in case of ovflw */ { scale_num = val; scale_den = d; proc_flag[SCALE] = FLAG_ON; } } else { (void)sprintf(msg, "--ipfe: No scale factor value specified in (%s)\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } --opt; /* to parse cur ch at cmd line */ break; case ('X'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } /* * xOffset:unit */ val = val1 = d = ch_ctr = 0; neg_flag = FLAG_OFF; while (opt < opt_len) { ch = argv[arg][opt++]; if ((ch == '-') && (ch_ctr == 0)) neg_flag = FLAG_ON; else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; if (d == 0) val = (val * 10) + ch; else if (d <= 1000) /* prec = 10**(-3) truncated */ { val1 = (val1 * 10) + ch; d = d * 10; } } else if (ch == '.') { d = 1; val1 = 0; } else { if ((ch == ':') && (opt < opt_len)) ch = argv[arg][opt++]; break; /* exit loop */ } ++ch_ctr; } /* end while (opt < opt_len) */ if (d == 0) d = 1; else val = (val * d) + val1; if (val != 0) { if (neg_flag == FLAG_ON) val = -(val); switch (ch) { case ('c'): d = d * 100; break; case ('i'): val = val * 254; d = d * 10000; break; case ('p'): val = val * 254; d = ((d * 720000) & 0x7fffffff); break; case ('P'): val = val * 254; d = ((d * 60000) & 0x7fffffff); break; default: d = d * 100; /* def=cm */ break; } /* end switch (ch) */ if (d != 0) /* last chk for div by 0 just in case of ovflw */ { xoff_num = val; xoff_den = d; proc_flag[X_OFFSET] = FLAG_ON; } } else { (void)sprintf(msg, "--ipfe: No xOffset value specified in (%s)\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } --opt; /* to parse cur ch at cmd line */ break; case ('Y'): if (strlen(&(argv[arg][opt])) > 1) ++opt; else { ++arg; opt = 0; opt_len = strlen(argv[arg]); } /* * yOffset:unit */ val = val1 = d = ch_ctr = 0; neg_flag = FLAG_OFF; while (opt < opt_len) { ch = argv[arg][opt++]; if ((ch == '-') && (ch_ctr == 0)) neg_flag = FLAG_ON; else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; if (d == 0) val = (val * 10) + ch; else if (d <= 1000) /* prec = 10**(-3) truncated */ { val1 = (val1 * 10) + ch; d = d * 10; } } else if (ch == '.') { d = 1; val1 = 0; } else { if ((ch == ':') && (opt < opt_len)) ch = argv[arg][opt++]; break; /* exit loop */ } ++ch_ctr; } /* end while (opt < opt_len) */ if (d == 0) d = 1; else val = (val * d) + val1; if (val != 0) { if (neg_flag == FLAG_ON) val = -(val); switch (ch) { case ('c'): d = d * 100; break; case ('i'): val = val * 254; d = d * 10000; break; case ('p'): val = val * 254; d = ((d * 720000) & 0x7fffffff); break; case ('P'): val = val * 254; d = ((d * 60000) & 0x7fffffff); break; default: d = d * 100; /* def=cm */ break; } /* end switch (ch) */ if (d != 0) /* last chk for div by 0 just in case of ovflw */ { yoff_num = val; yoff_den = d; proc_flag[Y_OFFSET] = FLAG_ON; } } else { (void)sprintf(msg, "--ipfe: No yOffset value specified in (%s)\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } --opt; /* to parse cur ch at cmd line */ break; default: (void)sprintf(msg, "--ipfe: Invalid option in %s (%s)\n", argv[arg], &(argv[arg][opt])); pip_error(msg); err_flag = FLAG_ON; break; } } break; case ('['): break; case ('>'): break; default: /* * the current arg is an input file; try to open it */ if (input_indx < MX_NO_INFILES) { _fmode = BINARY_FILE; workfile = fopen(argv[arg], "r"); if (workfile == NULL) { (void)sprintf(msg, "--ipfe: Error opening input file: %s\n", argv[arg]); pip_error(msg); err_flag = FLAG_ON; } else { /* * check for valid hdr */ retcd = get_ip_hdr(workfile, argv[arg]); if (retcd == OK) { (void)strcpy(input_name[input_indx], argv[arg]); /* * check for page range */ if (((arg + 1) < argc) && ((argv[arg+1][0] == '[') || (argv[arg+1][0] == '+') || (argv[arg+1][0] == '#'))) { ++arg; get_pagerange(arg, argv); } else merge_pg[input_indx][0] = (-1); infile_flag[input_indx] = FLAG_ON; ++input_indx; ++num_infiles; } else err_flag = FLAG_ON; (void)fclose(workfile); } } else { (void)sprintf(msg, "--ipfe: Maximum # of input files = %d; File: %s not processed\n", MX_NO_INFILES, argv[arg]); pip_error(msg); err_flag = FLAG_ON; } break; } /* end switch (argv[arg][0]) */ } /* end for (arg=1; arg < argc; arg++) */ if (err_flag == FLAG_ON) pip_error("\n"); } /**************************************************************** * * int get_ip_hdr(file, filename): * int get_ip_hdr: get the ip_hdr from the specified * file into a work_buf & return a * ptr to the buf * ****************************************************************/ int get_ip_hdr(file, filename) FILE *file; char *filename; { int i, retcd, hdr_flag; int c; /* must be int for stdio EOF compare */ char *ptr, msg[128]; retcd = OK; /* * get the header */ ptr = hdr_workbuf; hdr_flag = FLAG_OFF; for (i=0; i < MX_HDR_BUFLEN; i++) { c = getc_testeof(file, filename); /* get a char, */ *ptr++ = c; /* & stick it in the buffer */ if (c == ' ') /* if c=ip_hdr_terminate_char, */ { hdr_flag = FLAG_ON; /* set hdr_ok flag, */ break; /* & exit the loop */ } } *ptr = '\0'; /* * ... & check its validity */ if (hdr_flag == FLAG_OFF) { (void)sprintf(msg, "--ipfe: Hdr length > %d chars in file: %s\n", MX_HDR_BUFLEN, filename); pip_error(msg); retcd = ERROR; } if (mstrncmp(hdr_workbuf, IP_Header, IP_HDR_CHKLEN) != 0) { (void)sprintf(msg, "--ipfe: INVALID HEADER! in file: %s\n", filename); pip_error(msg); retcd = ERROR; } return(retcd); } /**************************************************************** * * get_pagerange(arg, argv): * get_pagerange: get cmd_line page range argument * for current input_indx from * specified argument * ****************************************************************/ get_pagerange(arg, argv) int arg; char *argv[]; { int i, opt, opt_len, d, val, val1, lp_ctr, ch_ctr, prv_mpg_num, err_flag, neg_flag; char ch, nc; char msg[128], name_buf[128]; merge_indx = val = 0; prv_mpg_num = 0; opt_len = strlen(argv[arg]); err_flag = FLAG_OFF; for (opt=1; ((opt < opt_len) && (err_flag == FLAG_OFF)); opt++) { switch (argv[arg][opt]) { case ('-'): merge_pg[input_indx][merge_indx] = (-1); ++merge_indx; break; /* * all of the following can just be ignored at this level */ case (','): case (']'): case (')'): case (SPC): case ('\n'): break; case ('['): case ('+'): /* * overlay filename */ if (strlen(&(argv[arg][opt])) > 1) { ch = '\0'; i = 0; ++opt; while (opt < opt_len) { ch = argv[arg][opt]; if ((ch == ':') || (ch == '(') || (ch == '@') || (ch == '+')) { --opt; /* reparse opt at switch level */ break; } else if ((ch == ']') || (ch == ',')) break; /* don't bother reparsing */ else { name_buf[i++] = ch; ++opt; } } name_buf[i] = '\0'; if (i > 0) { if (merge_indx == 0) { merge_pg[input_indx][0] = 1; ++merge_indx; } if (merge_pg[input_indx][(merge_indx-1)] > 0) { if (ovly_pg[input_indx][(merge_indx-1)] != (-1)) { merge_pg[input_indx][merge_indx] = merge_pg[input_indx][(merge_indx-1)]; ++merge_indx; } ovly_pg[input_indx][(merge_indx-1)] = ovly_indx; (void)strcpy(ovly_fname[ovly_indx], name_buf); ++ovly_indx; } else err_flag = FLAG_ON; } else err_flag = FLAG_ON; } else err_flag = FLAG_ON; break; case (':'): /* * overlay pagenum */ if ((ovly_indx == 0) || (ovly_pg[input_indx][merge_indx-1] == (-1)) || (ovly_pgnum[ovly_indx-1] != 0)) err_flag = FLAG_ON; else if (strlen(&(argv[arg][opt])) > 1) { val = 0; ++opt; while (opt < opt_len) { ch = argv[arg][opt]; if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; val = (val * 10) + ch; ++opt; } else { --opt; /* reparse everything else at the switch level */ break; } } /* * if the pagenum is good, process it */ if (val > 0) ovly_pgnum[ovly_indx-1] = val; } else err_flag = FLAG_ON; break; case ('('): case ('@'): /* * overlay page offset */ if ((ovly_indx == 0) || (ovly_pg[input_indx][merge_indx-1] == (-1))) err_flag = FLAG_ON; else if (strlen(&(argv[arg][opt])) > 1) { val = val1 = d = lp_ctr = ch_ctr = 0; neg_flag = FLAG_OFF; ++opt; while ((opt < opt_len) && (lp_ctr < 2)) { ch = argv[arg][opt++]; if ((ch == '-') && (ch_ctr == 0)) neg_flag = FLAG_ON; else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; if (d == 0) val = (val * 10) + ch; else if (d <= 1000) /* precision = 10**(-3) truncated */ { val1 = (val1 * 10) + ch; d = d * 10; } } else if (ch == '.') { d = 1; val1 = 0; } else { if (d != 0) val = (val * d) + val1; else d = 1; if (val != 0) { if (neg_flag == FLAG_ON) val = -(val); switch (ch) { case ('c'): d = d * 100; break; case ('i'): val = val * 254; d = d * 10000; break; case ('p'): val = val * 254; d = ((d * 720000) & 0x7fffffff); break; case ('P'): val = val * 254; d = ((d * 60000) & 0x7fffffff); break; default: d = d * 100; /* assume cm */ break; } if (d != 0) /* last chk for div by 0 just in case of ovflw */ { ovly_num[lp_ctr][ovly_indx-1] = val; ovly_den[lp_ctr][ovly_indx-1] = d; } if (lp_ctr == 0) { nc = argv[arg][opt]; if (((nc < '0') && (nc != '-')) || (nc > '9')) ++opt; /* assume only 1 separator after scale char */ } } val = d = 0; neg_flag = FLAG_OFF; ++lp_ctr; ch_ctr = (-1); if ((lp_ctr == 2) && ((ch == '+') || (ch == '[') || (ch == '-'))) --opt; /* reparse at switch level */ } ++ch_ctr; } --opt; /* to undo the automatic incr above */ } else err_flag = FLAG_ON; break; default: /* * current opt should be a pageNum */ val = 0; while (opt < opt_len) { ch = argv[arg][opt]; if ((ch >= '0') && (ch <= '9')) { ch = ch - '0'; val = (val * 10) + ch; ++opt; } else if ((ch == '-') || (ch == ',') || (ch == '[') || (ch == ']') || (ch == '+')) { --opt; /* reparse opt at switch level */ break; } else if ((ch == SPC) || (ch == '\n')) break; /* don't bother to reparse */ else { err_flag = FLAG_ON; break; } } /* * if the val is good, process it */ if (val > prv_mpg_num) { merge_pg[input_indx][merge_indx] = val; prv_mpg_num = val; ++merge_indx; } else err_flag = FLAG_ON; break; } /* end of switch (argv[arg][opt]) */ if (err_flag == FLAG_ON) { (void)sprintf(msg, "--ipfe: Invalid pagerange specification in %s (%s)\n", argv[arg], &(argv[arg][opt])); pip_error(msg); exit_status = 5; } } /* end of for (opt=1; ((opt < opt_len) && (err_flag == FLAG_OFF)); ++ opt) */ } /**************************************************************** * * int getc_testeof(file, filename): * int getc_testeof: get a char from input file; * if we get an EOF here, * it's an error; * else, * return the char as an int * ****************************************************************/ int getc_testeof(file, filename) FILE *file; char *filename; { int val; char msg[128]; val = mgetc(file); if (feof(file)) { (void)sprintf(msg, "\nUnexpected EOF! in file: %s\n", filename); pip_error(msg); longjmp(next_file, 1); } return(val); } /**************************************************************** * * indent(cnt, file): * indent: put <cnt> spcs to specified file * ****************************************************************/ indent(cnt, file) FILE *file; int cnt; { if (file != NULL) { if ((file == propfile) && (cnt > 0)) cur_col = cur_col + cnt; while (cnt-- > 0) { putc(' ', file); } } } /**************************************************************** * * init: * init_ipfe: initialization * ****************************************************************/ init_ipfe() { int i, j; abort_flag = debug_flag = FLAG_OFF; exit_status = 0; ovly_flag = FLAG_OFF; frstpg_flag = FLAG_OFF; num_infiles = out_filnum = 0; input_indx = output_indx = sif_indx = 0; num_aliases = 0; alias_indx = 0; prop_level = 0; hdr_len = 0; pos = in_offset = 0; block_indx = 0; block_flag = FLAG_OFF; out_beg_offset[block_indx] = 0; tnum_blocks = tnum_pages = tnum_sifs = 0; for (i=0; i < NUM_FNS; i++) proc_flag[i] = FLAG_OFF; chap_type = chap_val = 0; ipwrite_flag = FLAG_ON; merge_indx = ovly_indx = 0; for (i=0; i < MX_NO_INFILES; i++) { merge_pg[i][0] = (-1); /* init to all pages */ ovly_pg[i][0] = (-1); /* init to no overlay */ for (j=1; j < MX_NO_MPG_ENTRIES; j++) { merge_pg[i][j] = 0; ovly_pg[i][j] = (-1); } } for (i=0; i < MX_BLOCK_DEPTH; i++) blk_num_bytes[i] = 0; pg_num_bytes = 0; for (i=0; i < MX_NO_INFILES; i++) infile_flag[i] = 0; outputname = propfname = 0; /* * make the beginBlock & endBlock names upper case */ op_names[OP_beginBlock] = "BEGIN"; op_names[OP_endBlock] = "END"; } /**************************************************************** * * init_proc_file: initialize proc_file() loop * ****************************************************************/ init_proc_file() { sif_indx = 0; cur_indent = cur_col = 0; in_offset = 0; num_blocks = num_pages = num_sifs = 0; preamble_expected = FLAG_OFF; merge_indx = 0; bproc_indx = bop_indx = 0; bproc_flag = bop_flag = FLAG_OFF; ipwrite_flag = FLAG_ON; } /**************************************************************** * * init1: * init1_ipfe: initialization after getting cmd args * ****************************************************************/ init1_ipfe() { int i, tval, procflag, exit_flag; char msg[128]; if (num_infiles == 0) /* input_name req'd for now */ Usage(); else { /* * split the 1st input_name into input_fnm & input_ext */ i = mrstrichr(input_name[0], '.'); if (i != (-1)) { (void)mstrncpy(input_fnm, input_name[0], i); (void)strcpy(input_ext, (input_name[0] + i)); } else (void)strcpy(input_fnm, input_name[0]); /* * Open properties file */ if (proc_flag[PROPERTIES] == FLAG_ON) open_propfile(); /* * Tell about rotate, xOffset, yOffset, binding offset, duplex, and scale */ if ((proc_flag[LANDSCAPE] == FLAG_ON) || (proc_flag[ROTATE] == FLAG_ON)) { (void)sprintf(msg, "--ipfe: Rotate %d degrees\n", rot_deg); pip_error(msg); } if (proc_flag[X_OFFSET] == FLAG_ON) { (void)sprintf(msg, "--ipfe: xOffset = %ld/%ld meters\n", xoff_num, xoff_den); pip_error(msg); } if (proc_flag[Y_OFFSET] == FLAG_ON) { (void)sprintf(msg, "--ipfe: yOffset = %ld/%ld meters\n", yoff_num, yoff_den); pip_error(msg); } if (proc_flag[BINDING_OFFSET] == FLAG_ON) { (void)sprintf(msg, "--ipfe: Binding offset = %ld/%ld meters\n", boff_num, boff_den); pip_error(msg); if (proc_flag[DUPLEX] == FLAG_ON) pip_error("--ipfe: Duplex processing set\n"); } if (proc_flag[SCALE] == FLAG_ON) { (void)sprintf(msg, "--ipfe: Scale = %ld/%ld\n", scale_num, scale_den); pip_error(msg); } /* * Tell about chapterizing */ if (proc_flag[CHAPTERIZE] == FLAG_ON) { (void)sprintf(msg, "--ipfe: Chapterize every %d ", chap_val); pip_error(msg); switch (chap_type) { case (CH_PAGES): pip_error("pages"); break; case (CH_KBYTES): (void)sprintf(msg, "bytes (%d kbytes)", (chap_val / 1024)); pip_error(msg); break; case (CH_MBYTES): (void)sprintf(msg, "bytes (%d mbytes)", (chap_val / 1048576)); pip_error(msg); break; } pip_error("\n"); } /* * Show any aliases */ for (i=0; i < num_aliases; i++) { if (i == 0) pip_error("--ipfe: "); else pip_error("-- "); (void)sprintf(msg, "Alias: %s=%s\n", alias_ref[i], alias_act[i]); pip_error(msg); } if (num_infiles > 1) proc_flag[CONCAT] = FLAG_ON; if (proc_flag[DEBUG] == FLAG_ON) off_indent = 10; else off_indent = 0; /* * For now, IF the properties option flag is SET AND there is no output * file specified, * THEN set the environment for properties only (don't open output) */ if ((proc_flag[PROPERTIES] == FLAG_ON) && (outputname == 0)) ; /* process properties only; no output */ else { /* * open the output file */ if (outputname == 0) { /* * construct a default output filename by concatenating ".ip" to the * fnm component of the 1st input filename, making sure the resulting * filename doesn't already exist; if it does exist, append "1" to * the fnm, then "2" to the fnm, etc. until the filename doesn't exist */ tval = 0; exit_flag = procflag = FLAG_OFF; while (exit_flag == FLAG_OFF) { (void)strcpy(work_fname, input_fnm); if (procflag == FLAG_ON) (void)strcat(work_fname, itostr(tval)); (void)strcat(work_fname, ".ip"); _fmode = BINARY_FILE; workfile = fopen(work_fname, "r"); if (workfile == NULL) { outputname = work_fname; exit_flag = FLAG_ON; } else { (void)fclose(workfile); ++tval; procflag = FLAG_ON; } } } (void)strcpy(output_name, outputname); outputname = output_name; i = mrstrichr(outputname, '.'); if (i != (-1)) { (void)mstrncpy(output_fnm, outputname, i); (void)strcpy(output_ext, (outputname + i)); } else (void)strcpy(output_fnm, outputname); if (proc_flag[CHAPTERIZE] == FLAG_ON) { (void)strcpy(output_name, output_fnm); out_filnum = 1; (void)strcat(output_name, itostr(out_filnum)); (void)strcat(output_name, output_ext); } open_output(); } } } /**************************************************************** * * iocopyn(length, file, filename): * iocopyn: copy <length> bytes from specified * file to output, checking for * unexpected EOF * ****************************************************************/ iocopyn(length, file, filename) FILE *file; long length; char *filename; { while (length-- > 0) { ip_putc(getc_testeof(file, filename)); } } /**************************************************************** * * iogetn(length, file, filename, buf): * iogetn: read <length> bytes from specified * file into specified buf, checking * for unexpected EOF * -- throw the bytes away, for now * ****************************************************************/ iogetn(length, file, filename, buf) FILE *file; long length; char *filename, *buf; { while (length-- > 0) { *buf++ = getc_testeof(file, filename); } *buf = '\0'; } /**************************************************************** * * ioputn(length, buf): * ioputn: put <length> bytes from specified * buf to output * ****************************************************************/ ioputn(length, buf) long length; char *buf; { while (length-- > 0) { ip_putc(*buf++); } } /**************************************************************** * * ioreadn(length, file, filename): * ioreadn: read <length> bytes from specified * file, checking for unexpected EOF * -- throw the bytes away, for now * ****************************************************************/ ioreadn(length, file, filename) FILE *file; long length; char *filename; { while (length-- > 0) { (void)getc_testeof(file, filename); /* throw it away */ } } /**************************************************************** * * ip_putc(ch): * ip_putc: put char to (interpress) output & * bump out_offset * ****************************************************************/ ip_putc(ch) char ch; { if ((output != NULL) && (ipwrite_flag == FLAG_ON)) { putc(ch, output); ++out_offset; } } /**************************************************************** * * ip_puts(string): * ip_puts: put string to (interpress) output * & add strlen(string) to out_offset * ****************************************************************/ ip_puts(string) char *string; { if ((output != NULL) && (ipwrite_flag == FLAG_ON)) { fprintf(output, string); out_offset = out_offset + strlen(string); } } /**************************************************************** * * char *itostr(ival): * char *itostr: cvt int to ascii string; return ptr * ****************************************************************/ char *itostr(ival) int ival; { int i, digit, digit_flag; char num_buf[17], *s; s = num_buf; digit_flag = FLAG_OFF; for (i=10000; i > 0; i=i/10) { digit = ival / i; if ((digit == 0) && (digit_flag == FLAG_OFF) && (i > 1)) ; /* do nothing */ else { *s = digit + '0'; ++s; ival = ival - (digit * i); digit_flag = FLAG_ON; } } *s = '\0'; return(num_buf); } /**************************************************************** * * mgetc(file): * mgetc: get char from input & bump * appropriate counters * ****************************************************************/ int mgetc(file) FILE *file; { int val; val = getc(file); if (!(feof(file))) { val = val & 0xff; ++in_offset; ++blk_num_bytes[block_indx]; ++pg_num_bytes; } return(val); } /**************************************************************** * * mputc_prop(ch): * mputc_prop: put char to propfile * ****************************************************************/ mputc_prop(ch) { if ((propfile != NULL) && (ovly_flag == FLAG_OFF)) { putc(ch, propfile); if (ch == '\n') cur_col = 0; } } /**************************************************************** * * int mrstrichr(str, ch): * int mrstrichr: reverse srch for char in string; * if fnd, * return its pos (indexed from 0); * else * return (-1) * ****************************************************************/ int mrstrichr(str, ch) char *str, ch; { int i, indx, retcd; retcd = (-1); indx = strlen(str) - 1; str = str + indx; for (i=indx; i >= 0; i--, str--) { if (*str == ch) { retcd = i; break; } } return(retcd); } /**************************************************************** * * int mstrncmp(s1, s2, len): * int mstrncmp: cmp s1 to s2 for max of len bytes * (byte-wise compare, left to right); * if *s1 != *s2, * return (int)(*s1 - *s2) * (i.e., <0 if s1<s2, >0 if s1>s2) * else * return 0 * ****************************************************************/ int mstrncmp(s1, s2, len) int len; char *s1, *s2; { int i, retcd; retcd = 0; for (i=0; i < len; i++, s1++, s2++) { if (*s1 != *s2) { retcd = (int)(*s1 - *s2); break; } } return(retcd); } /**************************************************************** * * int mstrncpy(to, from, len): * int mstrncpy: copy from -> to for len; return * actual # bytes copied (will be * < len if <from> is null-terminated * shorter than len); * guarantees not overwriting allocated * space for <to> if sizeof(to) is at * least len + 1 (i.e., if len = * sizeof(to) - 1; * destination <to> is always null- * terminated * ****************************************************************/ int mstrncpy(to, from, len) int len; char *to, *from; { int cnt; cnt = 0; while ((len-- > 0) && (*from != '\0')) { *to++ = *from++; ++cnt; } *to = '\0'; return(cnt); } /**************************************************************** * * open_logfile(argc, argv): * open_logfile: open the logfile for processing * ****************************************************************/ open_logfile(argc, argv) int argc; char *argv[]; { int i; _fmode = TEXT_FILE; logfile = fopen(logfilename, "w"); if (logfile == NULL) { fprintf(STDERR, "--ipfe: Can't open log file: %s\n", logfilename); *logfilename = '\0'; } else { fprintf(STDERR, "--ipfe: Log file: %s is open\n", logfilename); fprintf(logfile, "\n"); for (i=0; i < argc; i++) fprintf(logfile, "%s ", argv[i]); fprintf(logfile, "\n\n"); } } /**************************************************************** * * open_output: open the output for processing * ****************************************************************/ open_output() { char msg[128]; _fmode = BINARY_FILE; output = fopen(outputname, "w"); if (output == NULL) { terrno = errno; /* save errno */ (void)sprintf(msg, "--ipfe: Error opening output file: %s, retcd=%d\n", outputname, errno); pip_error(msg); errno = terrno; exit(2); } } /**************************************************************** * * open_propfile: open the properties file for processing * ****************************************************************/ open_propfile() { char msg[128]; _fmode = TEXT_FILE; if (propfname == 0) { (void)strcpy(prop_fname, input_fnm); (void)strcat(prop_fname, ".prop"); propfname = prop_fname; (void)sprintf(msg, "--ipfe: No properties filename specified. Using: %s\n", propfname); pip_error(msg); } propfile = fopen(propfname, "w"); if (propfile == NULL) { (void)sprintf(msg, "--ipfe: Can't open properties file: %s\n", propfname); pip_error(msg); *propfname = '\0'; } else { (void)sprintf(msg, "--ipfe: Properties file: %s is open\n", propfname); pip_error(msg); } } /**************************************************************** * * char *op_name(op): * char *op_name: check op_names[] table of op_code * name strings for non-null entry; * if non_null, * return ptr to the string, * else, * return ptr to string * "--Unknown op: <op>" * ****************************************************************/ char *op_name(op) int op; { char buf[20]; if (op_names[op] == NULL) { (void)sprintf(buf, "--Unknown op: %d --", op); return(buf); } else return(op_names[op]); } /**************************************************************** * * pip_error(msg): * pip_error: put error msg to stdout & logfile * ****************************************************************/ pip_error(msg) char *msg; { if (proc_flag[QUIET] != FLAG_ON) fprintf(STDERR, msg); if (logfile != NULL) fprintf(logfile, msg); } /**************************************************************** * * pip_prop(msg): * pip_prop: put msg to propfile * ****************************************************************/ pip_prop(msg) char *msg; { if ((propfile != NULL) && (ovly_flag == FLAG_OFF)) { fprintf(propfile, msg); if (*(msg + strlen(msg) - 1) == '\n') cur_col = 0; else cur_col = cur_col + strlen(msg); } } /**************************************************************** * * preserve_SIF_copy(type_byte, length, file, filename): * preserve_SIF_copy: preserve SIF reference by copying * from specified input file to output * ****************************************************************/ copy_preserve_SIF(type_byte, length, file, filename) FILE *file; long length; int type_byte; char *filename; { put_seq_type_len(type_byte, length); iocopyn(length, file, filename); } /**************************************************************** * * preserve_SIF_put(type_byte, length, buf): * preserve_SIF_put: preserve SIF reference by copying * from specified buffer to output * ****************************************************************/ put_preserve_SIF(type_byte, length, buf) long length; int type_byte; char *buf; { put_seq_type_len(type_byte, length); ioputn(length, buf); } /**************************************************************** * * proc_alias(alias_string): * proc_alias: process alias argument * ****************************************************************/ proc_alias(alias_string) char *alias_string; { int indx, len; char msg[128]; len = strlen(alias_string); indx = mrstrichr(alias_string, ':'); if ((indx > 0) && (indx < (len - 1))) /* past beg & before end */ { (void)mstrncpy(alias_ref[alias_indx], alias_string, indx); ++indx; (void)mstrncpy(alias_act[alias_indx], (alias_string + indx), (len - indx)); ++alias_indx; ++num_aliases; } else { (void)sprintf(msg, "--ipfe: *** warning -- invalid alias specification (%s)\n", alias_string); pip_error(msg); exit_status = 4; } } /**************************************************************** * * proc_chapterize: test for & process chapterizing * ****************************************************************/ proc_chapterize() { long len, temp_end_offset; int i, op, terrno, tblock_indx, proc_op_flag, eof_flag, proc_type; int type_byte; /* must be int for stdio EOF */ char msg[128]; if ((proc_flag[CHAPTERIZE] == FLAG_ON) && (((chap_type == CH_PAGES) && (out_numpages == chap_val)) || (((chap_type == CH_KBYTES) || (chap_type == CH_MBYTES)) && (out_offset >= chap_val)))) { /* * Eventually, the next two lines should be rewritten to check to see * if we might somehow be nested in a body before putting the * OP_endblock(s) */ for (i=0; i < block_indx; i++) put_op(OP_endBlock); (void)fclose(output); /* * Now, check for OP_endBlock(s) appearing immediately in the input * file. If so, skip them: they were already put out above. In looking, * if we get an EOF and there are no more input files, don't open a * new output file. */ proc_op_flag = eof_flag = FLAG_OFF; tblock_indx = block_indx; /* because the actual block_indx can be dcr'd in the loop */ for (i=0; i <= tblock_indx; i++) { type_byte = mgetc(input); if (feof(input)) { /* * set eof_flag only if there are no more input files */ if (input_indx >= (num_infiles - 1)) eof_flag = FLAG_ON; break; } else if ((type_byte & OP_Mask) == (LONG_OP & OP_Mask)) { op = ((type_byte & 0x1f) << 8) + getc_testeof(input, inputname); if ((op == OP_endBlock) && (i < block_indx)) --block_indx; else { proc_op_flag = FLAG_ON; /* set flag for use below */ proc_type = LONG_OP; break; } } else { proc_op_flag = FLAG_ON; /* set flag for use below */ proc_type = ~(LONG_OP); break; } } if (eof_flag == FLAG_OFF) { (void)strcpy(work_fname, outputname); workfile = fopen(work_fname, "r"); if (workfile == NULL) { terrno = errno; /* save errno */ pip_error( "Chapterize error opening previous output file as input\n"); (void)sprintf(msg, " file=%s, retcd=%d\n", outputname, errno); pip_error(msg); pip_error(" Can't complete chapterization --\n\n"); pip_error(" *** ABORTING ***\n"); errno = terrno; exit(3); } else { ++out_filnum; (void)strcpy(output_name, output_fnm); (void)strcat(output_name, itostr(out_filnum)); (void)strcat(output_name, output_ext); (void)sprintf(msg, "--ipfe: Processing output file: %s\n", outputname); pip_error(msg); _fmode = BINARY_FILE; output = fopen(outputname, "w"); if (output == NULL) { terrno = errno; /* save errno */ (void)sprintf(msg, "--ipfe: Error opening output file=%s, retcd=%d\n", outputname, errno); pip_error(msg); errno = terrno; exit(4); } else { /* * Then, copy Hdr & BEGIN/Preamble(s) to new output */ out_numpages = 0; out_offset = 0; for (i=0; i <= block_indx; i++) { len = out_end_offset[i] - out_beg_offset[i] + 1; out_beg_offset[i] = out_offset; iocopyn(len, workfile, work_fname); temp_end_offset = out_end_offset[i]; out_end_offset[i] = out_offset - 1; if (i < block_indx) /* if there is more to do */ { len = out_beg_offset[i+1] - temp_end_offset - 1; ioreadn(len, workfile, work_fname); } } } (void)fclose(workfile); /* * Finally, if a token other than OP_endBlock token was read above, * process it */ if (proc_op_flag == FLAG_ON) { if (proc_type == LONG_OP) proc_long_op(op); else proc_ip_token(type_byte, input, inputname); } } } } } /**************************************************************** * * proc_file: process the input file * ****************************************************************/ proc_file() { long offset; int i, op, retcd, exit_flag; int type_byte; /* must be int for stdio EOF */ char msg[128]; if (setjmp(next_file) != 0) /* for error recovery of */ { /* unexpected EOF */ return; } offset = in_offset; retcd = get_ip_hdr(input, inputname); /* get the hdr */ if (retcd == OK) { (void)sprintf(msg, "-- Hdr : %s--\n", hdr_workbuf); pip_error(msg); mputc_prop('\n'); put_offset_msg_to_prop(offset, hdr_workbuf); pip_prop("--\n"); if (input_indx == 0) /* if 1st file, */ { if (proc_flag[CONCAT] == FLAG_ON) (void)strcpy((hdr_workbuf+IP_VERS_OFFSET), "2.1 "); (void)strcpy(hdr_buf, hdr_workbuf); /* save hdr */ if (output != NULL) { (void)sprintf(msg, "\nProcessing output file: %s\n", outputname); pip_error(msg); (void)sprintf(msg, "-- Output Hdr: %s--\n", hdr_workbuf); pip_error(msg); ip_puts(hdr_workbuf); /* copy hdr & add len to out_offset */ } /* * copy everything up to, but NOT including (will include later), * OP_beginBlock */ exit_flag = FLAG_OFF; while (exit_flag == FLAG_OFF) { type_byte = getc_testeof(input, inputname); if ((type_byte & OP_Mask) == (LONG_OP & OP_Mask)) { op = ((type_byte & 0x1f) << 8) + getc_testeof(input, inputname); if (op == OP_beginBlock) exit_flag = FLAG_ON; else { ip_putc(type_byte); ip_putc(op); } } else proc_ip_token(type_byte, input, inputname); } out_end_offset[0] = out_offset - 1; /* * if concatenating, wrap a BEGIN empty_preamble END after the hdr & * instructionsBody and around the rest of the output */ if (proc_flag[CONCAT] == FLAG_ON) { ++block_indx; out_beg_offset[block_indx] = out_offset; put_op(OP_beginBlock); put_op(OP_beginBody); put_op(OP_endBody); out_end_offset[block_indx] = out_offset - 1; } /* * NOW include the OP_beginBlock, & process the rest of the master */ proc_long_op(OP_beginBlock); } prc_ip_tokens(input, inputname); mputc_prop('\n'); indent(off_indent, propfile); (void)sprintf(msg, "--Number of Blocks:%4d\n", num_blocks); pip_prop(msg); indent(off_indent, propfile); (void)sprintf(msg, "--Number of Pages :%4d\n", num_pages); pip_prop(msg); indent(off_indent, propfile); (void)sprintf(msg, "--Number of SIFs :%4d\n", num_sifs); pip_prop(msg); for (i=0; merge_pg[input_indx][i] != 0; i++) { if (merge_pg[input_indx][i] > num_pages) { (void)sprintf(msg, "\n--ipfe: *** Page %d selected > # of pages in %s (%d)\n", merge_pg[input_indx][i], inputname, num_pages); pip_error(msg); break; } } } /*** else { (void)sprintf(msg, "(*** PROCESSING ABORTED ***)\n"); pip_error(msg); input_indx = num_infiles; abort_flag = FLAG_ON; } ***/ } /**************************************************************** * * prc_IF_bof(ifile, ifilename): * prc_IF_bof: read specified Interpress file & * discard everything up to, and * including, first OP_beginBlock * ****************************************************************/ prc_IF_bof(ifile, ifilename) FILE *ifile; char *ifilename; { int op, exit_flag; int type_byte; /* must be int for stdio EOF */ exit_flag = FLAG_OFF; while (exit_flag == FLAG_OFF) { type_byte = getc_testeof(ifile, ifilename); if ((type_byte & OP_Mask) == (LONG_OP & OP_Mask)) { op = ((type_byte & 0x1f) << 8) + getc_testeof(ifile, ifilename); if (op == OP_beginBlock) exit_flag = FLAG_ON; } } } /**************************************************************** * * prc_IF_fragment(ifile, ifilename): * prc_IF_fragment: process specified Interpress fragment * (i.e., skip everything up to, and * including the first OP_beginBlock; * then include everything up to, but * not including, the next OP_endBlock) * ****************************************************************/ prc_IF_fragment(ifile, ifilename) FILE *ifile; char *ifilename; { int op, exit_flag; int type_byte; /* must be int for stdio EOF */ /* * read & discard everything up to, and including, OP_beginBlock */ prc_IF_bof(ifile, ifilename); /* * read & copy everything up to, but NOT including OP_endBlock */ exit_flag = FLAG_OFF; while (exit_flag == FLAG_OFF) { type_byte = getc_testeof(ifile, ifilename); if ((type_byte & OP_Mask) == (LONG_OP & OP_Mask)) { op = ((type_byte & 0x1f) << 8) + getc_testeof(ifile, ifilename); if (op == OP_endBlock) exit_flag = FLAG_ON; else put_op(op); } else proc_ip_token(type_byte, ifile, ifilename); } } /**************************************************************** * * prc_IF_master(ifile, ifilename, pg): * prc_IF_master: process specified page of the * specified Interpress master * (i.e., skip everything up to, and * including the first OP_beginBlock; * then include the contents of the * preamble and the specified page, * without including the body tokens) * ****************************************************************/ prc_IF_master(ifile, ifilename, pg) FILE *ifile; int pg; char *ifilename; { int op, exit_flag, wrt_flag, blk_indx, pg_cnt; int level[MX_BLOCK_DEPTH], ctr[MX_BLOCK_DEPTH]; int type_byte; /* must be int for stdio EOF */ /* * read & discard everything up to, and including, OP_beginBlock */ prc_IF_bof(ifile, ifilename); /* * read & copy the contents of the preamble; then, copy only the * contents of the specified page */ blk_indx = pg_cnt = 0; level[blk_indx] = ctr[blk_indx] = 0; wrt_flag = FLAG_OFF; exit_flag = FLAG_OFF; while (exit_flag == FLAG_OFF) { type_byte = getc_testeof(ifile, ifilename); if ((type_byte & OP_Mask) == (LONG_OP & OP_Mask)) { op = ((type_byte & 0x1f) << 8) + getc_testeof(ifile, ifilename); if (op == OP_beginBlock) { ++blk_indx; level[blk_indx] = ctr[blk_indx] = 0; } else if (op == OP_endBlock) { if (blk_indx > 0) --blk_indx; else exit_flag = FLAG_ON; } else if (op == OP_beginBody) { if (level[blk_indx] == 0) { if (ctr[blk_indx] == 0) wrt_flag = FLAG_ON; /* processing preamble */ else { ++pg_cnt; if (pg == pg_cnt) wrt_flag = FLAG_ON; /* got the right pg */ } ++ctr[blk_indx]; } else if (wrt_flag == FLAG_ON) put_op(op); ++level[blk_indx]; } else if (op == OP_endBody) { --level[blk_indx]; if (level[blk_indx] == 0) { wrt_flag = FLAG_OFF; if (pg == pg_cnt) exit_flag = FLAG_ON; } else if (wrt_flag == FLAG_ON) put_op(op); } else if (wrt_flag == FLAG_ON) put_op(op); } else if (wrt_flag == FLAG_ON) proc_ip_token(type_byte, ifile, ifilename); } } /**************************************************************** * * proc_ip_token(type_byte, file, filename): * proc_ip_token: process interpress token of specified * type from specified file * ****************************************************************/ proc_ip_token(type_byte, file, filename) FILE *file; int type_byte; char *filename; { long len; int op; if (type_byte != EOF) { if ((type_byte & 0x80) == 0) /* token is a SHORT NUMBER */ { ip_putc(type_byte); /* 2-byte token */ ip_putc(getc_testeof(file, filename)); } else /* token is something else */ { switch (type_byte & OP_Mask) { case (SHORT_OP & OP_Mask): ip_putc(type_byte); /* 1-byte token */ break; case (LONG_OP & OP_Mask): op = ((type_byte & 0x1f) << 8) + getc_testeof(file, filename); /* 2-byte token */ proc_long_op(op); break; case (SHORT_SEQUENCE & OP_Mask): len = getc_testeof(file, filename); proc_sequence(type_byte, len, file, filename); break; case (LONG_SEQUENCE & OP_Mask): len = getc_testeof(file, filename) << 16; len = len + (getc_testeof(file, filename) << 8); len = len + getc_testeof(file, filename); proc_sequence(type_byte, len, file, filename); break; } } } } /**************************************************************** * * prc_ip_tokens(file, filename): * prc_ip_tokens: process interpress tokens * specified file * ****************************************************************/ prc_ip_tokens(file, filename) FILE *file; char *filename; { int type_byte; /* must be int for stdio EOF */ while ((type_byte = mgetc(file)) != EOF) { proc_ip_token(type_byte, file, filename); } } /**************************************************************** * * proc_long_op(op): * proc_long_op: process long_op * ****************************************************************/ proc_long_op(op) int op; { long val; int i, nesting_level; switch (op) { case (OP_beginBlock): put_op(op); ++num_blocks; ++tnum_blocks; if (block_indx == 0) out_end_offset[block_indx] = out_offset - 3; ++block_indx; out_beg_offset[block_indx] = out_offset - 2; blk_num_bytes[block_indx] = 2; put_opname_to_prop(op); preamble_expected = FLAG_ON; break; case (OP_endBlock): put_op(op); put_opname_to_prop(op); --block_indx; break; case (OP_beginBody): put_opname_to_prop(op); if (preamble_expected == FLAG_ON) { put_op(op); preamble_expected = FLAG_OFF; endpreamble_expected = FLAG_ON; } else if (bop_flag == FLAG_ON) { put_op(op); if (bop_iindx[bop_indx] == 0) bop_preamble_expected[bop_indx] = FLAG_ON; else if ((bop_iindx[bop_indx] == 1) && (bop_preamble_expected[bop_indx] == FLAG_ON)) bop_preamble_expected[bop_indx] = FLAG_OFF; ++bop_iindx[bop_indx]; } else /* we have a righteous pageBody */ { ++num_pages; ++tnum_pages; frstpg_flag = FLAG_ON; pg_num_bytes = 2; if ((merge_pg[input_indx][merge_indx] == 0) || (num_pages < merge_pg[input_indx][merge_indx])) ipwrite_flag = FLAG_OFF; else { ipwrite_flag = FLAG_ON; /* it should already be on */ put_op(op); if ((proc_flag[LANDSCAPE] == FLAG_ON) || (proc_flag[ROTATE] == FLAG_ON)) { put_Integer((long)rot_deg); put_op(OP_rotate); put_op(OP_concatt); if ((rxoff_den == 0) || (rxoff_den == 1)) put_Integer(rxoff_num); else put_seqRational(rxoff_num, rxoff_den); if ((ryoff_den == 0) || (ryoff_den == 1)) put_Integer(ryoff_num); else put_seqRational(ryoff_num, ryoff_den); put_op(OP_translate); put_op(OP_concatt); } if (proc_flag[BINDING_OFFSET] == FLAG_ON) { if ((proc_flag[DUPLEX] == FLAG_ON) && ((num_pages % 2) == 0)) val = -(boff_num); else val = boff_num; if (proc_flag[LANDSCAPE] == FLAG_ON) { put_Integer(0L); /* no xShift */ if ((boff_den == 0) || (boff_den == 1)) put_Integer(-(val)); /* -(yShift) */ else put_seqRational(-(val), boff_den); } else { if ((boff_den == 0) || (boff_den == 1)) put_Integer(val); else put_seqRational(val, boff_den); put_Integer(0L); /* no yShift */ } put_op(OP_translate); put_op(OP_concatt); } if ((proc_flag[X_OFFSET] == FLAG_ON) || (proc_flag[Y_OFFSET] == FLAG_ON)) { if ((xoff_den == 0) || (xoff_den == 1)) put_Integer(xoff_num); else put_seqRational(xoff_num, xoff_den); if ((yoff_den == 0) || (yoff_den == 1)) put_Integer(yoff_num); else put_seqRational(yoff_num, yoff_den); put_op(OP_translate); put_op(OP_concatt); } if (proc_flag[SCALE] == FLAG_ON) { if ((scale_den == 0) | (scale_den == 1)) put_Integer(scale_num); else put_seqRational(scale_num, scale_den); put_op(OP_scale); put_op(OP_concatt); } if ((merge_pg[input_indx][merge_indx] == (-1)) && (num_pages == merge_pg[input_indx][(merge_indx+1)])) ++merge_indx; if ((num_pages == merge_pg[input_indx][merge_indx]) && (ovly_pg[input_indx][merge_indx] != (-1))) { put_op(OP_dosavesimplebody); put_op(OP_beginBody); } } } begBody_flag = FLAG_ON; break; case (OP_endBody): put_opname_to_prop(op); if (bop_flag == FLAG_ON) { put_op(op); --bop_iindx[bop_indx]; if ((bop_iindx[bop_indx] == 0) && (bop_indx > 0)) --bop_indx; if ((bop_indx == 0) && (bop_iindx[bop_indx] == 0)) bop_flag = FLAG_OFF; } else /* bop_flag == FLAG_OFF */ { if (endpreamble_expected == FLAG_ON) /* then processing preamble -- can't chapterize */ { put_op(op); endpreamble_expected = FLAG_OFF; /* * this next code determines the length of each BEGIN/Preamble to copy * for chapterizing as part of handling nested blocks */ out_end_offset[block_indx] = out_offset - 1; } else /* we have a righteous endBody */ { if (ipwrite_flag == FLAG_ON) { put_op(op); ++out_numpages; ovly_flag = FLAG_OFF; while (num_pages == merge_pg[input_indx][merge_indx]) { if (ovly_pg[input_indx][merge_indx] != (-1)) { ovly_flag = FLAG_ON; proc_overlay(); } ++merge_indx; } if (ovly_flag == FLAG_ON) { put_op(OP_endBody); ovly_flag = FLAG_OFF; } proc_chapterize(); } if (merge_pg[input_indx][merge_indx] == 0) { if (proc_flag[CONCAT] == FLAG_ON) nesting_level = block_indx - 1; else nesting_level = block_indx; for (i=0; i < nesting_level; i++) put_op(OP_endBlock); ipwrite_flag = FLAG_OFF; } else ipwrite_flag = FLAG_ON; } } break; case (OP_makesimpleco): case (OP_dosavesimplebody): case (OP_if): case (OP_ifelse): case (OP_ifcopy): case (OP_correct): put_op(op); put_opname_to_prop(op); if (bop_flag == FLAG_OFF) { bop_indx = 0; bop_flag = FLAG_ON; } else ++bop_indx; bop_iindx[bop_indx] = 0; bop_preamble_expected[bop_indx] = FLAG_OFF; break; default: put_op(op); break; } } /**************************************************************** * * proc_overlay: process the current * ovly_pg[input_indx][merge_indx] * ****************************************************************/ proc_overlay() { put_op(OP_dosavesimplebody); put_op(OP_beginBody); ovly_indx = ovly_pg[input_indx][merge_indx]; if ((ovly_den[0][ovly_indx] != 0) || (ovly_den[1][ovly_indx] != 0)) { if ((ovly_den[0][ovly_indx] == 0) || (ovly_den[0][ovly_indx] == 1)) put_Integer(ovly_num[0][ovly_indx]); else put_seqRational(ovly_num[0][ovly_indx], ovly_den[0][ovly_indx]); if ((ovly_den[1][ovly_indx] == 0) || (ovly_den[1][ovly_indx] == 1)) put_Integer(ovly_num[1][ovly_indx]); else put_seqRational(ovly_num[1][ovly_indx], ovly_den[1][ovly_indx]); put_op(OP_translate); put_op(OP_concatt); } proc_ovly_file(ovly_fname[ovly_indx]); put_op(OP_endBody); } /**************************************************************** * * prc_ovly_file(fname): * proc_ovly_file: try to open specified filename; * if open_err, * create a SIF reference * else, * process as a SIF * ****************************************************************/ proc_ovly_file(fname) char *fname; { int retcd, pgnum; char msg[128]; ovly_file = fopen(fname, "r"); if (ovly_file == NULL) { (void)sprintf(msg, " --Error opening overlay file: %s\n", fname); pip_error(msg); create_SIF(fname); } else { retcd = get_ip_hdr(ovly_file, fname); if (retcd == ERROR) create_SIF(fname); else { /*** The following assumes we're not already nested in a body_operator (i.e., that we were at a real endBody when invoked) ***/ bop_flag = FLAG_ON; bop_indx = 0; bop_iindx[0] = 0; bop_preamble_expected[0] = FLAG_ON; if (strlen(hdr_workbuf) > IP_HDR_MASTERLEN) prc_IF_fragment(ovly_file, fname); else { if (ovly_pgnum[ovly_indx] == 0) pgnum = 1; else pgnum = ovly_pgnum[ovly_indx]; prc_IF_master(ovly_file, fname, pgnum); } bop_flag = FLAG_OFF; } (void)fclose(ovly_file); } } /**************************************************************** * * proc_sequence(type_byte, length, file, filename): * proc_sequence: process Interpress tokens of type * <sequence> * ****************************************************************/ proc_sequence(type_byte, length, file, filename) FILE *file; long length; int type_byte; char *filename; { if ((type_byte & 0x1f) == sequenceInsertFile) proc_SIF_token(type_byte, length, file, filename); else { put_seq_type_len(type_byte, length); iocopyn(length, file, filename); } } /**************************************************************** * * prc_SIF_file(sfile, sfilename): * prc_SIF_file: process sequenceInsertFile * ****************************************************************/ prc_SIF_file(sfile, sfilename) FILE *sfile; char *sfilename; { /* * if the IP_HDR indicates the SIF is a fragment, process as such; * else, for a regular SIF, just process the first page of a master */ if (strlen(hdr_workbuf) > IP_HDR_MASTERLEN) prc_IF_fragment(sfile, sfilename); else prc_IF_master(sfile, sfilename, 1); } /**************************************************************** * * proc_SIF_token(type, length, file, filename): * proc_SIF_token: process sequenceInsertFile token * ****************************************************************/ proc_SIF_token(type_byte, length, file, filename) FILE *file; long length; int type_byte; char *filename; { int i, retcd; char msg[128], buf[MX_HDR_BUFLEN], open_buf[MX_HDR_BUFLEN]; static char *preserve_msg = " --(Preserving the SIF reference)\n", *remove_msg = " --(Removing the SIF reference)\n"; ++num_sifs; ++tnum_sifs; test_newline(); put_offset_msg_to_prop((in_offset-1), "--SIF: "); if ((length == 0) || (length > MX_HDR_BUFLEN)) { (void)sprintf(msg, "--Warning: sequenceInsertFile token encountered with\n"); pip_error(msg); (void)sprintf(msg, " descriptor length = %d\n", length); pip_error(msg); (void)sprintf(msg, "(ERROR: Descriptor length = %d)\n", length); pip_prop(msg); if (proc_flag[REMOVE_SIFS] == FLAG_ON) { pip_error(remove_msg); ioreadn(length, file, filename); } else { pip_error(preserve_msg); /* * preserve the SIF reference */ copy_preserve_SIF(type_byte, length, file, filename); } } else { iogetn(length, file, filename, buf); (void)strcpy(open_buf, buf); (void)sprintf(msg, " --SIF: %s (nesting depth=%d)\n", buf, sif_indx); pip_error(msg); (void)sprintf(msg, "%s\n", buf); pip_prop(msg); /* * Check for alias */ for (i=0; i < num_aliases; i++) { if (strcmp(buf, alias_ref[i]) == 0) { (void)strcpy(open_buf, alias_act[i]); (void)sprintf(msg, " --Alias: %s=%s\n", buf, open_buf); pip_error(msg); indent((off_indent + cur_indent + 8), propfile); (void)sprintf(msg,"--Alias: %s=%s\n", buf, open_buf); pip_prop(msg); break; } } if (proc_flag[SATISFY_SIFS] == FLAG_OFF) { if (proc_flag[REMOVE_SIFS] == FLAG_ON) pip_error(remove_msg); else { pip_error( " -s switch (Satisfy SIFS option) not specified\n"); pip_error(preserve_msg); put_preserve_SIF(type_byte, length, buf); } } else if (sif_indx >= MX_SIF_DEPTH) { (void)sprintf(msg, "*** warning: maximum SIF nesting depth allowed in IPFE=%d\n", MX_SIF_DEPTH); pip_error(msg); if (proc_flag[REMOVE_SIFS] == FLAG_ON) pip_error(remove_msg); else { pip_error(preserve_msg); /* * preserve the SIF reference */ put_preserve_SIF(type_byte, length, buf); } } else { sif_file[sif_indx] = fopen(open_buf, "r"); if (sif_file[sif_indx] == NULL) { pip_error(" "); (void)sprintf(msg, "--Error opening SIF file: %s\n", open_buf); pip_error(msg); indent((off_indent + cur_indent + 8), propfile); pip_prop(msg); if (proc_flag[REMOVE_SIFS] == FLAG_ON) pip_error(remove_msg); else { pip_error(preserve_msg); /* * preserve the SIF reference */ put_preserve_SIF(type_byte, length, buf); } } else { /* * check the validity of the SIF hdr */ retcd = get_ip_hdr(sif_file[sif_indx], open_buf); if (retcd == ERROR) { if (proc_flag[REMOVE_SIFS] == FLAG_ON) pip_error(remove_msg); else { pip_error(preserve_msg); /* * preserve the SIF reference */ put_preserve_SIF(type_byte, length, buf); } } else { (void)strcpy(sif_name[sif_indx], open_buf); sifname = sif_name[sif_indx]; siffile = sif_file[sif_indx]; pip_error( " -- Processing SIF content --\n"); ++sif_indx; prc_SIF_file(siffile, sifname); --sif_indx; } (void)fclose(sif_file[sif_indx]); } } } } /**************************************************************** * * put_Integer(val): * put_Integer: if ((val > INTEGER_MAX) || * (val < INTEGER_MIN)) * put val out as seqInteger * else * put val out as Short Number * token (biased by 4000 (0xfa0)) * ****************************************************************/ put_Integer(val) long val; { int len; if ((val < INTEGER_MIN) || (val > INTEGER_MAX)) { len = count_int_bytes(val); put_seq_type_len(sequenceInteger, (long)len); put_intn(val, len); } else { val = val + INTEGER_ZERO; /* add bias */ ip_putc((char)((val >> 8) & 0x7f)); ip_putc((char)val); } } /**************************************************************** * * put_intn(val, len): * put_intn: put specified val out as len bytes * ****************************************************************/ put_intn(val, len) long val; int len; /* measured in bytes */ { int i; if (len > 0) { --len; for (i=len*8; i >= 0; i=i-8) ip_putc((char)(val >> i)); } } /**************************************************************** * * put_offset_msg_to_prop(off, msg): * put_offset_msg_to_prop: put specified in_offset (formatted) * + <: > + <cur_indent> + msg * to propfile * ****************************************************************/ put_offset_msg_to_prop(off, msg) long off; char *msg; { if (cur_col == 0) { if (proc_flag[DEBUG] == FLAG_ON) put_offp_to_prop(off); indent(cur_indent, propfile); } pip_prop(msg); } /**************************************************************** * * put_off_to_prop(off, format_flag): * put_off_to_prop: put specified in_offset (formatted) * to propfile * ****************************************************************/ put_off_to_prop(off, format_flag) long off; int format_flag; { int i, procflag; char digit; if (propfile != NULL) { procflag = FLAG_OFF; for (i=20; i >= 0; i=i-4) { digit = (off >> i) & 0x0f; if ((digit == 0) && (procflag == FLAG_OFF) && (i > 4)) { if (format_flag == FORMAT) mputc_prop(SPC); } else { if (digit > 9) digit = digit + 7; mputc_prop(digit + 0x30); procflag = FLAG_ON; } if ((i == 16) && ((format_flag == FORMAT) || (procflag == FLAG_ON))) mputc_prop(SPC); } } } /**************************************************************** * * put_offp_to_prop(off): * put_offp_to_prop: put specified in_offset (formatted * plus "+ " or ": " to propfile * ****************************************************************/ put_offp_to_prop(off) long off; { put_off_to_prop(off, FORMAT); if (off > 0xffffff) pip_prop("+ "); else pip_prop(": "); } /**************************************************************** * * put_op(op): * put_op: put specified op to output * ****************************************************************/ put_op(op) int op; { if (op <= SHORT_OP_LIMIT) ip_putc(op | SHORT_OP); else { ip_putc((op >> 8) | LONG_OP); ip_putc(op); } } /**************************************************************** * * put_opname_to_prop(op): * put_opname_to_prop: put specified op_name to propfile * ****************************************************************/ put_opname_to_prop(op) int op; { char msg[128]; if (op != OP_endBody) test_begBody(); begBody_flag = FLAG_OFF; /* reset because we're ALWAYS putting SOMETHING to propfile here */ switch (op) { case (OP_beginBlock): test_newline(); (void)sprintf(msg, "%s\n", op_name(op)); put_offset_msg_to_prop((in_offset-2), msg); cur_indent = cur_indent + INDENT_INCR; break; case (OP_endBlock): cur_indent = cur_indent - INDENT_INCR; test_newline(); put_offset_msg_to_prop((in_offset-2), op_name(op)); if (proc_flag[DEBUG] == FLAG_ON) { indent((INDENT_INCR - 1), propfile); mputc_prop('('); put_off_to_prop((in_offset-1), DONT_FORMAT); mputc_prop(')'); } mputc_prop('\n'); break; case (OP_beginBody): put_offset_msg_to_prop((in_offset-2), op_name(op)); indent((INDENT_INCR - 1), propfile); if ((proc_flag[PROPERTIES] == FLAG_ON) && (prop_level > 0)) { if ((preamble_expected == FLAG_OFF) && (endpreamble_expected == FLAG_OFF) && (bop_flag == FLAG_OFF)) { /* we have a righteous pageBody */ (void)sprintf(msg, "Pg%d", (tnum_pages + 1)); pip_prop(msg); indent((INDENT_INCR - 1), propfile); } } cur_indent = cur_indent + INDENT_INCR; break; case (OP_endBody): cur_indent = cur_indent - INDENT_INCR; if (cur_col == 0) indent((cur_indent + off_indent), propfile); pip_prop(op_name(op)); if ((proc_flag[PROPERTIES] == FLAG_ON) && (prop_level > 0)) { if ((endpreamble_expected == FLAG_OFF) && (bop_flag == FLAG_OFF)) { /* we have a righteous endBody */ indent((INDENT_INCR - 1), propfile); (void)sprintf(msg, "endPg%d", tnum_pages); pip_prop(msg); } } if (proc_flag[DEBUG] == FLAG_ON) { indent((INDENT_INCR - 1), propfile); mputc_prop('('); put_off_to_prop((in_offset-1), DONT_FORMAT); mputc_prop(')'); } if (debug_flag == FLAG_ON) { indent((INDENT_INCR - 1), propfile); (void)sprintf(msg,"[%d %d %d %d]", bop_indx, bop_iindx[bop_indx], bop_iindx[0], endpreamble_expected); pip_prop(msg); } mputc_prop('\n'); break; case (OP_makesimpleco): case (OP_dosavesimplebody): case (OP_if): case (OP_ifelse): case (OP_ifcopy): put_offset_msg_to_prop((in_offset-2), op_name(op)); mputc_prop('\n'); break; case (OP_correct): /* * don't do all those nasty CORRECT's unless the user forces us to */ if (prop_level > 1) { put_offset_msg_to_prop((in_offset-2), op_name(op)); mputc_prop('\n'); } break; default: break; } } /**************************************************************** * * put_seqRational(num, den): * put_seqRational: put specified numerator & denominator * out as a sequenceRational * ****************************************************************/ put_seqRational(num, den) long num, den; { int len, num_len, den_len; num_len = count_int_bytes(num); den_len = count_int_bytes(den); if (num_len > den_len) len = num_len; else len = den_len; put_seq_type_len(sequenceRational, (long)(len * 2)); put_intn(num, len); put_intn(den, len); } /**************************************************************** * * put_seq_type_len(type_byte, length): * put_seq_type_len: put specified type_byte & length * to output * ****************************************************************/ put_seq_type_len(type_byte, length) long length; int type_byte; { if (length > SHORT_SEQUENCE_LIMIT) { ip_putc((char)(LONG_SEQUENCE | (type_byte & 0x1f))); ip_putc((char)(length >> 16)); ip_putc((char)(length >> 8)); ip_putc((char)length); } else { ip_putc((char)(SHORT_SEQUENCE | (type_byte & 0x1f))); ip_putc((char)length); } } /**************************************************************** * * test_begBody: if beBody flag is set, * put a newline to propfile * ****************************************************************/ test_begBody() { if (begBody_flag == FLAG_ON) { mputc_prop('\n'); begBody_flag = FLAG_OFF; } } /**************************************************************** * * test_newline: if cur_col != 0, * put a newline to propfile * ****************************************************************/ test_newline() { if (cur_col != 0) mputc_prop('\n'); } /**************************************************************** * * usage: dsply the cmd_line interface * ****************************************************************/ Usage() { fprintf(STDERR, "Usage:\n"); fprintf(STDERR, " ipfe [ options ] file [pagerange ... [file [pagerange]...]\n"); fprintf(STDERR, "Options:\n"); fprintf(STDERR, " [-l logfile] [-dDiLqrRs] [-a alias:actual [-a alias:actual]\n"); fprintf(STDERR, " ...] [-b offset:unit] [-c count:unit] [-o outfile]\n"); fprintf(STDERR, " [-p level:propfile] [-S factor] [-X offset:unit]\n"); fprintf(STDERR, " [-Y offset:unit]\n\n"); fprintf(STDERR, " -a alias:actual (alias). If the -s option is specified,\n"); fprintf(STDERR, " replace any SIF matching the string \"alias\"\n"); fprintf(STDERR, " with the string \"actual\" before attempting\n"); fprintf(STDERR, " to satisfy the SIF. If \"actual\" cannot be\n"); fprintf(STDERR, " opened or there is some error, the SIF\n"); fprintf(STDERR, " \"alias\" is preserved, unless the -r option\n"); fprintf(STDERR, " is also specified.\n"); fprintf(STDERR, " -b offset:unit (binding offset). Shift the image offset units\n"); fprintf(STDERR, " in the x-direction, where unit may be: none\n"); fprintf(STDERR, " (default centimeters), c (centimeters), i\n"); fprintf(STDERR, " (inches), p (points), P (Picas). If the -L\n"); fprintf(STDERR, " (Landscape) switch is set, the image shift\n"); fprintf(STDERR, " is in the y-direction.\n"); fprintf(STDERR, " -c count:unit (chapterize) every count units, where unit\n"); fprintf(STDERR, " be: p (pages), k (kilobytes), m (megabytes).\n"); fprintf(STDERR, " -d (duplex). For resolving binding offset.\n"); fprintf(STDERR, " -D (debug). If the -p option is specified, also\n"); fprintf(STDERR, " write to the properties file the offsets of\n"); fprintf(STDERR, " each skeleton-level token encountered.\n"); fprintf(STDERR, " -i (insert SIF for overlay). Insert (create) a\n"); fprintf(STDERR, " SIF for any unresolvable overlays.\n"); fprintf(STDERR, " -l logfile (log). Keep a running log.\n"); fprintf(STDERR, " -L (Landscape). Rotate every page 90 degrees\n"); fprintf(STDERR, " counterclockwise and preserve the upper left\n"); fprintf(STDERR, " corner. Intended for printing text in\n"); fprintf(STDERR, " landscape orientation.\n"); fprintf(STDERR, " -o outfile (output). Where the output goes. If there is\n"); fprintf(STDERR, " no -o and there is a -p, only the properties\n"); fprintf(STDERR, " are written, else if there is no -o,\n"); fprintf(STDERR, " \"infile.ip\" is used if it doesn't already\n"); fprintf(STDERR, " exist, else \"infileN.ip\" is used, where N\n"); fprintf(STDERR, " is the lowest integer such that \"infileN.ip\"\n"); fprintf(STDERR, " does not already exist.\n"); fprintf(STDERR, " -p level:propfile\n"); fprintf(STDERR, " (properties). Where the properties are\n"); fprintf(STDERR, " written. Increasing levels provide increasing\n"); fprintf(STDERR, " information details.\n"); fprintf(STDERR, " -q (quiet). Don't write info and error msgs (to\n"); fprintf(STDERR, " STDERR).\n"); fprintf(STDERR, " -r (remove SIFS). If -s is also specified, it\n"); fprintf(STDERR, " takes precedence and a SIF reference is\n"); fprintf(STDERR, " removed only if it is unresolved or there is\n"); fprintf(STDERR, " some other error.\n"); fprintf(STDERR, " -R (Rotate). Rotate every page 90 degrees\n"); fprintf(STDERR, " clockwise and preserve the center point.\n"); fprintf(STDERR, " Intended for rotating an image created for a\n"); fprintf(STDERR, " \"landscape printer\" to print in portrait\n"); fprintf(STDERR, " orientation.\n"); fprintf(STDERR, " -s (satisfy SIFS). Replace any SIF reference\n"); fprintf(STDERR, " with the tokens found in the referenced file.\n"); fprintf(STDERR, " If the referenced file cannot be opened, the\n"); fprintf(STDERR, " SIF reference is preserved unless -r is also\n"); fprintf(STDERR, " specified.\n"); fprintf(STDERR, " -S factor (scale). Scale the image by factor.\n"); fprintf(STDERR, " -X offset:unit (X-imageShift). Shift the image offset units\n"); fprintf(STDERR, " in the x-direction, where unit may be: none\n"); fprintf(STDERR, " (default centimeters), c (centimeters), i\n"); fprintf(STDERR, " (inches), p (points), P (Picas). The shift\n"); fprintf(STDERR, " is independent of the -L and -R switches\n"); fprintf(STDERR, " (i.e., the x-direction is the same as the\n"); fprintf(STDERR, " unrotated image).\n"); fprintf(STDERR, " -Y offset:unit (Y-imageShift). Shift the image offset units\n"); fprintf(STDERR, " in the y-direction, where unit may be: none\n"); fprintf(STDERR, " (default centimeters), c (centimeters), i\n"); fprintf(STDERR, " (inches), p (points), P (Picas). The shift\n"); fprintf(STDERR, " is independent of the -L and -R switches\n"); fprintf(STDERR, " (i.e., the y-direction is the same as the\n"); fprintf(STDERR, " unrotated image).\n"); fprintf(STDERR, " infile [pagerange]\n"); fprintf(STDERR, " See the manual page for syntax details.\n"); fprintf(STDERR, " Example:\n"); fprintf(STDERR, " [1,4-6,9[pic1],10-11,12[pic2:2(2P,4P)][pic3(-4P,-2P)],15-]\n\n"); exit(1); } /*** end of file = IPFE.C *************************************/