Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * This file generates parts of LibCSS.
3
 * Licensed under the MIT License,
4
 *		  http://www.opensource.org/licenses/mit-license.php
5
 * Copyright 2010 Vincent Sanders 
6
 */
7
 
8
#include 
9
#include 
10
#include 
11
#include 
12
 
13
/* Descriptors are space separated key:value pairs brackets () are
14
 * used to quote in values.
15
 *
16
 * Examples:
17
 * list_style_image:CSS_PROP_LIST_STYLE_IMAGE IDENT:( INHERIT: NONE:0,LIST_STYLE_IMAGE_NONE IDENT:) URI:LIST_STYLE_IMAGE_URI
18
 *
19
 * list_style_position:CSS_PROP_LIST_STYLE_POSITION IDENT:( INHERIT: INSIDE:0,LIST_STYLE_POSITION_INSIDE OUTSIDE:0,LIST_STYLE_POSITION_OUTSIDE IDENT:)
20
*/
21
 
22
struct keyval {
23
	char *key;
24
	char *val;
25
};
26
 
27
struct keyval_list {
28
	struct keyval *item[100];
29
	int count;
30
};
31
 
32
struct keyval *get_keyval(char **pos)
33
{
34
	char *endpos;
35
	struct keyval *nkeyval;
36
	int kvlen;
37
 
38
	endpos = strchr(*pos, ' '); /* single space separated pairs */
39
	if (endpos == NULL) {
40
		/* no space, but might be the end of the input */
41
		kvlen = strlen(*pos);
42
		if (kvlen == 0)
43
			return NULL;
44
		endpos = *pos + kvlen;
45
	} else {
46
		kvlen = (endpos - *pos);
47
	}
48
	nkeyval = calloc(1, sizeof(struct keyval) + kvlen + 1);
49
 
50
	memcpy(nkeyval + 1, *pos, kvlen);
51
 
52
	nkeyval->key = (char *)nkeyval + sizeof(struct keyval);
53
 
54
	endpos = strchr(nkeyval->key, ':'); /* split key and value on : */
55
	if (endpos != NULL) {
56
		endpos[0] = 0; /* change : to null terminator */
57
		nkeyval->val = endpos + 1; /* skip : */
58
	}
59
 
60
	*pos += kvlen; /* update position */
61
 
62
	/* skip spaces */
63
	while ((*pos[0] != 0) &&
64
	       (*pos[0] == ' ')) {
65
		(*pos)++;
66
	}
67
 
68
	return nkeyval;
69
}
70
 
71
void output_header(FILE *outputf, const char *descriptor, struct keyval *parser_id, bool is_generic)
72
{
73
	fprintf(outputf,
74
		"/*\n"
75
		" * This file was generated by LibCSS gen_parser \n"
76
		" * \n"
77
		" * Generated from:\n"
78
		" *\n"
79
		" * %s\n"
80
		" * \n"
81
		" * Licensed under the MIT License,\n"
82
		" *		  http://www.opensource.org/licenses/mit-license.php\n"
83
		" * Copyright 2010 The NetSurf Browser Project.\n"
84
		" */\n"
85
		"\n"
86
		"#include \n"
87
		"#include \n"
88
		"\n"
89
		"#include \"bytecode/bytecode.h\"\n"
90
		"#include \"bytecode/opcodes.h\"\n"
91
		"#include \"parse/properties/properties.h\"\n"
92
		"#include \"parse/properties/utils.h\"\n"
93
		"\n"
94
		"/**\n"
95
		" * Parse %s\n"
96
		" *\n"
97
		" * \\param c	  Parsing context\n"
98
		" * \\param vector  Vector of tokens to process\n"
99
		" * \\param ctx	  Pointer to vector iteration context\n"
100
		" * \\param result  resulting style\n"
101
		"%s"
102
		" * \\return CSS_OK on success,\n"
103
		" *	   CSS_NOMEM on memory exhaustion,\n"
104
		" *	   CSS_INVALID if the input is not valid\n"
105
		" *\n"
106
		" * Post condition: \\a *ctx is updated with the next token to process\n"
107
		" *		   If the input is invalid, then \\a *ctx remains unchanged.\n"
108
		" */\n"
109
		"css_error css__parse_%s(css_language *c,\n"
110
		"		const parserutils_vector *vector, int *ctx,\n"
111
		"		css_style *result%s)\n"
112
		"{\n",
113
		descriptor,
114
		parser_id->key,
115
		is_generic ? " * \\param op	 Bytecode OpCode for CSS property to encode\n" : "",
116
		parser_id->key,
117
		is_generic ? ", enum css_properties_e op" : "");
118
}
119
 
