1 /*
2    netrik -- The ANTRIK Internet Viewer
3    Copyright (C) Olaf D. Buddenhagen AKA antrik, et al (see AUTHORS)
4    Published under the GNU GPL; see LICENSE for details.
5 */
6 /*
7  * parse-elements.c -- this one looks up the textual tags and parameters in the
8  * syntax tree and replaces them by enum numbers for further processing.
9  *
10  * (C) 2001 antrik
11  *     2002 Patrice
12  *
13  * It also contains a debug function which dumps all tag and parameter types to
14  * see if parse_tags recognized them correctly.
15  */
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 
20 #include "cfg.h"
21 #include "syntax.h"
22 
23 /* look up the element and attriubte name strings to find out what kind they are */
parse_elements(syntax_tree)24 void parse_elements(syntax_tree)
25 struct Element	*syntax_tree;    /* top of syntax parse tree */
26 {
27    struct Element	*cur_el;    /* element currently processed */
28    int			i;
29    int			cur_attr;    /* attribute currently processed */
30 
31 #ifdef DEBUG
32    if(strcmp(element_table[EL_NO].name, "?")) {    /* number of entries in "Element_type" enum doesn't match number of entries in "element_table[]" */
33       fprintf(stderr, "internal error: \"element_table[]\" broken\n");
34       exit(100);
35    } else if(strcmp(attr_table[ATTR_NO].name, "?")) {
36       fprintf(stderr, "internal error: \"attr_table[]\" broken\n");
37       exit(100);
38    }
39 #endif
40 
41    syntax_tree->name.type=EL_GLOBAL;    /* first element is always global element */
42 
43    for(cur_el=syntax_tree->list_next; cur_el->parent!=NULL; cur_el=cur_el->list_next) {    /* all elements in syntax parse tree */
44       if(cur_el->name.str!=NULL) {    /* element has a name string */
45 	 /* search this element's name in table */
46 	 for(i=0; i<EL_NO; ++i)
47 	    if(!strcmp(cur_el->name.str, element_table[i].name))    /* found -> don't search further */
48 	       break;
49 
50 	 if(cfg.warn_unknown) {
51 	    if(i==EL_NO)    /* unknown element */
52 	       fprintf(stderr, "warning: ignoring unknown element: %s\n", cur_el->name.str);
53 	 }
54 
55 	 free(cur_el->name.str);
56 	 cur_el->name.type=i;    /* set type (==EL_NO if not found in table) */
57 
58 	 for(cur_attr=0; cur_attr<cur_el->attr_count; ++cur_attr) {    /* all attributes */
59 	    /* search this attributes's name in table */
60 	    for(i=0; i<ATTR_NO; ++i)
61 	       if(!strcmp(cur_el->attr[cur_attr].name.str, attr_table[i].name))    /* found -> don't search further */
62 		  break;
63 
64 	    if(cfg.warn_unknown) {
65 	       if(i==ATTR_NO)    /* unknown attribute */
66 		  fprintf(stderr, "warning: ignoring unknown attribute: %s\n", cur_el->attr[cur_attr].name.str);
67 	    }
68 
69 	    free(cur_el->attr[cur_attr].name.str);
70 	    cur_el->attr[cur_attr].name.type=i;    /* set type (==ATTR_NO if not found in table) */
71 
72 	    /* avoid NULL values */
73 	    if(cur_el->attr[cur_attr].value.str==NULL) {
74 	       cur_el->attr[cur_attr].value.str=strdup("");
75 	       if(cur_el->attr[cur_attr].value.str==NULL) {
76 		  fprintf(stderr, "memory allocation error while parsing elements (in function parse_elements)\n");
77 		  exit(1);
78 	       }
79 	    }
80 
81 /* Patrice --> */
82             /* convert to a number if there is a numeric value expected */
83             if(attr_table[i].numeric) {
84                char	*tmpval=strdup(cur_el->attr[cur_attr].value.str);
85                free(cur_el->attr[cur_attr].value.str);
86                cur_el->attr[cur_attr].value.num=atoi(tmpval);
87                free(tmpval);
88             }
89 	 }    /* for all attributes */
90 
91          /* check if all mandatory attributes are set */
92 	 if(cur_el->name.type<EL_NO) {    /* normal element (not EL_NO or EL_GLOBAL) -> check (avoids addign all non-mandatory attributes to dummy elements!) */
93 	    for(i=0; i<ATTR_NO; ++i) {
94 	       if(attr_table[i].def_val!=0 && attr_table[i].el==cur_el->name.type) {
95 		  for(cur_attr=0; cur_attr<cur_el->attr_count; ++cur_attr)
96 		     if((int)cur_el->attr[cur_attr].name.type==i)    /* found -> don't search further */
97 			break;
98 		  if(cur_attr==cur_el->attr_count) {	/* need to add attribute */
99 		     cur_el->attr=realloc(cur_el->attr, (++cur_el->attr_count)*sizeof(struct Attr));    /* resize attribute array to hold new attribute */
100 		     if(cur_el->attr==NULL) {
101 			fprintf(stderr, "memory allocation error while parsing elements (in function parse_elements)\n");
102 		     }
103 		     cur_el->attr[cur_el->attr_count-1].name.type=i;
104 		     if(attr_table[i].numeric)
105 			cur_el->attr[cur_el->attr_count-1].value.num=atoi(attr_table[i].def_val);
106 		     else
107 			cur_el->attr[cur_el->attr_count-1].value.str=strdup(attr_table[i].def_val);
108 		  }
109 	       }
110 	    }
111 	 }    /* normal element */
112 /* <-- Patrice */
113 
114       } else    /* no name string => dummy element */
115 	 cur_el->name.type=EL_NO;
116    }    /* for all elements */
117 }
118