1 /* $Id: parsetagx.c,v 1.18 2006/06/07 03:52:03 inu Exp $ */
13 static int noConv(char *, char **);
14 static int toNumber(char *, int *);
15 static int toLength(char *, int *);
16 static int toAlign(char *, int *);
17 static int toVAlign(char *, int *);
20 static int (*toValFunc[]) () = {
21 noConv, /* VTYPE_NONE */
22 noConv, /* VTYPE_STR */
23 toNumber, /* VTYPE_NUMBER */
24 toLength, /* VTYPE_LENGTH */
25 toAlign, /* VTYPE_ALIGN */
26 toVAlign, /* VTYPE_VALIGN */
27 noConv, /* VTYPE_ACTION */
28 noConv, /* VTYPE_ENCTYPE */
29 noConv, /* VTYPE_METHOD */
30 noConv, /* VTYPE_MLENGTH */
31 noConv, /* VTYPE_TYPE */
36 noConv(char *oval, char **str)
43 toNumber(char *oval, int *num)
48 x = strtol(oval, &ep, 10);
59 toLength(char *oval, int *len)
62 if (!IS_DIGIT(oval[0]))
69 if (oval[strlen(oval) - 1] == '%')
77 toAlign(char *oval, int *align)
79 if (strcasecmp(oval, "left") == 0)
81 else if (strcasecmp(oval, "right") == 0)
83 else if (strcasecmp(oval, "center") == 0)
84 *align = ALIGN_CENTER;
85 else if (strcasecmp(oval, "top") == 0)
87 else if (strcasecmp(oval, "bottom") == 0)
88 *align = ALIGN_BOTTOM;
89 else if (strcasecmp(oval, "middle") == 0)
90 *align = ALIGN_MIDDLE;
97 toVAlign(char *oval, int *valign)
99 if (strcasecmp(oval, "top") == 0 || strcasecmp(oval, "baseline") == 0)
100 *valign = VALIGN_TOP;
101 else if (strcasecmp(oval, "bottom") == 0)
102 *valign = VALIGN_BOTTOM;
103 else if (strcasecmp(oval, "middle") == 0)
104 *valign = VALIGN_MIDDLE;
110 extern Hash_si tagtable;
111 #define MAX_TAG_LEN 64
114 parse_tag(char **s, int internal)
116 struct parsed_tag *tag = NULL;
118 char tagname[MAX_TAG_LEN], attrname[MAX_TAG_LEN];
120 int i, attr_id = 0, nattr;
129 while (*q && !IS_SPACE(*q) && !(tagname[0] != '/' && *q == '/') &&
130 *q != '>' && p - tagname < MAX_TAG_LEN - 1) {
131 *(p++) = TOLOWER(*q);
135 while (*q && !IS_SPACE(*q) && !(tagname[0] != '/' && *q == '/') &&
139 tag_id = getHash_si(&tagtable, tagname, HTML_UNKNOWN);
141 if (tag_id == HTML_UNKNOWN ||
142 (!internal && TagMAP[tag_id].flag & TFLG_INT))
143 goto skip_parse_tagarg;
145 tag = New(struct parsed_tag);
146 bzero(tag, sizeof(struct parsed_tag));
149 if ((nattr = TagMAP[tag_id].max_attribute) > 0) {
150 tag->attrid = NewAtom_N(unsigned char, nattr);
151 tag->value = New_N(char *, nattr);
152 tag->map = NewAtom_N(unsigned char, MAX_TAGATTR);
153 memset(tag->map, MAX_TAGATTR, MAX_TAGATTR);
154 memset(tag->attrid, ATTR_UNKNOWN, nattr);
155 for (i = 0; i < nattr; i++)
156 tag->map[TagMAP[tag_id].accept_attribute[i]] = i;
159 /* Parse tag arguments */
162 Str value = NULL, value_tmp = NULL;
163 if (*q == '>' || *q == '\0')
166 while (*q && *q != '=' && !IS_SPACE(*q) &&
167 *q != '>' && p - attrname < MAX_TAG_LEN - 1) {
168 *(p++) = TOLOWER(*q);
172 while (*q && *q != '=' && !IS_SPACE(*q) && *q != '>')
177 value_tmp = Strnew();
182 while (*q && *q != '"') {
183 Strcat_char(value_tmp, *q);
184 if (!tag->need_reconstruct && is_html_quote(*q))
185 tag->need_reconstruct = TRUE;
191 else if (*q == '\'') {
193 while (*q && *q != '\'') {
194 Strcat_char(value_tmp, *q);
195 if (!tag->need_reconstruct && is_html_quote(*q))
196 tag->need_reconstruct = TRUE;
203 while (*q && !IS_SPACE(*q) && *q != '>') {
204 Strcat_char(value_tmp, *q);
205 if (!tag->need_reconstruct && is_html_quote(*q))
206 tag->need_reconstruct = TRUE;
211 for (i = 0; i < nattr; i++) {
212 if ((tag)->attrid[i] == ATTR_UNKNOWN &&
213 strcmp(AttrMAP[TagMAP[tag_id].accept_attribute[i]].name,
215 attr_id = TagMAP[tag_id].accept_attribute[i];
222 for (j=0; j<i; j++) {
223 if (tag->attrid[j] == ATTR_TYPE &&
224 strcmp("hidden",tag->value[j]) == 0) {
229 if ((tag_id == HTML_INPUT || tag_id == HTML_INPUT_ALT) &&
230 attr_id == ATTR_VALUE && hidden) {
235 for (x = value_tmp->ptr; *x; x++) {
237 Strcat_char(value, *x);
244 ((AttrMAP[attr_id].flag & AFLG_INT) ||
245 (value && AttrMAP[attr_id].vtype == VTYPE_METHOD &&
246 !strcasecmp(value->ptr, "internal")))) {
247 tag->need_reconstruct = TRUE;
250 tag->attrid[i] = attr_id;
252 tag->value[i] = html_unquote(value->ptr);
254 tag->value[i] = NULL;
257 tag->need_reconstruct = TRUE;
262 while (*q != '>' && *q)
272 parsedtag_set_value(struct parsed_tag *tag, int id, char *value)
276 if (!parsedtag_accepts(tag, id))
282 tag->value[i] = allocStr(value, -1);
284 tag->value[i] = NULL;
285 tag->need_reconstruct = TRUE;
290 parsedtag_get_value(struct parsed_tag *tag, int id, void *value)
293 if (!parsedtag_exists(tag, id) || !tag->value[i = tag->map[id]])
295 return toValFunc[AttrMAP[id].vtype] (tag->value[i], value);
299 parsedtag2str(struct parsed_tag *tag)
302 int tag_id = tag->tagid;
303 int nattr = TagMAP[tag_id].max_attribute;
304 Str tagstr = Strnew();
305 Strcat_char(tagstr, '<');
306 Strcat_charp(tagstr, TagMAP[tag_id].name);
307 for (i = 0; i < nattr; i++) {
308 if (tag->attrid[i] != ATTR_UNKNOWN) {
309 Strcat_char(tagstr, ' ');
310 Strcat_charp(tagstr, AttrMAP[tag->attrid[i]].name);
312 Strcat(tagstr, Sprintf("=\"%s\"", html_quote(tag->value[i])));
315 Strcat_char(tagstr, '>');