120
 
121
void output_token_type_check(FILE *outputf, bool do_token_check, struct keyval_list *IDENT, struct keyval_list *URI, struct keyval_list *NUMBER)
122
{
123
	fprintf(outputf,
124
		"	int orig_ctx = *ctx;\n"
125
		"	css_error error;\n"
126
		"	const css_token *token;\n"
127
		"	bool match;\n\n"
128
		"	token = parserutils_vector_iterate(vector, ctx);\n"
129
		"	if (%stoken == NULL%s",
130
		do_token_check ? "(" : "",
131
		do_token_check ? ")" : "");
132
 
133
	if (do_token_check) {
134
		bool prev = false; /* there was a previous check - add && */
135
		fprintf(outputf," || (");
136
 
137
		if (IDENT->count > 0) {
138
			fprintf(outputf,"(token->type != CSS_TOKEN_IDENT)");
139
			prev = true;
140
		}
141
		if (URI->count > 0) {
142
			if (prev) fprintf(outputf," && ");
143
			fprintf(outputf,"(token->type != CSS_TOKEN_URI)");
144
			prev = true;
145
		}
146
		if (NUMBER->count > 0) {
147
			if (prev) fprintf(outputf," && ");
148
			fprintf(outputf,"(token->type != CSS_TOKEN_NUMBER)");
149
			prev = true;
150
		}
151
 
152
		fprintf(outputf,")");
153
	}
154
 
155
	fprintf(outputf,
156
		") {\n"
157
		"\t\t*ctx = orig_ctx;\n"
158
		"\t\treturn CSS_INVALID;\n"
159
		"\t}\n\n\t");
160
}
161
 
162
void output_ident(FILE *outputf, bool only_ident, struct keyval *parseid, struct keyval_list *IDENT)
163
{
164
	int ident_count;
165
 
166
	for (ident_count = 0 ; ident_count < IDENT->count; ident_count++) {
167
		struct keyval *ckv = IDENT->item[ident_count];
168
 
169
		fprintf(outputf,
170
			"if (");
171
		if (!only_ident) {
172
			fprintf(outputf,
173
			"(token->type == CSS_TOKEN_IDENT) && ");
174
		}
175
		fprintf(outputf,
176
			"(lwc_string_caseless_isequal(token->idata, c->strings[%s], &match) == lwc_error_ok && match)) {\n",
177
			ckv->key);
178
		if (strcmp(ckv->key,"INHERIT") == 0) {
179
		fprintf(outputf,
180
			"\t\t\terror = css_stylesheet_style_inherit(result, %s);\n",
181
			parseid->val);
182
		} else {
183
		fprintf(outputf,
184
			"\t\t\terror = css__stylesheet_style_appendOPV(result, %s, %s);\n",
185
			parseid->val,
186
			ckv->val);
187
		}
188
		fprintf(outputf,
189
			"\t} else ");
190
	}
191
}
192
 
