]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/form-tree.c
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 $".