fixnuta buga v remove_last (nesnizovala grow ptr, ktery tak ubiral znaky a nemenil...
[httpfs.git] / parser.c
blob15ee157ec210223d074e9fe9c87f8334f24a558c
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include "debug.h"
5 #include "grow.h"
6 #include "parser.h"
7 #include "urlencode.h"
10 struct tag {
11 char *name;
12 char *param;
13 } grab_tags[] = {
14 { "a", "href" },
15 { "applet", "code" },
16 { "area", "href" },
17 { "embed", "code" },
18 { "frame", "src" },
19 { "iframe", "src" },
20 { "img", "src" },
21 { "img", "href" },
22 { "link", "href" },
23 { "script", "src" },
24 { NULL, NULL }
27 static inline int good_tag(char *tn, char *pn)
29 int i;
30 struct tag *t;
32 for (i=0; t = &grab_tags[i], t->name; i++) {
33 if (!strcmp(t->name, tn) && !strcmp(t->param, pn))
34 return 1;
36 return 0;
40 #define otag(tn,pn,pv,cb,ctx) { if (good_tag(grow_cstr(tn), grow_cstr(pn))) cb(ctx, grow_cstr(pv), 0, 0); grow_reset(pv); grow_reset(pn); }
41 void generic_parse(char *input, parser_cb_t cb, void *ctx)
43 struct grow tn, pn, pv;
44 int c, state = 0;
46 grow_init(&tn);
47 grow_init(&pn);
48 grow_init(&pv);
50 while ((c=*input++)) {
51 switch(state) {
52 case 0:
53 if (c == '<')
54 state = 1;
55 break;
56 case 1:
57 if (c == '/' || isalpha(c)) {
58 grow_reset(&tn);
59 grow_put(&tn,tolower(c));
60 state = 2;
62 break;
63 case 2:
64 if (!isalpha(c)) {
65 if (c == '>')
66 state = 0;
67 else
68 state = 3;
69 } else {
70 grow_put(&tn,tolower(c));
72 break;
73 case 3:
74 if (c == '>') {
75 state = 0;
76 } else if (isalpha(c)) {
77 state = 4;
78 grow_reset(&pn);
79 grow_put(&pn, tolower(c));
81 break;
82 case 4:
83 if (c == '=') {
84 state = 5;
85 } else if (isalpha(c)) {
86 grow_put(&pn, tolower(c));
87 } else {
88 state = 3;
90 break;
91 case 5:
92 grow_reset(&pv);
93 if (c == '"') {
94 state = 6;
95 } else if (c == '\'') {
96 state = 7;
97 } else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
98 state = 3;
99 } else {
100 grow_put(&pv, c);
101 state = 8;
103 break;
104 case 6:
105 if (c == '\"') {
106 otag(&tn, &pn, &pv, cb, ctx);
107 state = 3;
108 } else {
109 grow_put(&pv,c);
111 break;
112 case 7:
113 if (c == '\'') {
114 otag(&tn, &pn, &pv, cb, ctx);
115 state = 3;
116 } else {
117 grow_put(&pv,c);
119 break;
120 case 8:
121 if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '>') {
122 otag(&tn, &pn, &pv, cb, ctx);
123 if (c == '>') {
124 state = 0;
125 } else {
126 state = 3;
128 } else {
129 grow_put(&pv, c);
131 break;
134 grow_free(&tn);
135 grow_free(&pn);
136 grow_free(&pv);
139 void parse(char *input, parser_cb_t cb, void *ctx)
141 generic_parse(input, cb, ctx);