2 * $Id: hswitch.c,v 1.1 1996/08/06 14:04:22 adam Exp $
11 #define TAG_MAX_LEN 32
13 #define SPACECHR " \t\r\n\f"
15 static int skipSpace (const char *cp)
18 while (strchr (SPACECHR, cp[i]))
23 static int skipTag (const char *cp, char *dst)
27 for (i=0; i<TAG_MAX_LEN-1 && cp[i] && !strchr (SPACECHR "/>=", cp[i]); i++)
28 dst[i] = tolower(cp[i]);
33 static int skipParm (const char *cp, char *name, char **value)
35 int i = skipTag (cp, name);
38 return skipSpace (cp);
39 i += skipSpace (cp + i);
44 i += skipSpace (cp + i);
48 while (cp[i] != '\"' && cp[i])
57 while (cp[i] && !strchr (SPACECHR ">", cp[i]))
61 *value = malloc (v1 - v0 + 1);
62 memcpy (*value, cp + v0, v1-v0);
63 (*value)[v1-v0] = '\0';
65 i += skipSpace (cp + i);
70 char name[TAG_MAX_LEN];
80 char name[TAG_MAX_LEN];
81 const char *body_start;
82 struct tagParm *tagParms;
85 static int tagLookup (struct tagInfo *tags, int tagNo, const char *tagString)
88 for (i = 0; i<tagNo; i++)
89 if (!strcmp (tags[i].pattern, tagString))
94 static int tagStart (struct tagInfo *tag, const char *tagString,
98 char parm_name[TAG_MAX_LEN];
100 struct tagParm **nParms;
102 if (tag && !tag->level)
104 strcpy (tag->name, tagString);
105 tag->tagParms = NULL;
106 nParms = &tag->tagParms;
110 while (cp[i] && cp[i] != '>')
112 int nor = skipParm (cp+i, parm_name, &parm_value);
114 if (nor && tag && !tag->level)
116 *nParms = malloc (sizeof(**nParms));
118 (*nParms)->next = NULL;
119 strcpy ((*nParms)->name, parm_name);
120 (*nParms)->value = parm_value;
134 tag->body_start = cp+i;
140 static int tagEnd (Tcl_Interp *interp, struct tagInfo *tag,
141 const char *tagString, const char *cp, const char *body_end)
148 if (tag && tag->level)
153 struct tagParm *tp = tag->tagParms;
154 char *value = malloc (body_end - tag->body_start + 1);
157 memcpy (value, tag->body_start, body_end - tag->body_start);
158 value[body_end - tag->body_start] = '\0';
159 Tcl_SetVar (interp, "body", value, 0);
163 char vname[TAG_MAX_LEN+30];
164 struct tagParm *tp0 = tp;
166 sprintf (vname, "parm(%s)", tp->name);
168 Tcl_SetVar (interp, vname, tp->value ? tp->value : "",0);
172 Tcl_Eval (interp, tag->code);
178 int htmlSwitch (ClientData clientData, Tcl_Interp *interp,
179 int argc, char **argv)
181 struct tagInfo *tags;
187 noTags = (argc - argi)/2;
191 "wrong # args: should be ?switches? string pattern body ...";
194 tags = malloc (sizeof(*tags) * noTags);
196 for (i = 0; i<noTags; i++)
199 tags[i].pattern = argv[argi++];
200 tags[i].code = argv[argi++];
204 if (cp[0] == '<' && cp[1] != '/') /* start tag */
206 char tagStr[TAG_MAX_LEN];
210 cp += skipTag (cp, tagStr);
211 tagI = tagLookup (tags, noTags, tagStr);
212 cp += tagStart (tagI >= 0 ? tags+tagI : NULL, tagStr, cp);
214 else if (cp[0] == '<') /* end tag */
216 char tagStr[TAG_MAX_LEN];
217 const char *body_end = cp;
221 cp += skipTag (cp, tagStr);
222 tagI = tagLookup (tags, noTags, tagStr);
223 cp += tagEnd (interp, tagI >= 0 ? tags+tagI : NULL,
224 tagStr, cp, body_end);