From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/RTF-1_06a1/reader.c | 1380 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1380 insertions(+) create mode 100644 support/RTF-1_06a1/reader.c (limited to 'support/RTF-1_06a1/reader.c') diff --git a/support/RTF-1_06a1/reader.c b/support/RTF-1_06a1/reader.c new file mode 100644 index 0000000000..c3ed341bf5 --- /dev/null +++ b/support/RTF-1_06a1/reader.c @@ -0,0 +1,1380 @@ +/* + reader.c - RTF file reader. Distribution 1.06. + + ASCII 10 (\n) and 13 (\r) are ignored and silently discarded. + (The read hook will still get a look at them.) + + "\:" is not a ":", it's a control symbol. But some versions of + Word seem to write "\:" for ":". This reader treats "\:" as a + plain text ":" + + This reader needs to catch \cf and \cb in the color table + reader? (Doesn't yet.) +*/ + +# include +# include +# include "rtf.h" + + +/* + Return pointer to new element of type t, or NULL +*/ + +# define New(t) ((t *) RTFAlloc (sizeof (t))) + + +extern char *index (); +extern char *malloc (); +extern char *strcpy (); + + +/* + Public variables (listed in rtf.h) +*/ + +char rtfTextBuf[rtfBufSiz]; +int rtfTextLen; +int rtfClass; +int rtfMajor; +int rtfMinor; +int rtfParam; + + +/* + Private stuff +*/ + + +static RTFFont *fontList = NULL; /* these lists MUST be */ +static RTFColor *colorList = NULL; /* initialized to NULL */ +static RTFStyle *styleList = NULL; + + +static FILE *rtffp = stdin; + +static int pushback = EOF; + + +static void _RTFGetToken (); +static int GetChar (); +static int HexVal (); +static void ReadFontTbl (); +static void ReadColorTbl (); +static void ReadStyleSheet (); +static void ReadInfoGroup (); +static void ReadPictGroup (); +static void LookupInit (); +static void Lookup (); +static int Hash (); + + +/* + Initialize the reader. This may be called multiple times. + The only thing not reset is the input stream. +*/ + +void RTFInit () +{ +int i; +RTFColor *cp; +RTFFont *fp; +RTFStyle *sp; +RTFStyleElt *eltList, *ep; + + /* initialize lookup table */ + LookupInit (); + + for (i = 0; i < rtfMaxClass; i++) + RTFSetClassCallback (i, NULL); + for (i = 0; i < rtfMaxDestination; i++) + RTFSetDestinationCallback (i, NULL); + + /* install built-in destination readers */ + RTFSetDestinationCallback (rtfFontTbl, ReadFontTbl); + RTFSetDestinationCallback (rtfColorTbl, ReadColorTbl); + RTFSetDestinationCallback (rtfStyleSheet, ReadStyleSheet); + RTFSetDestinationCallback (rtfInfo, ReadInfoGroup); + RTFSetDestinationCallback (rtfPict, ReadPictGroup); + + RTFSetReadHook (NULL); + + /* dump old lists if necessary */ + + while (fontList != NULL) + { + fp = fontList->rtfNextFont; + RTFFree (fontList->rtfFName); + RTFFree ((char *) fontList); + fontList = fp; + } + while (colorList != NULL) + { + cp = colorList->rtfNextColor; + RTFFree ((char *) colorList); + colorList = cp; + } + while (styleList != NULL) + { + sp = styleList->rtfNextStyle; + eltList = styleList->rtfSSEList; + while (eltList != NULL) + { + ep = eltList->rtfNextSE; + RTFFree (eltList->rtfSEText); + RTFFree ((char *) eltList); + eltList = ep; + } + RTFFree (styleList->rtfSName); + RTFFree ((char *) styleList); + styleList = sp; + } + + pushback = EOF; +} + + +/* + Set the reader's input stream to the given stream. Can + be used to redirect other than to the default (stdin). +*/ + +void RTFSetStream (stream) +FILE *stream; +{ + rtffp = stream; +} + + +/* ---------------------------------------------------------------------- */ + +/* + Callback table manipulation routines +*/ + + +/* + Install or return a writer callback for a token class +*/ + +static void (*ccb[rtfMaxClass]) (); /* class callbacks */ + +void RTFSetClassCallback (class, callback) +int class; +void (*callback) (); +{ + if (class >= 0 && class < rtfMaxClass) + ccb[class] = callback; +} + + +void (*RTFGetClassCallback (class)) () +int class; +{ + if (class >= 0 && class < rtfMaxClass) + return (ccb[class]); + return (NULL); +} + + +/* + Install or return a writer callback for a destination type +*/ + +static void (*dcb[rtfMaxDestination]) (); /* destination callbacks */ + +void RTFSetDestinationCallback (dest, callback) +int dest; +void (*callback) (); +{ + if (dest >= 0 && dest < rtfMaxDestination) + dcb[dest] = callback; +} + + +void (*RTFGetDestinationCallback (dest)) () +int dest; +{ + if (dest >= 0 && dest < rtfMaxDestination) + return (dcb[dest]); + return (NULL); +} + + +/* ---------------------------------------------------------------------- */ + +/* + Token reading routines +*/ + + +/* + Read the input stream, invoking the writer's callbacks + where appropriate. +*/ + +void RTFRead () +{ + while (RTFGetToken () != rtfEOF) + RTFRouteToken (); +} + + +/* + Route a token. If it's a destination for which a reader is + installed, process the destination internally, otherwise + pass the token to the writer's class callback. +*/ + +void RTFRouteToken () +{ +void (*p) (); + + if (rtfClass < 0 || rtfClass >= rtfMaxClass) /* watchdog */ + { + fprintf (stderr, "Unknown class %d: %s", rtfClass, rtfTextBuf); + fprintf (stderr, " (reader malfunction)\n"); + return; + } + if (RTFCheckCM (rtfControl, rtfDestination)) + { + /* invoke destination-specific callback if there is one */ + if ((p = RTFGetDestinationCallback (rtfMinor)) != NULL) + { + (*p) (); + return; + } + } + /* invoke class callback if there is one */ + if ((p = RTFGetClassCallback (rtfClass)) != NULL) + (*p) (); +} + + +/* + Skip to the end of the current group. When this returns, + writers that maintain a state stack may want to call their + state unstacker; global vars will still be set to the group's + closing brace. +*/ + +void RTFSkipGroup () +{ +int level = 1; + + while (RTFGetToken () != rtfEOF) + { + if (rtfClass == rtfGroup) + { + if (rtfMajor == rtfBeginGroup) + ++level; + else if (rtfMajor == rtfEndGroup) + { + if (--level < 1) + break; /* end of initial group */ + } + } + } +} + + +/* + Read one token. Call the read hook if there is one. The + token class is the return value. Returns rtfEOF when there + are no more tokens. +*/ + +int RTFGetToken () +{ +void (*p) (); + + for (;;) + { + _RTFGetToken (); + if ((p = RTFGetReadHook ()) != NULL) + (*p) (); /* give read hook a look at token */ + + /* Silently discard newlines and carriage returns. */ + if (!(rtfClass == rtfText + && (rtfMajor == '\n' || rtfMajor == '\r'))) + break; + } + return (rtfClass); +} + + +/* + Install or return a token reader hook. +*/ + +static void (*readHook) (); + +void RTFSetReadHook (f) +void (*f) (); +{ + readHook = f; +} + + +void (*RTFGetReadHook ()) () +{ + return (readHook); +} + + +static void _RTFGetToken () +{ +int sign; +int c; + + /* initialize token vars */ + + rtfClass = rtfUnknown; + rtfParam = 0; + rtfTextBuf[rtfTextLen = 0] = '\0'; + + /* get first character, which may be a pushback from previous token */ + + if (pushback != EOF) + { + c = pushback; + rtfTextBuf[rtfTextLen] = c; + rtfTextBuf[++rtfTextLen] = '\0'; + pushback = EOF; + } + else if ((c = GetChar ()) == EOF) + { + rtfClass = rtfEOF; + return; + } + + if (c == '{') + { + rtfClass = rtfGroup; + rtfMajor = rtfBeginGroup; + return; + } + if (c == '}') + { + rtfClass = rtfGroup; + rtfMajor = rtfEndGroup; + return; + } + if (c != '\\') + { + /* + Two possibilities here: + 1) ASCII 9, effectively like \tab control symbol + 2) literal text char + */ + if (c == '\t') /* ASCII 9 */ + { + rtfClass = rtfControl; + rtfMajor = rtfTab; + } + else + { + rtfClass = rtfText; + rtfMajor = c; + } + return; + } + if ((c = GetChar ()) == EOF) + { + /* early eof, whoops (class is rtfUnknown) */ + return; + } + if (!isalpha (c)) + { + /* + Three possibilities here: + 1) hex encoded text char, e.g., \'d5, \'d3 + 2) special escaped text char, e.g., \{, \} + 3) control symbol, e.g., \_, \-, \|, \<10> + */ + if (c == '\'') /* hex char */ + { + int c2; + + if ((c = GetChar ()) != EOF && (c2 = GetChar ()) != EOF) + { + /* should do isxdigit check! */ + rtfClass = rtfText; + rtfMajor = HexVal (c) * 16 + HexVal (c2); + return; + } + /* early eof, whoops (class is rtfUnknown) */ + return; + } + + if (index (":{}\\", c) != NULL) /* escaped char */ + { + rtfClass = rtfText; + rtfMajor = c; + return; + } + + /* control symbol */ + Lookup (rtfTextBuf); /* sets class, major, minor */ + return; + } + /* control word */ + while (isalpha (c)) + { + if ((c = GetChar ()) == EOF) + break; + } + + /* + At this point, the control word is all collected, so the + major/minor numbers are determined before the parameter + (if any) is scanned. There will be one too many characters + in the buffer, though, so fix up before and restore after + looking up. + */ + + if (c != EOF) + rtfTextBuf[rtfTextLen-1] = '\0'; + Lookup (rtfTextBuf); /* sets class, major, minor */ + if (c != EOF) + rtfTextBuf[rtfTextLen-1] = c; + + /* + Should be looking at first digit of parameter if there + is one, unless it's negative. In that case, next char + is '-', so need to gobble next char, and remember sign. + */ + + sign = 1; + if (c == '-') + { + sign = -1; + c = GetChar (); + } + if (c != EOF) + { + while (isdigit (c)) /* gobble parameter */ + { + rtfParam = rtfParam * 10 + c - '0'; + if ((c = GetChar ()) == EOF) + break; + } + rtfParam *= sign; + } + /* + If control symbol delimiter was a blank, gobble it. + Otherwise the character is first char of next token, so + push it back for next call. In either case, delete the + delimiter from the token buffer. + */ + if (c != EOF) + { + if (c != ' ') + pushback = c; + rtfTextBuf[--rtfTextLen] = '\0'; + } + return; +} + + +/* + Distributions up through 1.04 assumed high bit could be set in + RTF file characters. Beginning with 1.05, that's not true, but + still check and die if such a character is found. +*/ + +static int GetChar () +{ +int c; + + if ((c = getc (rtffp)) != EOF) + { + if (c & 0x80) + { + fprintf (stderr, "Char with high bit set (%#x) found\n", c); + exit (1); + } + rtfTextBuf[rtfTextLen] = c; + rtfTextBuf[++rtfTextLen] = '\0'; + } + return (c); +} + + +static int HexVal (c) +char c; +{ + if (isupper (c)) + c = tolower (c); + if (isdigit (c)) + return (c - '0'); /* '0'..'9' */ + return (c - 'a' + 10); /* 'a'..'f' */ +} + + +/* + Synthesize a token by setting the global variables to the + values supplied. Typically this is followed with a call + to RTFRouteToken(). + + If param is non-negative, it becomes part of the token text. +*/ + +void RTFSetToken (class, major, minor, param, text) +int class, major, minor, param; +char *text; +{ + rtfClass = class; + rtfMajor = major; + rtfMinor = minor; + rtfParam = param; + if (param >= 0) + sprintf (rtfTextBuf, "%s%d", text, param); + else + strcpy (rtfTextBuf, text); + rtfTextLen = strlen (rtfTextBuf); +} + + +/* ---------------------------------------------------------------------- */ + +/* + Special destination readers. They gobble the destination so the + writer doesn't have to deal with them. That's wrong for any + translator that wants to process any of these itself. In that + case, these readers should be overridden by installing a different + destination callback. + + The last token read by each of these reader will be the destination's + terminating '}', which will then be the current token. That token + is passed to RTFRouteToken() - the writer had already seen the '{' + that began the destination grou, and may have pushed a state; it also + needs to know at the end of the group that a state should be popped. + + It's important that rtf.h and the control token lookup table list + as many symbols as possible, because these readers unfortunately + make strict assumptions about the input they expect, and a token + of class rtfUnknown will throw them off easily. +*/ + + +/* + Read { \fonttbl ... } destination. Old font tables don't have + braces around each table entry; try to adjust for that. +*/ + +static void ReadFontTbl () +{ +RTFFont *fp; +char buf[rtfBufSiz], *bp; +int old = -1; + + for (;;) + { + (void) RTFGetToken (); + if (RTFCheckCM (rtfGroup, rtfEndGroup)) + break; + if (old < 0) /* first entry - determine tbl type */ + { + if (RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) + old = 1; /* no brace */ + else if (RTFCheckCM (rtfGroup, rtfBeginGroup)) + old = 0; /* brace */ + else + { /* can't tell! */ + fprintf (stderr, "Bad font table-1\n"); + exit (1); + } + } + if (old == 0) /* need to find "{" here */ + { + if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) + { + fprintf (stderr, "Bad font table-2\n"); + exit (1); + } + (void) RTFGetToken (); /* yes, skip to next token */ + } + if ((fp = New (RTFFont)) == NULL) + { + fprintf (stderr, "Can't allocate font entry\n"); + exit (1); + } + fp->rtfNextFont = fontList; + fontList = fp; + if (!RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) + { + fprintf (stderr, "Bad font table-3\n"); + exit (1); + } + fp->rtfFNum = rtfParam; + (void) RTFGetToken (); + if (!RTFCheckCM (rtfControl, rtfFontFamily)) + { + fprintf (stderr, "Bad font table-4\n"); + exit (1); + } + fp->rtfFFamily = rtfMinor; + bp = buf; + while (RTFGetToken () == rtfText) + { + if (rtfMajor == ';') + break; + *bp++ = rtfMajor; + } + *bp = '\0'; + if ((fp->rtfFName = RTFStrSave (buf)) == NULL) + { + fprintf (stderr, "Can't allocate font name\n"); + exit (1); + } + if (old == 0) /* need to see "}" here */ + { + (void) RTFGetToken (); + if (!RTFCheckCM (rtfGroup, rtfEndGroup)) + { + fprintf (stderr, "Bad font table-5\n"); + exit (1); + } + } + } + RTFRouteToken (); /* feed "}" back to router */ +} + + +/* + The color table entries have color values of -1 if + the default color should be used for the entry (only + a semi-colon is given in the definition, no color values). + There will be a problem if a partial entry (1 or 2 but + not 3 color values) is given. The possibility is ignored + here. +*/ + +static void ReadColorTbl () +{ +RTFColor *cp; +int cnum = 0; + + for (;;) + { + (void) RTFGetToken (); + if (RTFCheckCM (rtfGroup, rtfEndGroup)) + break; + if ((cp = New (RTFColor)) == NULL) + { + fprintf (stderr, "Can't allocate color entry\n"); + exit (1); + } + cp->rtfCNum = cnum++; + cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1; + cp->rtfNextColor = colorList; + colorList = cp; + for (;;) + { + if (!RTFCheckCM (rtfControl, rtfColorName)) + break; + switch (rtfMinor) + { + case rtfRed: cp->rtfCRed = rtfParam; break; + case rtfGreen: cp->rtfCGreen = rtfParam; break; + case rtfBlue: cp->rtfCBlue = rtfParam; break; + } + RTFGetToken (); + } + if (!RTFCheckCM (rtfText, (int) ';')) + { + fprintf (stderr, "Bad color table\n"); + exit (1); + } + } + RTFRouteToken (); /* feed "}" back to router */ +} + + +/* + The "Normal" style definition doesn't contain any style number + (why?), all others do. Normal style is given style 0. +*/ + +static void ReadStyleSheet () +{ +RTFStyle *sp; +RTFStyleElt *sep, *sepLast; +char buf[rtfBufSiz], *bp; + + for (;;) + { + (void) RTFGetToken (); + if (RTFCheckCM (rtfGroup, rtfEndGroup)) + break; + if ((sp = New (RTFStyle)) == NULL) + { + fprintf (stderr, "Can't allocate style entry\n"); + exit (1); + } + sp->rtfSNum = -1; + sp->rtfSBasedOn = rtfBasedOnNone; + sp->rtfSNextPar = -1; + sp->rtfSSEList = sepLast = NULL; + sp->rtfNextStyle = styleList; + sp->rtfExpanding = 0; + styleList = sp; + if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) + { + fprintf (stderr, "Bad stylesheet-1\n"); + exit (1); + } + while (RTFGetToken () == rtfControl) + { + if (RTFCheckMM (rtfParAttr, rtfStyleNum)) + { + sp->rtfSNum = rtfParam; + continue; + } + if (RTFCheckMM (rtfStyleAttr, rtfBasedOn)) + { + sp->rtfSBasedOn = rtfParam; + continue; + } + if (RTFCheckMM (rtfStyleAttr, rtfNext)) + { + sp->rtfSNextPar = rtfParam; + continue; + } + if ((sep = New (RTFStyleElt)) == NULL) + { + fprintf (stderr, "Can't allocate style element\n"); + exit (1); + } + sep->rtfSEClass = rtfClass; + sep->rtfSEMajor = rtfMajor; + sep->rtfSEMinor = rtfMinor; + sep->rtfSEParam = rtfParam; + if ((sep->rtfSEText = RTFStrSave (rtfTextBuf)) == NULL) + { + fprintf (stderr, "Can't allocate style element\n"); + exit (1); + } + if (sepLast == NULL) /* first style element */ + sp->rtfSSEList = sep; + else /* add to end */ + sepLast->rtfNextSE = sep; + sep->rtfNextSE = NULL; + sepLast = sep; + } + if (sp->rtfSNextPar == -1) /* \snext not given */ + sp->rtfSNextPar = sp->rtfSNum; /* next is itself */ + if (rtfClass != rtfText) + { + fprintf (stderr, "Bad stylesheet-2\n"); + exit (1); + } + bp = buf; + while (rtfClass == rtfText) + { + if (rtfMajor == ';') + { + (void) RTFGetToken (); + break; + } + *bp++ = rtfMajor; + (void) RTFGetToken (); + } + *bp = '\0'; + if (sp->rtfSNum < 0) /* no style number was specified */ + { /* (only legal for Normal style) */ + if (strcmp (buf, "Normal") != 0) + { + fprintf (stderr, "Bad stylesheet-3\n"); + exit (1); + } + sp->rtfSNum = 0; + } + if ((sp->rtfSName = RTFStrSave (buf)) == NULL) + { + fprintf (stderr, "Can't allocate style name\n"); + exit (1); + } + if (!RTFCheckCM (rtfGroup, rtfEndGroup)) + { + fprintf (stderr, "Bad stylesheet-4\n"); + exit (1); + } + } + RTFRouteToken (); /* feed "}" back to router */ +} + + +static void ReadInfoGroup () +{ + RTFSkipGroup (); + RTFRouteToken (); /* feed "}" back to router */ +} + + +static void ReadPictGroup () +{ + RTFSkipGroup (); + RTFRouteToken (); /* feed "}" back to router */ +} + + +/* ---------------------------------------------------------------------- */ + +/* + Routines to return pieces of stylesheet, or font or color tables +*/ + + +RTFStyle *RTFGetStyle (num) +int num; +{ +RTFStyle *s; + + if (num == -1) + return (styleList); + for (s = styleList; s != NULL; s = s->rtfNextStyle) + { + if (s->rtfSNum == num) + break; + } + return (s); /* NULL if not found */ +} + + +RTFFont *RTFGetFont (num) +int num; +{ +RTFFont *f; + + if (num == -1) + return (fontList); + for (f = fontList; f != NULL; f = f->rtfNextFont) + { + if (f->rtfFNum == num) + break; + } + return (f); /* NULL if not found */ +} + + +RTFColor *RTFGetColor (num) +int num; +{ +RTFColor *c; + + if (num == -1) + return (colorList); + for (c = colorList; c != NULL; c = c->rtfNextColor) + { + if (c->rtfCNum == num) + break; + } + return (c); /* NULL if not found */ +} + + +/* ---------------------------------------------------------------------- */ + + +/* + Expand style n, if there is such a style. +*/ + +void RTFExpandStyle (n) +int n; +{ +RTFStyle *s; +RTFStyleElt *se; + + if (n == -1 || (s = RTFGetStyle (n)) == NULL) + return; + if (s->rtfExpanding != 0) + { + fprintf (stderr, "Style expansion loop, style %d\n", n); + exit (1); + } + s->rtfExpanding = 1; /* set expansion flag for loop detection */ + /* + Expand "based-on" style. This is done by synthesizing + the token that the writer needs to see in order to trigger + another style expansion, and feeding to token back through + the router so the writer sees it. + */ + RTFSetToken (rtfControl, rtfParAttr, rtfStyleNum, s->rtfSBasedOn, "\\s"); + RTFRouteToken (); + /* + Now route the tokens unique to this style + */ + for (se = s->rtfSSEList; se != NULL; se = se->rtfNextSE) + { + rtfClass = se->rtfSEClass; + rtfMajor = se->rtfSEMajor; + rtfMinor = se->rtfSEMinor; + rtfParam = se->rtfSEParam; + strcpy (rtfTextBuf, se->rtfSEText); + rtfTextLen = strlen (rtfTextBuf); + RTFRouteToken (); + } + s->rtfExpanding = 0; /* done - clear expansion flag */ +} + + +/* ---------------------------------------------------------------------- */ + +/* + Control symbol lookup routines +*/ + + +typedef struct RTFKey RTFKey; + +struct RTFKey +{ + int rtfKMajor; /* major number */ + int rtfKMinor; /* minor number */ + char *rtfKStr; /* symbol name */ + int rtfKHash; /* symbol name hash value */ +}; + +/* + A minor number of -1 means the token has no minor number + (all valid minor numbers are >= 0). +*/ + +static RTFKey rtfKey[] = +{ + rtfSpecialChar, rtfCurHeadPict, "chpict", 0, /* ?? */ + + rtfSpecialChar, rtfCurHeadDate, "chdate", 0, + rtfSpecialChar, rtfCurHeadTime, "chtime", 0, + rtfSpecialChar, rtfCurHeadPage, "chpgn", 0, + rtfSpecialChar, rtfCurFNote, "chftn", 0, + rtfSpecialChar, rtfCurAnnotRef, "chatn", 0, + rtfSpecialChar, rtfFNoteSep, "chftnsep", 0, + rtfSpecialChar, rtfFNoteCont, "chftnsepc", 0, + rtfSpecialChar, rtfFormula, "|", 0, + rtfSpecialChar, rtfNoBrkSpace, "~", 0, + rtfSpecialChar, rtfNoReqHyphen, "-", 0, + rtfSpecialChar, rtfNoBrkHyphen, "_", 0, + rtfSpecialChar, rtfCell, "cell", 0, + rtfSpecialChar, rtfRow, "row", 0, + rtfSpecialChar, rtfPar, "par", 0, + rtfSpecialChar, rtfPar, "\n", 0, + rtfSpecialChar, rtfPar, "\r", 0, + rtfSpecialChar, rtfSect, "sect", 0, + rtfSpecialChar, rtfPage, "page", 0, + rtfSpecialChar, rtfColumn, "column", 0, + rtfSpecialChar, rtfLine, "line", 0, + rtfSpecialChar, rtfTab, "tab", 0, + rtfSpecialChar, rtfOptDest, "*", 0, + rtfSpecialChar, rtfIIntVersion, "vern", 0, + rtfSpecialChar, rtfICreateTime, "creatim", 0, + rtfSpecialChar, rtfIRevisionTime, "revtim", 0, + rtfSpecialChar, rtfIPrintTime, "printim", 0, + rtfSpecialChar, rtfIBackupTime, "buptim", 0, + rtfSpecialChar, rtfIEditTime, "edmins", 0, + rtfSpecialChar, rtfIYear, "yr", 0, + rtfSpecialChar, rtfIMonth, "mo", 0, + rtfSpecialChar, rtfIDay, "dy", 0, + rtfSpecialChar, rtfIHour, "hr", 0, + rtfSpecialChar, rtfIMinute, "min", 0, + rtfSpecialChar, rtfINPages, "nofpages", 0, + rtfSpecialChar, rtfINWords, "nofwords", 0, + rtfSpecialChar, rtfINChars, "nofchars", 0, + rtfSpecialChar, rtfIIntID, "id", 0, + + rtfCharAttr, rtfPlain, "plain", 0, + rtfCharAttr, rtfBold, "b", 0, + rtfCharAttr, rtfItalic, "i", 0, + rtfCharAttr, rtfStrikeThru, "strike", 0, + rtfCharAttr, rtfOutline, "outl", 0, + rtfCharAttr, rtfShadow, "shad", 0, + rtfCharAttr, rtfSmallCaps, "scaps", 0, + rtfCharAttr, rtfAllCaps, "caps", 0, + rtfCharAttr, rtfInvisible, "v", 0, + rtfCharAttr, rtfFontNum, "f", 0, + rtfCharAttr, rtfFontSize, "fs", 0, + rtfCharAttr, rtfExpand, "expnd", 0, + rtfCharAttr, rtfUnderline, "ul", 0, + rtfCharAttr, rtfWUnderline, "ulw", 0, + rtfCharAttr, rtfDUnderline, "uld", 0, + rtfCharAttr, rtfDbUnderline, "uldb", 0, + rtfCharAttr, rtfNoUnderline, "ulnone", 0, + rtfCharAttr, rtfSuperScript, "up", 0, + rtfCharAttr, rtfSubScript, "dn", 0, + rtfCharAttr, rtfRevised, "revised", 0, + rtfCharAttr, rtfForeColor, "cf", 0, + rtfCharAttr, rtfBackColor, "cb", 0, + + rtfParAttr, rtfParDef, "pard", 0, + rtfParAttr, rtfStyleNum, "s", 0, + rtfParAttr, rtfQuadLeft, "ql", 0, + rtfParAttr, rtfQuadRight, "qr", 0, + rtfParAttr, rtfQuadJust, "qj", 0, + rtfParAttr, rtfQuadCenter, "qc", 0, + rtfParAttr, rtfFirstIndent, "fi", 0, + rtfParAttr, rtfLeftIndent, "li", 0, + rtfParAttr, rtfRightIndent, "ri", 0, + rtfParAttr, rtfSpaceBefore, "sb", 0, + rtfParAttr, rtfSpaceAfter, "sa", 0, + rtfParAttr, rtfSpaceBetween, "sl", 0, + rtfParAttr, rtfInTable, "intbl", 0, + rtfParAttr, rtfKeep, "keep", 0, + rtfParAttr, rtfKeepNext, "keepn", 0, + rtfParAttr, rtfSideBySide, "sbys", 0, + rtfParAttr, rtfPBBefore, "pagebb", 0, + rtfParAttr, rtfNoLineNum, "noline", 0, + rtfParAttr, rtfTabPos, "tx", 0, + rtfParAttr, rtfTabRight, "tqr", 0, + rtfParAttr, rtfTabCenter, "tqc", 0, + rtfParAttr, rtfTabDecimal, "tqdec", 0, + rtfParAttr, rtfTabBar, "tb", 0, + rtfParAttr, rtfBorderTop, "brdrt", 0, + rtfParAttr, rtfBorderBottom, "brdrb", 0, + rtfParAttr, rtfBorderLeft, "brdrl", 0, + rtfParAttr, rtfBorderRight, "brdrr", 0, + rtfParAttr, rtfBorderBar, "bar", 0, + rtfParAttr, rtfBorderBox, "box", 0, + rtfParAttr, rtfBorderBetween, "brdrbtw", 0, + rtfParAttr, rtfBorderSingle, "brdrs", 0, + rtfParAttr, rtfBorderThick, "brdrth", 0, + rtfParAttr, rtfBorderShadow, "brdrsh", 0, + rtfParAttr, rtfBorderDouble, "brdrdb", 0, + rtfParAttr, rtfBorderDot, "brdrdot", 0, + rtfParAttr, rtfBorderHair, "brdrhair", 0, + rtfParAttr, rtfLeaderDot, "tldot", 0, + rtfParAttr, rtfLeaderHyphen, "tlhyph", 0, + rtfParAttr, rtfLeaderUnder, "tlul", 0, + rtfParAttr, rtfLeaderThick, "tlth", 0, + rtfParAttr, rtfBorderSpace, "brsp", 0, + + rtfSectAttr, rtfSectDef, "sectd", 0, + /*rtfSectAttr, rtfNoBreak, "nobreak", 0, + rtfSectAttr, rtfColBreak, "colbreak", 0, + rtfSectAttr, rtfPageBreak, "pagebreak", 0, + rtfSectAttr, rtfEvenBreak, "evenbreak", 0, + rtfSectAttr, rtfOddBreak, "oddbreak", 0,*/ + rtfSectAttr, rtfNoBreak, "sbknone", 0, + rtfSectAttr, rtfColBreak, "sbkcol", 0, + rtfSectAttr, rtfPageBreak, "sbkpage", 0, + rtfSectAttr, rtfEvenBreak, "sbkeven", 0, + rtfSectAttr, rtfOddBreak, "sbkodd", 0, + rtfSectAttr, rtfPageCont, "pgncont", 0, + rtfSectAttr, rtfPageStarts, "pgnstarts", 0, + rtfSectAttr, rtfPageRestart, "pgnrestart", 0, + rtfSectAttr, rtfPageDecimal, "pgndec", 0, + rtfSectAttr, rtfPageURoman, "pgnucrm", 0, + rtfSectAttr, rtfPageLRoman, "pgnlcrm", 0, + rtfSectAttr, rtfPageULetter, "pgnucltr", 0, + rtfSectAttr, rtfPageLLetter, "pgnlcltr", 0, + rtfSectAttr, rtfPageNumLeft, "pgnx", 0, + rtfSectAttr, rtfPageNumTop, "pgny", 0, + rtfSectAttr, rtfHeaderY, "headery", 0, + rtfSectAttr, rtfFooterY, "footery", 0, + rtfSectAttr, rtfLineModulus, "linemod", 0, + rtfSectAttr, rtfLineDist, "linex", 0, + rtfSectAttr, rtfLineStarts, "linestarts", 0, + rtfSectAttr, rtfLineRestart, "linerestart", 0, + rtfSectAttr, rtfLineRestartPg, "lineppage", 0, + rtfSectAttr, rtfLineCont, "linecont", 0, + rtfSectAttr, rtfTopVAlign, "vertalt", 0, + rtfSectAttr, rtfBottomVAlign, "vertal", 0, + rtfSectAttr, rtfCenterVAlign, "vertalc", 0, + rtfSectAttr, rtfJustVAlign, "vertalj", 0, + rtfSectAttr, rtfColumns, "cols", 0, + rtfSectAttr, rtfColumnSpace, "colsx", 0, + rtfSectAttr, rtfColumnLine, "linebetcol", 0, + rtfSectAttr, rtfENoteHere, "endnhere", 0, + rtfSectAttr, rtfTitleSpecial, "titlepg", 0, + + rtfDocAttr, rtfPaperWidth, "paperw", 0, + rtfDocAttr, rtfPaperHeight, "paperh", 0, + rtfDocAttr, rtfLeftMargin, "margl", 0, + rtfDocAttr, rtfRightMargin, "margr", 0, + rtfDocAttr, rtfTopMargin, "margt", 0, + rtfDocAttr, rtfBottomMargin, "margb", 0, + rtfDocAttr, rtfFacingPage, "facingp", 0, + rtfDocAttr, rtfGutterWid, "gutter", 0, + rtfDocAttr, rtfDefTab, "deftab", 0, + rtfDocAttr, rtfWidowCtrl, "widowctrl", 0, + rtfDocAttr, rtfHyphHotZone, "hyphhotz", 0, + rtfDocAttr, rtfFNoteEndSect, "endnotes", 0, + rtfDocAttr, rtfFNoteEndDoc, "enddoc", 0, + rtfDocAttr, rtfFNoteBottom, "ftnbj", 0, + rtfDocAttr, rtfFNoteText, "ftntj", 0, + rtfDocAttr, rtfFNoteStart, "ftnstart", 0, + rtfDocAttr, rtfFNoteRestart, "ftnrestart", 0, + rtfDocAttr, rtfPageStart, "pgnstart", 0, + rtfDocAttr, rtfLineStart, "linestart", 0, + rtfDocAttr, rtfLandscape, "landscape", 0, + rtfDocAttr, rtfFracWidth, "fracwidth", 0, + rtfDocAttr, rtfNextFile, "nextfile", 0, + rtfDocAttr, rtfTemplate, "template", 0, + rtfDocAttr, rtfMakeBackup, "makeback", 0, + rtfDocAttr, rtfRTFDefault, "defformat", 0, + rtfDocAttr, rtfRevisions, "revisions", 0, + rtfDocAttr, rtfMirrorMargin, "margmirror", 0, + rtfDocAttr, rtfRevDisplay, "revprop", 0, + rtfDocAttr, rtfRevBar, "revbar", 0, + + rtfStyleAttr, rtfBasedOn, "sbasedon", 0, + rtfStyleAttr, rtfNext, "snext", 0, + + rtfPictAttr, rtfMacQD, "macpict", 0, + rtfPictAttr, rtfWinMetafile, "wmetafile", 0, + rtfPictAttr, rtfWinBitmap, "wbitmap", 0, + rtfPictAttr, rtfPicWid, "picw", 0, + rtfPictAttr, rtfPicHt, "pich", 0, + rtfPictAttr, rtfPicGoalWid, "picwgoal", 0, + rtfPictAttr, rtfPicGoalWid, "picwGoal", 0, + rtfPictAttr, rtfPicGoalHt, "pichgoal", 0, + rtfPictAttr, rtfPicGoalHt, "pichGoal", 0, + rtfPictAttr, rtfPicScaleX, "picscalex", 0, + rtfPictAttr, rtfPicScaleY, "picscaley", 0, + rtfPictAttr, rtfPicScaled, "picscaled", 0, + rtfPictAttr, rtfPicCropTop, "piccropt", 0, + rtfPictAttr, rtfPicCropBottom, "piccropb", 0, + rtfPictAttr, rtfPicCropLeft, "piccropl", 0, + rtfPictAttr, rtfPicCropRight, "piccropr", 0, + rtfPictAttr, rtfPixelBits, "wbmbitspixel", 0, + rtfPictAttr, rtfBitmapPlanes, "wbmplanes", 0, + rtfPictAttr, rtfBitmapWid, "wbmwidthbytes", 0, + rtfPictAttr, rtfPicBinary, "bin", 0, + + rtfDestination, rtfPict, "pict", 0, + rtfDestination, rtfFootnote, "footnote", 0, + rtfDestination, rtfHeader, "header", 0, + rtfDestination, rtfHeaderLeft, "headerl", 0, + rtfDestination, rtfHeaderRight, "headerr", 0, + rtfDestination, rtfHeaderFirst, "headerf", 0, + rtfDestination, rtfFooter, "footer", 0, + rtfDestination, rtfFooterLeft, "footerl", 0, + rtfDestination, rtfFooterRight, "footerr", 0, + rtfDestination, rtfFooterFirst, "footerf", 0, + rtfDestination, rtfFNSep, "ftnsep", 0, + rtfDestination, rtfFNContSep, "ftnsepc", 0, + rtfDestination, rtfFNContNotice, "ftncn", 0, + rtfDestination, rtfInfo, "info", 0, + rtfDestination, rtfStyleSheet, "stylesheet", 0, + rtfDestination, rtfFontTbl, "fonttbl", 0, + rtfDestination, rtfColorTbl, "colortbl", 0, + rtfDestination, rtfAnnotation, "annotation", 0, + rtfDestination, rtfAnnotID, "atnid", 0, + rtfDestination, rtfField, "field", 0, + rtfDestination, rtfFieldInst, "fldinst", 0, + rtfDestination, rtfFieldResult, "fldrslt", 0, + rtfDestination, rtfIndex, "xe", 0, + rtfDestination, rtfIndexBold, "bxe", 0, + rtfDestination, rtfIndexItalic, "ixe", 0, + rtfDestination, rtfIndexText, "txe", 0, + rtfDestination, rtfIndexRange, "rxe", 0, + rtfDestination, rtfTOC, "tc", 0, + rtfDestination, rtfBookmarkStart, "bkmkstart", 0, + rtfDestination, rtfBookmarkEnd, "bkmkend", 0, + rtfDestination, rtfITitle, "title", 0, + rtfDestination, rtfISubject, "subject", 0, + rtfDestination, rtfIAuthor, "author", 0, + rtfDestination, rtfIOperator, "operator", 0, + rtfDestination, rtfIKeywords, "keywords", 0, + rtfDestination, rtfIComment, "comment", 0, + rtfDestination, rtfIVersion, "version", 0, + rtfDestination, rtfIDoccomm, "doccomm", 0, + + rtfTOCAttr, rtfTOCType, "tcf", 0, + rtfTOCAttr, rtfTOCLevel, "tcl", 0, + + rtfFontFamily, rtfFFNil, "fnil", 0, + rtfFontFamily, rtfFFRoman, "froman", 0, + rtfFontFamily, rtfFFSwiss, "fswiss", 0, + rtfFontFamily, rtfFFModern, "fmodern", 0, + rtfFontFamily, rtfFFScript, "fscript", 0, + rtfFontFamily, rtfFFDecor, "fdecor", 0, + rtfFontFamily, rtfFFTech, "ftech", 0, + + rtfColorName, rtfRed, "red", 0, + rtfColorName, rtfGreen, "green", 0, + rtfColorName, rtfBlue, "blue", 0, + + rtfCharSet, rtfMacCharSet, "mac", 0, + rtfCharSet, rtfAnsiCharSet, "ansi", 0, + rtfCharSet, rtfPcCharSet, "pc", 0, + rtfCharSet, rtfPcaCharSet, "pca", 0, + + rtfTblAttr, rtfCellBordBottom, "clbrdrb", 0, + rtfTblAttr, rtfCellBordTop, "clbrdrt", 0, + rtfTblAttr, rtfCellBordLeft, "clbrdrl", 0, + rtfTblAttr, rtfCellBordRight, "clbrdrr", 0, + rtfTblAttr, rtfRowDef, "trowd", 0, + rtfTblAttr, rtfRowLeft, "trql", 0, + rtfTblAttr, rtfRowRight, "trqr", 0, + rtfTblAttr, rtfRowCenter, "trqc", 0, + rtfTblAttr, rtfRowGapH, "trgaph", 0, + rtfTblAttr, rtfRowHt, "trrh", 0, + rtfTblAttr, rtfRowLeftEdge, "trleft", 0, + rtfTblAttr, rtfCellPos, "cellx", 0, + rtfTblAttr, rtfMergeRngFirst, "clmgf", 0, + rtfTblAttr, rtfMergePrevious, "clmrg", 0, + + rtfFieldAttr, rtfFieldDirty, "flddirty", 0, + rtfFieldAttr, rtfFieldEdited, "fldedit", 0, + rtfFieldAttr, rtfFieldLocked, "fldlock", 0, + rtfFieldAttr, rtfFieldPrivate, "fldpriv", 0, + + rtfPosAttr, rtfPosX, "posx", 0, + rtfPosAttr, rtfPosXCenter, "posxc", 0, + rtfPosAttr, rtfPosXInside, "posxi", 0, + rtfPosAttr, rtfPosXLeft, "posxl", 0, + rtfPosAttr, rtfPosXOutSide, "posxo", 0, + rtfPosAttr, rtfPosXRight, "posxr", 0, + rtfPosAttr, rtfPosY, "posy", 0, + rtfPosAttr, rtfPosYInline, "posyil", 0, + rtfPosAttr, rtfPosYTop, "posyt", 0, + rtfPosAttr, rtfPosYCenter, "posyc", 0, + rtfPosAttr, rtfPosYBottom, "posyb", 0, + rtfPosAttr, rtfAbsWid, "absw", 0, + rtfPosAttr, rtfTextDist, "dxfrtext", 0, + rtfPosAttr, rtfRPosMargV, "pvmrg", 0, + rtfPosAttr, rtfRPosPageV, "pvpg", 0, + rtfPosAttr, rtfRPosMargH, "phmrg", 0, + rtfPosAttr, rtfRPosPageH, "phpg", 0, + rtfPosAttr, rtfRPosColH, "phcol", 0, + + rtfVersion, -1, "rtf", 0, + rtfDefFont, -1, "deff", 0, + + 0, -1, NULL, 0 +}; + + +/* + Initialize lookup table hash values +*/ + +static void LookupInit () +{ +static int inited = 0; +RTFKey *rp; + + if (inited == 0) + { + for (rp = rtfKey; rp->rtfKStr != NULL; rp++) + rp->rtfKHash = Hash (rp->rtfKStr); + ++inited; + } +} + + +/* + Determine major and minor number of control token. If it's + not found, the class turns into rtfUnknown. +*/ + +static void Lookup (s) +char *s; +{ +RTFKey *rp; +int hash; + + ++s; /* skip over the leading \ character */ + hash = Hash (s); + for (rp = rtfKey; rp->rtfKStr != NULL; rp++) + { + if (hash == rp->rtfKHash && strcmp (s, rp->rtfKStr) == 0) + { + rtfClass = rtfControl; + rtfMajor = rp->rtfKMajor; + rtfMinor = rp->rtfKMinor; + return; + } + } + rtfClass = rtfUnknown; +} + + +/* + Compute hash value of symbol +*/ + +static int Hash (s) +char *s; +{ +char c; +int val = 0; + + while ((c = *s++) != '\0') + val += (int) c; + return (val); +} + + +/* ---------------------------------------------------------------------- */ + +/* + Memory allocation routines +*/ + + +/* + Return pointer to block of size bytes, or NULL if there's + not enough memory available. +*/ + +char *RTFAlloc (size) +int size; +{ + return (malloc (size)); +} + + +/* + Saves a string on the heap and returns a pointer to it. +*/ + + +char *RTFStrSave (s) +char *s; +{ +char *p; + + if ((p = RTFAlloc (strlen (s) + 1)) == NULL) + return (NULL); + return (strcpy (p, s)); +} + + +void RTFFree (p) +char *p; +{ + if (p != NULL) + free (p); +} + + +/* ---------------------------------------------------------------------- */ + + +/* + Token comparison routines +*/ + +int RTFCheckCM (class, major) +int class, major; +{ + return (rtfClass == class && rtfMajor == major); +} + + +int RTFCheckCMM (class, major, minor) +int class, major, minor; +{ + return (rtfClass == class && rtfMajor == major && rtfMinor == minor); +} + + +int RTFCheckMM (major, minor) +int major, minor; +{ + return (rtfMajor == major && rtfMinor == minor); +} -- cgit v1.2.3