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