1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <memfile.h>
5 #include "html2h.h"
6
usage()7 void usage()
8 {
9 printf("html2h v0.1\nusage:\n \
10 + html2h input.html [output.h]\n\n \
11 + if output is not set, input.h will be generated and overwritten!\n\n \
12 + debug messages are written to stderr!\n\n \
13 ");
14
15 exit(0);
16 }
17
main(int argc,char ** argv)18 int main(int argc, char **argv)
19 {
20 char *fout, *point;
21 seclist=calloc(1, sizeof(Section));
22
23 if(argc<2 || argc>3) usage();
24 if(argc==2){
25 fout=(char*)strdup(argv[1]);
26 point=strchr(fout, '.');
27 if(point == NULL) pexit("Couldn generate output filename - no . in input file\n", argv[1]);
28 strcpy(point, ".h");
29 }else
30 fout=argv[2];
31
32 if(!strcmp(fout, argv[1])){
33 printf("input and output files have the same name - exiting\n");
34 exit(1);
35 }
36
37 fileWrite(fileRead(argv[1]), fout);
38 return(0);
39 }
40
fileWrite(MFILE * mf,char * fname)41 void fileWrite(MFILE *mf, char *fname)
42 {
43 FILE *f=fopen(fname, "w");
44 if(f==NULL) pexit("Cannot write to output file ", fname);
45
46 fprintf(f, "/****************************************************\n");
47 fprintf(f, " * Header file generated with html2h 0.1 *\n");
48 fprintf(f, " * (c) 2000 by Sven@Dawitz.de *\n");
49 fprintf(f, " ****************************************************\n");
50 listDump(f);
51 fprintf(f, "\n ****************************************************/\n\n");
52
53 mfMFileToFile(mf, f);
54 fclose(f);
55 }
56
fileRead(char * fname)57 MFILE *fileRead(char *fname)
58 {
59 MFILE *mfin=mfopen(), *mfout=mfopen(), *mfbuf=mfopen();
60 FILE *f=fopen(fname, "r");
61 const char *flastok, *fhit, *fend;
62 if(f==NULL) pexit("Cannot read input file ", fname);
63
64 mfFileToMFile(f, mfin);
65 fclose(f);
66
67 flastok=fhit=fend=mfGetData(mfin);
68 while((fhit=strstr(flastok, "<!--#"))!=NULL){
69 searchInput(flastok, fhit);
70
71 fend=strstr(fhit, "-->");
72 if(fend==NULL) pexit("Parse error - '-->' expected - exiting\n", fhit);
73 if(commdepth==0)
74 escapeWrite((void*)flastok, fhit-flastok, mfout);
75 flastok=(const char*)(fend+3);
76 mfSetLength(mfbuf, 0);
77
78 mfwrite((void*)(fhit+5), 1, fend-(fhit+5), mfbuf);
79 parseMeta(mfout, mfGetData(mfbuf));
80 }
81 searchInput(flastok, (char*)0x8FFFFFFF);
82 escapeWrite((void*)flastok, strlen(flastok), mfout);
83 mfprintf(mfout, "\";\n");
84
85 mfclose(mfin);
86 return(mfout);
87 }
88
searchInput(const char * flastok,const char * fhit)89 void searchInput(const char *flastok, const char *fhit)
90 {
91 MFILE *mfbuf=mfopen();
92 const char *input, *ta, *hit, *select, *end, *test;
93
94 hit=flastok;
95 do{
96 input=strstr(hit, "<input");
97 ta=strstr(hit, "<textarea");
98 select=strstr(hit, "<select");
99 hit=(char*)0x8FFFFFFF;
100 if(input!=NULL && input<hit) hit=input;
101 if(ta!=NULL && ta<hit) hit=ta;
102 if(select!=NULL && select < hit) hit=select;
103 if(hit!=(char*)0x8FFFFFFF && hit<fhit){
104 end=strchr(hit, '>');
105 test=strchr(hit+1, '<');
106 if(test!=NULL && test<end) end=strchr(end+1, '>');
107 mfSetLength(mfbuf, 0);
108 mfwrite((void*)hit+1, 1, end-hit-1, mfbuf);
109 printf("Input: %s\n", mfGetData(mfbuf));
110 parseInput(mfGetData(mfbuf));
111 hit++;
112 }
113 }while(hit!=(char*)0x8FFFFFFF && hit<fhit);
114
115 mfclose(mfbuf);
116 }
117
parseInput(const char * input)118 void parseInput(const char *input)
119 {
120 char *name=parseInputValue(input, "name");
121 char *type=NULL;
122 if(secakt==NULL) pexit("Input: tried to insert, but no section found\n", input);
123
124 if(!strncasecmp(input, "select", 6))
125 type="select";
126 if(!strncasecmp(input, "textarea", 8))
127 type="textarea";
128 if(!strncasecmp(input, "input", 5))
129 type=parseInputValue(input, "type");
130 if(type==NULL)
131 type="unknown";
132
133 if(commdepth==0)
134 listInsertInput(name, type);
135 }
136
parseInputValue(const char * str,const char * name)137 char *parseInputValue(const char *str, const char *name)
138 {
139 char *hit, *nameeq, endc, *ret;
140 int length=strlen(name)+1, i=0;
141
142 nameeq=malloc(length+1);
143 sprintf(nameeq, "%s=", name);
144 hit=strstr(str, nameeq);
145 if(hit==NULL) return(NULL);
146 hit+=length;
147 if(*hit==0) return(NULL);
148
149 if(*hit=='"') { endc='"'; hit++; }
150 else endc=' ';
151
152 while(hit[i]!=0 && hit[i]!=endc) i++;
153
154 ret=malloc(i+1);
155 strncpy(ret, hit, i);
156 ret[i]=0;
157
158 return(ret);
159 }
160
parseMeta(MFILE * mfout,const char * toparse)161 void parseMeta(MFILE *mfout, const char *toparse)
162 {
163 char *tagend=strchr(toparse, ' ');
164 int taglen=tagend-toparse;
165
166 fprintf(stderr, "Parsing: %s\n", toparse);
167
168 if(!strcmp(toparse, "/*")){
169 commdepth++;
170 return;
171 }
172
173 if(!strcmp(toparse, "*/")){
174 commdepth--;
175 if(commdepth<0)
176 pexit("comment to deep - to many '*/' found - exiting\n", "");
177 return;
178 }
179
180 if(commdepth>0) return;
181
182 if(taglen<0)
183 pexit("tag wrong - ' ' expected - exiting\n", toparse);
184
185 if(!strncasecmp(toparse, "section", strlen("section")))
186 return parseSection(mfout, tagend+1);
187 if(!strncasecmp(toparse, "param", strlen("param")))
188 return (void)parseParam(mfout, secakt->list, tagend+1, false);
189 if(!strncasecmp(toparse, "slink", strlen("slink")))
190 return parseSLink(mfout, tagend+1);
191 }
192
parseSection(MFILE * mfout,const char * params)193 void parseSection(MFILE *mfout, const char *params)
194 {
195 char *name=(char*)params, *comment=strchr(params, ' '), *cend;
196
197 if(secakt!=NULL)
198 mfprintf(mfout, "\n\";\n");
199
200 if(comment!=NULL) {
201 *comment=0;
202 comment++;
203 if(comment[0]!=0 && comment[0]!='\'')
204 pexit("Section-Comment not started with ' - exiting\n", params);
205 comment++;
206 cend=strchr(comment, '\'');
207 if(cend==NULL) pexit("Section-Comment not ended with ' - exiting\n", params);
208 *cend=0;
209 }
210
211 secakt=listInsert(name, comment);
212 mfprintf(mfout, "\nconst char %s[]=\"", name);
213 }
214
parseParam(MFILE * mfout,Content * insat,const char * params,int printpname)215 char *parseParam(MFILE *mfout, Content *insat, const char *params, int printpname)
216 {
217 char *format=(char*)params, *name, *comment=NULL, *cend;
218 if(secakt==NULL) pexit("Param: tried to insert, but no section found\n", params);
219
220 name=strchr(format, ' ');
221 if(name==NULL) pexit("Param-Format not found - exiting\n", params);
222 *name=0; name++;
223 if(*name==0) pexit("Param-Name not found - exiting\n", name);
224
225 cend=strchr(name, ' ');
226 if(cend!=NULL){
227 *cend=0; cend++;
228 while(*cend==' ') cend++;
229
230 if(*cend=='\''){
231 comment=cend;
232 comment++;
233 cend=strchr(comment, '\'');
234 if(cend==NULL) pexit("Param-Comment not ended with ' - exiting\n", params);
235 *cend=0; cend++;
236 while(*cend!=0 && *cend==' ') cend++;
237 }
238 }
239
240 listInsertContent(insat, format, name, comment);
241 if(printpname)
242 mfprintf(mfout, "%s=%%%s", name, format);
243 else
244 mfprintf(mfout, "%%%s", format);
245
246 if(cend==NULL || *cend==0) return(NULL);
247 return(cend);
248 }
249
parseSLink(MFILE * mfout,const char * params)250 void parseSLink(MFILE *mfout, const char *params)
251 {
252 Content *c;
253 char *p=(char*)params, *comment, *cend;
254 if(secakt==NULL) pexit("SLink: tried to insert, but no section found\n", params);
255
256 if(*params!='\'') comment=(char*)strdup("");
257 else{
258 comment=(char*)(params+1);
259 cend=strchr(comment, '\'');
260 if(cend==NULL) pexit("SLink: comment not ended with ' - exiting\n", params);
261 *cend=0; cend++;
262 while(*cend==' ') cend++;
263 p=cend;
264 }
265
266 c=listInsertContent(secakt->list, "", "***SCRIPT LINK***", comment);
267 listInsertContent(c->sub, "s", "script", "Script Name");
268
269 mfprintf(mfout, "%%s?");
270 while((p=parseParam(mfout, c->sub, p, true))!=NULL)
271 mfputc('&', mfout);
272 }
273
listInsert(const char * name,const char * comment)274 Section *listInsert(const char *name, const char *comment)
275 {
276 Section *runner=seclist;
277
278 while(runner->next!=NULL) runner=runner->next;
279 runner->next=calloc(1, sizeof(Section));
280 runner->list=calloc(1, sizeof(Content));
281 runner->ilist=calloc(1, sizeof(Input));
282
283 runner->name=(char*)strdup(name);
284 if(comment!=NULL)
285 runner->comment=(char*)strdup(comment);
286 else
287 runner->comment=(char*)strdup("");
288
289 return(runner);
290 }
291
listInsertContent(Content * where,const char * format,const char * name,const char * comment)292 Content *listInsertContent(Content *where, const char *format,
293 const char *name, const char *comment)
294 {
295 while(where->next!=NULL) where=where->next;
296 where->next=calloc(1, sizeof(Content));
297 where->sub=calloc(1, sizeof(Content));
298
299 where->format=(char*)strdup(format);
300 where->name=(char*)strdup(name);
301 if(comment!=NULL && *comment!=0)
302 where->comment=(char*)strdup(comment);
303 else
304 where->comment=(char*)strdup("");
305
306 return(where);
307 }
308
listInsertInput(const char * name,const char * type)309 void listInsertInput(const char *name, const char *type)
310 {
311 Input *runner;
312 if(secakt==NULL) return;
313 runner=secakt->ilist;
314
315 while(runner->next!=NULL) runner=runner->next;
316 runner->next=calloc(1, sizeof(Input));
317 if(name!=NULL) runner->name=strdup(name);
318 else runner->name="";
319 if(type!=NULL) runner->type=strdup(type);
320 else runner->type="";
321 }
322
listDump(FILE * f)323 void listDump(FILE *f)
324 {
325 Section *runner=seclist;
326 Content *crunner, *crunner2;
327 Input *irunner;
328
329 while(runner->next!=NULL){
330 fprintf(f, "\n\n****************************************\n%-32s", runner->name);
331 if(runner->comment!=NULL && *runner->comment!=0)
332 fprintf(f, " \"%s\"", runner->comment);
333 fprintf(f, "\n****************************************\n\n");
334
335 // printf template
336
337 fprintf(f, "PRINTF-TEMPLATE\n");
338 fprintf(f, "----------------------------------------\n");
339 if(runner->list->next!=NULL)
340 fprintf(f, "printf(%s, ", runner->name);
341 else
342 fprintf(f, "printf(%s", runner->name);
343 crunner=runner->list;
344 while(crunner->next!=NULL){
345 if(crunner->sub->next==NULL){
346 if(crunner->next->next!=NULL)
347 fprintf(f, "%s, ", crunner->name);
348 else
349 fprintf(f, "%s", crunner->name);
350 }
351 crunner2=crunner->sub;
352 while(crunner2->next!=NULL){
353 if(crunner2->next->next!=NULL || crunner->next->next!=NULL)
354 fprintf(f, "%s, ", crunner2->name);
355 else
356 fprintf(f, "%s", crunner2->name);
357 crunner2=crunner2->next;
358 }
359 crunner=crunner->next;
360 }
361 fprintf(f, ");\n\n");
362
363 // form input names
364
365 fprintf(f, "%-31s %s\n", "FORM-INPUT-NAME", "FORM-INPUT-TYPE");
366 fprintf(f, "----------------------------------------\n");
367 irunner=runner->ilist;
368 while(irunner->next!=NULL){
369 fprintf(f, "%-31s %s\n", irunner->name, irunner->type);
370 irunner=irunner->next;
371 }
372
373 // parameter
374
375 fprintf(f, "\n%-10s %-20s %s\n", "FORMAT", "NAME", "COMMENT");
376 fprintf(f, "----------------------------------------\n");
377 crunner=runner->list;
378 while(crunner->next!=NULL){
379 fprintf(f, "%-10s %-20s", crunner->format, crunner->name);
380 if(crunner->comment!=NULL && *crunner->comment!=0)
381 fprintf(f, " \"%s\"", crunner->comment);
382 fprintf(f, "\n");
383 crunner2=crunner->sub;
384 while(crunner2->next!=NULL){
385 fprintf(f, "%-10s %-20s", crunner2->format, crunner2->name);
386 if(crunner2->comment!=NULL && *crunner2->comment!=0)
387 fprintf(f, " \"%s\"", crunner2->comment);
388 fprintf(f, "\n");
389 crunner2=crunner2->next;
390 }
391 crunner=crunner->next;
392 }
393 runner=runner->next;
394 }
395 }
396
escapeWrite(char * what,int length,MFILE * where)397 void escapeWrite(char *what, int length, MFILE *where)
398 {
399 int i=0;
400
401 for(i=0;i<length;i++)
402 switch(what[i]){
403 case '"' : mfputc('\\', where); mfputc('"', where); break;
404 case '%' : mfputc('%', where); mfputc('%', where); break;
405 default : mfputc(what[i], where);
406 }
407 }
408
pexit(char * msg,const char * comment)409 void pexit(char *msg, const char *comment)
410 {
411 fprintf(stderr, "%s%s\n", msg, comment);
412 exit(1);
413
414 }
415
416