home *** CD-ROM | disk | FTP | other *** search
- /*LINTLIBRARY*/
-
- #include "ansic.h"
- #include "cat.h"
-
- #ifndef lint
- #ifndef NOID
- static char elsieid[] = "@(#)catsup.c 4.1";
- #endif /* !defined NOID */
- #endif /* !defined lint */
-
- extern int qsort();
-
- #if !defined TRUE
- #define TRUE 1
- #define FALSE 0
- #endif /* !defined TRUE */
-
- typedef struct {
- int c_special;
- int c_tophalf;
- int c_catcode;
- int c_vfindex;
- int c_ftindex;
- char c_ntname[3];
- } catinfo;
-
- static catinfo cattbl[] = {
- /* SPECIAL TOPHALF CATCODE VFINDEX FTINDEX NTNAME */
- { -1, -1, -1, -1, 32, " " },
- { -1, -1, -1, -1, 32, "\\ " },
- { FALSE, TRUE, 37, 33, 33, "!" },
- { TRUE, FALSE, 24, 34, 34, "\"" },
- { TRUE, TRUE, 31, 35, 35, "#" },
- { FALSE, TRUE, 45, 36, 36, "$" },
- { FALSE, FALSE, 43, 37, 37, "%" },
- { FALSE, FALSE, 40, 38, 38, "&" },
- { FALSE, FALSE, 26, 39, 39, "'" },
- { TRUE, TRUE, 28, 39, 146, "\\'" },
- { FALSE, TRUE, 26, 40, 40, "(" },
- { FALSE, TRUE, 27, 41, 41, ")" },
- { FALSE, TRUE, 18, 42, 42, "*" },
- { TRUE, TRUE, 39, 57, 228, "**" },
- { FALSE, TRUE, 35, 43, 43, "+" },
- { FALSE, FALSE, 39, 44, 44, "," },
- { FALSE, FALSE, 32, 45, 45, "-" },
- { FALSE, TRUE, 19, 4, 136, "\\-" },
- { TRUE, TRUE, 21, 8, 205, "+-" },
- { TRUE, FALSE, 28, 52, 199, "<-" },
- { FALSE, FALSE, 36, 46, 46, "." },
- { FALSE, FALSE, 35, 47, 47, "/" },
- { FALSE, TRUE, 8, 48, 48, "0" },
- { FALSE, TRUE, 9, 49, 49, "1" },
- { FALSE, TRUE, 10, 50, 50, "2" },
- { FALSE, FALSE, 30, 18, 134, "12" },
- { FALSE, TRUE, 11, 51, 51, "3" },
- { FALSE, TRUE, 12, 52, 52, "4" },
- { FALSE, FALSE, 28, 17, 133, "14" },
- { FALSE, FALSE, 38, 19, 135, "34" },
- { FALSE, TRUE, 13, 53, 53, "5" },
- { FALSE, TRUE, 14, 54, 54, "6" },
- { FALSE, TRUE, 15, 55, 55, "7" },
- { FALSE, TRUE, 16, 56, 56, "8" },
- { FALSE, TRUE, 17, 57, 57, "9" },
- { FALSE, TRUE, 34, 58, 58, ":" },
- { FALSE, FALSE, 19, 59, 59, ";" },
- { TRUE, TRUE, 3, 60, 60, "<" },
- { FALSE, TRUE, 32, 61, 61, "=" },
- { TRUE, FALSE, 63, 49, 195, "~=" },
- { TRUE, TRUE, 22, 9, 192, "<=" },
- { TRUE, TRUE, 25, 51, 197, "!=" },
- { TRUE, TRUE, 24, 48, 193, "==" },
- { TRUE, TRUE, 23, 10, 191, ">=" },
- { TRUE, TRUE, 1, 62, 62, ">" },
- { TRUE, TRUE, 44, 53, 198, "->" },
- { FALSE, TRUE, 39, 63, 63, "?" },
- { TRUE, FALSE, 18, 64, 64, "@" },
- { FALSE, TRUE, 3, 65, 65, "A" },
- { FALSE, TRUE, 3, 65, 65, "*A" },
- { FALSE, FALSE, 61, 66, 66, "B" },
- { FALSE, FALSE, 61, 66, 66, "*B" },
- { FALSE, FALSE, 56, 67, 67, "C" },
- { TRUE, TRUE, 2, 78, 180, "*C" },
- { FALSE, FALSE, 60, 68, 68, "D" },
- { TRUE, FALSE, 60, 68, 177, "*D" },
- { FALSE, FALSE, 58, 69, 69, "E" },
- { FALSE, FALSE, 58, 69, 69, "*E" },
- { FALSE, TRUE, 1, 70, 70, "F" },
- { TRUE, FALSE, 45, 85, 185, "*F" },
- { FALSE, FALSE, 53, 71, 71, "G" },
- { TRUE, FALSE, 53, 67, 176, "*G" },
- { FALSE, FALSE, 48, 72, 72, "H" },
- { TRUE, FALSE, 46, 72, 178, "*H" },
- { FALSE, FALSE, 54, 73, 73, "I" },
- { FALSE, FALSE, 54, 73, 73, "*I" },
- { FALSE, TRUE, 5, 74, 74, "J" },
- { FALSE, TRUE, 7, 75, 75, "K" },
- { FALSE, TRUE, 7, 75, 75, "*K" },
- { FALSE, FALSE, 51, 76, 76, "L" },
- { TRUE, FALSE, 51, 75, 179, "*L" },
- { FALSE, FALSE, 50, 77, 77, "M" },
- { FALSE, FALSE, 50, 77, 77, "*M" },
- { FALSE, FALSE, 49, 78, 78, "N" },
- { FALSE, FALSE, 49, 78, 78, "*N" },
- { FALSE, FALSE, 47, 79, 79, "O" },
- { FALSE, FALSE, 47, 79, 79, "*O" },
- { FALSE, FALSE, 55, 80, 80, "P" },
- { TRUE, FALSE, 55, 80, 181, "*P" },
- { FALSE, FALSE, 45, 81, 81, "Q" },
- { TRUE, FALSE, 34, 87, 186, "*Q" },
- { FALSE, FALSE, 52, 82, 82, "R" },
- { FALSE, FALSE, 55, 80, 80, "*R" },
- { FALSE, FALSE, 62, 83, 83, "S" },
- { TRUE, FALSE, 62, 82, 182, "*S" },
- { FALSE, FALSE, 46, 84, 84, "T" },
- { FALSE, FALSE, 46, 84, 84, "*T" },
- { FALSE, TRUE, 6, 85, 85, "U" },
- { TRUE, TRUE, 6, 84, 184, "*U" },
- { FALSE, FALSE, 57, 86, 86, "V" },
- { FALSE, TRUE, 4, 87, 87, "W" },
- { TRUE, FALSE, 47, 88, 187, "*W" },
- { FALSE, TRUE, 2, 88, 88, "X" },
- { FALSE, TRUE, 2, 88, 88, "*X" },
- { FALSE, FALSE, 63, 89, 89, "Y" },
- { FALSE, FALSE, 48, 72, 72, "*Y" },
- { FALSE, FALSE, 59, 90, 90, "Z" },
- { FALSE, FALSE, 59, 90, 90, "*Z" },
- { FALSE, TRUE, 28, 91, 91, "[" },
- { TRUE, FALSE, 33, 92, 92, "\\" },
- { FALSE, TRUE, 29, 93, 93, "]" },
- { TRUE, TRUE, 30, 94, 94, "^" },
- { -1, -1, -1, -1, 150, "\\^" },
- { TRUE, FALSE, 32, 95, 95, "_" },
- { FALSE, FALSE, 24, 96, 96, "`" },
- { TRUE, TRUE, 29, 96, 147, "\\`" },
- { FALSE, FALSE, 21, 97, 97, "a" },
- { TRUE, FALSE, 19, 55, 201, "da" },
- { TRUE, TRUE, 5, 28, 207, "ca" },
- { TRUE, FALSE, 21, 97, 152, "*a" },
- { TRUE, TRUE, 28, 39, 146, "aa" },
- { TRUE, FALSE, 30, 54, 200, "ua" },
- { TRUE, TRUE, 29, 96, 147, "ga" },
- { FALSE, FALSE, 10, 98, 98, "b" },
- { TRUE, TRUE, 15, 23, 235, "rb" },
- { TRUE, TRUE, 40, 91, 210, "ib" },
- { TRUE, TRUE, 12, 21, 233, "lb" },
- { TRUE, FALSE, 10, 98, 153, "*b" },
- { TRUE, FALSE, 56, 26, 208, "sb" },
- { FALSE, FALSE, 23, 99, 99, "c" },
- { TRUE, TRUE, 8, 19, 242, "rc" },
- { TRUE, TRUE, 45, 56, 144, "sc" },
- { TRUE, TRUE, 18, 18, 241, "lc" },
- { TRUE, FALSE, 11, 110, 165, "*c" },
- { FALSE, FALSE, 9, 100, 100, "d" },
- { TRUE, FALSE, 59, 121, 213, "pd" },
- { TRUE, FALSE, 9, 100, 155, "*d" },
- { TRUE, TRUE, 37, 89, 225, "dd" },
- { FALSE, FALSE, 25, 101, 101, "e" },
- { TRUE, FALSE, 25, 101, 156, "*e" },
- { FALSE, TRUE, 30, 11, 142, "de" },
- { FALSE, FALSE, 12, 102, 102, "f" },
- { TRUE, TRUE, 17, 16, 239, "lf" },
- { TRUE, TRUE, 16, 17, 240, "rf" },
- { TRUE, FALSE, 13, 117, 172, "*f" },
- { FALSE, TRUE, 22, 3, 139, "ff" },
- { TRUE, FALSE, 36, 1, 212, "if" },
- { FALSE, FALSE, 37, 103, 103, "g" },
- { TRUE, FALSE, 37, 99, 154, "*g" },
- { FALSE, TRUE, 31, 12, 143, "dg" },
- { FALSE, TRUE, 33, 15, 221, "rg" },
- { FALSE, FALSE, 1, 104, 104, "h" },
- { TRUE, FALSE, 2, 104, 159, "*h" },
- { TRUE, FALSE, 40, 4, 226, "rh" },
- { TRUE, TRUE, 32, 30, 227, "lh" },
- { FALSE, FALSE, 6, 105, 105, "i" },
- { TRUE, FALSE, 6, 105, 160, "*i" },
- { TRUE, FALSE, 52, 45, 194, "mi" },
- { FALSE, TRUE, 25, 9, 140, "Fi" },
- { FALSE, TRUE, 20, 1, 137, "fi" },
- { TRUE, TRUE, 20, 47, 204, "di" },
- { TRUE, TRUE, 41, 93, 231, "ci" },
- { FALSE, FALSE, 13, 106, 106, "j" },
- { FALSE, FALSE, 15, 107, 107, "k" },
- { TRUE, FALSE, 15, 106, 161, "*k" },
- { TRUE, TRUE, 14, 25, 237, "rk" },
- { TRUE, TRUE, 11, 24, 236, "lk" },
- { FALSE, FALSE, 5, 108, 108, "l" },
- { FALSE, TRUE, 24, 10, 141, "Fl" },
- { FALSE, TRUE, 21, 2, 138, "fl" },
- { TRUE, TRUE, 4, 14, 149, "sl" },
- { TRUE, FALSE, 5, 107, 162, "*l" },
- { TRUE, TRUE, 43, 43, 220, "pl" },
- { TRUE, FALSE, 32, 95, 148, "ul" },
- { FALSE, FALSE, 4, 109, 109, "m" },
- { FALSE, TRUE, 40, 13, 145, "fm" },
- { TRUE, FALSE, 4, 108, 163, "*m" },
- { FALSE, FALSE, 18, 6, 131, "em" },
- { FALSE, FALSE, 3, 110, 110, "n" },
- { TRUE, FALSE, 49, 6, 190, "rn" },
- { TRUE, FALSE, 3, 109, 164, "*n" },
- { FALSE, FALSE, 27, 111, 111, "o" },
- { FALSE, TRUE, 43, 14, 222, "co" },
- { TRUE, TRUE, 7, 29, 215, "no" },
- { TRUE, TRUE, 33, 31, 219, "mo" },
- { TRUE, FALSE, 27, 111, 166, "*o" },
- { FALSE, FALSE, 17, 112, 112, "p" },
- { TRUE, FALSE, 17, 112, 167, "*p" },
- { TRUE, FALSE, 38, 2, 211, "ip" },
- { TRUE, FALSE, 57, 27, 209, "sp" },
- { TRUE, FALSE, 58, 50, 196, "ap" },
- { FALSE, FALSE, 34, 113, 113, "q" },
- { TRUE, FALSE, 1, 119, 174, "*q" },
- { TRUE, FALSE, 26, 61, 202, "eq" },
- { FALSE, TRUE, 44, 8, 130, "sq" },
- { FALSE, FALSE, 29, 114, 114, "r" },
- { TRUE, FALSE, 43, 40, 214, "gr" },
- { TRUE, FALSE, 61, 11, 188, "sr" },
- { TRUE, FALSE, 22, 124, 230, "or" },
- { TRUE, FALSE, 29, 113, 168, "*r" },
- { TRUE, TRUE, 38, 90, 223, "br" },
- { FALSE, FALSE, 8, 115, 115, "s" },
- { TRUE, FALSE, 8, 114, 169, "*s" },
- { TRUE, FALSE, 54, 13, 216, "is" },
- { TRUE, FALSE, 50, 12, 189, "ts" },
- { TRUE, FALSE, 35, 7, 229, "bs" },
- { TRUE, TRUE, 35, 122, 218, "es" },
- { FALSE, FALSE, 2, 116, 116, "t" },
- { TRUE, TRUE, 13, 22, 234, "rt" },
- { FALSE, TRUE, 23, 16, 224, "ct" },
- { TRUE, TRUE, 9, 20, 232, "lt" },
- { TRUE, FALSE, 31, 115, 170, "*t" },
- { TRUE, FALSE, 39, 3, 217, "pt" },
- { FALSE, FALSE, 14, 117, 117, "u" },
- { TRUE, FALSE, 48, 5, 206, "cu" },
- { FALSE, TRUE, 38, 7, 129, "bu" },
- { TRUE, TRUE, 19, 42, 203, "mu" },
- { FALSE, FALSE, 22, 5, 132, "ru" },
- { TRUE, FALSE, 14, 116, 171, "*u" },
- { FALSE, FALSE, 31, 118, 118, "v" },
- { TRUE, TRUE, 10, 15, 238, "bv" },
- { FALSE, FALSE, 33, 119, 119, "w" },
- { TRUE, FALSE, 41, 120, 175, "*w" },
- { FALSE, FALSE, 11, 120, 120, "x" },
- { TRUE, FALSE, 23, 118, 173, "*x" },
- { FALSE, FALSE, 41, 121, 121, "y" },
- { FALSE, FALSE, 32, 45, 128, "hy" },
- { TRUE, FALSE, 12, 103, 158, "*y" },
- { FALSE, FALSE, 7, 122, 122, "z" },
- { TRUE, FALSE, 7, 102, 157, "*z" },
- { TRUE, TRUE, 26, 123, 123, "{" },
- { FALSE, TRUE, 41, 124, 124, "|" },
- { -1, -1, -1, -1, 127, "\\|" },
- { TRUE, TRUE, 27, 125, 125, "}" },
- { TRUE, TRUE, 34, 126, 126, "~" },
- { -1, -1, -1, -1, 0, "" }
- };
-
- #if !defined NVPC
- #define NVPC 256 /* Number of Values Per Character */
- #endif /* !defined NVPC */
-
- static const catinfo * code2cip[2][2][CAT_MAX_FLASH + 1];
- static const catinfo * char2cip[NVPC];
- static int didinit;
-
- static void
- tblinit()
- {
- const catinfo * acip;
- const catinfo * bcip;
- int i;
- int c;
-
- if (didinit)
- return;
- for (acip = cattbl; acip->c_ntname[0] != '\0'; ++acip) {
- if ((c = acip->c_ntname[1]) == '\0')
- c = acip->c_ntname[0];
- if (char2cip[(unsigned char) c] == NULL)
- char2cip[(unsigned char) c] = acip;
- if (acip->c_catcode <= 0)
- continue;
- bcip = code2cip[acip->c_special]
- [acip->c_tophalf]
- [acip->c_catcode];
- if (bcip != NULL && (bcip->c_ntname[1] == '\0' ||
- (acip->c_ntname[1] != '\0' &&
- acip->c_ntname[1] == '\\')))
- continue;
- code2cip[acip->c_special]
- [acip->c_tophalf]
- [acip->c_catcode] = acip;
- }
- for (i = 0; i < NVPC; ++i)
- if (char2cip[i] == NULL)
- char2cip[i] = acip;
- didinit = TRUE;
- }
-
- static const catinfo *
- ntn2cip(name)
- char * name;
- {
- const catinfo * cip;
- int c;
-
- if (!didinit)
- tblinit();
- if (name == NULL)
- return NULL;
- if (name[1] == '\0')
- return char2cip[(unsigned char) name[0]];
- if (name[0] == '\\' && name[1] == '(')
- name += 2;
- if (name[0] == '\0')
- return NULL;
- if ((c = name[1]) == '\0')
- c = name[0];
- else if (name[2] != '\0')
- return NULL;
- cip = char2cip[(unsigned char) c];
- while (cip->c_ntname[0] != '\0')
- if (cip->c_ntname[0] == name[0] &&
- cip->c_ntname[1] == name[1])
- return cip;
- else ++cip;
- return NULL;
- }
-
- int
- ntn2vfi(name)
- char * const name;
- {
- const catinfo * cip;
-
- return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_vfindex;
- }
-
- int
- ntn2fti(name)
- char * const name;
- {
- const catinfo * cip;
-
- return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_ftindex;
- }
-
- const char *
- fti2ntn(fti)
- int const fti;
- {
- catinfo * cip;
-
- for (cip = cattbl; ; ++cip)
- if (cip->c_ntname[0] == '\0')
- return NULL;
- else if (cip->c_ftindex == fti)
- return cip->c_ntname;
- }
-
- int
- ntnons(name)
- char * const name;
- {
- const catinfo * cip;
-
- return ((cip = ntn2cip(name)) == NULL) ? -1 : cip->c_special;
- }
-
- int
- ntnonr(name)
- char * const name;
- {
- const catinfo * cip;
-
- return ((cip = ntn2cip(name)) == NULL) ? -1 : !cip->c_special;
- }
-
- /*
- ** Now here's something we hope you'll really like. . .
- */
-
- extern char * malloc();
- extern char * realloc();
-
- static int curfont = 0; /* current font */
- static long horizontal = -16; /* horizontal position */
- static long vertical = 0 ; /* vertical position */
- static int escape_forward = TRUE; /* should escape forward */
- static int lead_forward = TRUE; /* should lead forward */
- static int tophalf = FALSE; /* TRUE if top half of font is wanted */
- static int true_point_size = 10;
-
- static void
- catinit()
- {
- escape_forward = TRUE;
- lead_forward = TRUE;
- tophalf = FALSE;
- curfont = 0;
- true_point_size = 10; /* troff default */
- horizontal = -16;
- }
-
- typedef struct {
- long horizontal;
- long vertical;
- char size;
- char fontname[3];
- char charname[3];
- } memory;
-
- static int
- mcomp(avp, bvp)
- void * const avp;
- void * const bvp;
- {
- const memory * const amp = (const memory *) avp;
- const memory * const bmp = (const memory *) bvp;
- long diff = amp->horizontal - bmp->horizontal;
-
- if (diff == 0) {
- diff = amp->size - bmp->size;
- if (diff == 0)
- return 0;
- }
- return (diff > 0) ? 1 : -1;
- }
-
- static char fontnicks[8][3] = {
- "R",
- "",
- "I",
- "",
- "B",
- "",
- "S",
- "",
- };
-
- static int
- doflash(catcode, outp, dosort)
- int const catcode;
- int (* const outp)();
- int const dosort;
- {
- const catinfo * cip;
- memory * mp;
- static memory * memories;
- static int memused;
- static int memavail;
- static memory zm;
-
- if (fontnicks[curfont][0] == 'S' && fontnicks[curfont][1] == '\0')
- cip = code2cip[TRUE][tophalf][catcode];
- else cip = code2cip[FALSE][tophalf][catcode];
- if (!dosort)
- if (catcode <= 0)
- return 0;
- else return ((*outp)(cip->c_ntname, horizontal, vertical,
- true_point_size, fontnicks[curfont]) == 0) ?
- 0 : -1;
- /*
- ** Flush if appropriate.
- */
- if (memused > 0 && (catcode <= 0 || vertical != memories[0].vertical)) {
- int i;
-
- (void) qsort((char *) memories, memused,
- sizeof *memories, mcomp);
- for (i = 0; i < memused; ++i) {
- mp = &memories[i];
- if ((*outp)(mp->charname,
- mp->horizontal, mp->vertical,
- mp->size, mp->fontname) != 0)
- return -1;
- }
- memused = 0;
- }
- /*
- ** Remember if appropriate.
- */
- if (catcode <= 0)
- return 0;
- if (memused >= memavail) {
- if (memavail++ == 0)
- memories = (memory *) malloc(sizeof *memories);
- else memories = (memory *) realloc((char *) memories,
- (unsigned) (memavail * sizeof *memories));
- if (memories == NULL) {
- memavail = 0;
- return -1;
- }
- memories[memused] = zm;
- }
- mp = &memories[memused];
- mp->horizontal = horizontal;
- mp->vertical = vertical;
- mp->size = true_point_size;
- mp->fontname[0] = fontnicks[curfont][0];
- mp->fontname[1] = fontnicks[curfont][1];
- mp->charname[0] = cip->c_ntname[0];
- mp->charname[1] = cip->c_ntname[1];
- ++memused;
- return 0;
- }
-
- int
- catsup(inp, outp, dosort, skipinit)
- int (* const inp)();
- int (* const outp)();
- int const dosort;
- int const skipinit;
- {
- int c;
- int i;
-
- if (inp == NULL || outp == NULL ||
- (dosort != TRUE && dosort != FALSE) ||
- (skipinit != TRUE && skipinit != FALSE))
- return -1;
- if (!skipinit) {
- catinit();
- vertical = 0;
- }
- tblinit();
- while ((c = (*inp)()) >= 0) {
- if (CAT_IS_FLASH(c)) {
- if (doflash(c, outp, dosort) != 0)
- return -1;
- } else if (CAT_IS_ESCAPE(c)) {
- i = CAT_ESCAPE(c);
- if (escape_forward)
- horizontal += i;
- else {
- horizontal -= i;
- if (horizontal < 0)
- horizontal = 0;
- }
- } else if (CAT_IS_LEADING(c)) {
- i = CAT_LEAD(c);
- if (lead_forward)
- vertical += i;
- else vertical -= i;
- } else if (CAT_IS_SIZE_CHANGE(c)) {
- i = CAT_SIZE_CHANGE(c);
- if (CAT_IS_DOUBLE_TO_SINGLE(true_point_size, i))
- horizontal += CAT_LENSE_COMPENSATION;
- else if (CAT_IS_SINGLE_TO_DOUBLE(true_point_size, i)) {
- horizontal -= CAT_LENSE_COMPENSATION;
- if (horizontal < 0)
- horizontal = 0;
- }
- true_point_size = i;
- } else switch (c) {
- case CAT_INITIALIZE:
- catinit();
- break;
- case CAT_UPPER_RAIL:
- curfont |= CAT_RAIL;
- break;
- case CAT_LOWER_RAIL:
- curfont &= ~CAT_RAIL;
- break;
- case CAT_UPPER_MAGAZINE:
- curfont |= CAT_MAGAZINE;
- break;
- case CAT_LOWER_MAGAZINE:
- curfont &= ~CAT_MAGAZINE;
- break;
- case CAT_TILT_UP:
- curfont |= CAT_TILT;
- break;
- case CAT_TILT_DOWN:
- curfont &= ~CAT_TILT;
- break;
- case CAT_UPPER_FONT:
- tophalf = TRUE;
- break;
- case CAT_LOWER_FONT:
- tophalf = FALSE;
- break;
- case CAT_ESCAPE_FORWARD:
- escape_forward = TRUE;
- break;
- case CAT_ESCAPE_BACKWARD:
- escape_forward = FALSE;
- break;
- case CAT_LEAD_FORWARD:
- lead_forward = TRUE;
- break;
- case CAT_LEAD_BACKWARD:
- lead_forward = FALSE;
- break;
- case CAT_STOP:
- break; /* ? */
- default:
- return -1;
- }
- }
- if (doflash(0, outp, dosort) != 0)
- return -1;
- return 0;
- }
-