2
* "$Id: form-tree.c 6649 2007-07-11 21:46:42Z mike $"
4
* CUPS form document tree routines for the Common UNIX Printing
7
* Copyright 2007 by Apple Inc.
8
* Copyright 1997-2005 by Easy Software Products.
10
* These coded instructions, statements, and computer programs are the
11
* property of Apple Inc. and are protected by Federal copyright
12
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
13
* which should have been included with this file. If this file is
14
* file is missing or damaged, see the license at "http://www.cups.org/".
16
* This file is subject to the Apple OS-Developed Software exception.
23
* Include necessary headers...
33
static int compare_attr(attr_t *a0, attr_t *a1);
34
static int compare_elements(char **e0, char **e1);
35
static int parse_attr(tree_t *t, FILE *fp);
36
static int parse_element(tree_t *t, FILE *fp);
43
static char *elements[] =
77
* 'formDelete()' - Delete a node and its children.
81
formDelete(tree_t *t) /* I - Tree node */
87
* 'formGetAttr()' - Get a node attribute value.
90
char * /* O - Value or NULL */
91
formGetAttr(tree_t *t, /* I - Tree node */
92
const char *name) /* I - Name of attribute */
98
* 'formNew()' - Create a new form node.
101
tree_t * /* O - New tree node */
102
formNew(tree_t *p) /* I - Parent node */
104
tree_t *t; /* New tree node */
108
* Allocate the new node...
111
if ((t = (tree_t *)calloc(sizeof(tree_t), 1)) == NULL)
115
* Set/copy attributes...
123
t->halign = HALIGN_LEFT;
124
t->valign = VALIGN_MIDDLE;
125
t->typeface = "Courier";
130
memcpy(t, p, sizeof(tree_t));
135
t->last_child = NULL;
143
* Return the new node...
151
* 'formRead()' - Read a form tree from a file.
154
tree_t * /* O - New form tree */
155
formRead(FILE *fp, /* I - File to read from */
156
tree_t *p) /* I - Parent node */
158
int ch, /* Character from file */
159
closech, /* Closing character */
160
have_whitespace; /* Leading whitespace? */
161
static char s[10240]; /* String from file */
162
uchar *ptr, /* Pointer in string */
163
glyph[16], /* Glyph name (&#nnn;) */
164
*glyphptr; /* Pointer in glyph string */
165
tree_t *tree, /* "top" of this tree */
166
*t, /* New tree node */
167
*prev, /* Previous tree node */
168
*temp; /* Temporary looping var */
169
uchar *face, /* Typeface for FONT tag */
170
*color, /* Color for FONT tag */
171
*size; /* Size for FONT tag */
175
* Start off with no previous tree node...
182
* Parse data until we hit end-of-file...
185
while ((ch = getc(fp)) != EOF)
188
* Ignore leading whitespace...
194
if (p == NULL || !p->preformatted)
196
while (isspace(ch & 255))
207
* Allocate a new tree node - use calloc() to get zeroed data...
213
* See what the character was...
219
* Markup char; grab the next char to see if this is a /...
226
* Illegal lone "<"! Ignore it...
236
if (parse_element(t, fp) < 0)
242
if ((closech = getc(fp)) == '/')
246
* If this is the matching close mark, or if we are starting the same
247
* element, or if we've completed a list, we're done!
253
* Close element; find matching element...
256
for (temp = p; temp != NULL; temp = temp->p)
257
if (temp->element == t->element)
268
else if (t->preformatted)
271
* Read a pre-formatted string into the current tree node...
275
while (ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1))
279
for (glyphptr = glyph;
280
(ch = getc(fp)) != EOF && (glyphptr - glyph) < 15;
282
if (!isalnum(ch & 255))
290
else if (strcmp(glyph, "lt") == 0)
292
else if (strcmp(glyph, "gt") == 0)
294
else if (strcmp(glyph, "quot") == 0)
296
else if (strcmp(glyph, "nbsp") == 0)
316
t->element = ELEMENT_FRAGMENT;
322
* Read the next string fragment...
329
while (!isspace(ch & 255) && ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1))
333
for (glyphptr = glyph;
334
(ch = getc(fp)) != EOF && (glyphptr - glyph) < 15;
336
if (!isalnum(ch & 255))
344
else if (strcmp(glyph, "lt") == 0)
346
else if (strcmp(glyph, "gt") == 0)
348
else if (strcmp(glyph, "quot") == 0)
350
else if (strcmp(glyph, "nbsp") == 0)
362
if (isspace(ch & 255))
370
t->element = ELEMENT_FRAGMENT;
375
* If the p tree pointer is not NULL and this is the first
376
* entry we've read, set the child pointer...
379
if (p != NULL && prev == NULL)
386
* Do the prev/next links...
399
* Do child stuff as needed...
403
t->child = formRead(t, fp);
411
* 'formSetAttr()' - Set a node attribute.
415
formSetAttr(tree_t *t, /* I - Tree node */
416
const char *name, /* I - Attribute name */
417
const char *value) /* I - Attribute value */
423
* 'compare_attr()' - Compare two attributes.
426
static int /* O - -1 if a0 < a1, etc. */
427
compare_attr(attr_t *a0, /* I - First attribute */
428
attr_t *a1) /* I - Second attribute */
430
return (strcasecmp(a0->name, a1->name));
435
* 'compare_elements()' - Compare two elements.
438
static int /* O - -1 if e0 < e1, etc. */
439
compare_elements(char **e0, /* I - First element */
440
char **e1) /* I - Second element */
442
return (strcasecmp(*e0, *e1));
447
* 'parse_attr()' - Parse an element attribute string.
450
static int /* O - -1 on error, 0 on success */
451
parse_attr(tree_t *t, /* I - Current tree node */
452
FILE *fp) /* I - Input file */
454
char name[1024], /* Name of attr */
455
value[10240], /* Value of attr */
456
*ptr; /* Temporary pointer */
457
int ch; /* Character from file */
461
while ((ch = getc(fp)) != EOF)
462
if (isalnum(ch & 255))
464
if (ptr < (name + sizeof(name) - 1))
472
while (isspace(ch & 255) || ch == '\r')
479
return (formSetAttr(t, name, NULL));
486
while (isspace(ch & 255) || ch == '\r')
494
while ((ch = getc(fp)) != EOF)
497
else if (ptr < (value + sizeof(value) - 1))
504
while ((ch = getc(fp)) != EOF)
507
else if (ptr < (value + sizeof(value) - 1))
515
while ((ch = getc(fp)) != EOF)
516
if (isspace(ch & 255) || ch == '>' || ch == '/' || ch == '\r')
518
else if (ptr < (value + sizeof(value) - 1))
522
if (ch == '>' || ch == '/')
526
return (formSetAttr(t, name, value));
532
* 'parse_element()' - Parse an element.
535
static int /* O - -1 on error or ELEMENT_nnnn */
536
parse_element(tree_t *t, /* I - Current tree node */
537
FILE *fp) /* I - Input file */
539
int ch; /* Character from file */
540
char element[255], /* Element string... */
541
*eptr, /* Current character... */
542
comment[10240], /* Comment string */
543
*cptr, /* Current char... */
544
**temp; /* Element variable entry */
549
while ((ch = getc(fp)) != EOF && eptr < (element + sizeof(element) - 1))
550
if (ch == '>' || ch == '/' || isspace(ch & 255))
558
return (ELEMENT_ERROR);
561
temp = bsearch(&mptr, elements, sizeof(elements) / sizeof(elements[0]),
563
(int (*)(const void *, const void *))compare_elements);
568
* Unrecognized element stuff...
571
t->element = ELEMENT_COMMENT;
572
strcpy(comment, element);
573
cptr = comment + strlen(comment);
577
t->element = (element_t)((char **)temp - elements);
581
if (t->element == ELEMENT_COMMENT)
583
while (ch != EOF && ch != '>' && cptr < (comment + sizeof(comment) - 1))
590
t->data = strdup(comment);
594
while (ch != EOF && ch != '>' && ch != '/')
596
if (!isspace(ch & 255))
599
parse_variable(t, fp);
614
* End of "$Id: form-tree.c 6649 2007-07-11 21:46:42Z mike $".