2 * $Id: hswitch.c,v 1.5 2001/11/08 10:23:02 adam Exp $
11 #define TAG_MAX_LEN 64
13 #define SPACECHR " \t\r\n\f"
17 static int skipSpace (const char *cp)
20 while (cp[i] && 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];
88 char name[TAG_MAX_LEN];
89 const char *body_start;
90 struct tagParm *tagParms;
93 static int tagLookup (struct tagInfo *tags, int tagNo, const char *tagString)
96 for (i = 0; i<tagNo; i++)
97 if (!strcmp (tags[i].pattern, tagString))
102 static int tagStart (struct tagInfo *tag, const char *tagString,
106 char parm_name[TAG_MAX_LEN];
108 struct tagParm **nParms;
110 if (tag && !tag->level)
112 strcpy (tag->name, tagString);
113 DEBUG(printf ("------ consuming this %s\n", tag->name));
114 tag->tagParms = NULL;
115 nParms = &tag->tagParms;
119 while (cp[i] && cp[i] != '>')
121 int nor = skipParm (cp+i, parm_name, &parm_value);
125 DEBUG(printf ("parm_name=%s parm_value=%s\n", parm_name, parm_value));
127 if (nor && tag && !tag->level)
129 *nParms = malloc (sizeof(**nParms));
131 strcpy ((*nParms)->name, parm_name);
132 (*nParms)->value = parm_value;
133 (*nParms)->next = NULL;
134 nParms = &(*nParms)->next;
148 tag->body_start = cp+i;
154 static int tagEnd (Tcl_Interp *interp, struct tagInfo *tag,
155 const char *tagString, const char *cp, const char *body_end)
162 if (tag && tag->level)
168 struct tagParm *tp = tag->tagParms;
169 char *value = malloc (body_end - tag->body_start + 1);
172 memcpy (value, tag->body_start, body_end - tag->body_start);
173 value[body_end - tag->body_start] = '\0';
174 Tcl_SetVar (interp, "body", value, 0);
177 char vname[TAG_MAX_LEN+30];
178 struct tagParm *tp0 = tp;
180 sprintf (vname, "parm(%s)", tp->name);
181 DEBUG(printf ("vname=%s\n", vname));
183 Tcl_SetVar (interp, vname, tp->value ? tp->value : "",0);
187 tcl_err = Tcl_Eval (interp, tag->code);
189 if (tcl_err == TCL_ERROR)
191 printf ("Error: code=%d %s\n", tcl_err, interp->result);
199 int htmlSwitch (ClientData clientData, Tcl_Interp *interp,
200 int argc, char **argv)
202 struct tagInfo *tags;
208 noTags = (argc - argi)/2;
212 "wrong # args: should be ?switches? string pattern body ...";
215 tags = malloc (sizeof(*tags) * noTags);
217 while (argi < argc-1)
221 if (!strcmp(argv[argi], "-nonest"))
226 else if (!strcmp(argv[argi], "-nest"))
231 tags[i].pattern = argv[argi++];
232 tags[i].code = argv[argi++];
238 if (cp[0] == '<' && cp[1] != '/') /* start tag */
240 char tagStr[TAG_MAX_LEN];
242 const char *body_start = cp;
245 cp += skipTag (cp, tagStr);
246 tagI = tagLookup (tags, noTags, tagStr);
247 DEBUG(printf ("tagStr = %s tagI = %d\n", tagStr, tagI));
248 cp += tagStart (tagI >= 0 ? tags+tagI : NULL, tagStr, cp);
249 if (tagI >= 0 && tags[tagI].nest == 0)
251 cp += tagEnd (interp, tags+tagI, tagStr, body_start, cp);
254 else if (cp[0] == '<' && cp[1] == '/')/* end tag */
256 char tagStr[TAG_MAX_LEN];
257 const char *body_end = cp;
261 cp += skipTag (cp, tagStr);
262 tagI = tagLookup (tags, noTags, tagStr);
263 cp += tagEnd (interp, tagI >= 0 ? tags+tagI : NULL,
264 tagStr, cp, body_end);