2 * $Id: hswitch.c,v 1.2 1998/10/15 12:31:01 adam Exp $
11 #define TAG_MAX_LEN 32
13 #define SPACECHR " \t\r\n\f"
17 static int skipSpace (const char *cp)
20 while (strchr (SPACECHR, cp[i]))
25 static int skipTag (const char *cp, char *dst)
30 for (i=0; cp[i] && !strchr (SPACECHR "/>=", cp[i]); i++)
31 if (j < TAG_MAX_LEN-1)
33 dst[j] = tolower(cp[j]);
40 static int skipParm (const char *cp, char *name, char **value)
42 int i = skipTag (cp, name);
45 return skipSpace (cp);
46 i += skipSpace (cp + i);
51 i += skipSpace (cp + i);
55 while (cp[i] != '\"' && cp[i])
64 while (cp[i] && !strchr (SPACECHR ">", cp[i]))
68 *value = malloc (v1 - v0 + 1);
69 memcpy (*value, cp + v0, v1-v0);
70 (*value)[v1-v0] = '\0';
72 i += skipSpace (cp + i);
77 char name[TAG_MAX_LEN];
87 char name[TAG_MAX_LEN];
88 const char *body_start;
89 struct tagParm *tagParms;
92 static int tagLookup (struct tagInfo *tags, int tagNo, const char *tagString)
95 for (i = 0; i<tagNo; i++)
96 if (!strcmp (tags[i].pattern, tagString))
101 static int tagStart (struct tagInfo *tag, const char *tagString,
105 char parm_name[TAG_MAX_LEN];
107 struct tagParm **nParms;
109 if (tag && !tag->level)
111 strcpy (tag->name, tagString);
112 DEBUG(printf ("------ consuming this %s\n", tag->name));
113 tag->tagParms = NULL;
114 nParms = &tag->tagParms;
118 while (cp[i] && cp[i] != '>')
120 int nor = skipParm (cp+i, parm_name, &parm_value);
124 DEBUG(printf ("parm_name=%s parm_value=%s\n", parm_name, parm_value));
126 if (nor && tag && !tag->level)
128 *nParms = malloc (sizeof(**nParms));
130 strcpy ((*nParms)->name, parm_name);
131 (*nParms)->value = parm_value;
132 (*nParms)->next = NULL;
133 nParms = &(*nParms)->next;
147 tag->body_start = cp+i;
153 static int tagEnd (Tcl_Interp *interp, struct tagInfo *tag,
154 const char *tagString, const char *cp, const char *body_end)
161 if (tag && tag->level)
166 struct tagParm *tp = tag->tagParms;
167 char *value = malloc (body_end - tag->body_start + 1);
170 memcpy (value, tag->body_start, body_end - tag->body_start);
171 value[body_end - tag->body_start] = '\0';
172 Tcl_SetVar (interp, "body", value, 0);
176 char vname[TAG_MAX_LEN+30];
177 struct tagParm *tp0 = tp;
179 sprintf (vname, "parm(%s)", tp->name);
180 DEBUG(printf ("vname=%s\n", vname));
182 Tcl_SetVar (interp, vname, tp->value ? tp->value : "",0);
186 Tcl_Eval (interp, tag->code);
192 int htmlSwitch (ClientData clientData, Tcl_Interp *interp,
193 int argc, char **argv)
195 struct tagInfo *tags;
201 noTags = (argc - argi)/2;
205 "wrong # args: should be ?switches? string pattern body ...";
208 tags = malloc (sizeof(*tags) * noTags);
210 for (i = 0; i<noTags; i++)
213 tags[i].pattern = argv[argi++];
214 tags[i].code = argv[argi++];
218 if (cp[0] == '<' && cp[1] != '/') /* start tag */
220 char tagStr[TAG_MAX_LEN];
224 cp += skipTag (cp, tagStr);
225 tagI = tagLookup (tags, noTags, tagStr);
226 DEBUG(printf ("tagStr = %s tagI = %d\n", tagStr, tagI));
227 cp += tagStart (tagI >= 0 ? tags+tagI : NULL, tagStr, cp);
229 else if (cp[0] == '<' && cp[1] == '/')/* end tag */
231 char tagStr[TAG_MAX_LEN];
232 const char *body_end = cp;
236 cp += skipTag (cp, tagStr);
237 tagI = tagLookup (tags, noTags, tagStr);
238 cp += tagEnd (interp, tagI >= 0 ? tags+tagI : NULL,
239 tagStr, cp, body_end);