193
void output_uri(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
194
{
195
	struct keyval *ckv = kvlist->item[0];
196
 
197
	fprintf(outputf,
198
		"if (token->type == CSS_TOKEN_URI) {\n"
199
		"		lwc_string *uri = NULL;\n"
200
		"		uint32_t uri_snumber;\n"
201
		"\n"
202
		"		error = c->sheet->resolve(c->sheet->resolve_pw,\n"
203
		"				c->sheet->url,\n"
204
		"				token->idata, &uri);\n"
205
		"		if (error != CSS_OK) {\n"
206
		"			*ctx = orig_ctx;\n"
207
		"			return error;\n"
208
		"		}\n"
209
		"\n"
210
		"		error = css__stylesheet_string_add(c->sheet, uri, &uri_snumber);\n"
211
		"		if (error != CSS_OK) {\n"
212
		"			*ctx = orig_ctx;\n"
213
		"			return error;\n"
214
		"		}\n"
215
		"\n"
216
		"		error = css__stylesheet_style_appendOPV(result, %s, 0, %s);\n"
217
		"		if (error != CSS_OK) {\n"
218
		"			*ctx = orig_ctx;\n"
219
		"			return error;\n"
220
		"		}\n"
221
		"\n"
222
		"		error = css__stylesheet_style_append(result, uri_snumber);\n"
223
		"	} else ",
224
		parseid->val,
225
		ckv->val);
226
}
227
 
228
void output_number(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
229
{
230
	struct keyval *ckv = kvlist->item[0];
231
	int ident_count;
232
 
233
	fprintf(outputf,
234
		"if (token->type == CSS_TOKEN_NUMBER) {\n"
235
		"\t\tcss_fixed num = 0;\n"
236
		"\t\tsize_t consumed = 0;\n\n"
237
		"\t\tnum = css__number_from_lwc_string(token->idata, %s, &consumed);\n"
238
		"\t\t/* Invalid if there are trailing characters */\n"
239
		"\t\tif (consumed != lwc_string_length(token->idata)) {\n"
240
		"\t\t\t*ctx = orig_ctx;\n"
241
		"\t\t\treturn CSS_INVALID;\n"
242
		"\t\t}\n",
243
		ckv->key);
244
 
245
	for (ident_count = 1 ; ident_count < kvlist->count; ident_count++) {
246
		struct keyval *ulkv = kvlist->item[ident_count];
247
 
248
		if (strcmp(ulkv->key, "RANGE") == 0) {
249
			fprintf(outputf,
250
				"\t\tif (%s) {\n"
251
				"\t\t\t*ctx = orig_ctx;\n"
252
				"\t\t\treturn CSS_INVALID;\n"
253
				"\t\t}\n\n",
254
				ulkv->val);
255
		}
256
 
257
	}
258
 
259
	fprintf(outputf,
260
		"\t\terror = css__stylesheet_style_appendOPV(result, %s, 0, %s);\n"
261
		"\t\tif (error != CSS_OK) {\n"
262
		"\t\t\t*ctx = orig_ctx;\n"
263
		"\t\t\treturn error;\n"
264
		"\t\t}\n\n"
265
		"\t\terror = css__stylesheet_style_append(result, num);\n"
266
		"\t} else ",
267
		parseid->val,
268
		ckv->val);
269
}
270
 
271
void output_color(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
272
{
273
	fprintf(outputf,
274
		"{\n"
275
		"\t\tuint16_t value = 0;\n"
276
		"\t\tuint32_t color = 0;\n"
277
		"\t\t*ctx = orig_ctx;\n\n"
278
		"\t\terror = css__parse_colour_specifier(c, vector, ctx, &value, &color);\n"
279
		"\t\tif (error != CSS_OK) {\n"
280
		"\t\t\t*ctx = orig_ctx;\n"
281
		"\t\t\treturn error;\n"
282
		"\t\t}\n\n"
283
		"\t\terror = css__stylesheet_style_appendOPV(result, %s, 0, value);\n"
284
		"\t\tif (error != CSS_OK) {\n"
285
		"\t\t\t*ctx = orig_ctx;\n"
286
		"\t\t\treturn error;\n"
287
		"\t\t}\n"
288
		"\n"
289
		"\t\tif (value == COLOR_SET)\n"
290
		"\t\t\terror = css__stylesheet_style_append(result, color);\n"
291
		"\t}\n\n",
292
		parseid->val);
293
}
294
 
295
void output_length_unit(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
296
{
297
	struct keyval *ckv = kvlist->item[0];
298
	int ident_count;
299
 
300
 
301
	fprintf(outputf,
302
		"{\n"
303
		"\t\tcss_fixed length = 0;\n"
304
		"\t\tuint32_t unit = 0;\n"
305
		"\t\t*ctx = orig_ctx;\n\n"
306
		"\t\terror = css__parse_unit_specifier(c, vector, ctx, %s, &length, &unit);\n"
307
		"\t\tif (error != CSS_OK) {\n"
308
		"\t\t\t*ctx = orig_ctx;\n"
309
		"\t\t\treturn error;\n"
310
		"\t\t}\n\n",
311
		ckv->key);
312
 
313
	for (ident_count = 1 ; ident_count < kvlist->count; ident_count++) {
314
		struct keyval *ulkv = kvlist->item[ident_count];
315
 
316
		if (strcmp(ulkv->key, "ALLOW") == 0) {
317
			fprintf(outputf,
318
				"\t\tif ((%s) == false) {\n"
319
				"\t\t\t*ctx = orig_ctx;\n"
320
				"\t\t\treturn CSS_INVALID;\n"
321
				"\t\t}\n\n",
322
				ulkv->val);
323
		} else if (strcmp(ulkv->key, "DISALLOW") == 0) {
324
			fprintf(outputf,
325
				"\t\tif (%s) {\n"
326
				"\t\t\t*ctx = orig_ctx;\n"
327
				"\t\t\treturn CSS_INVALID;\n"
328
				"\t\t}\n\n",
329
				ulkv->val);
330
		} else if (strcmp(ulkv->key, "RANGE") == 0) {
331
			fprintf(outputf,
332
				"\t\tif (length %s) {\n"
333
				"\t\t\t*ctx = orig_ctx;\n"
334
				"\t\t\treturn CSS_INVALID;\n"
335
				"\t\t}\n\n",
336
				ulkv->val);
337
		}
338
 
339
	}
340
 
341
	fprintf(outputf,
342
		"\t\terror = css__stylesheet_style_appendOPV(result, %s, 0, %s);\n"
343
		"\t\tif (error != CSS_OK) {\n"
344
		"\t\t\t*ctx = orig_ctx;\n"
345
		"\t\t\treturn error;\n"
346
		"\t\t}\n"
347
		"\n"
348
		"\t\terror = css__stylesheet_style_vappend(result, 2, length, unit);\n"
349
		"\t}\n\n",
350
		parseid->val,
351
		ckv->val);
352
}
353
 
354
void output_ident_list(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
355
{
356
	struct keyval *ckv = kvlist->item[0]; /* list type : opv value */
357
	if (strcmp(ckv->key, "STRING_OPTNUM") == 0) {
358
		/* list of IDENT and optional numbers */
359
		struct keyval *ikv = kvlist->item[1]; /* numeric default : end condition */
360
 
361
		fprintf(outputf,
362
			"{\n"
363
			"\t\terror = css__stylesheet_style_appendOPV(result, %s, 0, %s);\n"
364
			"\t\tif (error != CSS_OK) {\n"
365
			"\t\t\t*ctx = orig_ctx;\n"
366
			"\t\t\treturn error;\n"
367
			"\t\t}\n\n"
368
			"\t\twhile ((token != NULL) && (token->type == CSS_TOKEN_IDENT)) {\n"
369
			"\t\t\tuint32_t snumber;\n"
370
			"\t\t\tcss_fixed num;\n"
371
			"\t\t\tint pctx;\n\n"
372
			"\t\t\terror = css__stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);\n"
373
			"\t\t\tif (error != CSS_OK) {\n"
374
			"\t\t\t\t*ctx = orig_ctx;\n"
375
			"\t\t\t\treturn error;\n"
376
			"\t\t\t}\n\n"
377
			"\t\t\terror = css__stylesheet_style_append(result, snumber);\n"
378
			"\t\t\tif (error != CSS_OK) {\n"
379
			"\t\t\t\t*ctx = orig_ctx;\n"
380
			"\t\t\t\treturn error;\n"
381
			"\t\t\t}\n\n"
382
			"\t\t\tconsumeWhitespace(vector, ctx);\n\n"
383
			"\t\t\tpctx = *ctx;\n"
384
			"\t\t\ttoken = parserutils_vector_iterate(vector, ctx);\n"
385
			"\t\t\tif ((token != NULL) && (token->type == CSS_TOKEN_NUMBER)) {\n"
386
			"\t\t\t\tsize_t consumed = 0;\n\n"
387
			"\t\t\t\tnum = css__number_from_lwc_string(token->idata, true, &consumed);\n"
388
			"\t\t\t\tif (consumed != lwc_string_length(token->idata)) {\n"
389
			"\t\t\t\t\t*ctx = orig_ctx;\n"
390
			"\t\t\t\t\treturn CSS_INVALID;\n"
391
			"\t\t\t\t}\n"
392
			"\t\t\t\tconsumeWhitespace(vector, ctx);\n\n"
393
			"\t\t\t\tpctx = *ctx;\n"
394
			"\t\t\t\ttoken = parserutils_vector_iterate(vector, ctx);\n"
395
			"\t\t\t} else {\n"
396
			"\t\t\t\tnum = INTTOFIX(%s);\n"
397
			"\t\t\t}\n\n"
398
			"\t\t\terror = css__stylesheet_style_append(result, num);\n"
399
			"\t\t\tif (error != CSS_OK) {\n"
400
			"\t\t\t\t*ctx = orig_ctx;\n"
401
			"\t\t\t\treturn error;\n"
402
			"\t\t\t}\n\n"
403
			"\t\t\tif (token == NULL)\n"
404
			"\t\t\t\tbreak;\n\n"
405
			"\t\t\tif (token->type == CSS_TOKEN_IDENT) {\n"
406
			"\t\t\t\terror = css__stylesheet_style_append(result, %s);\n"
407
			"\t\t\t\tif (error != CSS_OK) {\n"
408
			"\t\t\t\t\t*ctx = orig_ctx;\n"
409
			"\t\t\t\t\treturn error;\n"
410
			"\t\t\t\t}\n"
411
			"\t\t\t} else {\n"
412
			"\t\t\t\t*ctx = pctx; /* rewind one token back */\n"
413
			"\t\t\t}\n"
414
			"\t\t}\n\n"
415
			"\t\terror = css__stylesheet_style_append(result, %s);\n"
416
			"\t}\n\n",
417
			parseid->val,
418
			ckv->val,
419
			ikv->key,
420
			ckv->val,
421
			ikv->val);
422
 
423
	} else {
424
		fprintf(stderr, "unknown IDENT list type %s\n",ckv->key);
425
		exit(4);
426
	}
427
 
428
}
429
 
430
void output_invalidcss(FILE *outputf)
431
{
432
	fprintf(outputf, "{\n\t\terror = CSS_INVALID;\n\t}\n\n");
433
}
434
 
435
void output_footer(FILE *outputf)
436
{
437
	fprintf(outputf,
438
		"	if (error != CSS_OK)\n"
439
		"		*ctx = orig_ctx;\n"
440
		"	\n"
441
		"	return error;\n"
442
		"}\n\n");
443
}
444
 
445
void output_wrap(FILE *outputf, struct keyval *parseid, struct keyval_list *WRAP)
446
{
447
	struct keyval *ckv = WRAP->item[0];
448
	fprintf(outputf,
449
		"	return %s(c, vector, ctx, result, %s);\n}\n",
450
		ckv->val,
451
		parseid->val);
452
}
453
 
454
char str_INHERIT[] = "INHERIT";
455
 
456
struct keyval ident_inherit = {
457
	.key = str_INHERIT,
458
};
459
 
4821 ashmew2 460
#if 0
3584 sourcerer 461
int main(int argc, char **argv)
462
{
463
	char *descriptor;
464
	char *curpos; /* current position in input string */
465
	struct keyval *parser_id; /* the parser we are creating output for */
466
	FILE *outputf;
467
	struct keyval *rkv; /* current read key:val */
468
	struct keyval_list *curlist;
469
	bool do_token_check = true; /* if the check for valid tokens is done */
470
	bool only_ident = true; /* if the only token type is ident */
471
	bool is_generic = false;
472
 
473
	struct keyval_list base;
474
	struct keyval_list IDENT;
475
	struct keyval_list IDENT_LIST;
476
	struct keyval_list LENGTH_UNIT;
477
	struct keyval_list URI;
478
	struct keyval_list WRAP;
479
	struct keyval_list NUMBER;
480
	struct keyval_list COLOR;
481
 
482
 
483
	if (argc < 2) {
484
		fprintf(stderr,"Usage: %s [-o ] \n", argv[0]);
485
		return 1;
486
	}
487
 
488
	if ((argv[1][0] == '-') && (argv[1][1] == 'o')) {
489
		if (argc != 4) {
490
			fprintf(stderr,"Usage: %s [-o ] \n", argv[0]);
491
			return 1;
492
		}
493
		outputf = fopen(argv[2], "w");
494
		if (outputf == NULL) {
495
			perror("unable to open file");
496
		}
497
		descriptor = strdup(argv[3]);
498
	} else {
499
		outputf = stdout;
500
		descriptor = strdup(argv[1]);
501
	}
502
	curpos = descriptor;
503
 
504
	base.count = 0;
505
	IDENT.count = 0;
506
	URI.count = 0;
507
	WRAP.count = 0;
508
	NUMBER.count = 0;
509
	COLOR.count = 0;
510
	LENGTH_UNIT.count = 0;
511
	IDENT_LIST.count = 0;
512
 
513
	curlist = &base;
514
 
515
	while (*curpos != 0) {
516
		rkv = get_keyval(&curpos);
517
		if (rkv == NULL) {
518
			fprintf(stderr,"Token error at offset %ld\n", curpos - descriptor);
519
			fclose(outputf);
520
			return 2;
521
		}
522
 
523
		if (strcmp(rkv->key, "WRAP") == 0) {
524
			WRAP.item[WRAP.count++] = rkv;
525
			only_ident = false;
526
		} else if (strcmp(rkv->key, "NUMBER") == 0) {
527
			if (rkv->val[0] == '(') {
528
				curlist = &NUMBER;
529
			} else if (rkv->val[0] == ')') {
530
				curlist = &base;
531
			} else {
532
				NUMBER.item[NUMBER.count++] = rkv;
533
			}
534
			only_ident = false;
535
		} else if (strcmp(rkv->key, "IDENT") == 0) {
536
			if (rkv->val[0] == '(') {
537
				curlist = &IDENT;
538
			} else if (rkv->val[0] == ')') {
539
				curlist = &base;
540
			} else if (strcmp(rkv->val, str_INHERIT) == 0) {
541
				IDENT.item[IDENT.count++] = &ident_inherit;
542
			}
543
		} else if (strcmp(rkv->key, "IDENT_LIST") == 0) {
544
			if (rkv->val[0] == '(') {
545
				curlist = &IDENT_LIST;
546
			} else if (rkv->val[0] == ')') {
547
				curlist = &base;
548
			}
549
		} else if (strcmp(rkv->key, "LENGTH_UNIT") == 0) {
550
			if (rkv->val[0] == '(') {
551
				curlist = &LENGTH_UNIT;
552
			} else if (rkv->val[0] == ')') {
553
				curlist = &base;
554
			}
555
			only_ident = false;
556
			do_token_check = false;
557
		} else if (strcmp(rkv->key, "COLOR") == 0) {
558
			COLOR.item[COLOR.count++] = rkv;
559
			do_token_check = false;
560
			only_ident = false;
561
		} else if (strcmp(rkv->key, "URI") == 0) {
562
			URI.item[URI.count++] = rkv;
563
			only_ident = false;
564
		} else if (strcmp(rkv->key, "GENERIC") == 0) {
565
			is_generic = true;
566
		} else {
567
			/* just append to current list */
568
			curlist->item[curlist->count++] = rkv;
569
		}
570
	}
571
 
572
	if (base.count != 1) {
573
		fprintf(stderr,"Incorrect base element count (got %d expected 1)\n", base.count);
574
		fclose(outputf);
575
		return 3;
576
	}
577
 
578
 
579
	/* header */
580
output_header(outputf, descriptor, base.item[0], is_generic);
581
 
582
	if (WRAP.count > 0) {
583
		output_wrap(outputf, base.item[0], &WRAP);
584
	} else {
585
		/* check token type is correct */
586
		output_token_type_check(outputf, do_token_check,  &IDENT, &URI, &NUMBER);
587
 
588
		if (IDENT.count > 0)
589
			output_ident(outputf, only_ident, base.item[0], &IDENT);
590
 
591
		if (URI.count > 0)
592
			output_uri(outputf, base.item[0], &URI);
593
 
594
		if (NUMBER.count > 0)
595
			output_number(outputf, base.item[0], &NUMBER);
596
 
597
		/* terminal blocks, these end the ladder ie no trailing else */
598
		if (COLOR.count > 0) {
599
			output_color(outputf, base.item[0], &COLOR);
600
		} else if (LENGTH_UNIT.count > 0) {
601
			output_length_unit(outputf, base.item[0], &LENGTH_UNIT);
602
		} else if (IDENT_LIST.count > 0) {
603
			output_ident_list(outputf, base.item[0], &IDENT_LIST);
604
		} else {
605
			output_invalidcss(outputf);
606
		}
607
 
608
		output_footer(outputf);
609
 
610
	}
611
 
612
	fclose(outputf);
613
 
614
	return 0;
615
}
4821 ashmew2 616
#endif