Review: Libcss property parser and string table handling refactor

Vincent Sanders vince at netsurf-browser.org
Tue Jan 18 22:11:48 GMT 2011


Added files


Index: src/parse/properties/cue_before.c
===================================================================
--- /dev/null	2011-01-18 08:20:14.799282769 +0000
+++ src/parse/properties/cue_before.c	2011-01-18 22:06:03.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * This file is part of LibCSS.
+ * Licensed under the MIT License,
+ *		  http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "bytecode/bytecode.h"
+#include "bytecode/opcodes.h"
+#include "parse/properties/properties.h"
+#include "parse/properties/utils.h"
+
+/**
+ * Parse cue-before
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
+css_error parse_cue_before(css_language *c, 
+		const parserutils_vector *vector, int *ctx, 
+		css_style *result)
+{
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	/* URI | IDENT (none, inherit) */
+	token = parserutils_vector_iterate(vector, ctx);
+	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
+			token->type != CSS_TOKEN_URI)) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(
+		    token->idata, c->strings[INHERIT],
+		    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_BEFORE,
+						       FLAG_INHERIT,
+						       0);
+	} else if ((token->type == CSS_TOKEN_IDENT) && 
+		   (lwc_string_caseless_isequal(
+			   token->idata, c->strings[NONE],
+			   &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_BEFORE,
+						       0,
+						       CUE_AFTER_NONE);
+	} else if (token->type == CSS_TOKEN_URI) {
+		/* cue after with uri */
+		lwc_string *uri = NULL;
+		uint32_t uri_snumber;
+
+		error = c->sheet->resolve(c->sheet->resolve_pw,
+				c->sheet->url,
+				token->idata, &uri);
+
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_string_add(c->sheet, uri, &uri_snumber);
+
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_BEFORE,
+						       0,
+						       CUE_AFTER_URI);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, uri_snumber);
+
+	} else {
+		error = CSS_INVALID;
+	}
+
+	if (error != CSS_OK) {
+		*ctx = orig_ctx;
+	}
+
+	return error;
+}
Index: src/parse/properties/css_property_parser_gen.c
===================================================================
--- /dev/null	2011-01-18 08:20:14.799282769 +0000
+++ src/parse/properties/css_property_parser_gen.c	2011-01-18 22:06:09.000000000 +0000
@@ -0,0 +1,599 @@
+/* generates parsers for libcss */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+/* Descriptors are space separated key:value pairs brackets () are
+ * used to quote in values.
+ *
+ * Examples:
+ * list_style_image:CSS_PROP_LIST_STYLE_IMAGE IDENT:( INHERIT: NONE:0,LIST_STYLE_IMAGE_NONE IDENT:) URI:LIST_STYLE_IMAGE_URI
+ *
+ * list_style_position:CSS_PROP_LIST_STYLE_POSITION IDENT:( INHERIT: INSIDE:0,LIST_STYLE_POSITION_INSIDE OUTSIDE:0,LIST_STYLE_POSITION_OUTSIDE IDENT:)
+*/
+
+struct keyval {
+	char *key;
+	char *val;
+};
+
+struct keyval_list {
+	struct keyval *item[100];
+	int count;
+};
+
+struct keyval *get_keyval(char **pos)
+{
+	char *endpos;
+	struct keyval *nkeyval;
+	int kvlen;
+
+	endpos = strchr(*pos, ' '); /* single space separated pairs */
+	if (endpos == NULL) {
+		/* no space, but might be the end of the input */
+		kvlen = strlen(*pos);
+		if (kvlen == 0)
+			return NULL;
+		endpos = *pos + kvlen;
+	} else {
+		kvlen = (endpos - *pos);
+	}
+	nkeyval = calloc(1, sizeof(struct keyval) + kvlen + 1);
+
+	memcpy(nkeyval + 1, *pos, kvlen);
+
+	nkeyval->key = (char *)nkeyval + sizeof(struct keyval);
+
+	endpos = strchr(nkeyval->key, ':'); /* split key and value on : */
+	if (endpos != NULL) {
+		endpos[0] = 0; /* change : to null terminator */
+		nkeyval->val = endpos + 1; /* skip : */
+	}
+
+	*pos += kvlen; /* update position */
+
+	/* skip spaces */
+	while ((*pos[0] != 0) &&
+	       (*pos[0] == ' ')) {
+		(*pos)++;
+	}
+
+	return nkeyval;
+}
+
+void output_header(FILE *outputf, const char *descriptor, struct keyval *parser_id)
+{
+	fprintf(outputf,
+		"/*\n"
+		" * This file was generated by LibCSS gen_parser \n"
+		" * \n"
+		" * Generated from:\n"
+		" *\n"
+		" * %s\n"
+		" * \n"
+		" * Licensed under the MIT License,\n"
+		" *		  http://www.opensource.org/licenses/mit-license.php\n"
+		" * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>\n"
+		" */\n"
+		"\n"
+		"#include <assert.h>\n"
+		"#include <string.h>\n"
+		"\n"
+		"#include \"bytecode/bytecode.h\"\n"
+		"#include \"bytecode/opcodes.h\"\n"
+		"#include \"parse/properties/properties.h\"\n"
+		"#include \"parse/properties/utils.h\"\n"
+		"\n"
+		"/**\n"
+		" * Parse %s\n"
+		" *\n"
+		" * \\param c	  Parsing context\n"
+		" * \\param vector  Vector of tokens to process\n"
+		" * \\param ctx	  Pointer to vector iteration context\n"
+		" * \\param result  resulting style\n"
+		" * \\return CSS_OK on success,\n"
+		" *	   CSS_NOMEM on memory exhaustion,\n"
+		" *	   CSS_INVALID if the input is not valid\n"
+		" *\n"
+		" * Post condition: \\a *ctx is updated with the next token to process\n"
+		" *		   If the input is invalid, then \\a *ctx remains unchanged.\n"
+		" */\n"
+		"css_error parse_%s(css_language *c,\n"
+		"		const parserutils_vector *vector, int *ctx,\n"
+		"		css_style *result)\n"
+		"{\n",
+		descriptor, parser_id->key, parser_id->key);
+}
+
+
+void output_token_type_check(FILE *outputf, bool do_token_check, struct keyval_list *IDENT, struct keyval_list *URI, struct keyval_list *NUMBER)
+{
+	fprintf(outputf,
+		"	int orig_ctx = *ctx;\n"
+		"	css_error error;\n"
+		"	const css_token *token;\n"
+		"	bool match;\n\n"
+		"	token = parserutils_vector_iterate(vector, ctx);\n"
+		"	if ((token == NULL)");
+
+	if (do_token_check) {
+		bool prev = false; /* there was a previous check - add && */
+		fprintf(outputf," || (");
+
+		if (IDENT->count > 0) {
+			fprintf(outputf,"(token->type != CSS_TOKEN_IDENT)");
+			prev = true;
+		}
+		if (URI->count > 0) {
+			if (prev) fprintf(outputf," && ");
+			fprintf(outputf,"(token->type != CSS_TOKEN_URI)");
+			prev = true;
+		}
+		if (NUMBER->count > 0) {
+			if (prev) fprintf(outputf," && ");
+			fprintf(outputf,"(token->type != CSS_TOKEN_NUMBER)");
+			prev = true;
+		}
+
+		fprintf(outputf,")");
+	}
+
+	fprintf(outputf,
+		") {\n"
+		"\t\t*ctx = orig_ctx;\n"
+		"\t\treturn CSS_INVALID;\n"
+		"\t}\n\n\t");
+}
+
+void output_ident(FILE *outputf, bool only_ident, struct keyval *parseid, struct keyval_list *IDENT)
+{
+	int ident_count;
+
+	for (ident_count = 0 ; ident_count < IDENT->count; ident_count++) {
+		struct keyval *ckv = IDENT->item[ident_count];
+
+		fprintf(outputf,
+			"if (");
+		if (!only_ident) {
+			fprintf(outputf,
+			"(token->type == CSS_TOKEN_IDENT) && ");
+		}
+		fprintf(outputf,
+			"(lwc_string_caseless_isequal(token->idata, c->strings[%s], &match) == lwc_error_ok && match)) {\n",
+			ckv->key);
+		if (strcmp(ckv->key,"INHERIT") == 0) {
+		fprintf(outputf,
+			"\t\t\terror = css_stylesheet_style_inherit(result, %s);\n",
+			parseid->val);
+		} else {
+		fprintf(outputf,
+			"\t\t\terror = css_stylesheet_style_appendOPV(result, %s, %s);\n",
+			parseid->val,
+			ckv->val);
+		}
+		fprintf(outputf,
+			"\t} else ");
+	}
+}
+
+void output_uri(FILE *outputf, struct keyval *parseid, struct keyval_list *URI)
+{
+
+	fprintf(outputf,
+		"if (token->type == CSS_TOKEN_URI) {\n"
+		"		lwc_string *uri = NULL;\n"
+		"		uint32_t uri_snumber;\n"
+		"\n"
+		"		error = c->sheet->resolve(c->sheet->resolve_pw,\n"
+		"				c->sheet->url,\n"
+		"				token->idata, &uri);\n"
+		"		if (error != CSS_OK) {\n"
+		"			*ctx = orig_ctx;\n"
+		"			return error;\n"
+		"		}\n"
+		"\n"
+		"		error = css_stylesheet_string_add(c->sheet, uri, &uri_snumber);\n"
+		"		if (error != CSS_OK) {\n"
+		"			*ctx = orig_ctx;\n"
+		"			return error;\n"
+		"		}\n"
+		"\n"
+		"		error = css_stylesheet_style_appendOPV(result,\n"
+		"				CSS_PROP_LIST_STYLE_IMAGE,\n"
+		"				0,\n"
+		"				LIST_STYLE_IMAGE_URI);\n"
+		"		if (error != CSS_OK) {\n"
+		"			*ctx = orig_ctx;\n"
+		"			return error;\n"
+		"		}\n"
+		"\n"
+		"		error = css_stylesheet_style_append(result, uri_snumber);\n"
+		"	} else ");
+}
+
+void output_number(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
+{
+	struct keyval *ckv = kvlist->item[0];
+	int ident_count;
+
+	fprintf(outputf,
+		"if (token->type == CSS_TOKEN_NUMBER) {\n"
+		"\t\tcss_fixed num = 0;\n"
+		"\t\tsize_t consumed = 0;\n\n"
+		"\t\tnum = number_from_lwc_string(token->idata, %s, &consumed);\n"
+		"\t\t/* Invalid if there are trailing characters */\n"
+		"\t\tif (consumed != lwc_string_length(token->idata)) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn CSS_INVALID;\n"
+		"\t\t}\n",
+		ckv->key);
+
+	for (ident_count = 1 ; ident_count < kvlist->count; ident_count++) {
+		struct keyval *ulkv = kvlist->item[ident_count];
+
+		if (strcmp(ulkv->key, "RANGE") == 0) {
+			fprintf(outputf,
+				"\t\tif (%s) {\n"
+				"\t\t\t*ctx = orig_ctx;\n"
+				"\t\t\treturn CSS_INVALID;\n"
+				"\t\t}\n\n", 
+				ulkv->val);
+		}
+
+	}
+
+	fprintf(outputf,
+		"\t\terror = css_stylesheet_style_appendOPV(result, %s, 0, %s);\n"
+		"\t\tif (error != CSS_OK) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn error;\n"
+		"\t\t}\n\n"
+		"\t\terror = css_stylesheet_style_append(result, num);\n"
+		"\t} else ",
+		parseid->val,
+		ckv->val);	
+}
+
+void output_color(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
+{
+	struct keyval *ckv = kvlist->item[0];
+
+	fprintf(outputf,
+		"{\n"
+		"\t\tuint32_t color = 0;\n"
+		"\t\t*ctx = orig_ctx;\n\n"
+		"\t\terror = parse_colour_specifier(c, vector, ctx, &color);\n"
+		"\t\tif (error != CSS_OK) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn error;\n"
+		"\t\t}\n\n"
+		"\t\terror = css_stylesheet_style_appendOPV(result, %s, 0, %s);\n"
+		"\t\tif (error != CSS_OK) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn error;\n"
+		"\t\t}\n"
+		"\n"
+		"\t\terror = css_stylesheet_style_append(result, color);\n"
+		"\t}\n\n",
+		parseid->val,
+		ckv->val);
+}
+
+void output_length_unit(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
+{
+	struct keyval *ckv = kvlist->item[0];
+	int ident_count;
+
+
+	fprintf(outputf,
+		"{\n"
+		"\t\tcss_fixed length = 0;\n"
+		"\t\tuint32_t unit = 0;\n"
+		"\t\t*ctx = orig_ctx;\n\n"
+		"\t\terror = parse_unit_specifier(c, vector, ctx, %s, &length, &unit);\n"
+		"\t\tif (error != CSS_OK) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn error;\n"
+		"\t\t}\n\n",
+		ckv->key);
+
+	for (ident_count = 1 ; ident_count < kvlist->count; ident_count++) {
+		struct keyval *ulkv = kvlist->item[ident_count];
+
+		if (strcmp(ulkv->key, "ALLOW") == 0) {
+			fprintf(outputf,
+				"\t\tif ((%s) == false) {\n"
+				"\t\t\t*ctx = orig_ctx;\n"
+				"\t\t\treturn CSS_INVALID;\n"
+				"\t\t}\n\n", 
+				ulkv->val);
+		} else if (strcmp(ulkv->key, "DISALLOW") == 0) {
+			fprintf(outputf,
+				"\t\tif (%s) {\n"
+				"\t\t\t*ctx = orig_ctx;\n"
+				"\t\t\treturn CSS_INVALID;\n"
+				"\t\t}\n\n", 
+				ulkv->val);
+		} else if (strcmp(ulkv->key, "RANGE") == 0) {
+			fprintf(outputf,
+				"\t\tif (length %s) {\n"
+				"\t\t\t*ctx = orig_ctx;\n"
+				"\t\t\treturn CSS_INVALID;\n"
+				"\t\t}\n\n", 
+				ulkv->val);
+		}
+
+	}
+
+	fprintf(outputf,
+		"\t\terror = css_stylesheet_style_appendOPV(result, %s, 0, %s);\n"
+		"\t\tif (error != CSS_OK) {\n"
+		"\t\t\t*ctx = orig_ctx;\n"
+		"\t\t\treturn error;\n"
+		"\t\t}\n"
+		"\n"
+		"\t\terror = css_stylesheet_style_vappend(result, 2, length, unit);\n"
+		"\t}\n\n",
+		parseid->val,
+		ckv->val);
+}
+
+void output_ident_list(FILE *outputf, struct keyval *parseid, struct keyval_list *kvlist)
+{
+	struct keyval *ckv = kvlist->item[0]; /* list type : opv value */
+	if (strcmp(ckv->key, "STRING_OPTNUM") == 0) {
+		/* list of IDENT and optional numbers */
+		struct keyval *ikv = kvlist->item[1]; /* numeric default : end condition */
+
+		fprintf(outputf,
+			"{\n"
+			"\t\terror = css_stylesheet_style_appendOPV(result, %s, 0, %s);\n"
+			"\t\tif (error != CSS_OK) {\n"
+			"\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\treturn error;\n"
+			"\t\t}\n\n"
+			"\t\twhile ((token != NULL) && (token->type == CSS_TOKEN_IDENT)) {\n"
+			"\t\t\tuint32_t snumber;\n"
+			"\t\t\tcss_fixed num;\n"
+			"\t\t\tint pctx;\n\n"
+			"\t\t\terror = css_stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);\n"
+			"\t\t\tif (error != CSS_OK) {\n"
+			"\t\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\t\treturn error;\n"
+			"\t\t\t}\n\n"
+			"\t\t\terror = css_stylesheet_style_append(result, snumber);\n"	
+			"\t\t\tif (error != CSS_OK) {\n"
+			"\t\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\t\treturn error;\n"
+			"\t\t\t}\n\n"
+			"\t\t\tconsumeWhitespace(vector, ctx);\n\n"
+			"\t\t\tpctx = *ctx;\n"
+			"\t\t\ttoken = parserutils_vector_iterate(vector, ctx);\n"
+			"\t\t\tif ((token != NULL) && (token->type == CSS_TOKEN_NUMBER)) {\n"
+			"\t\t\t\tsize_t consumed = 0;\n\n"
+			"\t\t\t\tnum = number_from_lwc_string(token->idata, true, &consumed);\n"
+			"\t\t\t\tif (consumed != lwc_string_length(token->idata)) {\n"
+			"\t\t\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\t\t\treturn CSS_INVALID;\n"
+			"\t\t\t\t}\n"
+			"\t\t\t\tconsumeWhitespace(vector, ctx);\n\n"
+			"\t\t\t\tpctx = *ctx;\n"
+			"\t\t\t\ttoken = parserutils_vector_iterate(vector, ctx);\n"
+			"\t\t\t} else {\n"
+			"\t\t\t\tnum = INTTOFIX(%s);\n"
+			"\t\t\t}\n\n"
+			"\t\t\terror = css_stylesheet_style_append(result, num);\n"
+			"\t\t\tif (error != CSS_OK) {\n"
+			"\t\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\t\treturn error;\n"
+			"\t\t\t}\n\n"
+			"\t\t\tif (token == NULL)\n"
+			"\t\t\t\tbreak;\n\n"
+			"\t\t\tif (token->type == CSS_TOKEN_IDENT) {\n"
+			"\t\t\t\terror = css_stylesheet_style_append(result, %s);\n"
+			"\t\t\t\tif (error != CSS_OK) {\n"
+			"\t\t\t\t\t*ctx = orig_ctx;\n"
+			"\t\t\t\t\treturn error;\n"
+			"\t\t\t\t}\n"
+			"\t\t\t} else {\n"
+			"\t\t\t\t*ctx = pctx; /* rewind one token back */\n"
+			"\t\t\t}\n"
+			"\t\t}\n\n"
+			"\t\terror = css_stylesheet_style_append(result, %s);\n"
+			"\t}\n\n",
+			parseid->val,
+			ckv->val,
+			ikv->key,
+			ckv->val,
+			ikv->val);
+
+	} else {
+		fprintf(stderr, "unknown IDENT list type %s\n",ckv->key);
+		exit(4);
+	}
+
+}
+
+void output_invalidcss(FILE *outputf)
+{
+	fprintf(outputf, "{\n\t\terror = CSS_INVALID;\n\t}\n\n");
+}
+
+void output_footer(FILE *outputf)
+{
+	fprintf(outputf,
+		"	if (error != CSS_OK)\n"
+		"		*ctx = orig_ctx;\n"
+		"	\n"
+		"	return error;\n"
+		"}\n\n");
+}
+
+void output_wrap(FILE *outputf, struct keyval *parseid, struct keyval_list *WRAP)
+{
+	struct keyval *ckv = WRAP->item[0];
+	fprintf(outputf,
+		"	return %s(c, vector, ctx, result, %s);\n}\n",
+		ckv->val,
+		parseid->val);
+}
+
+char str_INHERIT[] = "INHERIT";
+
+struct keyval ident_inherit = {
+	.key = str_INHERIT,
+};
+
+int main(int argc, char **argv)
+{
+	char *descriptor;
+	char *curpos; /* current position in input string */
+	struct keyval *parser_id; /* the parser we are creating output for */
+	FILE *outputf;
+	struct keyval *rkv; /* current read key:val */
+	struct keyval_list *curlist;
+	bool do_token_check = true; /* if the check for valid tokens is done */
+	bool only_ident = true; /* if the only token type is ident */
+
+	struct keyval_list base;
+	struct keyval_list IDENT;
+	struct keyval_list IDENT_LIST;
+	struct keyval_list LENGTH_UNIT;
+	struct keyval_list URI;
+	struct keyval_list WRAP;
+	struct keyval_list NUMBER;
+	struct keyval_list COLOR;
+
+
+	if (argc < 2) {
+		fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>", argv[0]);
+		return 1;
+	}
+
+	if ((argv[1][0] == '-') && (argv[1][1] == 'o')) {
+		if (argc != 4) {
+			fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>", argv[0]);
+			return 1;
+		}
+		outputf = fopen(argv[2], "w");
+		if (outputf == NULL) {
+			perror("unable to open file");
+		}
+		descriptor = strdup(argv[3]);
+	} else {
+		outputf = stdout;
+		descriptor = strdup(argv[1]);
+	}
+	curpos = descriptor;
+
+	base.count = 0;
+	IDENT.count = 0;
+	URI.count = 0;
+	WRAP.count = 0;
+	NUMBER.count = 0;
+	COLOR.count = 0;
+	LENGTH_UNIT.count = 0;
+	IDENT_LIST.count = 0;
+
+	curlist = &base;
+
+	while (*curpos != 0) {
+		rkv = get_keyval(&curpos);
+		if (rkv == NULL) {
+			fprintf(stderr,"Token error at offset %ld", curpos - descriptor);
+			fclose(outputf);
+			return 2;
+		}
+
+		if (strcmp(rkv->key, "WRAP") == 0) {
+			WRAP.item[WRAP.count++] = rkv;
+			only_ident = false;
+		} else if (strcmp(rkv->key, "NUMBER") == 0) {
+			if (rkv->val[0] == '(') {
+				curlist = &NUMBER;
+			} else if (rkv->val[0] == ')') {
+				curlist = &base;
+			} else {
+				NUMBER.item[NUMBER.count++] = rkv;
+			}
+			only_ident = false;
+		} else if (strcmp(rkv->key, "IDENT") == 0) {
+			if (rkv->val[0] == '(') {
+				curlist = &IDENT;
+			} else if (rkv->val[0] == ')') {
+				curlist = &base;
+			} else if (strcmp(rkv->val, str_INHERIT) == 0) {
+				IDENT.item[IDENT.count++] = &ident_inherit;
+			}
+		} else if (strcmp(rkv->key, "IDENT_LIST") == 0) {
+			if (rkv->val[0] == '(') {
+				curlist = &IDENT_LIST;
+			} else if (rkv->val[0] == ')') {
+				curlist = &base;
+			} 
+		} else if (strcmp(rkv->key, "LENGTH_UNIT") == 0) {
+			if (rkv->val[0] == '(') {
+				curlist = &LENGTH_UNIT;
+			} else if (rkv->val[0] == ')') {
+				curlist = &base;
+			} 
+			only_ident = false;
+			do_token_check = false;
+		} else if (strcmp(rkv->key, "COLOR") == 0) {
+			COLOR.item[COLOR.count++] = rkv;
+			do_token_check = false;
+			only_ident = false;
+		} else if (strcmp(rkv->key, "URI") == 0) {
+			URI.item[URI.count++] = rkv;
+			only_ident = false;
+		} else {
+			/* just append to current list */
+			curlist->item[curlist->count++] = rkv;
+		}
+	}
+
+	if (base.count != 1) {
+		fprintf(stderr,"Too many base elements (got %d expected 1)", base.count);
+		fclose(outputf);
+		return 3;
+	}
+
+
+	/* header */
+	output_header(outputf, descriptor, base.item[0]);
+
+	if (WRAP.count > 0) {
+		output_wrap(outputf, base.item[0], &WRAP);
+	} else {
+		/* check token type is correct */
+		output_token_type_check(outputf, do_token_check,  &IDENT, &URI, &NUMBER);
+
+		if (IDENT.count > 0)
+			output_ident(outputf, only_ident, base.item[0], &IDENT);
+
+		if (URI.count > 0)
+			output_uri(outputf, base.item[0], &URI);
+
+		if (NUMBER.count > 0)
+			output_number(outputf, base.item[0], &NUMBER);
+
+		/* terminal blocks, these end the ladder ie no trailing else */
+		if (COLOR.count > 0) {
+			output_color(outputf, base.item[0], &COLOR);
+		} else if (LENGTH_UNIT.count > 0) {
+			output_length_unit(outputf, base.item[0], &LENGTH_UNIT);
+		} else if (IDENT_LIST.count > 0) {
+			output_ident_list(outputf, base.item[0], &IDENT_LIST);
+		} else {
+			output_invalidcss(outputf);
+		}
+
+		output_footer(outputf);
+
+	}
+
+	fclose(outputf);
+
+	return 0;
+}
Index: src/parse/properties/list.sh
===================================================================
--- /dev/null	2011-01-18 08:20:14.799282769 +0000
+++ src/parse/properties/list.sh	2011-01-18 22:06:09.000000000 +0000
@@ -0,0 +1,159 @@
+#!/bin/sh
+
+GEN=./gen_parser
+
+##Common templates
+#
+#${GEN} -o .c ": IDENT:( INHERIT: IDENT:)"
+#${GEN} -o .c ": IDENT:INHERIT NUMBER:( false: RANGE: NUMBER:)"
+#${GEN} -o .c ": IDENT:INHERIT LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW: DISALLOW: RANGE:<0 LENGTH_UNIT:)"
+#${GEN} -o .c ": IDENT:( INHERIT: IDENT:) LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW: DISALLOW: RANGE:<0 LENGTH_UNIT:)"
+#${GEN} -o .c ": WRAP:"
+
+exit 0
+
+${GEN} -o color.c "color:CSS_PROP_COLOR IDENT:INHERIT COLOR:COLOR_SET"
+
+#generic for padding_{top, bottom, left, right}.c
+${GEN} -o padding_side.c "padding_side:op IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:PADDING_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ  RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o padding_bottom.c "padding_bottom:CSS_PROP_PADDING_BOTTOM WRAP:parse_padding_side"
+${GEN} -o padding_left.c "padding_left:CSS_PROP_PADDING_LEFT WRAP:parse_padding_side"
+${GEN} -o padding_top.c "padding_top:CSS_PROP_PADDING_TOP WRAP:parse_padding_side"
+${GEN} -o padding_right.c "padding_right:CSS_PROP_PADDING_RIGHT WRAP:parse_padding_side"
+
+
+#generic for margin_{top, bottom, left, right}.c
+${GEN} -o margin_side.c "margin_side:op IDENT:( INHERIT: AUTO:0,MARGIN_AUTO IDENT:) LENGTH_UNIT:( UNIT_PX:MARGIN_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)"
+
+${GEN} -o margin_top.c "margin_top:CSS_PROP_MARGIN_TOP WRAP:parse_margin_side"
+${GEN} -o margin_bottom.c "margin_bottom:CSS_PROP_MARGIN_BOTTOM WRAP:parse_margin_side"
+${GEN} -o margin_left.c "margin_left:CSS_PROP_MARGIN_LEFT WRAP:parse_margin_side"
+${GEN} -o margin_right.c "margin_right:CSS_PROP_MARGIN_RIGHT WRAP:parse_margin_side"
+
+#generic for {top, bottom, left, right}.c
+${GEN} -o side.c "side:op IDENT:( INHERIT: AUTO:0,BOTTOM_AUTO IDENT:) LENGTH_UNIT:( UNIT_PX:BOTTOM_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)"
+
+${GEN} -o top.c "top:CSS_PROP_TOP WRAP:parse_side"
+${GEN} -o bottom.c "bottom:CSS_PROP_BOTTOM WRAP:parse_side"
+${GEN} -o left.c "left:CSS_PROP_LEFT WRAP:parse_side"
+${GEN} -o right.c "right:CSS_PROP_RIGHT WRAP:parse_side"
+
+
+#generic for border_{top, bottom, left, right}_width.c
+${GEN} -o border_side_width.c "border_side_width:op IDENT:( INHERIT: THIN:0,BORDER_WIDTH_THIN MEDIUM:0,BORDER_WIDTH_MEDIUM THICK:0,BORDER_WIDTH_THICK IDENT:) LENGTH_UNIT:( UNIT_PX:BORDER_WIDTH_SET DISALLOW:unit==UNIT_PCT||unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o border_top_width.c "border_top_width:CSS_PROP_BORDER_TOP_WIDTH WRAP:parse_border_side_width"
+${GEN} -o border_bottom_width.c "border_bottom_width:CSS_PROP_BORDER_BOTTOM_WIDTH WRAP:parse_border_side_width"
+${GEN} -o border_left_width.c "border_left_width:CSS_PROP_BORDER_LEFT_WIDTH WRAP:parse_border_side_width"
+${GEN} -o border_right_width.c "border_right_width:CSS_PROP_BORDER_RIGHT_WIDTH WRAP:parse_border_side_width"
+
+
+#generic for border_{top, bottom, left, right}_style.c
+${GEN} -o border_side_style.c "border_side_style:op  IDENT:( INHERIT: NONE:0,BORDER_STYLE_NONE HIDDEN:0,BORDER_STYLE_HIDDEN DOTTED:0,BORDER_STYLE_DOTTED DASHED:0,BORDER_STYLE_DASHED SOLID:0,BORDER_STYLE_SOLID LIBCSS_DOUBLE:0,BORDER_STYLE_DOUBLE GROOVE:0,BORDER_STYLE_GROOVE RIDGE:0,BORDER_STYLE_RIDGE INSET:0,BORDER_STYLE_INSET OUTSET:0,BORDER_STYLE_OUTSET IDENT:)"
+
+${GEN} -o border_top_style.c "border_top_style:CSS_PROP_BORDER_TOP_STYLE WRAP:parse_border_side_style"
+${GEN} -o border_bottom_style.c "border_bottom_style:CSS_PROP_BORDER_BOTTOM_STYLE WRAP:parse_border_side_style"
+${GEN} -o border_left_style.c "border_left_style:CSS_PROP_BORDER_LEFT_STYLE WRAP:parse_border_side_style"
+${GEN} -o border_right_style.c "border_right_style:CSS_PROP_BORDER_RIGHT_STYLE WRAP:parse_border_side_style"
+
+#generic for border_{top, bottom, left, right}_color.c
+${GEN} -o border_side_color.c "border_side_color:op IDENT:( INHERIT: TRANSPARENT:0,BORDER_COLOR_TRANSPARENT IDENT:) COLOR:BORDER_COLOR_SET"
+
+${GEN} -o border_top_color.c "border_top_color:CSS_PROP_BORDER_TOP_COLOR WRAP:parse_border_side_color"
+${GEN} -o border_bottom_color.c "border_bottom_color:CSS_PROP_BORDER_BOTTOM_COLOR WRAP:parse_border_side_color"
+${GEN} -o border_left_color.c "border_left_color:CSS_PROP_BORDER_LEFT_COLOR WRAP:parse_border_side_color"
+${GEN} -o border_right_color.c "border_right_color:CSS_PROP_BORDER_RIGHT_COLOR WRAP:parse_border_side_color"
+
+
+${GEN} -o counter_increment.c "counter_increment:CSS_PROP_COUNTER_INCREMENT IDENT:( INHERIT: NONE:0,COUNTER_INCREMENT_NONE IDENT:) IDENT_LIST:( STRING_OPTNUM:COUNTER_INCREMENT_NAMED 1:COUNTER_INCREMENT_NONE IDENT_LIST:)"
+
+${GEN} -o counter_reset.c "counter_reset:CSS_PROP_COUNTER_RESET IDENT:( INHERIT: NONE:0,COUNTER_RESET_NONE IDENT:) IDENT_LIST:( STRING_OPTNUM:COUNTER_RESET_NAMED 0:COUNTER_RESET_NONE IDENT_LIST:)"
+
+
+${GEN} -o background_attachment.c "background_attachment:CSS_PROP_BACKGROUND_ATTACHMENT IDENT:( INHERIT: FIXED:0,BACKGROUND_ATTACHMENT_FIXED SCROLL:0,BACKGROUND_ATTACHMENT_SCROLL IDENT:)"
+
+${GEN} -o background_color.c "background_color:CSS_PROP_BACKGROUND_COLOR IDENT:( INHERIT: TRANSPARENT:0,BACKGROUND_COLOR_TRANSPARENT IDENT:) COLOR:BACKGROUND_COLOR_SET"
+
+${GEN} -o caption_side.c "caption_side:CSS_PROP_CAPTION_SIDE IDENT:( INHERIT: TOP:0,CAPTION_SIDE_TOP BOTTOM:0,CAPTION_SIDE_BOTTOM IDENT:)"
+
+${GEN} -o clear.c "clear:CSS_PROP_CLEAR IDENT:( INHERIT: RIGHT:0,CLEAR_RIGHT LEFT:0,CLEAR_LEFT BOTH:0,CLEAR_BOTH NONE:0,CLEAR_NONE IDENT:)"
+
+${GEN} -o background_image.c "background_image:CSS_PROP_BACKGROUND_IMAGE IDENT:( INHERIT NONE,0,BACKGROUND_IMAGE_NONE ) URI:BACKGROUND_IMAGE_URI"
+
+${GEN} -o list_style_image.c "list_style_image:CSS_PROP_LIST_STYLE_IMAGE IDENT:( INHERIT: NONE:0,LIST_STYLE_IMAGE_NONE IDENT:) URI:LIST_STYLE_IMAGE_URI"
+
+${GEN} -o list_style_position.c "list_style_position:CSS_PROP_LIST_STYLE_POSITION IDENT:( INHERIT: INSIDE:0,LIST_STYLE_POSITION_INSIDE OUTSIDE:0,LIST_STYLE_POSITION_OUTSIDE IDENT:)"
+
+${GEN} -o orphans.c "orphans:CSS_PROP_ORPHANS IDENT:INHERIT NUMBER:( true:ORPHANS_SET RANGE:num<0 NUMBER:)"
+
+${GEN} -o outline_color.c "outline_color:CSS_PROP_OUTLINE_COLOR IDENT:( INHERIT: INVERT:0,OUTLINE_COLOR_INVERT IDENT:) COLOR:OUTLINE_COLOR_SET"
+
+## ${GEN} -o border_top_style.c "border_top_style:CSS_PROP_BORDER_TOP_STYLE IDENT:( INHERIT: NONE:BORDER_STYLE_NONE HIDDEN:BORDER_STYLE_HIDDEN DOTTED:BORDER_STYLE_DOTTED DASHED:BORDER_STYLE_DASHED SOLID:BORDER_STYLE_SOLID LIBCSS_DOUBLE:BORDER_STYLE_DOUBLE GROOVE:BORDER_STYLE_GROOVE RIDGE:BORDER_STYLE_RIDGE INSET:BORDER_STYLE_INSET OUTSET:BORDER_STYLE_OUTSET IDENT:)"
+${GEN} -o border_top_style.c "border_top_style:CSS_PROP_BORDER_TOP_STYLE WRAP:parse_border_side_style"
+
+${GEN} -o outline_style.c "outline_style:CSS_PROP_OUTLINE_STYLE IDENT:( INHERIT: NONE:0,BORDER_STYLE_NONE DOTTED:0,BORDER_STYLE_DOTTED DASHED:0,BORDER_STYLE_DASHED SOLID:0,BORDER_STYLE_SOLID LIBCSS_DOUBLE:0,BORDER_STYLE_DOUBLE GROOVE:0,BORDER_STYLE_GROOVE RIDGE:0,BORDER_STYLE_RIDGE INSET:0,BORDER_STYLE_INSET OUTSET:0,BORDER_STYLE_OUTSET IDENT:)"
+
+${GEN} -o outline_width.c "outline_width:CSS_PROP_OUTLINE_WIDTH WRAP:parse_border_side_width"
+
+${GEN} -o overflow.c "overflow:CSS_PROP_OVERFLOW IDENT:( INHERIT: VISIBLE:0,OVERFLOW_VISIBLE HIDDEN:0,OVERFLOW_HIDDEN SCROLL:0,OVERFLOW_SCROLL AUTO:0,OVERFLOW_AUTO  IDENT:)"
+
+
+${GEN} -o page_break_after.c "page_break_after:CSS_PROP_PAGE_BREAK_AFTER IDENT:( INHERIT: AUTO:0,PAGE_BREAK_AFTER_AUTO ALWAYS:0,PAGE_BREAK_AFTER_ALWAYS AVOID:0,PAGE_BREAK_AFTER_AVOID LEFT:0,PAGE_BREAK_AFTER_LEFT RIGHT:0,PAGE_BREAK_AFTER_RIGHT IDENT:)"
+
+${GEN} -o page_break_before.c "page_break_before:CSS_PROP_PAGE_BREAK_BEFORE IDENT:( INHERIT: AUTO:0,PAGE_BREAK_BEFORE_AUTO ALWAYS:0,PAGE_BREAK_BEFORE_ALWAYS AVOID:0,PAGE_BREAK_BEFORE_AVOID LEFT:0,PAGE_BREAK_BEFORE_LEFT RIGHT:0,PAGE_BREAK_BEFORE_RIGHT IDENT:)"
+
+${GEN} -o page_break_inside.c "page_break_inside:CSS_PROP_PAGE_BREAK_INSIDE IDENT:( INHERIT: AUTO:0,PAGE_BREAK_INSIDE_AUTO AVOID:0,PAGE_BREAK_INSIDE_AVOID IDENT:)"
+
+${GEN} -o pause_after.c "pause_after:CSS_PROP_PAUSE_AFTER IDENT:INHERIT LENGTH_UNIT:( UNIT_S:PAUSE_AFTER_SET DISALLOW:(unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o pause_before.c "pause_before:CSS_PROP_PAUSE_BEFORE IDENT:INHERIT LENGTH_UNIT:( UNIT_S:PAUSE_BEFORE_SET DISALLOW:(unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o pitch.c "pitch:CSS_PROP_PITCH IDENT:( INHERIT: X_LOW:0,PITCH_X_LOW LOW:0,PITCH_LOW MEDIUM:0,PITCH_MEDIUM HIGH:0,PITCH_HIGH X_HIGH:0,PITCH_X_HIGH IDENT:) LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW:unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o pitch_range.c "pitch_range:CSS_PROP_PITCH_RANGE IDENT:INHERIT NUMBER:( false:PITCH_RANGE_SET RANGE:num<0||num>F_100 NUMBER:)"
+
+${GEN} -o position.c "position:CSS_PROP_POSITION IDENT:( INHERIT: LIBCSS_STATIC:0,POSITION_STATIC RELATIVE:0,POSITION_RELATIVE ABSOLUTE:0,POSITION_ABSOLUTE FIXED:0,POSITION_FIXED IDENT:)"
+
+${GEN} -o richness.c "richness:CSS_PROP_RICHNESS IDENT:INHERIT NUMBER:( false:RICHNESS_SET RANGE:num<0||num>F_100 NUMBER:)"
+
+${GEN} -o speak.c "speak:CSS_PROP_SPEAK IDENT:( INHERIT: NORMAL:0,SPEAK_NORMAL NONE:0,SPEAK_NONE SPELL_OUT:0,SPEAK_SPELL_OUT IDENT:)"
+
+${GEN} -o speak_header.c "speak_header:CSS_PROP_SPEAK_HEADER IDENT:( INHERIT: ONCE:0,SPEAK_HEADER_ONCE ALWAYS:0,SPEAK_HEADER_ALWAYS IDENT:)"
+
+${GEN} -o speak_numeral.c "speak_numeral:CSS_PROP_SPEAK_NUMERAL IDENT:( INHERIT: DIGITS:0,SPEAK_NUMERAL_DIGITS CONTINUOUS:0,SPEAK_NUMERAL_CONTINUOUS IDENT:)"
+
+${GEN} -o speak_punctuation.c "speak_punctuation:CSS_PROP_SPEAK_PUNCTUATION IDENT:( INHERIT: CODE:0,SPEAK_PUNCTUATION_CODE NONE:0,SPEAK_PUNCTUATION_NONE IDENT:)"
+
+${GEN} -o speech_rate.c "speech_rate:CSS_PROP_SPEECH_RATE IDENT:( INHERIT: X_SLOW:0,SPEECH_RATE_X_SLOW SLOW:0,SPEECH_RATE_SLOW MEDIUM:0,SPEECH_RATE_MEDIUM FAST:0,SPEECH_RATE_FAST X_FAST:0,SPEECH_RATE_X_FAST FASTER:0,SPEECH_RATE_FASTER SLOWER:0,SPEECH_RATE_SLOWER IDENT:) NUMBER:( false:SPEECH_RATE_SET RANGE:num<0 NUMBER:)"
+
+${GEN} -o stress.c "stress:CSS_PROP_STRESS IDENT:INHERIT NUMBER:( false:STRESS_SET RANGE:num<0||num>INTTOFIX(100) NUMBER:)"
+
+${GEN} -o table_layout.c "table_layout:CSS_PROP_TABLE_LAYOUT IDENT:( INHERIT: AUTO:0,TABLE_LAYOUT_AUTO FIXED:0,TABLE_LAYOUT_FIXED IDENT:)"
+
+${GEN} -o text_align.c "text_align:CSS_PROP_TEXT_ALIGN IDENT:( INHERIT: LEFT:0,TEXT_ALIGN_LEFT RIGHT:0,TEXT_ALIGN_RIGHT CENTER:0,TEXT_ALIGN_CENTER JUSTIFY:0,TEXT_ALIGN_JUSTIFY LIBCSS_LEFT:0,TEXT_ALIGN_LIBCSS_LEFT LIBCSS_CENTER:0,TEXT_ALIGN_LIBCSS_CENTER LIBCSS_RIGHT:0,TEXT_ALIGN_LIBCSS_RIGHT IDENT:)"
+
+${GEN} -o text_indent.c "text_indent:CSS_PROP_TEXT_INDENT IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:TEXT_INDENT_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)"
+
+${GEN} -o text_transform.c "text_transform:CSS_PROP_TEXT_TRANSFORM IDENT:( INHERIT: CAPITALIZE:0,TEXT_TRANSFORM_CAPITALIZE UPPERCASE:0,TEXT_TRANSFORM_UPPERCASE LOWERCASE:0,TEXT_TRANSFORM_LOWERCASE NONE:0,TEXT_TRANSFORM_NONE IDENT:)"
+
+${GEN} -o top.c "top:CSS_PROP_TOP WRAP:parse_side"
+
+${GEN} -o unicode_bidi.c "unicode_bidi:CSS_PROP_UNICODE_BIDI IDENT:( INHERIT: NORMAL:0,UNICODE_BIDI_NORMAL EMBED:0,UNICODE_BIDI_EMBED BIDI_OVERRIDE:0,UNICODE_BIDI_BIDI_OVERRIDE IDENT:)"
+
+${GEN} -o vertical_align.c "vertical_align:CSS_PROP_VERTICAL_ALIGN IDENT:( INHERIT: BASELINE:0,VERTICAL_ALIGN_BASELINE SUB:0,VERTICAL_ALIGN_SUB SUPER:0,VERTICAL_ALIGN_SUPER TOP:0,VERTICAL_ALIGN_TOP TEXT_TOP:0,VERTICAL_ALIGN_TEXT_TOP MIDDLE:0,VERTICAL_ALIGN_MIDDLE BOTTOM:0,VERTICAL_ALIGN_BOTTOM TEXT_BOTTOM:0,VERTICAL_ALIGN_TEXT_BOTTOM IDENT:) LENGTH_UNIT:( UNIT_PX:VERTICAL_ALIGN_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)"
+
+${GEN} -o visibility.c "visibility:CSS_PROP_VISIBILITY IDENT:( INHERIT: VISIBLE:0,VISIBILITY_VISIBLE HIDDEN:0,VISIBILITY_HIDDEN COLLAPSE:0,VISIBILITY_COLLAPSE IDENT:)"
+
+${GEN} -o volume.c "volume:CSS_PROP_VOLUME IDENT:( INHERIT: SILENT:0,VOLUME_SILENT X_SOFT:0,VOLUME_X_SOFT SOFT:0,VOLUME_SOFT MEDIUM:0,VOLUME_MEDIUM LOUD:0,VOLUME_LOUD X_LOUD:0,VOLUME_X_LOUD IDENT:) NUMBER:( false:VOLUME_NUMBER RANGE:num<0||num>F_100 NUMBER:) LENGTH_UNIT:( UNIT_PX:VOLUME_DIMENSION ALLOW:unit&UNIT_PCT RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o white_space.c "white_space:CSS_PROP_WHITE_SPACE IDENT:( INHERIT: NORMAL:0,WHITE_SPACE_NORMAL PRE:0,WHITE_SPACE_PRE NOWRAP:0,WHITE_SPACE_NOWRAP PRE_WRAP:0,WHITE_SPACE_PRE_WRAP PRE_LINE:0,WHITE_SPACE_PRE_LINE  IDENT:)"
+
+${GEN} -o widows.c "widows:CSS_PROP_WIDOWS IDENT:INHERIT NUMBER:( true:WIDOWS_SET RANGE:num<0 NUMBER:)"
+
+
+${GEN} -o width.c "width:CSS_PROP_WIDTH IDENT:( INHERIT: AUTO:0,WIDTH_AUTO IDENT:) LENGTH_UNIT:( UNIT_PX:WIDTH_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:)"
+
+${GEN} -o word_spacing.c "word_spacing:CSS_PROP_WORD_SPACING IDENT:( INHERIT: NORMAL:0,WORD_SPACING_NORMAL IDENT:) LENGTH_UNIT:( UNIT_PX:WORD_SPACING_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ||unit&UNIT_PCT LENGTH_UNIT:)"
+
+${GEN} -o z_index.c "z_index:CSS_PROP_Z_INDEX IDENT:( INHERIT: AUTO:0,Z_INDEX_AUTO IDENT:) NUMBER:( true:Z_INDEX_SET NUMBER:)"
Index: src/parse/properties/cue_after.c
===================================================================
--- /dev/null	2011-01-18 08:20:14.799282769 +0000
+++ src/parse/properties/cue_after.c	2011-01-18 22:06:11.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * This file is part of LibCSS.
+ * Licensed under the MIT License,
+ *		  http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "bytecode/bytecode.h"
+#include "bytecode/opcodes.h"
+#include "parse/properties/properties.h"
+#include "parse/properties/utils.h"
+
+/**
+ * Parse cue-after
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
+css_error parse_cue_after(css_language *c, 
+		const parserutils_vector *vector, int *ctx, 
+		css_style *result)
+{
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	/* URI | IDENT (none, inherit) */
+	token = parserutils_vector_iterate(vector, ctx);
+	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
+			token->type != CSS_TOKEN_URI)) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(
+		    token->idata, c->strings[INHERIT],
+		    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_AFTER,
+						       FLAG_INHERIT,
+						       0);
+	} else if ((token->type == CSS_TOKEN_IDENT) && 
+		   (lwc_string_caseless_isequal(
+			   token->idata, c->strings[NONE],
+			   &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_AFTER,
+						       0,
+						       CUE_AFTER_NONE);
+	} else if (token->type == CSS_TOKEN_URI) {
+		/* cue after with uri */
+		lwc_string *uri = NULL;
+		uint32_t uri_snumber;
+
+		error = c->sheet->resolve(c->sheet->resolve_pw,
+				c->sheet->url,
+				token->idata, &uri);
+
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_string_add(c->sheet, uri, &uri_snumber);
+
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CUE_AFTER,
+						       0,
+						       CUE_AFTER_URI);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, uri_snumber);
+
+	} else {
+		error = CSS_INVALID;
+	}
+
+	if (error != CSS_OK) {
+		*ctx = orig_ctx;
+	}
+
+	return error;
+}
Index: src/parse/properties/counter_reset.c
===================================================================
--- /dev/null	2011-01-18 08:20:14.799282769 +0000
+++ src/parse/properties/counter_reset.c	2011-01-18 22:06:14.000000000 +0000
@@ -0,0 +1,126 @@
+/*
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * counter_reset:CSS_PROP_COUNTER_RESET IDENT:( INHERIT: NONE:0,COUNTER_RESET_NONE IDENT:) IDENT_LIST:( STRING_OPTNUM:COUNTER_RESET_NAMED 1:COUNTER_RESET_NONE IDENT_LIST:)
+ * 
+ * Licensed under the MIT License,
+ *		  http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "bytecode/bytecode.h"
+#include "bytecode/opcodes.h"
+#include "parse/properties/properties.h"
+#include "parse/properties/utils.h"
+
+/**
+ * Parse counter_reset
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
+css_error parse_counter_reset(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
+{
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_COUNTER_RESET);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_COUNTER_RESET, 0,COUNTER_RESET_NONE);
+	} else {
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_COUNTER_RESET, 0, COUNTER_RESET_NAMED);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		while ((token != NULL) && (token->type == CSS_TOKEN_IDENT)) {
+			uint32_t snumber;
+			css_fixed num;
+			int pctx;
+
+			error = css_stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			error = css_stylesheet_style_append(result, snumber);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			consumeWhitespace(vector, ctx);
+
+			pctx = *ctx;
+			token = parserutils_vector_iterate(vector, ctx);
+			if ((token != NULL) && (token->type == CSS_TOKEN_NUMBER)) {
+				size_t consumed = 0;
+
+				num = number_from_lwc_string(token->idata, true, &consumed);
+				if (consumed != lwc_string_length(token->idata)) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+				consumeWhitespace(vector, ctx);
+
+				pctx = *ctx;
+				token = parserutils_vector_iterate(vector, ctx);
+			} else {
+				num = INTTOFIX(0);
+			}
+
+			error = css_stylesheet_style_append(result, num);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			if (token == NULL)
+				break;
+
+			if (token->type == CSS_TOKEN_IDENT) {
+				error = css_stylesheet_style_append(result, COUNTER_RESET_NAMED);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+			} else {
+				*ctx = pctx; /* rewind one token back */
+			}
+		}
+
+		error = css_stylesheet_style_append(result, COUNTER_RESET_NONE);
+	}
+
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
+}
+


Changed files


 src/bytecode/bytecode.h                      |   14 
 src/parse/important.c                        |  256 +---
 src/parse/language.c                         |   15 
 src/parse/properties/Makefile                |   91 -
 src/parse/properties/azimuth.c               |   28 
 src/parse/properties/background.c            |  291 ++--
 src/parse/properties/background_attachment.c |   11 
 src/parse/properties/background_color.c      |   80 -
 src/parse/properties/background_image.c      |   92 -
 src/parse/properties/background_position.c   |   35 
 src/parse/properties/background_repeat.c     |   61 
 src/parse/properties/border.c                |   85 -
 src/parse/properties/border_bottom.c         |    4 
 src/parse/properties/border_bottom_color.c   |    5 
 src/parse/properties/border_bottom_style.c   |    5 
 src/parse/properties/border_bottom_width.c   |    5 
 src/parse/properties/border_collapse.c       |   45 
 src/parse/properties/border_color.c          |  267 +---
 src/parse/properties/border_left.c           |    4 
 src/parse/properties/border_left_color.c     |    5 
 src/parse/properties/border_left_style.c     |    5 
 src/parse/properties/border_left_width.c     |    5 
 src/parse/properties/border_right.c          |    4 
 src/parse/properties/border_right_color.c    |    5 
 src/parse/properties/border_right_style.c    |    5 
 src/parse/properties/border_right_width.c    |    5 
 src/parse/properties/border_spacing.c        |   50 
 src/parse/properties/border_style.c          |  283 +---
 src/parse/properties/border_top.c            |    4 
 src/parse/properties/border_top_color.c      |    5 
 src/parse/properties/border_top_style.c      |    5 
 src/parse/properties/border_top_width.c      |    5 
 src/parse/properties/border_width.c          |  290 +---
 src/parse/properties/bottom.c                |    4 
 src/parse/properties/caption_side.c          |   47 
 src/parse/properties/clear.c                 |   43 
 src/parse/properties/clip.c                  |   93 -
 src/parse/properties/color.c                 |   80 -
 src/parse/properties/content.c               |  457 +++++--
 src/parse/properties/counter_increment.c     |  106 +
 src/parse/properties/cue.c                   |  284 ----
 src/parse/properties/cursor.c                |  281 ----
 src/parse/properties/direction.c             |   36 
 src/parse/properties/display.c               |   18 
 src/parse/properties/elevation.c             |   26 
 src/parse/properties/empty_cells.c           |   38 
 src/parse/properties/float.c                 |   60 
 src/parse/properties/font.c                  |  341 ++---
 src/parse/properties/font_family.c           |   70 -
 src/parse/properties/font_size.c             |   30 
 src/parse/properties/font_style.c            |   60 
 src/parse/properties/font_variant.c          |   35 
 src/parse/properties/font_weight.c           |   21 
 src/parse/properties/height.c                |   26 
 src/parse/properties/left.c                  |    4 
 src/parse/properties/letter_spacing.c        |   54 
 src/parse/properties/line_height.c           |   43 
 src/parse/properties/list_style.c            |  183 +-
 src/parse/properties/list_style_image.c      |   88 -
 src/parse/properties/list_style_position.c   |   73 -
 src/parse/properties/list_style_type.c       |   18 
 src/parse/properties/margin.c                |  276 +---
 src/parse/properties/margin_bottom.c         |   20 
 src/parse/properties/margin_left.c           |   19 
 src/parse/properties/margin_right.c          |   19 
 src/parse/properties/margin_top.c            |   19 
 src/parse/properties/max_height.c            |   26 
 src/parse/properties/max_width.c             |   26 
 src/parse/properties/min_height.c            |   26 
 src/parse/properties/min_width.c             |   26 
 src/parse/properties/orphans.c               |   81 -
 src/parse/properties/outline.c               |  184 +-
 src/parse/properties/outline_color.c         |   80 -
 src/parse/properties/outline_style.c         |   65 -
 src/parse/properties/outline_width.c         |   21 
 src/parse/properties/overflow.c              |   84 -
 src/parse/properties/padding.c               |  272 +---
 src/parse/properties/padding_bottom.c        |   20 
 src/parse/properties/padding_left.c          |   20 
 src/parse/properties/padding_right.c         |   20 
 src/parse/properties/padding_top.c           |   20 
 src/parse/properties/page_break_after.c      |   92 -
 src/parse/properties/page_break_before.c     |   92 -
 src/parse/properties/page_break_inside.c     |   74 -
 src/parse/properties/pause.c                 |  161 --
 src/parse/properties/pause_after.c           |   66 -
 src/parse/properties/pause_before.c          |   67 -
 src/parse/properties/pitch.c                 |  119 -
 src/parse/properties/pitch_range.c           |   73 -
 src/parse/properties/play_during.c           |   42 
 src/parse/properties/position.c              |   84 -
 src/parse/properties/properties.h            |  232 +--
 src/parse/properties/quotes.c                |  179 --
 src/parse/properties/richness.c              |   71 -
 src/parse/properties/right.c                 |    4 
 src/parse/properties/speak.c                 |   68 -
 src/parse/properties/speak_header.c          |   64 -
 src/parse/properties/speak_numeral.c         |   64 -
 src/parse/properties/speak_punctuation.c     |   64 -
 src/parse/properties/speech_rate.c           |  125 -
 src/parse/properties/stress.c                |   70 -
 src/parse/properties/table_layout.c          |   73 -
 src/parse/properties/text_align.c            |  105 -
 src/parse/properties/text_decoration.c       |   62 
 src/parse/properties/text_indent.c           |   89 -
 src/parse/properties/text_transform.c        |   86 -
 src/parse/properties/top.c                   |    4 
 src/parse/properties/unicode_bidi.c          |   80 -
 src/parse/properties/utils.c                 | 1693 +++++----------------------
 src/parse/properties/utils.h                 |  174 ++
 src/parse/properties/vertical_align.c        |  155 --
 src/parse/properties/visibility.c            |   78 -
 src/parse/properties/voice_family.c          |   69 -
 src/parse/properties/volume.c                |  158 --
 src/parse/properties/white_space.c           |   92 -
 src/parse/properties/widows.c                |   81 -
 src/parse/properties/width.c                 |   98 -
 src/parse/properties/word_spacing.c          |   98 -
 src/parse/properties/z_index.c               |   86 -
 src/select/properties/content.c              |   30 
 src/select/properties/counter_increment.c    |    7 
 src/select/properties/counter_reset.c        |    6 
 src/select/properties/cursor.c               |    6 
 src/select/properties/font_family.c          |   11 
 src/select/properties/helpers.c              |   14 
 src/select/properties/quotes.c               |   15 
 src/select/properties/voice_family.c         |   11 
 src/select/select.c                          |    4 
 src/select/select.h                          |    4 
 src/stylesheet.c                             |  251 ++--
 src/stylesheet.h                             |   33 
 test/data/parse/colours.dat                  |   24 
 test/data/parse2/au.dat                      |   42 
 test/data/parse2/bg.dat                      |   34 
 test/data/parse2/bgpos.dat                   |   38 
 test/data/parse2/border.dat                  |   35 
 test/data/parse2/font.dat                    |   42 
 test/data/parse2/list.dat                    |   63 +
 test/data/parse2/margin.dat                  |   49 
 test/data/parse2/outline.dat                 |   49 
 test/data/parse2/padding.dat                 |   49 
 test/dump.h                                  |   82 -
 test/parse-auto.c                            |  110 +
 143 files changed, 5079 insertions(+), 7035 deletions(-)


Index: test/dump.h
===================================================================
--- test/dump.h	(revision 11378)
+++ test/dump.h	(working copy)
@@ -629,7 +629,7 @@
 void dump_bytecode(css_style *style, char **ptr, uint32_t depth)
 {
 	void *bytecode = style->bytecode;
-	size_t length = style->length;
+	size_t length = (style->used * sizeof(css_code_t));
 	uint32_t offset = 0;
 
 #define ADVANCE(n) do {					\
@@ -759,10 +759,11 @@
 					break;
 				case BACKGROUND_IMAGE_URI:
 				{
-					lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-					ADVANCE(sizeof(he));
+					uint32_t snum = *((uint32_t *) bytecode);					lwc_string *he;
+					css_stylesheet_string_get(style->sheet, 
+								  snum, 
+								  &he);
+					ADVANCE(sizeof(snum));
 					*ptr += sprintf(*ptr, "url('%.*s')", 
 							(int) lwc_string_length(he), 
 							lwc_string_data(he));
@@ -1095,22 +1096,23 @@
 				}
 
 				while (value != CONTENT_NORMAL) {
-					lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
+					uint32_t snum = *((uint32_t *) bytecode);					
+					lwc_string *he;
 					const char *end = "";
 
 					switch (value & 0xff) {
 					case CONTENT_COUNTER:
-						ADVANCE(sizeof(he));
+						css_stylesheet_string_get(style->sheet, snum, &he);
+						ADVANCE(sizeof(snum));
 						dump_counter(he, value, ptr);
 						break;
+
 					case CONTENT_COUNTERS:
 					{
 						lwc_string *sep;
+						css_stylesheet_string_get(style->sheet, snum, &he);
+						ADVANCE(sizeof(snum));
 
-						ADVANCE(sizeof(he));
-
 						sep = *((lwc_string **) bytecode);
 						ADVANCE(sizeof(sep));
 
@@ -1118,9 +1120,11 @@
 							ptr);
 					}
 						break;
+
 					case CONTENT_URI:
 					case CONTENT_ATTR:	
 					case CONTENT_STRING:
+						css_stylesheet_string_get(style->sheet, snum, &he);
 						if (value == CONTENT_URI) 
 							*ptr += sprintf(*ptr, "url(");
 						if (value == CONTENT_ATTR)
@@ -1128,22 +1132,26 @@
 						if (value != CONTENT_STRING)
 							end = ")";
 
-						ADVANCE(sizeof(he));
+						ADVANCE(sizeof(snum));
 
 						*ptr += sprintf(*ptr, "'%.*s'%s",
                                                                 (int) lwc_string_length(he),
                                                                 lwc_string_data(he),
 							end);
 						break;
+
 					case CONTENT_OPEN_QUOTE:
 						*ptr += sprintf(*ptr, "open-quote");
 						break;
+
 					case CONTENT_CLOSE_QUOTE:
 						*ptr += sprintf(*ptr, "close-quote");
 						break;
+
 					case CONTENT_NO_OPEN_QUOTE:
 						*ptr += sprintf(*ptr, "no-open-quote");
 						break;
+
 					case CONTENT_NO_CLOSE_QUOTE:
 						*ptr += sprintf(*ptr, "no-close-quote");
 						break;
@@ -1167,10 +1175,11 @@
 				case COUNTER_INCREMENT_NAMED:
 					while (value != COUNTER_INCREMENT_NONE) {
 						css_fixed val;
-						lwc_string *he = 
-							*((lwc_string **) 
-							bytecode);
-						ADVANCE(sizeof(he));
+					uint32_t snum = *((uint32_t *) bytecode);					lwc_string *he;
+					css_stylesheet_string_get(style->sheet, 
+								  snum, 
+								  &he);
+						ADVANCE(sizeof(snum));
 						*ptr += sprintf(*ptr, "%.*s ", 
                                                                 (int)lwc_string_length(he),
                                                                 lwc_string_data(he));
@@ -1194,10 +1203,11 @@
 				break;
 			case CSS_PROP_CURSOR:
 				while (value == CURSOR_URI) {
-					lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-					ADVANCE(sizeof(ptr));
+					uint32_t snum = *((uint32_t *) bytecode);					lwc_string *he;
+					css_stylesheet_string_get(style->sheet, 
+								  snum, 
+								  &he);
+					ADVANCE(sizeof(snum));
 					*ptr += sprintf(*ptr, "url('%.*s'), ", 
 							(int) lwc_string_length(he),
 							lwc_string_data(he));
@@ -1380,10 +1390,10 @@
 					case FONT_FAMILY_STRING:
 					case FONT_FAMILY_IDENT_LIST:
 					{
-						lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-						ADVANCE(sizeof(he));
+						uint32_t snum = *((uint32_t *) bytecode);					
+						lwc_string *he;
+						css_stylesheet_string_get(style->sheet, snum, &he);
+						ADVANCE(sizeof(snum));
 						*ptr += sprintf(*ptr, "'%.*s'", 
                                                                 (int) lwc_string_length(he), 
                                                                 lwc_string_data(he));
@@ -1799,10 +1809,10 @@
 				switch (value) {
 				case PLAY_DURING_URI:
 				{
-					lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-					ADVANCE(sizeof(he));
+					uint32_t snum = *((uint32_t *) bytecode);					
+					lwc_string *he;
+					css_stylesheet_string_get(style->sheet, snum, &he);
+					ADVANCE(sizeof(snum));
 					*ptr += sprintf(*ptr, "'%.*s'", 
                                                         (int) lwc_string_length(he), 
                                                         lwc_string_data(he));
@@ -1841,10 +1851,10 @@
 				switch (value) {
 				case QUOTES_STRING:
 					while (value != QUOTES_NONE) {
-						lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-						ADVANCE(sizeof(he));
+						uint32_t snum = *((uint32_t *) bytecode);					
+						lwc_string *he;
+						css_stylesheet_string_get(style->sheet, snum, &he);
+						ADVANCE(sizeof(snum));
 						*ptr += sprintf(*ptr, " '%.*s' ", 
                                                                 (int) lwc_string_length(he), 
                                                                 lwc_string_data(he));
@@ -2075,10 +2085,10 @@
 					case VOICE_FAMILY_STRING:
 					case VOICE_FAMILY_IDENT_LIST:
 					{
-						lwc_string *he = 
-						*((lwc_string **) 
-						bytecode);
-						ADVANCE(sizeof(he));
+						uint32_t snum = *((uint32_t *) bytecode);					
+						lwc_string *he;
+						css_stylesheet_string_get(style->sheet, snum, &he);
+						ADVANCE(sizeof(snum));
 						*ptr += sprintf(*ptr, "'%.*s'", 
                                                                 (int) lwc_string_length(he),
                                                                 lwc_string_data(he));
Index: test/parse-auto.c
===================================================================
--- test/parse-auto.c	(revision 11378)
+++ test/parse-auto.c	(working copy)
@@ -49,8 +49,7 @@
 static void parse_expected(line_ctx *ctx, const char *data, size_t len);
 static void run_test(const uint8_t *data, size_t len, 
 		exp_entry *exp, size_t explen);
-static void validate_rule_selector(css_rule_selector *s, exp_entry *e, 
-		int testnum);
+static bool validate_rule_selector(css_rule_selector *s, exp_entry *e);
 static void validate_rule_charset(css_rule_charset *s, exp_entry *e, 
 		int testnum);
 static void validate_rule_import(css_rule_import *s, exp_entry *e, 
@@ -241,7 +240,6 @@
 			goto start_rule;
 		}
 
-		/** \todo how to deal with pointers? */
 		while (next < data + len) {
 			/* Skip whitespace */
 			while (next < data + len && isspace(*next))
@@ -302,7 +300,7 @@
 				rule->stringtab[rule->stused].string[
 						next - str - 1]	 = '\0';
 
-				rule->bcused += sizeof(void *);
+				rule->bcused += sizeof(css_code_t);
 				rule->stused++;
 			} else {
 				/* Assume hexnum */
@@ -317,6 +315,28 @@
 	}
 }
 
+static void report_fail(const uint8_t *data, size_t datalen, exp_entry *e)
+{
+	uint32_t bcoff;
+
+	printf("    Data: %.*s\n", (int)datalen, data);
+
+	printf("    Expected entry:\n");
+	printf("        entry type:%d name:%s\n", e->type, e->name);
+	printf("        bytecode len:%ld used:%ld\n", e->bclen, e->bcused);
+	printf("        bytecode ");
+	for (bcoff = 0; bcoff < e->bcused; bcoff++) {
+		printf("%.2x ", ((uint8_t *) e->bytecode)[bcoff]);
+	}
+	printf("\n        string table len:%ld used %ld\n", e->stlen, e->stused);
+/*
+	struct stentry {
+		size_t off;
+		char *string;
+	} *stringtab;
+*/
+}
+
 void run_test(const uint8_t *data, size_t len, exp_entry *exp, size_t explen)
 {
 	css_stylesheet *sheet;
@@ -324,6 +344,7 @@
 	css_error error;
 	size_t e;
 	static int testnum;
+	bool failed;
 	
 	assert(css_stylesheet_create(CSS_LEVEL_21, "UTF-8", "foo", NULL,
 			false, false, myrealloc, NULL, resolve_url, NULL, 
@@ -370,6 +391,8 @@
 	e = 0;
 	testnum++;
 
+	printf("Test %d: ", testnum);
+
 	if (sheet->rule_count != explen) {
 		printf("%d: Got %d rules. Expected %u\n",
 				testnum, sheet->rule_count, (int) explen);
@@ -385,32 +408,40 @@
 
 		switch (rule->type) {
 		case CSS_RULE_SELECTOR:
-			validate_rule_selector((css_rule_selector *) rule,
-					&exp[e], testnum);
+			failed = validate_rule_selector((css_rule_selector *) rule, &exp[e]);
 			break;
 		case CSS_RULE_CHARSET:
 			validate_rule_charset((css_rule_charset *) rule,
 					&exp[e], testnum);
+			failed = false;
 			break;
 		case CSS_RULE_IMPORT:
 			validate_rule_import((css_rule_import *) rule,
 					&exp[e], testnum);
+			failed = false;
 			break;
 		default:
 			printf("%d: Unhandled rule type %d\n",
 				testnum, rule->type);
+			failed = false;
 			break;
 		}
+
+		if (failed) {
+			report_fail(data, len, &exp[e]);
+			assert(0);
+		}
 	}
 
 	assert(e == explen);
 
 	css_stylesheet_destroy(sheet);
 
-	printf("Test %d: PASS\n", testnum);
+	printf("PASS\n");
 }
 
-void validate_rule_selector(css_rule_selector *s, exp_entry *e, int testnum)
+
+bool validate_rule_selector(css_rule_selector *s, exp_entry *e)
 {
 	char name[MAX_RULE_NAME_LEN];
 	char *ptr = name;
@@ -428,28 +459,30 @@
 
 	/* Compare with expected selector */
 	if (strcmp(e->name, name) != 0) {
-		printf("%d: Got name '%s'. Expected '%s'\n",
-			testnum, name, e->name);
-		assert(0 && "Mismatched names");
+		printf("FAIL Mismatched names\n"
+		       "     Got name '%s'. Expected '%s'\n",
+		       name, e->name);
+		return true;
 	}
 
 	/* Now compare bytecode */
 	if (e->bytecode != NULL && s->style == NULL) {
-		printf("%d: Expected bytecode but none created\n",
-			testnum);
-		assert(0 && "No bytecode");
+		printf("FAIL No bytecode\n"
+		       "    Expected bytecode but none created\n");
+		return true;
 	} else if (e->bytecode == NULL && s->style != NULL) {
-		printf("%d: No bytecode expected but some created\n",
-			testnum);
-		assert(0 && "Unexpected bytecode");
+		printf("FAIL Unexpected bytecode\n"
+		       "    No bytecode expected but some created\n");
+		return true;
 	} else if (e->bytecode != NULL && s->style != NULL) {
 		size_t i;
 
-		if (s->style->length != e->bcused) {
-			printf("%d: Got length %d, Expected %u\n",
-				testnum, s->style->length, 
+		if ((s->style->used * sizeof(css_code_t)) != e->bcused) {
+			printf("FAIL Bytecode lengths differ\n"
+			       "    Got length %ld, Expected %u\n",
+				(s->style->used * sizeof(css_code_t)), 
 				(int) e->bcused);
-			assert(0 && "Bytecode lengths differ");
+			return true;
 		}
 
 		for (i = 0; i < e->bcused; i++) {
@@ -461,38 +494,43 @@
 			}
 
 			if (j != e->stused) {
-				lwc_string **p = (void *) ((uint8_t *) 
-						s->style->bytecode + i);
+				/* String */
+				uint32_t idx = (s->style->bytecode[
+						i / sizeof(css_code_t)]) - 1;
+				lwc_string *p = s->style->sheet->
+						string_vector[idx];
 
-				if (lwc_string_length(*p) != 
+				if (lwc_string_length(p) != 
 					strlen(e->stringtab[j].string) ||
-					memcmp(lwc_string_data(*p), 
+					memcmp(lwc_string_data(p), 
 						e->stringtab[j].string,
-						lwc_string_length(*p)) != 0) {
-					printf("%d: Got string '%.*s'. "
-						"Expected '%s'\n",
-						testnum, 
-						(int) lwc_string_length(*p), 
-						lwc_string_data(*p), 
+						lwc_string_length(p)) != 0) {
+					printf("FAIL Strings differ\n"
+					       "    Got string '%.*s'. "
+					       "Expected '%s'\n",
+						(int) lwc_string_length(p), 
+						lwc_string_data(p), 
 						e->stringtab[j].string);
-					assert(0 && "Strings differ");
+					return true;
 				}
 
-				i += sizeof (void *) - 1;
+				i += sizeof (css_code_t) - 1;
 			} else if (((uint8_t *) s->style->bytecode)[i] != 
 					e->bytecode[i]) {
-				printf("%d: Bytecode differs at %u\n",
-					testnum, (int) i);
+				printf("FAIL Bytecode differs\n"
+				       "    Bytecode differs at %u\n    ",
+					(int) i);
 				while (i < e->bcused) {
 					printf("%.2x ", 
 						((uint8_t *) s->style->bytecode)[i]);
 					i++;
 				}
 				printf("\n");
-				assert(0 && "Bytecode differs");
+				return true;
 			}
 		}
 	}
+	return false;
 }
 
 void validate_rule_charset(css_rule_charset *s, exp_entry *e, int testnum)
Index: test/data/parse/colours.dat
===================================================================
--- test/data/parse/colours.dat	(revision 11378)
+++ test/data/parse/colours.dat	(working copy)
@@ -90,3 +90,27 @@
 |   0x02000018 0x7fff0000
 #reset
 
+#data
+* { color: rgba(255, 0, 0, 1.1) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0xffff0000
+#reset
+
+#data
+* { color: rgba(255, 0, 0, 128) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0xffff0000
+#reset
+
+#data
+* { color: rgba(-255, 0, 0, -255) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0x00000000
+#reset
+
Index: test/data/parse2/bgpos.dat
===================================================================
--- test/data/parse2/bgpos.dat	(revision 11378)
+++ test/data/parse2/bgpos.dat	(working copy)
@@ -19,3 +19,41 @@
 | *
 #reset
 
+#data
+* { background-position: left top inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { background-position: inherit left top; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { background-position: left top; }
+#errors
+#expected
+| *
+|  background-position: left top
+#reset
+
+#data
+* { background-position: left center; }
+#errors
+#expected
+| *
+|  background-position: left center
+#reset
+
+#data
+* { background-position: 62% center; }
+#errors
+#expected
+| *
+|  background-position: 62% center
+#reset
+
Index: test/data/parse2/list.dat
===================================================================
--- test/data/parse2/list.dat	(revision 11378)
+++ test/data/parse2/list.dat	(working copy)
@@ -180,10 +180,73 @@
 | *
 #reset
 
+#data
+* { list-style: inherit circle; }
+#errors
+#expected
+| *
+#reset
 
+#data
+* { list-style: disc inherit; }
+#errors
+#expected
+| *
+#reset
 
+#data
+* { list-style: circle inside inherit; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { list-style: inherit disc inside; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { list-style: disc circle; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { list-style: inside inherit url('PicoDrive'); }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { list-style: !important disc circle; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { list-style: !important disc inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { list-style: disc inherit !important; }
+#errors
+#expected
+| *
+#reset
+
+
+
+
+#data
 * { list-style: inherit !important; }
 #errors
 #expected
Index: test/data/parse2/margin.dat
===================================================================
--- test/data/parse2/margin.dat	(revision 11378)
+++ test/data/parse2/margin.dat	(working copy)
@@ -221,9 +221,58 @@
 | *
 #reset
 
+#data
+* { margin: 2px inherit; }
+#errors
+#expected
+| *
+#reset
 
+#data
+* { margin: inherit 2px; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { margin: 2px 3em inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { margin: 2px inherit 3em; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { margin: 2px 0 0 0 inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { margin: inherit inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { margin: inherit 0 !important; }
+#errors
+#expected
+| *
+#reset
+
+
+
+#data
 * { margin-top: inherit;}
 #errors
 #expected
Index: test/data/parse2/border.dat
===================================================================
--- test/data/parse2/border.dat	(revision 11378)
+++ test/data/parse2/border.dat	(working copy)
@@ -597,8 +597,43 @@
 | *
 #reset
 
+#data
+* { border: thin inherit; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { border: inherit thin; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { border: thin solid black inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { border: thin inherit solid; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { border: inherit !important #ff9; }
+#errors
+#expected
+| *
+#reset
+
+
+#data
 * { border-color: red; }
 #errors
 #expected
Index: test/data/parse2/outline.dat
===================================================================
--- test/data/parse2/outline.dat	(revision 11378)
+++ test/data/parse2/outline.dat	(working copy)
@@ -341,8 +341,57 @@
 | *
 #reset
 
+#data
+* { outline: thin solid red inherit; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { outline: inherit thin solid #fff; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { outline: inherit thin; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { outline: thin inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { outline: inherit inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { outline: inherit #BBC !important; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { outline: #BBC !important inherit; }
+#errors
+#expected
+| *
+#reset
+
+
+#data
 * { outline-color: red; }
 #errors
 #expected
Index: test/data/parse2/bg.dat
===================================================================
--- test/data/parse2/bg.dat	(revision 11378)
+++ test/data/parse2/bg.dat	(working copy)
@@ -60,8 +60,42 @@
 | *
 #reset
 
+#data
+* { background: #fff inherit; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { background: inherit #fff; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { background: #fff inherit top left; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { background: inherit fixed !important; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { background: #fff url(foo) repeat fixed right bottom inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
 * { background: red !important; }
 #errors
 #expected
Index: test/data/parse2/au.dat
===================================================================
--- test/data/parse2/au.dat	(revision 11378)
+++ test/data/parse2/au.dat	(working copy)
@@ -105,6 +105,48 @@
 #reset
 
 #data
+* { cue: inherit inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { cue: none inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { cue: inherit none; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { cue: none url(foo) !important inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { cue: inherit none url(foo) !important; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { cue: inherit url(foo) !important; }
+#errors
+#expected
+| *
+#reset
+
+#data
 * { cue:}
 #errors
 #expected
Index: test/data/parse2/padding.dat
===================================================================
--- test/data/parse2/padding.dat	(revision 11378)
+++ test/data/parse2/padding.dat	(working copy)
@@ -159,9 +159,58 @@
 | *
 #reset
 
+#data
+* { padding: 2px inherit; }
+#errors
+#expected
+| *
+#reset
 
+#data
+* { padding: inherit 2px; }
+#errors
+#expected
+| *
+#reset
 
 #data
+* { padding: 2px 3em inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { padding: 2px inherit 3em; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { padding: 2px 0 0 0 inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { padding: inherit inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { padding: inherit 0 !important; }
+#errors
+#expected
+| *
+#reset
+
+
+
+#data
 * { padding-top: inherit;}
 #errors
 #expected
Index: test/data/parse2/font.dat
===================================================================
--- test/data/parse2/font.dat	(revision 11378)
+++ test/data/parse2/font.dat	(working copy)
@@ -295,6 +295,48 @@
 #reset
 
 #data
+* { font: 10pt inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { font: inherit 10pt; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { font: 'Sonic the Hedgehog' 12pt inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { font: 'Sonic the Hedgehog' inherit 12pt; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { font: inherit 12pt 'Sonic the Hedgehog'; }
+#errors
+#expected
+| *
+#reset
+
+#data
+* { font: inherit inherit; }
+#errors
+#expected
+| *
+#reset
+
+#data
 * { font-family: inherit; }
 #errors
 #expected
Index: src/select/select.c
===================================================================
--- src/select/select.c	(revision 11378)
+++ src/select/select.c	(working copy)
@@ -1283,10 +1283,10 @@
 {
 	css_style s = *style;
 
-	while (s.length > 0) {
+	while (s.used > 0) {
 		opcode_t op;
 		css_error error;
-		uint32_t opv = *((uint32_t *) s.bytecode);
+		css_code_t opv = *s.bytecode;
 
 		advance_bytecode(&s, sizeof(opv));
 
Index: src/select/select.h
===================================================================
--- src/select/select.h	(revision 11378)
+++ src/select/select.h	(working copy)
@@ -60,8 +60,8 @@
 
 static inline void advance_bytecode(css_style *style, uint32_t n_bytes)
 {
-	style->length -= n_bytes;
-	style->bytecode = ((uint8_t *) style->bytecode) + n_bytes;
+	style->used -= (n_bytes / sizeof(css_code_t));
+	style->bytecode = style->bytecode + (n_bytes / sizeof(css_code_t));
 }
 
 bool outranks_existing(uint16_t op, bool important, css_select_state *state,
Index: src/select/properties/quotes.c
===================================================================
--- src/select/properties/quotes.c	(revision 11378)
+++ src/select/properties/quotes.c	(working copy)
@@ -30,11 +30,11 @@
 			lwc_string *open, *close;
 			lwc_string **temp;
 
-			open = *((lwc_string **) style->bytecode);
-			advance_bytecode(style, sizeof(lwc_string *));
+			open = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
+			advance_bytecode(style, sizeof(css_code_t));
 
-			close = *((lwc_string **) style->bytecode);
-			advance_bytecode(style, sizeof(lwc_string *));
+			close = style->sheet->string_vector[(*((css_code_t *)style->bytecode)) - 1];
+			advance_bytecode(style, sizeof(css_code_t));
 
 			temp = state->computed->alloc(quotes, 
 					(n_quotes + 2) * sizeof(lwc_string *), 
@@ -172,11 +172,8 @@
 	bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t);
 	
 	while (value == QUOTES_STRING) {
-		lwc_string **str = ((lwc_string **)bytecode);
-		consumed += sizeof(lwc_string*) * 2;
-		bytecode = ((uint8_t*)bytecode) + (sizeof(lwc_string*) * 2);
-		lwc_string_unref(str[0]);
-		lwc_string_unref(str[1]);
+		consumed += sizeof(css_code_t) * 2;
+		bytecode = ((uint8_t*)bytecode) + (sizeof(css_code_t) * 2);
 			
 		consumed += sizeof(uint32_t);
 		value = *((uint32_t*)bytecode);
Index: src/select/properties/helpers.c
===================================================================
--- src/select/properties/helpers.c	(revision 11378)
+++ src/select/properties/helpers.c	(working copy)
@@ -28,12 +28,7 @@
 {
 	bool has_uri = (getValue(*((uint32_t*)bytecode)) & BACKGROUND_IMAGE_URI) == BACKGROUND_IMAGE_URI;
 	
-	if (has_uri) {
-		void *vstr = (((uint8_t*)bytecode) + sizeof(uint32_t));
-		lwc_string *str = *(lwc_string **) vstr;
-		lwc_string_unref(str);
-	}
-	return sizeof(uint32_t) + (has_uri ? sizeof(lwc_string*) : 0);
+	return sizeof(css_code_t) + (has_uri ? sizeof(css_code_t) : 0);
 }
 
 uint32_t generic_destroy_length(void *bytecode)
@@ -128,8 +123,8 @@
 			break;
 		case BACKGROUND_IMAGE_URI:
 			value = CSS_BACKGROUND_IMAGE_IMAGE;
-			uri = *((lwc_string **) style->bytecode);
-			advance_bytecode(style, sizeof(uri));
+			uri = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
+			advance_bytecode(style, sizeof(css_code_t));
 			break;
 		}
 	}
@@ -437,8 +432,7 @@
 				lwc_string *name;
 				css_fixed val = 0;
 
-				name = *((lwc_string **)
-						style->bytecode);
+				name = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
 				advance_bytecode(style, sizeof(name));
 
 				val = *((css_fixed *) style->bytecode);
Index: src/select/properties/voice_family.c
===================================================================
--- src/select/properties/voice_family.c	(revision 11378)
+++ src/select/properties/voice_family.c	(working copy)
@@ -31,9 +31,8 @@
 			switch (v) {
 			case VOICE_FAMILY_STRING:
 			case VOICE_FAMILY_IDENT_LIST:
-				voice = *((lwc_string **) 
-						style->bytecode);
-				advance_bytecode(style, sizeof(voice));
+				voice = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
+				advance_bytecode(style, sizeof(css_code_t));
 				break;
 			case VOICE_FAMILY_MALE:
 				if (value == 0)
@@ -142,10 +141,8 @@
 	
 	while (value != VOICE_FAMILY_END) {
 		if (value == VOICE_FAMILY_STRING || value == VOICE_FAMILY_IDENT_LIST) {
-			lwc_string *str = *((lwc_string **)bytecode);
-			consumed += sizeof(lwc_string*);
-			bytecode = ((uint8_t*)bytecode) + sizeof(lwc_string*);
-			lwc_string_unref(str);
+			consumed += sizeof(css_code_t);
+			bytecode = ((uint8_t*)bytecode) + sizeof(css_code_t);
 		}
 		
 		consumed += sizeof(uint32_t);
Index: src/select/properties/content.c
===================================================================
--- src/select/properties/content.c	(revision 11378)
+++ src/select/properties/content.c	(working copy)
@@ -32,7 +32,7 @@
 			value = CSS_CONTENT_SET;
 			
 			while (v != CONTENT_NORMAL) {
-				lwc_string *he = *((lwc_string **) style->bytecode);
+				lwc_string *he = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
 				css_computed_content_item *temp;
 				
 				temp = state->computed->alloc(content,
@@ -51,7 +51,7 @@
 
 				switch (v & 0xff) {
 				case CONTENT_COUNTER:
-					advance_bytecode(style, sizeof(he));
+					advance_bytecode(style, sizeof(css_code_t));
 
 					content[n_contents].type =
 						CSS_COMPUTED_CONTENT_COUNTER;
@@ -62,11 +62,10 @@
 				{
 					lwc_string *sep;
 	
-					advance_bytecode(style, sizeof(he));
+					advance_bytecode(style, sizeof(css_code_t));
 
-					sep = *((lwc_string **) 
-							style->bytecode);
-					advance_bytecode(style, sizeof(sep));
+					sep = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
+					advance_bytecode(style, sizeof(css_code_t));
 
 					content[n_contents].type =
 						CSS_COMPUTED_CONTENT_COUNTERS;
@@ -76,21 +75,21 @@
 				}
 					break;
 				case CONTENT_URI:
-					advance_bytecode(style, sizeof(he));
+					advance_bytecode(style, sizeof(css_code_t));
 
 					content[n_contents].type =
 						CSS_COMPUTED_CONTENT_URI;
 					content[n_contents].data.uri = he;
 					break;
 				case CONTENT_ATTR:
-					advance_bytecode(style, sizeof(he));
+					advance_bytecode(style, sizeof(css_code_t));
 
 					content[n_contents].type =
 						CSS_COMPUTED_CONTENT_ATTR;
 					content[n_contents].data.attr = he;
 					break;
 				case CONTENT_STRING:
-					advance_bytecode(style, sizeof(he));
+					advance_bytecode(style, sizeof(css_code_t));
 
 					content[n_contents].type =
 						CSS_COMPUTED_CONTENT_STRING;
@@ -257,19 +256,16 @@
 	while (value != 0) {
 		switch (value & 0xff) {
 		case CONTENT_COUNTERS: {
-			lwc_string *str = *(lwc_string **)bytecode;
-			lwc_string_unref(str);
-			consumed += sizeof(lwc_string*);
-			bytecode = (uint8_t*)bytecode + sizeof(lwc_string *);
+			consumed += sizeof(css_code_t);
+			bytecode = (uint8_t*)bytecode + sizeof(css_code_t);
 		}
+			/* falls through */
 		case CONTENT_STRING:
 		case CONTENT_URI:
 		case CONTENT_COUNTER:
 		case CONTENT_ATTR: {
-			lwc_string *str = *(lwc_string **)bytecode;
-			lwc_string_unref(str);
-			consumed += sizeof(lwc_string*);
-			bytecode = (uint8_t*)bytecode + sizeof(lwc_string *);
+			consumed += sizeof(css_code_t);
+			bytecode = (uint8_t*)bytecode + sizeof(css_code_t);
 		}
 		}
 		consumed += sizeof(uint32_t);
Index: src/select/properties/cursor.c
===================================================================
--- src/select/properties/cursor.c	(revision 11378)
+++ src/select/properties/cursor.c	(working copy)
@@ -217,10 +217,8 @@
 	bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t);
 	
 	while (value == CURSOR_URI) {
-		lwc_string *str = *((lwc_string **)bytecode);
-		consumed += sizeof(lwc_string*);
-		bytecode = ((uint8_t*)bytecode) + sizeof(lwc_string*);
-		lwc_string_unref(str);
+		consumed += sizeof(css_code_t);
+		bytecode = ((uint8_t*)bytecode) + sizeof(css_code_t);
 		
 		consumed += sizeof(uint32_t);
 		value = *((uint32_t*)bytecode);
Index: src/select/properties/font_family.c
===================================================================
--- src/select/properties/font_family.c	(revision 11378)
+++ src/select/properties/font_family.c	(working copy)
@@ -31,9 +31,8 @@
 			switch (v) {
 			case FONT_FAMILY_STRING:
 			case FONT_FAMILY_IDENT_LIST:
-				font = *((lwc_string **) 
-						style->bytecode);
-				advance_bytecode(style, sizeof(font));
+				font = style->sheet->string_vector[(*((css_code_t *) style->bytecode)) - 1];
+				advance_bytecode(style, sizeof(css_code_t));
 				break;
 			case FONT_FAMILY_SERIF:
 				if (value == CSS_FONT_FAMILY_INHERIT)
@@ -200,10 +199,8 @@
 	
 	while (value != FONT_FAMILY_END) {
 		if (value == FONT_FAMILY_STRING || value == FONT_FAMILY_IDENT_LIST) {
-			lwc_string *str = *((lwc_string **)bytecode);
-			consumed += sizeof(lwc_string*);
-			bytecode = ((uint8_t*)bytecode) + sizeof(lwc_string*);
-			lwc_string_unref(str);
+			consumed += sizeof(uint32_t);
+			bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t);
 		}
 		
 		consumed += sizeof(uint32_t);
Index: src/select/properties/counter_reset.c
===================================================================
--- src/select/properties/counter_reset.c	(revision 11378)
+++ src/select/properties/counter_reset.c	(working copy)
@@ -100,10 +100,8 @@
 	
 	if (value == COUNTER_INCREMENT_NAMED) {
 		while (value != COUNTER_INCREMENT_NONE) {
-			lwc_string *str = *((lwc_string **)bytecode);
-			consumed += sizeof(lwc_string*) + sizeof(css_fixed);
-			bytecode = ((uint8_t*)bytecode) + sizeof(lwc_string*) + sizeof(css_fixed);
-			lwc_string_unref(str);
+			consumed += sizeof(css_code_t) + sizeof(css_fixed);
+			bytecode = ((uint8_t*)bytecode) + sizeof(css_code_t) + sizeof(css_fixed);
 			
 			consumed += sizeof(uint32_t);
 			value = *((uint32_t*)bytecode);
Index: src/select/properties/counter_increment.c
===================================================================
--- src/select/properties/counter_increment.c	(revision 11378)
+++ src/select/properties/counter_increment.c	(working copy)
@@ -101,11 +101,8 @@
 	
 	if (value == COUNTER_INCREMENT_NAMED) {
 		while (value != COUNTER_INCREMENT_NONE) {
-			lwc_string *str = *((lwc_string **)bytecode);
-			consumed += sizeof(lwc_string*) + sizeof(css_fixed);
-			bytecode = ((uint8_t*)bytecode) + sizeof(lwc_string*) + sizeof(css_fixed);
-			lwc_string_unref(str);
-			
+			consumed += sizeof(css_code_t) + sizeof(css_fixed);
+			bytecode = ((uint8_t*)bytecode) + sizeof(css_code_t) + sizeof(css_fixed);
 			consumed += sizeof(uint32_t);
 			value = *((uint32_t*)bytecode);
 			bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t);
Index: src/stylesheet.h
===================================================================
--- src/stylesheet.h	(revision 11378)
+++ src/stylesheet.h	(working copy)
@@ -18,6 +18,7 @@
 #include <libcss/stylesheet.h>
 #include <libcss/types.h>
 
+#include "bytecode/bytecode.h"
 #include "parse/parse.h"
 #include "select/hash.h"
 
@@ -25,8 +26,10 @@
 typedef struct css_selector css_selector;
 
 typedef struct css_style {
-	uint32_t length;		/**< Length, in bytes, of bytecode */
-	void *bytecode;			/**< Pointer to bytecode */
+	css_code_t *bytecode;	      /**< Pointer to bytecode */
+	uint32_t used;		      /**< number of code entries used */
+	uint32_t allocated;	      /**< number of allocated code entries */
+	struct css_stylesheet *sheet; /**< containing sheet */
 } css_style;
 
 typedef enum css_selector_type {
@@ -168,8 +171,6 @@
 
 	size_t size;				/**< Size, in bytes */
 
-	css_style *free_styles[4];		/**< Free styles: 16B buckets */
-
 	css_import_notification_fn import;	/**< Import notification function */
 	void *import_pw;			/**< Private word */
 
@@ -184,11 +185,27 @@
 	uint32_t string_vector_c;               /**< The number of string vector entries used */ 
 };
 
-css_error css_stylesheet_style_create(css_stylesheet *sheet, uint32_t len,
-		css_style **style);
-css_error css_stylesheet_style_destroy(css_stylesheet *sheet, css_style *style,
-				       bool suppress_bytecode_cleanup);
+css_error css_stylesheet_style_create(css_stylesheet *sheet, css_style **style);
+css_error css_stylesheet_style_append(css_style *style, css_code_t code);
+css_error css_stylesheet_style_vappend(css_style *style, uint32_t style_count, ...);
+css_error css_stylesheet_style_destroy(css_style *style, bool suppress_bytecode_cleanup);
+css_error css_stylesheet_merge_style(css_style *target, css_style *style);
 
+/** Helper function to avoid distinct buildOPV call */ 
+static inline css_error css_stylesheet_style_appendOPV(css_style *style, opcode_t opcode, uint8_t flags, uint16_t value)
+{
+	return css_stylesheet_style_append(style, buildOPV(opcode, flags, value));
+}
+
+/** Helper function to set inherit flag */ 
+static inline css_error css_stylesheet_style_inherit(css_style *style, opcode_t opcode)
+{
+	return css_stylesheet_style_append(style, buildOPV(opcode, FLAG_INHERIT, 0));
+}
+
+
+
+
 css_error css_stylesheet_selector_create(css_stylesheet *sheet,
 		lwc_string *name, css_selector **selector);
 css_error css_stylesheet_selector_destroy(css_stylesheet *sheet,
Index: src/parse/language.c
===================================================================
--- src/parse/language.c	(revision 11378)
+++ src/parse/language.c	(working copy)
@@ -1273,8 +1273,13 @@
 	handler = property_handlers[i - FIRST_PROP];
 	assert(handler != NULL);
 
-	/* Call it */
-	error = handler(c, vector, ctx, &style);
+        /* allocate style */
+	error = css_stylesheet_style_create(c->sheet, &style);
+	if (error != CSS_OK) 
+		return error;
+
+	/* Call the handler */
+	error = handler(c, vector, ctx, style);
 	if (error != CSS_OK)
 		return error;
 
@@ -1283,7 +1288,7 @@
 	/* Determine if this declaration is important or not */
 	error = parse_important(c, vector, ctx, &flags);
 	if (error != CSS_OK) {
-	  css_stylesheet_style_destroy(c->sheet, style, false);
+		css_stylesheet_style_destroy(style, false);
 		return error;
 	}
 
@@ -1292,7 +1297,7 @@
 	token = parserutils_vector_iterate(vector, ctx);
 	if (token != NULL) {
 		/* Trailing junk, so discard declaration */
-                css_stylesheet_style_destroy(c->sheet, style, false);
+                css_stylesheet_style_destroy(style, false);
 		return CSS_INVALID;
 	}
 
@@ -1303,7 +1308,7 @@
 	/* Append style to rule */
 	error = css_stylesheet_rule_append_style(c->sheet, rule, style);
 	if (error != CSS_OK) {
-                css_stylesheet_style_destroy(c->sheet, style, false);
+                css_stylesheet_style_destroy(style, false);
 		return error;
 	}
 
Index: src/parse/properties/border_collapse.c
===================================================================
--- src/parse/properties/border_collapse.c	(revision 11378)
+++ src/parse/properties/border_collapse.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_border_collapse(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (collapse, separate, inherit) */
@@ -47,33 +44,33 @@
 	}
 
 	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		     ident->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_BORDER_COLLAPSE,
+				FLAG_INHERIT,
+				0);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[COLLAPSE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_COLLAPSE_COLLAPSE;
+			    ident->idata, c->strings[COLLAPSE],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_BORDER_COLLAPSE,
+				0,
+				BORDER_COLLAPSE_COLLAPSE);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[SEPARATE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_COLLAPSE_SEPARATE;
+			    ident->idata, c->strings[SEPARATE],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_BORDER_COLLAPSE,
+				0,
+				BORDER_COLLAPSE_SEPARATE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_BORDER_COLLAPSE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
-		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/border_bottom_width.c
===================================================================
--- src/parse/properties/border_bottom_width.c	(revision 11378)
+++ src/parse/properties/border_bottom_width.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_bottom_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_width(c, vector, ctx, 
-			CSS_PROP_BORDER_BOTTOM_WIDTH, result);
+	return parse_border_side_width(c, vector, ctx, result, CSS_PROP_BORDER_BOTTOM_WIDTH);
 }
Index: src/parse/properties/utils.c
===================================================================
--- src/parse/properties/utils.c	(revision 11378)
+++ src/parse/properties/utils.c	(working copy)
@@ -13,97 +13,9 @@
 #include "bytecode/opcodes.h"
 #include "parse/properties/properties.h"
 #include "parse/properties/utils.h"
+#include "utils/parserutilserror.h"
 
-/**
- * Common parser for pause-after and pause-before
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param op	  Opcode to parse for
- * \param result  Pointer to location to receive resulting style
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-css_error parse_pause_common(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		uint16_t op, css_style **result)
-{
-	int orig_ctx = *ctx;
-	css_error error;
-	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
-	bool match;
 
-	/* time | percentage | IDENT(inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_S,
-				&length, &unit);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
-
-		if ((unit & UNIT_TIME) == false && (unit & UNIT_PCT) == false) {
-			*ctx = orig_ctx;
-			return CSS_INVALID;
-		}
-
-		/* Negative values are illegal */
-		if (length < 0) {
-			*ctx = orig_ctx;
-			return CSS_INVALID;
-		}
-
-		value = PAUSE_AFTER_SET;
-	}
-
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
-}
-
 /**
  * Parse list-style-type value
  *
@@ -189,629 +101,9 @@
 	return CSS_OK;
 }
 
-/**
- * Parse content list
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param value	  Pointer to location to receive value
- * \param buffer  Pointer to output buffer, or NULL to read required length
- * \param buflen  Pointer to location to receive buffer length
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-css_error parse_content_list(css_language *c,
-		const parserutils_vector *vector, int *ctx,
-		uint16_t *value, uint8_t *buffer, uint32_t *buflen)
-{
-	int orig_ctx = *ctx;
-	int prev_ctx = *ctx;
-	css_error error;
-	const css_token *token;
-	bool first = true;
-	uint32_t offset = 0;
-	uint32_t opv;
-	bool match;
 
-	/* [
-	 *	IDENT(open-quote, close-quote, no-open-quote, no-close-quote) |
-	 *	STRING | URI |
-	 *	FUNCTION(attr) IDENT ')' |
-	 *	FUNCTION(counter) IDENT (',' IDENT)? ')' |
-	 *	FUNCTION(counters) IDENT ',' STRING (',' IDENT)? ')'
-	 * ]+
-	 */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
 
-	while (token != NULL) {
-		if (token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[OPEN_QUOTE],
-				&match) == lwc_error_ok && match)) {
-			opv = CONTENT_OPEN_QUOTE;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			} 
-		} else if (token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[CLOSE_QUOTE],
-				&match) == lwc_error_ok && match)) {
-			opv = CONTENT_CLOSE_QUOTE;
-
-			if (first == false) {				
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-		} else if (token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[NO_OPEN_QUOTE],
-				&match) == lwc_error_ok && match)) {
-			opv = CONTENT_NO_OPEN_QUOTE;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-		} else if (token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[NO_CLOSE_QUOTE],
-				&match) == lwc_error_ok && match)) {
-			opv = CONTENT_NO_CLOSE_QUOTE;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-		} else if (token->type == CSS_TOKEN_STRING) {
-			opv = CONTENT_STRING;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-
-			if (buffer != NULL) {
-				lwc_string_ref(token->idata);
-				memcpy(buffer + offset, &token->idata,
-						sizeof(token->idata));
-			}
-
-			offset += sizeof(token->idata);
-		} else if (token->type == CSS_TOKEN_URI) {
-			lwc_string *uri;
-
-			opv = CONTENT_URI;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-
-			if (buffer != NULL) {
-				error = c->sheet->resolve(c->sheet->resolve_pw,
-					c->sheet->url,
-					token->idata, &uri);
-				if (error != CSS_OK) {
-					*ctx = orig_ctx;
-					return error;
-				}
-
-				/* Don't ref URI -- we want to pass ownership 
-				 * to the bytecode */
-				memcpy(buffer + offset, &uri, sizeof(uri));
-			}
-
-			offset += sizeof(uri);
-		} else if (token->type == CSS_TOKEN_FUNCTION &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[ATTR],
-				&match) == lwc_error_ok && match)) {
-			opv = CONTENT_ATTR;
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect IDENT */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || token->type != CSS_TOKEN_IDENT) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (buffer != NULL) {
-				lwc_string_ref(token->idata);
-				memcpy(buffer + offset, &token->idata, 
-						sizeof(token->idata));
-			}
-
-			offset += sizeof(token->idata);
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect ')' */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || tokenIsChar(token, ')') == false) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-		} else if (token->type == CSS_TOKEN_FUNCTION &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[COUNTER],
-				&match) == lwc_error_ok && match)) {
-			lwc_string *name;
-
-			opv = CONTENT_COUNTER;
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect IDENT */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || token->type != CSS_TOKEN_IDENT) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			name = token->idata;
-
-			consumeWhitespace(vector, ctx);
-
-			/* Possible ',' */
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token == NULL || 
-					(tokenIsChar(token, ',') == false &&
-					tokenIsChar(token, ')') == false)) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (tokenIsChar(token, ',')) {
-				uint16_t v;
-
-				parserutils_vector_iterate(vector, ctx);
-
-				consumeWhitespace(vector, ctx);
-
-				/* Expect IDENT */
-				token = parserutils_vector_peek(vector, *ctx);
-				if (token == NULL || token->type != 
-						CSS_TOKEN_IDENT) {
-					*ctx = orig_ctx;
-					return CSS_INVALID;
-				}
-
-				error = parse_list_style_type_value(c,
-						token, &v);
-				if (error != CSS_OK) {
-					*ctx = orig_ctx;
-					return error;
-				}
-
-				opv |= v << CONTENT_COUNTER_STYLE_SHIFT;
-
-				parserutils_vector_iterate(vector, ctx);
-
-				consumeWhitespace(vector, ctx);
-			} else {
-				opv |= LIST_STYLE_TYPE_DECIMAL << 
-						CONTENT_COUNTER_STYLE_SHIFT;
-			}
-
-			/* Expect ')' */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || tokenIsChar(token,	')') == false) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-
-			if (buffer != NULL) {
-				lwc_string_ref(name);
-				memcpy(buffer + offset, &name, sizeof(name));
-			}
-
-			offset += sizeof(name);
-		} else if (token->type == CSS_TOKEN_FUNCTION &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[COUNTERS],
-				&match) == lwc_error_ok && match)) {
-			lwc_string *name;
-			lwc_string *sep;
-
-			opv = CONTENT_COUNTERS;
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect IDENT */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || token->type != CSS_TOKEN_IDENT) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			name = token->idata;
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect ',' */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || tokenIsChar(token, ',') == false) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			consumeWhitespace(vector, ctx);
-
-			/* Expect STRING */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || token->type != CSS_TOKEN_STRING) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			sep = token->idata;
-
-			consumeWhitespace(vector, ctx);
-
-			/* Possible ',' */
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token == NULL || 
-					(tokenIsChar(token, ',') == false && 
-					tokenIsChar(token, ')') == false)) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (tokenIsChar(token, ',')) {
-				uint16_t v;
-
-				parserutils_vector_iterate(vector, ctx);
-
-				consumeWhitespace(vector, ctx);
-
-				/* Expect IDENT */
-				token = parserutils_vector_peek(vector, *ctx);
-				if (token == NULL || token->type != 
-						CSS_TOKEN_IDENT) {
-					*ctx = orig_ctx;
-					return CSS_INVALID;
-				}
-
-				error = parse_list_style_type_value(c,
-						token, &v);
-				if (error != CSS_OK) {
-					*ctx = orig_ctx;
-					return error;
-				}
-
-				opv |= v << CONTENT_COUNTERS_STYLE_SHIFT;
-
-				parserutils_vector_iterate(vector, ctx);
-
-				consumeWhitespace(vector, ctx);
-			} else {
-				opv |= LIST_STYLE_TYPE_DECIMAL <<
-						CONTENT_COUNTERS_STYLE_SHIFT;
-			}
-
-			/* Expect ')' */
-			token = parserutils_vector_iterate(vector, ctx);
-			if (token == NULL || tokenIsChar(token, ')') == false) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (first == false) {
-				if (buffer != NULL) {
-					memcpy(buffer + offset, 
-							&opv, sizeof(opv));
-				}
-
-				offset += sizeof(opv);
-			}
-
-			if (buffer != NULL) {
-				lwc_string_ref(name);
-				memcpy(buffer + offset, &name, sizeof(name));
-			}
-
-			offset += sizeof(name);
-
-			if (buffer != NULL) {
-				lwc_string_ref(sep);
-				memcpy(buffer + offset, &sep, sizeof(sep));
-			}
-
-			offset += sizeof(sep);
-		} else if (first) {
-			/* Invalid if this is the first iteration */
-			*ctx = orig_ctx;
-			return CSS_INVALID;
-		} else {
-			/* Give up, ensuring current token is reprocessed */
-			*ctx = prev_ctx;
-			break;
-		}
-
-		if (first && value != NULL) {
-			*value = opv;
-		}
-		first = false;
-
-		consumeWhitespace(vector, ctx);
-
-		prev_ctx = *ctx;
-		token = parserutils_vector_iterate(vector, ctx);
-	}
-
-	/* Write list terminator */
-	opv = CONTENT_NORMAL;
-
-	if (buffer != NULL) {
-		memcpy(buffer + offset, &opv, sizeof(opv));
-	}
-
-	offset += sizeof(opv);
-
-	if (buflen != NULL) {
-		*buflen = offset;
-	}
-
-	return CSS_OK;
-}
-
 /**
- * Common parser for counter-increment and counter-reset
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param op	  Opcode to parse for
- * \param result  Pointer to location to receive resulting style
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-css_error parse_counter_common(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		uint16_t op, css_style **result)
-{
-	int orig_ctx = *ctx;
-	css_error error;
-	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
-	bool match;
-
-	/* [IDENT <integer>? ]+ | IDENT(none, inherit) */
-
-	/* Pass 1: validate input and calculate bytecode size */
-	token = parserutils_vector_iterate(vector, &temp_ctx);
-	if (token == NULL || token->type != CSS_TOKEN_IDENT) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = COUNTER_INCREMENT_NONE;
-	} else {
-		bool first = true;
-
-		value = COUNTER_INCREMENT_NAMED;
-
-		while (token != NULL) {
-			lwc_string *name = token->idata;
-			css_fixed increment = 
-					(op == CSS_PROP_COUNTER_INCREMENT) 
-					? INTTOFIX(1) : INTTOFIX(0);
-
-			consumeWhitespace(vector, &temp_ctx);
-
-			/* Optional integer */
-			token = parserutils_vector_peek(vector, temp_ctx);
-			if (token != NULL && token->type != CSS_TOKEN_IDENT &&
-					token->type != CSS_TOKEN_NUMBER) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (token != NULL && token->type == CSS_TOKEN_NUMBER) {
-				size_t consumed = 0;
-
-				increment = number_from_lwc_string(
-						token->idata, true, &consumed);
-
-				if (consumed != lwc_string_length(
-						token->idata)) {
-					*ctx = orig_ctx;
-					return CSS_INVALID;
-				}
-
-				parserutils_vector_iterate(vector, &temp_ctx);
-
-				consumeWhitespace(vector, &temp_ctx);
-			}
-
-			if (first == false) {
-				required_size += sizeof(opv);
-			}
-			required_size += sizeof(name) + sizeof(increment);
-
-			first = false;
-
-			token = parserutils_vector_peek(vector, temp_ctx);
-			if (token != NULL && token->type != CSS_TOKEN_IDENT) {
-				break;
-			}
-
-			token = parserutils_vector_iterate(vector, &temp_ctx);
-		}
-
-		/* And for the terminator */
-		required_size += sizeof(opv);
-	}
-
-	opv = buildOPV(op, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
-
-	/* Pass 2: construct bytecode */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || token->type != CSS_TOKEN_IDENT) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match) ||
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		/* Nothing to do */
-	} else {
-		bool first = true;
-
-		opv = COUNTER_INCREMENT_NAMED;
-
-		while (token != NULL) {
-			lwc_string *name = token->idata;
-			css_fixed increment = 
-					(op == CSS_PROP_COUNTER_INCREMENT) 
-					? INTTOFIX(1) : INTTOFIX(0);
-
-			consumeWhitespace(vector, ctx);
-
-			/* Optional integer */
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token != NULL && token->type != CSS_TOKEN_IDENT &&
-					token->type != CSS_TOKEN_NUMBER) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-
-			if (token != NULL && token->type == CSS_TOKEN_NUMBER) {
-				size_t consumed = 0;
-
-				increment = number_from_lwc_string(
-						token->idata, true, &consumed);
-
-				if (consumed != lwc_string_length(
-						token->idata)) {
-					*ctx = orig_ctx;
-					return CSS_INVALID;
-				}
-
-				parserutils_vector_iterate(vector, ctx);
-
-				consumeWhitespace(vector, ctx);
-			}
-
-			if (first == false) {
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
-			
-			lwc_string_ref(name);
-			memcpy(ptr, &name, sizeof(name));
-			ptr += sizeof(name);
-			
-			memcpy(ptr, &increment, sizeof(increment));
-			ptr += sizeof(increment);
-
-			first = false;
-
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token != NULL && token->type != CSS_TOKEN_IDENT) {
-				break;
-			}
-
-			token = parserutils_vector_iterate(vector, ctx);
-		}
-
-		/* And for the terminator */
-		opv = COUNTER_INCREMENT_NONE;
-		memcpy(ptr, &opv, sizeof(opv));
-		ptr += sizeof(opv);
-	}
-
-	return CSS_OK;
-}
-
-/**
  * Parse border-{top,right,bottom,left} shorthand
  *
  * \param c	  Parsing context
@@ -828,82 +120,86 @@
  */
 css_error parse_border_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint32_t side, css_style **result)
+		css_style *result, enum border_side_e side)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *color = NULL;
-	css_style *style = NULL;
-	css_style *width = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
-	bool match;
-	css_error error;
+	css_error error = CSS_OK;
+	bool color = true;
+	bool style = true;
+	bool width = true;
+	css_style *color_style;
+	css_style *style_style;
+	css_style *width_style;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			3 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_COLOR + side);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_STYLE + side);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_COLOR + side,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_STYLE + side,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_WIDTH + side,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_WIDTH + side);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		parserutils_vector_iterate(vector, ctx);
+		return error;
+	} 
 
-		*result = ret;
+	/* allocate styles */
+	error = css_stylesheet_style_create(c->sheet, &color_style);
+	if (error != CSS_OK) 
+		return error;
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+	error = css_stylesheet_style_create(c->sheet, &style_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(color_style, true);
+		return error;
 	}
 
-	/* Attempt to parse individual properties */
+	error = css_stylesheet_style_create(c->sheet, &width_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(color_style, true);
+		css_stylesheet_style_destroy(width_style, true);
+		return error;
+	}
+
+	/* Attempt to parse the various longhand properties */
 	do {
 		prev_ctx = *ctx;
 		error = CSS_OK;
 
 		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
+		if (token != NULL && is_css_inherit(c, token)) {
 			error = CSS_INVALID;
-			goto cleanup;
+			goto parse_border_side_cleanup;
 		}
 
-		if (color == NULL &&
-				(error = parse_border_side_color(c, vector, ctx,
-				CSS_PROP_BORDER_TOP_COLOR + side, &color)) == 
-				CSS_OK) {
-		} else if (style == NULL &&
-				(error = parse_border_side_style(c, vector, ctx,
-				CSS_PROP_BORDER_TOP_STYLE + side, &style)) == 
-				CSS_OK) {
-		} else if (width == NULL &&
-				(error = parse_border_side_width(c, vector, ctx,
-				CSS_PROP_BORDER_TOP_WIDTH + side, &width)) == 
-				CSS_OK) {
-		}
+		/* Try each property parser in turn, but only if we
+		 * haven't already got a value for this property.
+		 */
+		if ((color) && 
+		    (error = parse_border_side_color(c, vector, ctx, 
+			     color_style, CSS_PROP_BORDER_TOP_COLOR + side)) == CSS_OK) {
+			color = false;
+		} else if ((style) && 
+			   (error = parse_border_side_style(c, vector, ctx,
+				    style_style, CSS_PROP_BORDER_TOP_STYLE + side)) == CSS_OK) {
+			style = false;
+		} else if ((width) && 
+			   (error = parse_border_side_width(c, vector, ctx,
+				    width_style, CSS_PROP_BORDER_TOP_WIDTH + side)) == CSS_OK) {
+			width = false;
+		} 
 
 		if (error == CSS_OK) {
 			consumeWhitespace(vector, ctx);
@@ -915,75 +211,46 @@
 		}
 	} while (*ctx != prev_ctx && token != NULL);
 
-	/* Calculate size of resultant style */
-	required_size = 0;
-	if (color)
-		required_size += color->length;
-
-	if (style)
-		required_size += style->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (width)
-		required_size += width->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
+/* color has no default?
 	if (color) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				color->bytecode, color->length);
-		required_size += color->length;
+		error = css_stylesheet_style_appendOPV(color_style, 
+				CSS_PROP_BORDER_TOP_COLOR + side, 0, 
+				BORDER_COLOR_TRANSPARENT);
+		if (error != CSS_OK)
+			goto parse_border_side_cleanup;
 	}
-
+*/
 	if (style) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				style->bytecode, style->length);
-		required_size += style->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BORDER_TOP_STYLE + side,
-				0, BORDER_STYLE_NONE);
-		required_size += sizeof(uint32_t);
+		error = css_stylesheet_style_appendOPV(style_style, 
+				CSS_PROP_BORDER_TOP_STYLE + side, 0, 
+				BORDER_STYLE_NONE);
+		if (error != CSS_OK)
+			goto parse_border_side_cleanup;
 	}
 
 	if (width) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				width->bytecode, width->length);
-		required_size += width->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BORDER_TOP_WIDTH + side,
+		error = css_stylesheet_style_appendOPV(width_style, 
+				CSS_PROP_BORDER_TOP_WIDTH + side,
 				0, BORDER_WIDTH_MEDIUM);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_border_side_cleanup;
 	}
 
-	assert(required_size == ret->length);
+	error = css_stylesheet_merge_style(result, color_style);
+	if (error != CSS_OK)
+		goto parse_border_side_cleanup;
 
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
+	error = css_stylesheet_merge_style(result, style_style);
+	if (error != CSS_OK)
+		goto parse_border_side_cleanup;
 
-	/* Clean up after ourselves */
-cleanup:
-	if (color)
-		css_stylesheet_style_destroy(c->sheet, color, error == CSS_OK);
-	if (style)
-		css_stylesheet_style_destroy(c->sheet, style, error == CSS_OK);
-	if (width)
-		css_stylesheet_style_destroy(c->sheet, width, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
+	error = css_stylesheet_merge_style(result, width_style);
 
+parse_border_side_cleanup:
+	css_stylesheet_style_destroy(color_style, true);
+	css_stylesheet_style_destroy(style_style, true);
+	css_stylesheet_style_destroy(width_style, true);
+
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
@@ -1007,68 +274,52 @@
  */
 css_error parse_border_side_color(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint32_t opv;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t colour = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* colour | IDENT (transparent, inherit) */
-	token= parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[TRANSPARENT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BORDER_COLOR_TRANSPARENT;
+	if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(token->idata, 
+				 c->strings[INHERIT], 
+				 &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
+	} else if ((token->type == CSS_TOKEN_IDENT) && 
+		   (lwc_string_caseless_isequal(token->idata, 
+				c->strings[TRANSPARENT], 
+				&match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_COLOR_TRANSPARENT);
 	} else {
-		error = parse_colour_specifier(c, vector, ctx, &colour);
+		uint32_t color = 0;
+		*ctx = orig_ctx;
+
+		error = parse_colour_specifier(c, vector, ctx, &color);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		value = BORDER_COLOR_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, op, 0, BORDER_COLOR_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_COLOR_SET)
-		required_size += sizeof(colour);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_append(result, color);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_COLOR_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&colour, sizeof(colour));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
 
 /**
@@ -1088,86 +339,49 @@
  */
 css_error parse_border_side_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (none, hidden, dotted, dashed, solid, double, groove, 
-	 * ridge, inset, outset, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_NONE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[HIDDEN],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_HIDDEN;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[DOTTED],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_DOTTED;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[DASHED],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_DASHED;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[SOLID],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_SOLID;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LIBCSS_DOUBLE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_DOUBLE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[GROOVE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_GROOVE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RIDGE],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_RIDGE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INSET],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_INSET;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[OUTSET],
-			&match) == lwc_error_ok && match)) {
-		value = BORDER_STYLE_OUTSET;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_NONE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_HIDDEN);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DOTTED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_DOTTED);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DASHED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_DASHED);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[SOLID], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_SOLID);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_DOUBLE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_DOUBLE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[GROOVE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_GROOVE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIDGE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_RIDGE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[INSET], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_INSET);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[OUTSET], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BORDER_STYLE_OUTSET);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(op, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
 
 /**
@@ -1187,96 +401,61 @@
  */
 css_error parse_border_side_width(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | IDENT(thin, medium, thick, inherit) */
-	token= parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[THIN],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BORDER_WIDTH_THIN;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[MEDIUM],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BORDER_WIDTH_MEDIUM;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[THICK],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BORDER_WIDTH_THICK;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[THIN], &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result, op, 0, BORDER_WIDTH_THIN);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MEDIUM], &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result, op, 0, BORDER_WIDTH_MEDIUM);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[THICK], &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result, op, 0, BORDER_WIDTH_THICK);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit == UNIT_PCT || unit & UNIT_ANGLE ||
-				unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit==UNIT_PCT||unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		/* Length must be positive */
-		if (length < 0) {
+		if (length <0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = BORDER_WIDTH_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, op, 0, BORDER_WIDTH_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_WIDTH_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_WIDTH_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
 
 /**
@@ -1295,77 +474,52 @@
  */
 css_error parse_margin_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(auto, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = MARGIN_AUTO;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,MARGIN_AUTO);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = MARGIN_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, op, 0, MARGIN_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == MARGIN_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == MARGIN_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
 
 /**
@@ -1384,77 +538,55 @@
  */
 css_error parse_padding_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		/* Negative lengths are invalid */
-		if (length < 0) {
+		if (length <0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = PADDING_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, op, 0, PADDING_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == PADDING_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == PADDING_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
 
 /**
@@ -1474,77 +606,52 @@
  */
 css_error parse_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result)
+		css_style *result, enum css_properties_e op)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(auto, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BOTTOM_AUTO;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, op);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, op, 0,BOTTOM_AUTO);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = BOTTOM_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, op, 0, BOTTOM_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BOTTOM_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BOTTOM_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
 
 /**
@@ -2113,108 +1220,92 @@
 }
 
 /**
- * Parse a comma separated list, calculating the storage space required
+ * Create a string from a list of IDENT/S tokens
  *
- * \param c         Parsing context
- * \param vector    Vector of tokens to process
- * \param ctx       Pointer to vector iteration context
- * \param token     Pointer to current token
- * \param reserved  Callback to determine if an identifier is reserved
- * \param size      Pointer to location to receive required storage
- * \return CSS_OK      on success,
- *         CSS_INVALID if the input is invalid
+ * \param c          Parsing context
+ * \param vector     Vector containing tokens
+ * \param ctx        Vector iteration context
+ * \param reserved   Callback to determine if an identifier is reserved
+ * \param result     Pointer to location to receive resulting string
+ * \return CSS_OK on success, appropriate error otherwise.
  *
  * Post condition: \a *ctx is updated with the next token to process
  *                 If the input is invalid, then \a *ctx remains unchanged.
+ *
+ *                 The resulting string's reference is passed to the caller
  */
-css_error comma_list_length(css_language *c,
+static css_error ident_list_to_string(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		const css_token *token,
 		bool (*reserved)(css_language *c, const css_token *ident),
-		uint32_t *size)
+		lwc_string **result)
 {
 	int orig_ctx = *ctx;
-	uint32_t opv;
-	uint32_t required_size = 0;
-	bool first = true;
+	const css_token *token;
+	css_error error = CSS_OK;
+	parserutils_buffer *buffer;
+	parserutils_error perror;
+	lwc_string *interned;
+	lwc_error lerror;
 
-	while (token != NULL) {
-		if (token->type == CSS_TOKEN_IDENT) {
-			/* IDENT+ */
-			required_size += first ? 0 : sizeof(opv);
+	perror = parserutils_buffer_create((parserutils_alloc) c->alloc, 
+			c->pw, &buffer);
+	if (perror != PARSERUTILS_OK)
+		return css_error_from_parserutils_error(perror);
 
-			if (reserved(c, token) == false) {
-				required_size += sizeof(lwc_string *);
+	/* We know this token exists, and is an IDENT */
+	token = parserutils_vector_iterate(vector, ctx);
 
-				/* Skip past [ IDENT* S* ]* */
-				while (token != NULL) {
-					token = parserutils_vector_peek(
-							vector, *ctx);
-					if (token != NULL &&
-						token->type !=
-							CSS_TOKEN_IDENT &&
-							token->type !=
-							CSS_TOKEN_S) {
-						break;
-					}
-
-					/* Idents must not be reserved */
-					if (token != NULL && token->type ==
-							CSS_TOKEN_IDENT &&
-							reserved(c, token)) {
-						*ctx = orig_ctx;
-						return CSS_INVALID;
-					}
-
-					token = parserutils_vector_iterate(
-						vector, ctx);
-				}
+	/* Consume all subsequent IDENT or S tokens */	
+	while (token != NULL && (token->type == CSS_TOKEN_IDENT ||
+			token->type == CSS_TOKEN_S)) {
+		if (token->type == CSS_TOKEN_IDENT) {
+			/* IDENT -- if reserved, reject style */
+			if (reserved(c, token)) {
+				error = CSS_INVALID;
+				goto cleanup;
 			}
-		} else if (token->type == CSS_TOKEN_STRING) {
-			/* STRING */
-			required_size += first ? 0 : sizeof(opv);
 
-			required_size += sizeof(lwc_string *);
+			perror = parserutils_buffer_append(buffer, 
+					(const uint8_t *) lwc_string_data(token->idata), 
+					lwc_string_length(token->idata));
 		} else {
-			/* Invalid token */
-			*ctx = orig_ctx;
-			return CSS_INVALID;
+			/* S */
+			perror = parserutils_buffer_append(buffer, 
+					(const uint8_t *) " ", 1);
 		}
 
-		consumeWhitespace(vector, ctx);
+		if (perror != PARSERUTILS_OK) {
+			error = css_error_from_parserutils_error(perror);
+			goto cleanup;
+		}
 
-		/* Look for a comma */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && tokenIsChar(token, ',')) {
-			/* Got one. Move past it */
-			parserutils_vector_iterate(vector, ctx);
+		token = parserutils_vector_iterate(vector, ctx);
+	}
 
-			consumeWhitespace(vector, ctx);
+	/* Rewind context by one step if we consumed an unacceptable token */
+	if (token != NULL)
+		*ctx = *ctx - 1;
 
-			/* Ensure that a valid token follows */
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-					token->type != CSS_TOKEN_STRING)) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
-		} else {
-			/* No comma, so we're done */
-			break;
-		}
+	/* Strip trailing whitespace */
+	while (buffer->length > 0 && buffer->data[buffer->length - 1] == ' ')
+		buffer->length--;
 
-		/* Flag that this is no longer the first pass */
-		first = false;
-
-		/* Iterate for next chunk */
-		token = parserutils_vector_iterate(vector, ctx);
+	/* Intern the buffer contents */
+	lerror = lwc_intern_string((char *) buffer->data, buffer->length, &interned);
+	if (lerror != lwc_error_ok) {
+		error = css_error_from_lwc_error(lerror);
+		goto cleanup;
 	}
 
-	required_size += sizeof(opv);
+	*result = interned;
 
-	*size = required_size;
+cleanup:
+	parserutils_buffer_destroy(buffer);
 
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+
+	return error;
 }
 
 /**
@@ -2223,167 +1314,84 @@
  * \param c          Parsing context
  * \param vector     Vector of tokens to process
  * \param ctx        Pointer to vector iteration context
- * \param token      Pointer to current token
  * \param reserved   Callback to determine if an identifier is reserved
  * \param get_value  Callback to retrieve bytecode value for a token
- * \param bytecode   Pointer to pointer to bytecode buffer. Updated on exit.
+ * \param style      Pointer to output style
  * \return CSS_OK      on success,
  *         CSS_INVALID if the input is invalid
  *
- * \note The bytecode buffer must be at least comma_list_length() bytes long.
- *
  * Post condition: \a *ctx is updated with the next token to process
  *                 If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error comma_list_to_bytecode(css_language *c,
+css_error comma_list_to_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		const css_token *token,
 		bool (*reserved)(css_language *c, const css_token *ident),
-		uint16_t (*get_value)(css_language *c, const css_token *token),
-		uint8_t **bytecode)
+		css_code_t (*get_value)(css_language *c, const css_token *token, bool first),
+		css_style *result)
 {
 	int orig_ctx = *ctx;
-	uint8_t *ptr = *bytecode;
+	int prev_ctx = orig_ctx;
+	const css_token *token;
 	bool first = true;
-	uint32_t opv;
-	uint8_t *buf = NULL;
-	uint32_t buflen = 0;
 	css_error error = CSS_OK;
 
+	token = parserutils_vector_iterate(vector, ctx);
+	if (token == NULL) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
 	while (token != NULL) {
 		if (token->type == CSS_TOKEN_IDENT) {
-			lwc_string *tok_idata = token->idata;
-			lwc_string *name = tok_idata;
-			lwc_string *newname;
+			css_code_t value = get_value(c, token, first);
 
-			opv = get_value(c, token);
-
-			if (first == false) {
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
-
 			if (reserved(c, token) == false) {
-				uint32_t len = lwc_string_length(token->idata);
-				const css_token *temp_token = token;
-				int temp_ctx = *ctx;
-				lwc_error lerror;
-				uint8_t *p;
+				lwc_string *str = NULL;
+				uint32_t snumber;
 
-				/* Calculate required length of temp buffer */
-				while (temp_token != NULL) {
-					temp_token = parserutils_vector_peek(
-							vector, temp_ctx);
-					if (temp_token != NULL &&
-						temp_token->type !=
-						CSS_TOKEN_IDENT &&
-							temp_token->type !=
-							CSS_TOKEN_S) {
-						break;
-					}
+				*ctx = prev_ctx;
 
-					if (temp_token != NULL &&
-						temp_token->type ==
-							CSS_TOKEN_IDENT) {
-						len += lwc_string_length(
-							temp_token->idata);
-					} else if (temp_token != NULL) {
-						len += 1;
-					}
+				error = ident_list_to_string(c, vector, ctx,
+						reserved, &str);
+				if (error != CSS_OK)
+					goto cleanup;
 
-					temp_token = parserutils_vector_iterate(
-							vector, &temp_ctx);
-				}
+				error = css_stylesheet_string_add(c->sheet,
+						str, &snumber);
+				if (error != CSS_OK)
+					goto cleanup;
 
-				if (len > buflen) {
-					/* Allocate buffer */
-					uint8_t *b = c->alloc(buf, len, c->pw);
-					if (b == NULL) {
-						error = CSS_NOMEM;
-						goto cleanup;
-					}
-
-					buf = b;
-					buflen = len;
-				}
-
-				p = buf;
-
-				/* Populate buffer with string data */
-				memcpy(p, lwc_string_data(token->idata),
-					lwc_string_length(token->idata));
-				p += lwc_string_length(token->idata);
-
-				while (token != NULL) {
-					token = parserutils_vector_peek(
-							vector, *ctx);
-					if (token != NULL && token->type !=
-							CSS_TOKEN_IDENT &&
-							token->type !=
-							CSS_TOKEN_S) {
-						break;
-					}
-
-					if (token != NULL && token->type ==
-							CSS_TOKEN_IDENT) {
-						memcpy(p, lwc_string_data(
-								token->idata),
-							lwc_string_length(
-								token->idata));
-						p += lwc_string_length(
-								token->idata);
-					} else if (token != NULL) {
-						*p++ = ' ';
-					}
-
-					token = parserutils_vector_iterate(
-							vector, ctx);
-				}
-
-				/* Strip trailing whitespace */
-				while (p > buf && p[-1] == ' ')
-					p--;
-
-				/* Insert into hash, if it's different
-				 * from the name we already have */
-				lerror = lwc_intern_string(
-						(char *) buf, p - buf,
-						&newname);
-				if (lerror != lwc_error_ok) {
-					error = css_error_from_lwc_error(
-							lerror);
+				error = css_stylesheet_style_append(result, 
+						value);
+				if (error != CSS_OK)
 					goto cleanup;
-				}
 
-				if (newname == name) {
-					lwc_string_unref(newname);
-				}
-
-				name = newname;
-
-				/* Only ref 'name' again if the token owns it,
-				 * otherwise we already own the only ref to the
-				 * new name generated above.
-				 */
-				if (name == tok_idata) {
-					lwc_string_ref(name);
-				}
-
-				memcpy(ptr, &name, sizeof(name));
-				ptr += sizeof(name);
+				error = css_stylesheet_style_append(result,
+						snumber);
+				if (error != CSS_OK)
+					goto cleanup;
+			} else {
+				error = css_stylesheet_style_append(result,
+						value);
+				if (error != CSS_OK)
+					goto cleanup;
 			}
 		} else if (token->type == CSS_TOKEN_STRING) {
-			opv = get_value(c, token);
+			css_code_t value = get_value(c, token, first);
+			uint32_t snumber;
 
-			if (first == false) {
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
+			error = css_stylesheet_string_add(c->sheet, 
+					lwc_string_ref(token->idata), &snumber);
+			if (error != CSS_OK)
+				goto cleanup;
 
-			lwc_string_ref(token->idata);
+			error = css_stylesheet_style_append(result, value);
+			if (error != CSS_OK)
+				goto cleanup;
 
-			memcpy(ptr, &token->idata, sizeof(token->idata));
-			ptr += sizeof(token->idata);
+			error = css_stylesheet_style_append(result, snumber);
+			if (error != CSS_OK)
+				goto cleanup;
 		} else {
 			error = CSS_INVALID;
 			goto cleanup;
@@ -2409,15 +1417,12 @@
 
 		first = false;
 
+		prev_ctx = *ctx;
+
 		token = parserutils_vector_iterate(vector, ctx);
 	}
 
-	*bytecode = ptr;
-
 cleanup:
-	if (buf)
-		c->alloc(buf, 0, c->pw);
-
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/border_bottom.c
===================================================================
--- src/parse/properties/border_bottom.c	(revision 11378)
+++ src/parse/properties/border_bottom.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_border_bottom(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side(c, vector, ctx, BORDER_SIDE_BOTTOM, result);
+	return parse_border_side(c, vector, ctx, result, BORDER_SIDE_BOTTOM);
 }
Index: src/parse/properties/properties.h
===================================================================
--- src/parse/properties/properties.h	(revision 11378)
+++ src/parse/properties/properties.h	(working copy)
@@ -18,355 +18,355 @@
  */
 typedef css_error (*css_prop_handler)(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 
 extern const css_prop_handler property_handlers[LAST_PROP + 1 - FIRST_PROP];
 
 css_error parse_azimuth(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_background(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_background_attachment(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_background_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_background_image(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_background_position(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_background_repeat(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_bottom(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_bottom_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_bottom_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_bottom_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_color(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_collapse(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_left(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_left_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_left_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_left_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_right(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_right_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_right_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_right_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_spacing(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_top(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_border_top_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_top_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_top_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_border_width(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_bottom(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_caption_side(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_clear(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_clip(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_content(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_counter_increment(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_counter_reset(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_cue(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_cue_after(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_cue_before(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_cursor(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_direction(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_display(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_elevation(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_empty_cells(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_float(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_font(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_font_family(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_font_size(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_font_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_font_variant(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_font_weight(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_height(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_left(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_letter_spacing(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_line_height(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_list_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_list_style_image(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_list_style_position(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_list_style_type(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_margin(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_margin_bottom(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_margin_left(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_margin_right(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_margin_top(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_max_height(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_max_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_min_height(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_min_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_orphans(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_outline(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_outline_color(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_outline_style(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_outline_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_overflow(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_padding(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_padding_bottom(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_padding_left(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_padding_right(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_padding_top(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_page_break_after(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_page_break_before(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_page_break_inside(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_pause(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result);
+		css_style *result);
 css_error parse_pause_after(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_pause_before(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_pitch_range(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_pitch(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_play_during(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_position(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_quotes(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_richness(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_right(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_speak_header(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_speak_numeral(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_speak_punctuation(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_speak(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_speech_rate(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_stress(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_table_layout(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_text_align(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_text_decoration(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_text_indent(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_text_transform(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_top(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_unicode_bidi(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_vertical_align(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_visibility(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_voice_family(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_volume(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_white_space(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_widows(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_width(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_word_spacing(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 css_error parse_z_index(css_language *c,
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result);
+		css_style *result);
 
 #endif
 
Index: src/parse/properties/padding_right.c
===================================================================
--- src/parse/properties/padding_right.c	(revision 11378)
+++ src/parse/properties/padding_right.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * padding_right:CSS_PROP_PADDING_RIGHT WRAP:parse_padding_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse padding-right
+ * Parse padding_right
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_padding_right(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_padding_right(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_padding_side(c, vector, ctx, 
-			CSS_PROP_PADDING_RIGHT, result);
+	return parse_padding_side(c, vector, ctx, result, CSS_PROP_PADDING_RIGHT);
 }
Index: src/parse/properties/display.c
===================================================================
--- src/parse/properties/display.c	(revision 11378)
+++ src/parse/properties/display.c	(working copy)
@@ -29,14 +29,13 @@
  */
 css_error parse_display(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (inline, block, list-item, run-in, inline-block, table,
@@ -122,17 +121,10 @@
 		return CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_DISPLAY, flags, value);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_DISPLAY, flags, value);
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
Index: src/parse/properties/utils.h
===================================================================
--- src/parse/properties/utils.h	(revision 11378)
+++ src/parse/properties/utils.h	(working copy)
@@ -10,71 +10,181 @@
 
 #include "parse/language.h"
 
-css_error parse_pause_common(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-			     uint16_t op, css_style **result);
+static inline bool is_css_inherit(css_language *c, const css_token *token) 
+{
+	bool match;
+	return ((token->type == CSS_TOKEN_IDENT) &&
+		(lwc_string_caseless_isequal(
+			token->idata, c->strings[INHERIT],
+			&match) == lwc_error_ok && match));
+}
 
-css_error parse_list_style_type_value(css_language *c,
-		const css_token *token, uint16_t *value);
-css_error parse_content_list(css_language *c,
-		const parserutils_vector *vector, int *ctx,
-		uint16_t *value, uint8_t *buffer, uint32_t *buflen);
-css_error parse_counter_common(css_language *c,
-		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+enum border_side_e { BORDER_SIDE_TOP = 0, BORDER_SIDE_RIGHT = 1, BORDER_SIDE_BOTTOM = 2, BORDER_SIDE_LEFT = 3 };
 
-
-enum { BORDER_SIDE_TOP = 0, BORDER_SIDE_RIGHT = 1, BORDER_SIDE_BOTTOM = 2, BORDER_SIDE_LEFT = 3 };
-
+/**
+ * Parse border-{top,right,bottom,left} shorthand
+ *
+ * \param c	  Parsing context.
+ * \param vector  Vector of tokens to process.
+ * \param ctx	  Pointer to vector iteration context.
+ * \param result  Result style.
+ * \param side	  The side we're parsing for.
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_border_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint32_t side, css_style **result);
+		css_style *result, enum border_side_e side);
+
+/**
+ * Parse border-{top,right,bottom,left}-color
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \param op	  Opcode to parse for (encodes side)
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_border_side_color(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+		css_style *result, enum css_properties_e op);
+
+/**
+ * Parse border-{top,right,bottom,left}-style
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \param op	  Opcode to parse for (encodes side)
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_border_side_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+		css_style *result, enum css_properties_e op);
+
+
+/**
+ * Parse border-{top,right,bottom,left}-width
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \param op	  Opcode to parse for (encodes side)
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_border_side_width(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+		css_style *result, enum css_properties_e op);
 
-css_error parse_margin_side(css_language *c,
-		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
 
+/**
+ * Parse {top,right,bottom,left}
+ *
+ * \param c       Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx     Pointer to vector iteration context
+ * \param op      Opcode to parse for
+ * \param result  Pointer to location to receive resulting style
+ * \return CSS_OK on success,
+ *         CSS_NOMEM on memory exhaustion,
+ *         CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *                 If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+		css_style *result, enum css_properties_e op);
 
+
+/**
+ * Parse margin-{top,right,bottom,left}
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
+css_error parse_margin_side(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result, enum css_properties_e op);
+
+/**
+ * Parse padding-{top,right,bottom,left}
+ *
+ * \param c	  Parsing context
+ * \param vector  Vector of tokens to process
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  Pointer to location to receive resulting style
+ * \return CSS_OK on success,
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ *		   If the input is invalid, then \a *ctx remains unchanged.
+ */
 css_error parse_padding_side(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		uint16_t op, css_style **result);
+		css_style *result, enum css_properties_e op);
 
+
+
+
+
+
+
+css_error parse_list_style_type_value(css_language *c,
+		const css_token *token, uint16_t *value);
+
 css_error parse_colour_specifier(css_language *c,
 		const parserutils_vector *vector, int *ctx,
 		uint32_t *result);
+
 css_error parse_named_colour(css_language *c, lwc_string *data, 
 		uint32_t *result);
+
 css_error parse_hash_colour(lwc_string *data, uint32_t *result);
 
 css_error parse_unit_specifier(css_language *c,
 		const parserutils_vector *vector, int *ctx,
 		uint32_t default_unit,
 		css_fixed *length, uint32_t *unit);
+
 css_error parse_unit_keyword(const char *ptr, size_t len, 
 		css_unit *unit);
 
-css_error comma_list_length(css_language *c,
+css_error comma_list_to_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		const css_token *token, 
 		bool (*reserved)(css_language *c, const css_token *ident),
-		uint32_t *size);
-css_error comma_list_to_bytecode(css_language *c,
-		const parserutils_vector *vector, int *ctx,
-		const css_token *token, 
-		bool (*reserved)(css_language *c, const css_token *ident),
-		uint16_t (*get_value)(css_language *c, const css_token *token),
-		uint8_t **bytecode);
+		css_code_t (*get_value)(css_language *c, const css_token *token, bool first),
+		css_style *result);
 
 #endif
Index: src/parse/properties/font.c
===================================================================
--- src/parse/properties/font.c	(revision 11378)
+++ src/parse/properties/font.c	(working copy)
@@ -29,64 +29,106 @@
  */
 css_error parse_font(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
+	const css_token *token;
+	css_error error;
 	int orig_ctx = *ctx;
 	int prev_ctx;
-	const css_token *token;
-	css_style *style = NULL;
-	css_style *variant = NULL;
-	css_style *weight = NULL;
-	css_style *size = NULL;
-	css_style *line_height = NULL;
-	css_style *family = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
-	bool match;
+	bool style = true;
+	bool variant = true;
+	bool weight = true;
+	bool size = true;
+	bool line_height = true;
+	bool family = true;
+	css_style *style_style;
+	css_style *variant_style;
+	css_style *weight_style;
+	css_style *size_style;
+	css_style *line_height_style;
+	css_style *family_style;
 	int svw;
-	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_STYLE);
+		if (error != CSS_OK) 
+			return error;
 
-		error = css_stylesheet_style_create(c->sheet, 
-				6 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_VARIANT);
+		if (error != CSS_OK) 
+			return error;		
+
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_WEIGHT);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_SIZE);
+		if (error != CSS_OK) 
+			return error;
 
-		*(bytecode++) = buildOPV(CSS_PROP_FONT_STYLE, 
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_FONT_VARIANT,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_FONT_WEIGHT,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_FONT_SIZE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_LINE_HEIGHT,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_FONT_FAMILY,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_LINE_HEIGHT);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_FAMILY);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+
+	/* allocate styles */
+	error = css_stylesheet_style_create(c->sheet, &style_style);
+	if (error != CSS_OK) 
+		return error;
+
+	error = css_stylesheet_style_create(c->sheet, &variant_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(style_style, true);
+		return error;
 	}
 
+	error = css_stylesheet_style_create(c->sheet, &weight_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(style_style, true);
+		css_stylesheet_style_destroy(variant_style, true);
+		return error;
+	}
+
+	error = css_stylesheet_style_create(c->sheet, &size_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(style_style, true);
+		css_stylesheet_style_destroy(variant_style, true);
+		css_stylesheet_style_destroy(weight_style, true);
+		return error;
+	}
+
+	error = css_stylesheet_style_create(c->sheet, &line_height_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(style_style, true);
+		css_stylesheet_style_destroy(variant_style, true);
+		css_stylesheet_style_destroy(weight_style, true);
+		css_stylesheet_style_destroy(size_style, true);
+		return error;
+	}
+
+	error = css_stylesheet_style_create(c->sheet, &family_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(style_style, true);
+		css_stylesheet_style_destroy(variant_style, true);
+		css_stylesheet_style_destroy(weight_style, true);
+		css_stylesheet_style_destroy(size_style, true);
+		css_stylesheet_style_destroy(line_height_style, true);
+		return error;
+	}
+
+
 	/* Attempt to parse the optional style, variant, and weight */
 	for (svw = 0; svw < 3; svw++) {
 		prev_ctx = *ctx;
@@ -94,23 +136,23 @@
 
 		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
+		if ((token != NULL) && is_css_inherit(c, token)) {
 			error = CSS_INVALID;
-			goto cleanup;
+			goto parse_font_cleanup;
 		}
 
-		if (style == NULL && 
-				(error = parse_font_style(c, vector,
-				ctx, &style)) == CSS_OK) {
-		} else if (variant == NULL && 
-				(error = parse_font_variant(c, vector, ctx,
-				&variant)) == CSS_OK) {
-		} else if (weight == NULL && 
-				(error = parse_font_weight(c, vector, ctx,
-				&weight)) == CSS_OK) {
+		if ((style) && 
+		    (error = parse_font_style(c, vector,
+					ctx, style_style)) == CSS_OK) {
+			style = false;
+		} else if ((variant) && 
+			   (error = parse_font_variant(c, vector, ctx,
+					variant_style)) == CSS_OK) {
+			variant = false;
+		} else if ((weight) && 
+			   (error = parse_font_weight(c, vector, ctx,
+				weight_style)) == CSS_OK) {
+			weight = false;
 		}
 
 		if (error == CSS_OK) {
@@ -127,179 +169,126 @@
 
 	/* Ensure that we're not about to parse another inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
+	if ((token != NULL) && is_css_inherit(c, token)) {
 		error = CSS_INVALID;
-		goto cleanup;
+		goto parse_font_cleanup;
 	}
 
 	/* Now expect a font-size */
-	error = parse_font_size(c, vector, ctx, &size);
+	error = parse_font_size(c, vector, ctx, size_style);
 	if (error != CSS_OK)
-		goto cleanup;
+		goto parse_font_cleanup;
+	size = false;
 
 	consumeWhitespace(vector, ctx);
 
 	/* Potential line-height */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && tokenIsChar(token, '/')) {
+	if ((token != NULL) && tokenIsChar(token, '/')) {
 		parserutils_vector_iterate(vector, ctx);
 
 		consumeWhitespace(vector, ctx);
 
 		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
+		if ((token != NULL) && is_css_inherit(c, token)) {
 			error = CSS_INVALID;
-			goto cleanup;
+			goto parse_font_cleanup;
 		}
 
-		error = parse_line_height(c, vector, ctx, &line_height);
+		error = parse_line_height(c, vector, ctx, line_height_style);
 		if (error != CSS_OK)
-			goto cleanup;
+			goto parse_font_cleanup;
+
+		line_height = false;
 	}
 
 	consumeWhitespace(vector, ctx);
 
 	/* Ensure that we're not about to parse another inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
+	if ((token != NULL) && is_css_inherit(c, token)) {
 		error = CSS_INVALID;
-		goto cleanup;
+		goto parse_font_cleanup;
 	}
 
 	/* Now expect a font-family */
-	error = parse_font_family(c, vector, ctx, &family);
+	error = parse_font_family(c, vector, ctx, family_style);
 	if (error != CSS_OK)
-		goto cleanup;
+		goto parse_font_cleanup;
+	family = false;
 
 	/* Must have size and family */
-	assert(size != NULL);
-	assert(family != NULL);
+	assert(size != true);
+	assert(family != true);
 
-	/* Calculate the required size of the resultant style,
-	 * defaulting the unspecified properties to their initial values */
-	required_size = 0;
 
-	if (style)
-		required_size += style->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (variant)
-		required_size += variant->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (weight)
-		required_size += weight->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	required_size += size->length;
-
-	if (line_height)
-		required_size += line_height->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	required_size += family->length;
-
-	/* Create and populate it */
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
+	/* defaults */
 	if (style) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				style->bytecode, style->length);
-		required_size += style->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_FONT_STYLE,
-				0, FONT_STYLE_NORMAL);
-		required_size += sizeof(uint32_t);
+		error = css_stylesheet_style_appendOPV(style_style, 
+				CSS_PROP_FONT_STYLE, 0, 
+				FONT_STYLE_NORMAL);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 	}
 
 	if (variant) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				variant->bytecode, variant->length);
-		required_size += variant->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_FONT_VARIANT,
-				0, FONT_VARIANT_NORMAL);
-		required_size += sizeof(uint32_t);
+		error = css_stylesheet_style_appendOPV(variant_style, 
+				CSS_PROP_FONT_VARIANT, 0, 
+				FONT_VARIANT_NORMAL);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 	}
 
 	if (weight) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				weight->bytecode, weight->length);
-		required_size += weight->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_FONT_WEIGHT,
+		error = css_stylesheet_style_appendOPV(weight_style, 
+				CSS_PROP_FONT_WEIGHT,
 				0, FONT_WEIGHT_NORMAL);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 	}
 
-	memcpy(((uint8_t *) ret->bytecode) + required_size,
-			size->bytecode, size->length);
-	required_size += size->length;
-
 	if (line_height) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				line_height->bytecode, line_height->length);
-		required_size += line_height->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_LINE_HEIGHT,
+		error = css_stylesheet_style_appendOPV(line_height_style, 
+				CSS_PROP_LINE_HEIGHT,
 				0, LINE_HEIGHT_NORMAL);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 	}
 
-	memcpy(((uint8_t *) ret->bytecode) + required_size,
-			family->bytecode, family->length);
-	required_size += family->length;
+	/* merge final output */
+	error = css_stylesheet_merge_style(result, style_style);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 
-	assert(required_size == ret->length);
+	error = css_stylesheet_merge_style(result, variant_style);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
+	error = css_stylesheet_merge_style(result, weight_style);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 
-	/* Clean up after ourselves */
-cleanup:
-	if (style)
-		css_stylesheet_style_destroy(c->sheet, style, error == CSS_OK);
-	if (variant)
-		css_stylesheet_style_destroy(c->sheet, variant, error == CSS_OK);
-	if (weight)
-		css_stylesheet_style_destroy(c->sheet, weight, error == CSS_OK);
-	if (size)
-		css_stylesheet_style_destroy(c->sheet, size, error == CSS_OK);
-	if (line_height)
-		css_stylesheet_style_destroy(c->sheet, line_height, error == CSS_OK);
-	if (family)
-		css_stylesheet_style_destroy(c->sheet, family, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
+	error = css_stylesheet_merge_style(result, size_style);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
 
+	error = css_stylesheet_merge_style(result, line_height_style);
+		if (error != CSS_OK)
+			goto parse_font_cleanup;
+
+	error = css_stylesheet_merge_style(result, family_style);
+
+
+
+parse_font_cleanup:
+	css_stylesheet_style_destroy(style_style, true);
+	css_stylesheet_style_destroy(variant_style, true);
+	css_stylesheet_style_destroy(weight_style, true);
+	css_stylesheet_style_destroy(size_style, true);
+	css_stylesheet_style_destroy(line_height_style, true);
+	css_stylesheet_style_destroy(family_style, true);
+
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/padding.c
===================================================================
--- src/parse/properties/padding.c	(revision 11378)
+++ src/parse/properties/padding.c	(working copy)
@@ -29,92 +29,66 @@
  */
 css_error parse_padding(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t num_sides = 0;
-	uint32_t required_size;
-	bool match;
+	css_fixed side_length[4];
+	uint32_t side_unit[4];
+	uint32_t side_count = 0;
 	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			4 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_TOP);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_RIGHT);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_PADDING_TOP,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_PADDING_RIGHT,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_PADDING_BOTTOM,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_PADDING_LEFT,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_BOTTOM);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_LEFT);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
 	/* Attempt to parse up to 4 widths */
 	do {
 		prev_ctx = *ctx;
-		error = CSS_OK;
 
-		/* Ensure that we're not about to parse another inherit */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
+		if ((token != NULL) && is_css_inherit(c, token)) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
 		}
 
-		if (top == NULL &&
-				(error = parse_padding_side(c, vector, ctx, 
-				CSS_PROP_PADDING_TOP, &top)) == CSS_OK) {
-			num_sides = 1;
-		} else if (right == NULL &&
-				(error = parse_padding_side(c, vector, ctx, 
-				CSS_PROP_PADDING_RIGHT, &right)) == CSS_OK) {
-			num_sides = 2;
-		} else if (bottom == NULL &&
-				(error = parse_padding_side(c, vector, ctx, 
-				CSS_PROP_PADDING_BOTTOM, &bottom)) == CSS_OK) {
-			num_sides = 3;
-		} else if (left == NULL &&
-				(error = parse_padding_side(c, vector, ctx, 
-				CSS_PROP_PADDING_LEFT, &left)) == CSS_OK) {
-			num_sides = 4;
-		}
-
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &side_length[side_count], &side_unit[side_count]);
 		if (error == CSS_OK) {
+			if (side_unit[side_count] & UNIT_ANGLE ||
+			    side_unit[side_count] & UNIT_TIME ||
+			    side_unit[side_count] & UNIT_FREQ) {
+				*ctx = orig_ctx;
+				return CSS_INVALID;
+			}
+		
+			if (side_length[side_count] < 0) {
+				*ctx = orig_ctx;
+				return CSS_INVALID;
+			}
+
+			side_count++;
+
 			consumeWhitespace(vector, ctx);
 
 			token = parserutils_vector_peek(vector, *ctx);
@@ -122,140 +96,50 @@
 			/* Forcibly cause loop to exit */
 			token = NULL;
 		}
-	} while (*ctx != prev_ctx && token != NULL);
+	} while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
 
-	if (num_sides == 0) {
+#define SIDE_APPEND(OP,NUM)							\
+	error = css_stylesheet_style_appendOPV(result, (OP), 0, PADDING_SET);	\
+	if (error != CSS_OK)							\
+		break;								\
+	error = css_stylesheet_style_append(result, side_length[(NUM)]);	\
+	if (error != CSS_OK)							\
+		break;								\
+	error = css_stylesheet_style_append(result, side_unit[(NUM)]);		\
+	if (error != CSS_OK)							\
+		break;
+
+	switch (side_count) {
+	case 1:
+		SIDE_APPEND(CSS_PROP_PADDING_TOP, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_LEFT, 0);
+		break;
+	case 2:
+		SIDE_APPEND(CSS_PROP_PADDING_TOP, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_LEFT, 1);
+		break;
+	case 3:
+		SIDE_APPEND(CSS_PROP_PADDING_TOP, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 2);
+		SIDE_APPEND(CSS_PROP_PADDING_LEFT, 1);
+		break;
+	case 4:
+		SIDE_APPEND(CSS_PROP_PADDING_TOP, 0);
+		SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 2);
+		SIDE_APPEND(CSS_PROP_PADDING_LEFT, 3);
+		break;
+	default:
 		error = CSS_INVALID;
-		goto cleanup;
+		break;
 	}
 
-	/* Calculate size of resultant style */
-	if (num_sides == 1) {
-		required_size = 4 * top->length;
-	} else if (num_sides == 2) {
-		required_size = 2 * top->length + 2 * right->length;
-	} else if (num_sides == 3) {
-		required_size = top->length + 2 * right->length + 
-				bottom->length;
-	} else {
-		required_size = top->length + right->length +
-				bottom->length + left->length;
-	}
-
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
 	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_sides == 1) {
-		uint32_t *opv = ((uint32_t *) top->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_PADDING_RIGHT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_PADDING_BOTTOM, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_PADDING_LEFT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-	} else if (num_sides == 2) {
-		uint32_t *vopv = ((uint32_t *) top->bytecode);
-		uint32_t *hopv = ((uint32_t *) right->bytecode);
-		uint8_t vflags = getFlags(*vopv);
-		uint8_t hflags = getFlags(*hopv);
-		uint16_t vvalue = getValue(*vopv);
-		uint16_t hvalue = getValue(*hopv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		*vopv = buildOPV(CSS_PROP_PADDING_BOTTOM, vflags, vvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*hopv = buildOPV(CSS_PROP_PADDING_LEFT, hflags, hvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else if (num_sides == 3) {
-		uint32_t *opv = ((uint32_t *) right->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		*opv = buildOPV(CSS_PROP_PADDING_LEFT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				left->bytecode, left->length);
-		required_size += left->length;
-	}
-
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
-	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
Index: src/parse/properties/volume.c
===================================================================
--- src/parse/properties/volume.c	(revision 11378)
+++ src/parse/properties/volume.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * volume:CSS_PROP_VOLUME IDENT:( INHERIT: SILENT:0,VOLUME_SILENT X_SOFT:0,VOLUME_X_SOFT SOFT:0,VOLUME_SOFT MEDIUM:0,VOLUME_MEDIUM LOUD:0,VOLUME_LOUD X_LOUD:0,VOLUME_X_LOUD IDENT:) NUMBER:( false:VOLUME_NUMBER RANGE:num<0||num>F_100 NUMBER:) LENGTH_UNIT:( UNIT_PX:VOLUME_DIMENSION ALLOW:unit&UNIT_PCT RANGE:<0 LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -19,143 +24,98 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
- *	 CSS_NOMEM on memory exhaustion,
- *	 CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *		 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_volume(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_volume(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* number | percentage | IDENT(silent, x-soft, soft, medium, loud, 
-	 *			       x-loud, inherit)
-	 */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SILENT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_SILENT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_SOFT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_X_SOFT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SOFT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_SOFT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[MEDIUM],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_MEDIUM;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[LOUD],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_LOUD;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_LOUD],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_X_LOUD;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_VOLUME);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SILENT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_SILENT);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_SOFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_X_SOFT);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SOFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_SOFT);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MEDIUM], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_MEDIUM);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[LOUD], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_LOUD);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_LOUD], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0,VOLUME_X_LOUD);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
-		length = number_from_lwc_string(token->idata, false, &consumed);
+
+		num = number_from_lwc_string(token->idata, false, &consumed);
+		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Must be between 0 and 100 */
-		if (length < 0 || length > F_100) {
+		if (num<0||num>F_100) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		parserutils_vector_iterate(vector, ctx);
-		value = VOLUME_NUMBER;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0, VOLUME_NUMBER);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		/* Yes, really UNIT_PX -- percentages MUST have a % sign */
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if ((unit & UNIT_PCT) == false) {
+		if ((unit&UNIT_PCT) == false) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		/* Must be positive */
-		if (length < 0) {
+		if (length <0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = VOLUME_DIMENSION;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_VOLUME, 0, VOLUME_DIMENSION);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_VOLUME, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == VOLUME_NUMBER)
-		required_size += sizeof(length);
-	else if ((flags & FLAG_INHERIT) == false && value == VOLUME_DIMENSION)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && (value == VOLUME_NUMBER || 
-			value == VOLUME_DIMENSION))
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-	if ((flags & FLAG_INHERIT) == false && value == VOLUME_DIMENSION)
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/orphans.c
===================================================================
--- src/parse/properties/orphans.c	(revision 11378)
+++ src/parse/properties/orphans.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * orphans:CSS_PROP_ORPHANS IDENT:INHERIT NUMBER:( true:ORPHANS_SET RANGE:num<0 NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,83 +21,63 @@
 /**
  * Parse orphans
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_orphans(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_orphans(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* <integer> | IDENT (inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_ORPHANS);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, true, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Negative values are nonsensical */
-		if (num < 0) {
+		if (num<0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = ORPHANS_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_ORPHANS, 0, ORPHANS_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_ORPHANS, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == ORPHANS_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == ORPHANS_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/outline_color.c
===================================================================
--- src/parse/properties/outline_color.c	(revision 11378)
+++ src/parse/properties/outline_color.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * outline_color:CSS_PROP_OUTLINE_COLOR IDENT:( INHERIT: INVERT:0,OUTLINE_COLOR_INVERT IDENT:) COLOR:OUTLINE_COLOR_SET
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse outline-color
+ * Parse outline_color
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,68 +32,47 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_outline_color(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_outline_color(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t colour = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* colour | IDENT (invert, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INVERT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = OUTLINE_COLOR_INVERT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_OUTLINE_COLOR);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INVERT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_COLOR, 0,OUTLINE_COLOR_INVERT);
 	} else {
-		error = parse_colour_specifier(c, vector, ctx, &colour);
+		uint32_t color = 0;
+		*ctx = orig_ctx;
+
+		error = parse_colour_specifier(c, vector, ctx, &color);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		value = OUTLINE_COLOR_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_COLOR, 0, OUTLINE_COLOR_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_OUTLINE_COLOR, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == OUTLINE_COLOR_SET)
-		required_size += sizeof(colour);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_append(result, color);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == OUTLINE_COLOR_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&colour, sizeof(colour));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/right.c
===================================================================
--- src/parse/properties/right.c	(revision 11378)
+++ src/parse/properties/right.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_right(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_side(c, vector, ctx, CSS_PROP_RIGHT, result);
+	return parse_side(c, vector, ctx, result, CSS_PROP_RIGHT);
 }
Index: src/parse/properties/margin.c
===================================================================
--- src/parse/properties/margin.c	(revision 11378)
+++ src/parse/properties/margin.c	(working copy)
@@ -29,92 +29,73 @@
  */
 css_error parse_margin(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t num_sides = 0;
-	uint32_t required_size;
+	uint16_t side_val[4];
+	css_fixed side_length[4];
+	uint32_t side_unit[4];
+	uint32_t side_count = 0;
 	bool match;
 	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			4 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_MARGIN_TOP);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_MARGIN_RIGHT);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_MARGIN_TOP,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_MARGIN_RIGHT,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_MARGIN_BOTTOM,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_MARGIN_LEFT,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_MARGIN_BOTTOM);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_MARGIN_LEFT);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
 	/* Attempt to parse up to 4 widths */
 	do {
 		prev_ctx = *ctx;
-		error = CSS_OK;
 
-		/* Ensure that we're not about to parse another inherit */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
+		if ((token != NULL) && is_css_inherit(c, token)) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
 		}
 
-		if (top == NULL &&
-				(error = parse_margin_side(c, vector, ctx, 
-				CSS_PROP_MARGIN_TOP, &top)) == CSS_OK) {
-			num_sides = 1;
-		} else if (right == NULL &&
-				(error = parse_margin_side(c, vector, ctx, 
-				CSS_PROP_MARGIN_RIGHT, &right)) == CSS_OK) {
-			num_sides = 2;
-		} else if (bottom == NULL &&
-				(error = parse_margin_side(c, vector, ctx, 
-				CSS_PROP_MARGIN_BOTTOM, &bottom)) == CSS_OK) {
-			num_sides = 3;
-		} else if (left == NULL &&
-				(error = parse_margin_side(c, vector, ctx, 
-				CSS_PROP_MARGIN_LEFT, &left)) == CSS_OK) {
-			num_sides = 4;
+		if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			side_val[side_count] =  MARGIN_AUTO;
+			parserutils_vector_iterate(vector, ctx);
+			error = CSS_OK;
+		} else {
+			side_val[side_count] = MARGIN_SET;
+
+			error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &side_length[side_count], &side_unit[side_count]);
+			if (error == CSS_OK) {
+				if (side_unit[side_count] & UNIT_ANGLE||
+				    side_unit[side_count] & UNIT_TIME||
+				    side_unit[side_count] & UNIT_FREQ) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+			}
 		}
 
 		if (error == CSS_OK) {
+			side_count++;
+
 			consumeWhitespace(vector, ctx);
 
 			token = parserutils_vector_peek(vector, *ctx);
@@ -122,147 +103,54 @@
 			/* Forcibly cause loop to exit */
 			token = NULL;
 		}
-	} while (*ctx != prev_ctx && token != NULL);
+	} while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
 
-	if (num_sides == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
-	}
 
-	/* Calculate size of resultant style */
-	if (num_sides == 1) {
-		required_size = 4 * top->length;
-	} else if (num_sides == 2) {
-		required_size = 2 * top->length + 2 * right->length;
-	} else if (num_sides == 3) {
-		required_size = top->length + 2 * right->length + 
-				bottom->length;
-	} else {
-		required_size = top->length + right->length +
-				bottom->length + left->length;
+#define SIDE_APPEND(OP,NUM)								\
+	error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]);	\
+	if (error != CSS_OK)								\
+		break;									\
+	if (side_val[(NUM)] == MARGIN_SET) {						\
+		error = css_stylesheet_style_append(result, side_length[(NUM)]);	\
+		if (error != CSS_OK)							\
+			break;								\
+		error = css_stylesheet_style_append(result, side_unit[(NUM)]);		\
+		if (error != CSS_OK)							\
+			break;								\
 	}
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_sides == 1) {
-		uint32_t *opv = ((uint32_t *) top->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_MARGIN_RIGHT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_MARGIN_BOTTOM, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_MARGIN_LEFT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-	} else if (num_sides == 2) {
-		uint32_t *vopv = ((uint32_t *) top->bytecode);
-		uint32_t *hopv = ((uint32_t *) right->bytecode);
-		uint8_t vflags = getFlags(*vopv);
-		uint8_t hflags = getFlags(*hopv);
-		uint16_t vvalue = getValue(*vopv);
-		uint16_t hvalue = getValue(*hopv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		*vopv = buildOPV(CSS_PROP_MARGIN_BOTTOM, vflags, vvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*hopv = buildOPV(CSS_PROP_MARGIN_LEFT, hflags, hvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else if (num_sides == 3) {
-		uint32_t *opv = ((uint32_t *) right->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		*opv = buildOPV(CSS_PROP_MARGIN_LEFT, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				left->bytecode, left->length);
-		required_size += left->length;
+	switch (side_count) {
+	case 1:
+		SIDE_APPEND(CSS_PROP_MARGIN_TOP, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_RIGHT, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_BOTTOM, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_LEFT, 0);
+		break;
+	case 2:
+		SIDE_APPEND(CSS_PROP_MARGIN_TOP, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_MARGIN_BOTTOM, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_LEFT, 1);
+		break;
+	case 3:
+		SIDE_APPEND(CSS_PROP_MARGIN_TOP, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_MARGIN_BOTTOM, 2);
+		SIDE_APPEND(CSS_PROP_MARGIN_LEFT, 1);
+		break;
+	case 4:
+		SIDE_APPEND(CSS_PROP_MARGIN_TOP, 0);
+		SIDE_APPEND(CSS_PROP_MARGIN_RIGHT, 1);
+		SIDE_APPEND(CSS_PROP_MARGIN_BOTTOM, 2);
+		SIDE_APPEND(CSS_PROP_MARGIN_LEFT, 3);
+		break;
+	default:
+		error = CSS_INVALID;
 	}
 
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
 }
 
-
-
-
-
-
Index: src/parse/properties/font_weight.c
===================================================================
--- src/parse/properties/font_weight.c	(revision 11378)
+++ src/parse/properties/font_weight.c	(working copy)
@@ -29,14 +29,13 @@
  */
 css_error parse_font_weight(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* NUMBER (100, 200, 300, 400, 500, 600, 700, 800, 900) | 
@@ -95,17 +94,13 @@
 		return CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_FONT_WEIGHT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	error = css_stylesheet_style_appendOPV(result,
+					       CSS_PROP_FONT_WEIGHT,
+					       flags,
+					       value);
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
+	
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/background.c
===================================================================
--- src/parse/properties/background.c	(revision 11378)
+++ src/parse/properties/background.c	(working copy)
@@ -29,85 +29,121 @@
  */
 css_error parse_background(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *attachment = NULL;
-	css_style *color = NULL;
-	css_style *image = NULL;
-	css_style *position = NULL;
-	css_style *repeat = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
-	bool match;
-	css_error error;
+	css_error error = CSS_OK;
+	bool attachment = true;
+	bool color = true;
+	bool image = true;
+	bool position = true;
+	bool repeat = true;
+	css_style * attachment_style;
+	css_style * color_style;
+	css_style * image_style;
+	css_style * position_style;
+	css_style * repeat_style;
 
+
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_ATTACHMENT);
+		if (error != CSS_OK) 
+			return error;
 
-		error = css_stylesheet_style_create(c->sheet, 
-				5 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_COLOR);
+		if (error != CSS_OK) 
+			return error;		
+
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_IMAGE);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_POSITION);
+		if (error != CSS_OK) 
+			return error;
 
-		*(bytecode++) = buildOPV(CSS_PROP_BACKGROUND_ATTACHMENT, 
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BACKGROUND_COLOR,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BACKGROUND_IMAGE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BACKGROUND_POSITION,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BACKGROUND_REPEAT,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_REPEAT);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		parserutils_vector_iterate(vector, ctx);
+		return error;
+	} 
 
-		*result = ret;
+	/* allocate styles */
+	error = css_stylesheet_style_create(c->sheet, &attachment_style);
+	if (error != CSS_OK) 
+		return error;
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+	error = css_stylesheet_style_create(c->sheet, &color_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(attachment_style, true);
+		return error;
 	}
 
+	error = css_stylesheet_style_create(c->sheet, &image_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(attachment_style, true);
+		css_stylesheet_style_destroy(color_style, true);
+		return error;
+	}
+
+	error = css_stylesheet_style_create(c->sheet, &position_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(attachment_style, true);
+		css_stylesheet_style_destroy(color_style, true);
+		css_stylesheet_style_destroy(image_style, true);
+		return error;
+	}
+
+	error = css_stylesheet_style_create(c->sheet, &repeat_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(attachment_style, true);
+		css_stylesheet_style_destroy(color_style, true);
+		css_stylesheet_style_destroy(image_style, true);
+		css_stylesheet_style_destroy(position_style, true);
+		return error;
+	}
+
 	/* Attempt to parse the various longhand properties */
 	do {
 		prev_ctx = *ctx;
 		error = CSS_OK;
 
+		if (is_css_inherit(c, token)) {
+			error = CSS_INVALID;
+			goto parse_background_cleanup;
+		}
+
 		/* Try each property parser in turn, but only if we
 		 * haven't already got a value for this property.
-		 * To achieve this, we end up with a bunch of empty
-		 * if/else statements. Perhaps there's a clearer way 
-		 * of expressing this. */
-		if (attachment == NULL && 
-				(error = parse_background_attachment(c, vector,
-				ctx, &attachment)) == CSS_OK) {
-		} else if (color == NULL && 
-				(error = parse_background_color(c, vector, ctx,
-				&color)) == CSS_OK) {
-		} else if (image == NULL && 
-				(error = parse_background_image(c, vector, ctx,
-				&image)) == CSS_OK) {
-		} else if (position == NULL &&
-				(error = parse_background_position(c, vector, 
-				ctx, &position)) == CSS_OK) {
-		} else if (repeat == NULL &&
-				(error = parse_background_repeat(c, vector, 
-				ctx, &repeat)) == CSS_OK) {
+		 */
+		if ((attachment) && 
+		    (error = parse_background_attachment(c, vector, ctx, 
+					    attachment_style)) == CSS_OK) {
+			attachment = false;
+		} else if ((color) && 
+			   (error = parse_background_color(c, vector, ctx,
+					    color_style)) == CSS_OK) {
+			color = false;
+		} else if ((image) && 
+			   (error = parse_background_image(c, vector, ctx,
+					    image_style)) == CSS_OK) {
+			image = false;
+		} else if ((position) &&
+			   (error = parse_background_position(c, vector, ctx, 
+					position_style)) == CSS_OK) {
+			position = false;
+		} else if ((repeat) &&
+			   (error = parse_background_repeat(c, vector, ctx, 
+					repeat_style)) == CSS_OK) {
+			repeat = false;
 		}
 
 		if (error == CSS_OK) {
@@ -120,129 +156,78 @@
 		}
 	} while (*ctx != prev_ctx && token != NULL);
 
-	/* Calculate the required size of the resultant style,
-	 * defaulting the unspecified properties to their initial values */
-	required_size = 0;
-
-	if (attachment)
-		required_size += attachment->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (color)
-		required_size += color->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (image)
-		required_size += image->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (position)
-		required_size += position->length;
-	else
-		required_size += sizeof(uint32_t); /* Use top left, not 0% 0% */
-
-	if (repeat)
-		required_size += repeat->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	/* Create and populate it */
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
 	if (attachment) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				attachment->bytecode, attachment->length);
-		required_size += attachment->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BACKGROUND_ATTACHMENT,
-				0, BACKGROUND_ATTACHMENT_SCROLL);
-		required_size += sizeof(uint32_t);
+		error = css_stylesheet_style_appendOPV(attachment_style, 
+				CSS_PROP_BACKGROUND_ATTACHMENT, 0, 
+				BACKGROUND_ATTACHMENT_SCROLL);
+		if (error != CSS_OK)
+			goto parse_background_cleanup;
 	}
 
 	if (color) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				color->bytecode, color->length);
-		required_size += color->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BACKGROUND_COLOR,
-				0, BACKGROUND_COLOR_TRANSPARENT);
-		required_size += sizeof(uint32_t);
+		error = css_stylesheet_style_appendOPV(color_style, 
+				CSS_PROP_BACKGROUND_COLOR, 0, 
+				BACKGROUND_COLOR_TRANSPARENT);
+		if (error != CSS_OK)
+			goto parse_background_cleanup;
 	}
 
 	if (image) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				image->bytecode, image->length);
-		required_size += image->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BACKGROUND_IMAGE,
+		error = css_stylesheet_style_appendOPV(image_style, 
+				CSS_PROP_BACKGROUND_IMAGE,
 				0, BACKGROUND_IMAGE_NONE);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_background_cleanup;
 	}
 
 	if (position) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				position->bytecode, position->length);
-		required_size += position->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BACKGROUND_POSITION,
+		error = css_stylesheet_style_appendOPV(position_style,
+				CSS_PROP_BACKGROUND_POSITION,
 				0, BACKGROUND_POSITION_HORZ_LEFT |
 				BACKGROUND_POSITION_VERT_TOP);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_background_cleanup;
 	}
 
 	if (repeat) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				repeat->bytecode, repeat->length);
-		required_size += repeat->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_BACKGROUND_REPEAT,
+		error = css_stylesheet_style_appendOPV(repeat_style, 
+				CSS_PROP_BACKGROUND_REPEAT,
 				0, BACKGROUND_REPEAT_REPEAT);
-		required_size += sizeof(uint32_t);
+		if (error != CSS_OK)
+			goto parse_background_cleanup;
 	}
 
-	assert(required_size == ret->length);
+	error = css_stylesheet_merge_style(result, attachment_style);
+	if (error != CSS_OK)
+		goto parse_background_cleanup;
 
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
+	error = css_stylesheet_merge_style(result, color_style);
+	if (error != CSS_OK)
+		goto parse_background_cleanup;
 
-	/* Clean up after ourselves */
-cleanup:
-	if (attachment)
-		css_stylesheet_style_destroy(c->sheet, attachment, error == CSS_OK);
-	if (color)
-		css_stylesheet_style_destroy(c->sheet, color, error == CSS_OK);
-	if (image)
-		css_stylesheet_style_destroy(c->sheet, image, error == CSS_OK);
-	if (position)
-		css_stylesheet_style_destroy(c->sheet, position, error == CSS_OK);
-	if (repeat)
-		css_stylesheet_style_destroy(c->sheet, repeat, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
+	error = css_stylesheet_merge_style(result, image_style);
+	if (error != CSS_OK)
+		goto parse_background_cleanup;
 
+	error = css_stylesheet_merge_style(result, position_style);
 	if (error != CSS_OK)
+		goto parse_background_cleanup;
+
+	error = css_stylesheet_merge_style(result, repeat_style);
+
+parse_background_cleanup:
+	css_stylesheet_style_destroy(attachment_style, true);
+	css_stylesheet_style_destroy(color_style, true);
+	css_stylesheet_style_destroy(image_style, true);
+	css_stylesheet_style_destroy(position_style, true);
+	css_stylesheet_style_destroy(repeat_style, true);
+
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
+
+
 }
 
 
Index: src/parse/properties/empty_cells.c
===================================================================
--- src/parse/properties/empty_cells.c	(revision 11378)
+++ src/parse/properties/empty_cells.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_empty_cells(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (show, hide, inherit) */
@@ -49,31 +46,30 @@
 	if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_EMPTY_CELLS,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[SHOW],
 			&match) == lwc_error_ok && match)) {
-		value = EMPTY_CELLS_SHOW;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_EMPTY_CELLS,
+						       0,
+						       EMPTY_CELLS_SHOW);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[HIDE],
 			&match) == lwc_error_ok && match)) {
-		value = EMPTY_CELLS_HIDE;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_EMPTY_CELLS,
+						       0,
+						       EMPTY_CELLS_HIDE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_EMPTY_CELLS, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+		
+	return error;
 }
Index: src/parse/properties/quotes.c
===================================================================
--- src/parse/properties/quotes.c	(revision 11378)
+++ src/parse/properties/quotes.c	(working copy)
@@ -27,145 +27,83 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_quotes(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_quotes(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
 	bool match;
 
-	/* [ STRING STRING ]+ | IDENT(none,inherit) */ 
-
-	/* Pass 1: validate input and calculate bytecode size */
-	token = parserutils_vector_iterate(vector, &temp_ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_STRING)) {
+	/* [ STRING STRING ]+ | IDENT(none,inherit) */
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) ||
+	    ((token->type != CSS_TOKEN_IDENT) &&
+	     (token->type != CSS_TOKEN_STRING))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT) {
-		if ((lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
+	if ((token->type == CSS_TOKEN_IDENT) &&
+	    (lwc_string_caseless_isequal(token->idata,
+			c->strings[INHERIT],
+			&match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_QUOTES);
+	} else if ((token->type == CSS_TOKEN_IDENT) &&
+		   (lwc_string_caseless_isequal(token->idata,
+				c->strings[NONE],
 				&match) == lwc_error_ok && match)) {
-			flags = FLAG_INHERIT;
-		} else if ((lwc_string_caseless_isequal(
-				token->idata, c->strings[NONE],
-				&match) == lwc_error_ok && match)) {
-			value = QUOTES_NONE;
-		} else {
-			*ctx = orig_ctx;
-			return CSS_INVALID;
-		}
-	} else {
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_QUOTES, 0, QUOTES_NONE);
+	} else if (token->type == CSS_TOKEN_STRING) {
 		bool first = true;
 
-		/* [ STRING STRING ] + */
-		while (token != NULL && token->type == CSS_TOKEN_STRING) {
-			lwc_string *open = token->idata;
-			lwc_string *close;
+/* Macro to output the value marker, awkward because we need to check
+ * first to determine how the value is constructed.
+ */
+#define CSS_FIRST_APPEND(CSSVAL) css_stylesheet_style_append(result, first?buildOPV(CSS_PROP_QUOTES, 0, CSSVAL):CSSVAL)
 
-			consumeWhitespace(vector, &temp_ctx);
+		/* [ STRING STRING ]+ */
+		while ((token != NULL) && (token->type == CSS_TOKEN_STRING)) {
+			uint32_t open_snumber;
+			uint32_t close_snumber;
 
-			token = parserutils_vector_peek(vector, temp_ctx);
-			if (token == NULL || token->type != CSS_TOKEN_STRING) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
+			error = css_stylesheet_string_add(c->sheet, 
+					lwc_string_ref(token->idata), 
+					&open_snumber);
+			if (error != CSS_OK) 
+				break;
 
-			close = token->idata;
+			consumeWhitespace(vector, ctx);
 
-			parserutils_vector_iterate(vector, &temp_ctx);
-
-			consumeWhitespace(vector, &temp_ctx);
-
-			if (first == false) {
-				required_size += sizeof(opv);
-			} else {
-				value = QUOTES_STRING;
+			token = parserutils_vector_iterate(vector, ctx);
+			if ((token == NULL) || 
+			    (token->type != CSS_TOKEN_STRING)) {
+				error = CSS_INVALID;
+				break;
 			}
-			required_size += sizeof(open) + sizeof(close);
 
-			first = false;
-
-			token = parserutils_vector_peek(vector, temp_ctx);
-			if (token == NULL || token->type != CSS_TOKEN_STRING)
+			error = css_stylesheet_string_add(c->sheet, 
+					lwc_string_ref(token->idata), 
+					&close_snumber);
+			if (error != CSS_OK) 
 				break;
-			token = parserutils_vector_iterate(vector, &temp_ctx);
-		}
 
-		/* Terminator */
-		required_size += sizeof(opv);
-	}
-
-	opv = buildOPV(CSS_PROP_QUOTES, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
-
-	/* Pass 2: construct bytecode */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_STRING)) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT) {
-		/* Nothing to do */
-	} else {
-		bool first = true;
-
-		/* [ STRING STRING ]+ */
-		while (token != NULL && token->type == CSS_TOKEN_STRING) {
-			lwc_string *open = token->idata;
-			lwc_string *close;
-
 			consumeWhitespace(vector, ctx);
 
-			token = parserutils_vector_peek(vector, *ctx);
-			if (token == NULL || token->type != CSS_TOKEN_STRING) {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
-			}
+			error = CSS_FIRST_APPEND(QUOTES_STRING);
+			if (error != CSS_OK) 
+				break;
 
-			close = token->idata;
+			error = css_stylesheet_style_append(result, open_snumber);
+			if (error != CSS_OK) 
+				break;
 
-			parserutils_vector_iterate(vector, ctx);
+			error = css_stylesheet_style_append(result, close_snumber);
+			if (error != CSS_OK) 
+				break;
 
-			consumeWhitespace(vector, ctx);
-
-			if (first == false) {
-				opv = QUOTES_STRING;
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
-			
-			lwc_string_ref(open);
-			memcpy(ptr, &open, sizeof(open));
-			ptr += sizeof(open);
-			
-			lwc_string_ref(close);
-			memcpy(ptr, &close, sizeof(close));
-			ptr += sizeof(close);
-
 			first = false;
 
 			token = parserutils_vector_peek(vector, *ctx);
@@ -174,11 +112,16 @@
 			token = parserutils_vector_iterate(vector, ctx);
 		}
 
-		/* Terminator */
-		opv = QUOTES_NONE;
-		memcpy(ptr, &opv, sizeof(opv));
-		ptr += sizeof(opv);
+		if (error == CSS_OK) {
+			/* AddTerminator */
+			error = css_stylesheet_style_append(result, QUOTES_NONE);
+		} 
+	} else {
+		error = CSS_INVALID;
 	}
 
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+
+	return error;
 }
Index: src/parse/properties/vertical_align.c
===================================================================
--- src/parse/properties/vertical_align.c	(revision 11378)
+++ src/parse/properties/vertical_align.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * vertical_align:CSS_PROP_VERTICAL_ALIGN IDENT:( INHERIT: BASELINE:0,VERTICAL_ALIGN_BASELINE SUB:0,VERTICAL_ALIGN_SUB SUPER:0,VERTICAL_ALIGN_SUPER TOP:0,VERTICAL_ALIGN_TOP TEXT_TOP:0,VERTICAL_ALIGN_TEXT_TOP MIDDLE:0,VERTICAL_ALIGN_MIDDLE BOTTOM:0,VERTICAL_ALIGN_BOTTOM TEXT_BOTTOM:0,VERTICAL_ALIGN_TEXT_BOTTOM IDENT:) LENGTH_UNIT:( UNIT_PX:VERTICAL_ALIGN_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,134 +19,80 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse vertical-align
+ * Parse vertical_align
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_vertical_align(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_vertical_align(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(baseline, sub, super, top, text-top,
-	 *                             middle, bottom, text-bottom, inherit)
-	 */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[BASELINE],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_BASELINE;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SUB],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_SUB;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SUPER],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_SUPER;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[TOP],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_TOP;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[TEXT_TOP],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_TEXT_TOP;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[MIDDLE],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_MIDDLE;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[BOTTOM],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_BOTTOM;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[TEXT_BOTTOM],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = VERTICAL_ALIGN_TEXT_BOTTOM;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_VERTICAL_ALIGN);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[BASELINE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_BASELINE);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SUB], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_SUB);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SUPER], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_SUPER);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[TOP], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_TOP);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[TEXT_TOP], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_TEXT_TOP);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MIDDLE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_MIDDLE);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[BOTTOM], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_BOTTOM);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[TEXT_BOTTOM], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0,VERTICAL_ALIGN_TEXT_BOTTOM);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = VERTICAL_ALIGN_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_VERTICAL_ALIGN, 0, VERTICAL_ALIGN_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_VERTICAL_ALIGN, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == VERTICAL_ALIGN_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == VERTICAL_ALIGN_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/border_left_color.c
===================================================================
--- src/parse/properties/border_left_color.c	(revision 11378)
+++ src/parse/properties/border_left_color.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_left_color(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_color(c, vector, ctx, 
-			CSS_PROP_BORDER_LEFT_COLOR, result);
+	return parse_border_side_color(c, vector, ctx, result, CSS_PROP_BORDER_LEFT_COLOR);
 }
Index: src/parse/properties/speak_numeral.c
===================================================================
--- src/parse/properties/speak_numeral.c	(revision 11378)
+++ src/parse/properties/speak_numeral.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * speak_numeral:CSS_PROP_SPEAK_NUMERAL IDENT:( INHERIT: DIGITS:0,SPEAK_NUMERAL_DIGITS CONTINUOUS:0,SPEAK_NUMERAL_CONTINUOUS IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse speak-numeral
+ * Parse speak_numeral
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,53 +32,34 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_speak_numeral(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_speak_numeral(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (digits, continuous, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[DIGITS],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_NUMERAL_DIGITS;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[CONTINUOUS],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_NUMERAL_CONTINUOUS;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_SPEAK_NUMERAL);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DIGITS], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_NUMERAL, 0,SPEAK_NUMERAL_DIGITS);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[CONTINUOUS], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_NUMERAL, 0,SPEAK_NUMERAL_CONTINUOUS);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_SPEAK_NUMERAL, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/border_right_style.c
===================================================================
--- src/parse/properties/border_right_style.c	(revision 11378)
+++ src/parse/properties/border_right_style.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_right_style(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_style(c, vector, ctx, 
-			CSS_PROP_BORDER_RIGHT_STYLE, result);
+	return parse_border_side_style(c, vector, ctx, result, CSS_PROP_BORDER_RIGHT_STYLE);
 }
Index: src/parse/properties/Makefile
===================================================================
--- src/parse/properties/Makefile	(revision 11378)
+++ src/parse/properties/Makefile	(working copy)
@@ -1,51 +1,62 @@
 # Sources
-DIR_SOURCES := utils.c properties.c \
-	azimuth.c \
+#	background.c 
+#	border.c 
+#	border_color.c 
+# 	border_style.c 
+# 	border_width.c 
+# 	content.c 
+# 	cue.c 
+#	cursor.c 
+# 	font.c 
+#	font_family.c 
+# 	list_style.c 
+# 	margin.c 
+# 	outline.c 
+#	padding.c 
+#	pause.c 
+# 	play_during.c 
+#	quotes.c 
+# 	text_decoration.c 
+# 	voice_family.c 
+
+DIR_SOURCES := 	azimuth.c \
 	background_attachment.c \
-	background.c \
 	background_color.c \
 	background_image.c \
 	background_position.c \
 	background_repeat.c \
+	border_spacing.c \
+	border_collapse.c \
 	border_bottom.c \
+	border_left.c \
+	border_right.c \
+	border_top.c \
 	border_bottom_color.c \
+	border_left_color.c \
+	border_right_color.c \
+	border_top_color.c \
 	border_bottom_style.c \
+	border_left_style.c \
+	border_right_style.c \
+	border_top_style.c \
 	border_bottom_width.c \
-	border.c \
-	border_collapse.c \
-	border_color.c \
-	border_left.c \
-	border_left_color.c \
-	border_left_style.c \
 	border_left_width.c \
-	border_right.c \
-	border_right_color.c \
-	border_right_style.c \
 	border_right_width.c \
-	border_spacing.c \
-	border_style.c \
-	border_top.c \
-	border_top_color.c \
-	border_top_style.c \
 	border_top_width.c \
-	border_width.c \
 	bottom.c \
 	caption_side.c \
 	clear.c \
 	clip.c \
 	color.c \
-	content.c \
-	conter_reset.c \
+	counter_reset.c \
 	counter_increment.c \
-	cue.c \
-	cursor.c \
+	cue_before.c \
+	cue_after.c \
 	direction.c \
 	display.c \
 	elevation.c \
 	empty_cells.c \
 	float.c \
-	font.c \
-	font_family.c \
 	font_size.c \
 	font_style.c \
 	font_variant.c \
@@ -54,12 +65,10 @@
 	left.c \
 	letter_spacing.c \
 	line_height.c \
-	list_style.c \
 	list_style_image.c \
 	list_style_position.c \
 	list_style_type.c \
 	margin_bottom.c \
-	margin.c \
 	margin_left.c \
 	margin_right.c \
 	margin_top.c \
@@ -68,13 +77,11 @@
 	min_height.c \
 	min_width.c \
 	orphans.c \
-	outline.c \
 	outline_color.c \
 	outline_style.c \
 	outline_width.c \
 	overflow.c \
 	padding_bottom.c \
-	padding.c \
 	padding_left.c \
 	padding_right.c \
 	padding_top.c \
@@ -83,12 +90,9 @@
 	page_break_inside.c \
 	pause_after.c \
 	pause_before.c \
-	pause.c \
 	pitch.c \
 	pitch_range.c \
-	play_during.c \
 	position.c \
-	quotes.c \
 	richness.c \
 	right.c \
 	speak.c \
@@ -99,19 +103,38 @@
 	stress.c \
 	table_layout.c \
 	text_align.c \
-	text_decoration.c \
 	text_indent.c \
 	text_transform.c \
 	top.c \
 	unicode_bidi.c \
 	vertical_align.c \
 	visibility.c \
-	voice_family.c \
 	volume.c \
 	white_space.c \
 	widows.c \
 	width.c \
 	word_spacing.c \
-	z_index.c 
+	z_index.c \
+	background.c \
+	border.c \
+	border_color.c \
+	border_style.c \
+	border_width.c \
+	content.c \
+	cue.c \
+	cursor.c \
+	font.c \
+	font_family.c \
+	list_style.c \
+	margin.c \
+	outline.c \
+	padding.c \
+	pause.c \
+	play_during.c \
+	quotes.c \
+	text_decoration.c \
+	voice_family.c \
+	properties.c \
+	utils.c 
 
 include build/makefiles/Makefile.subdir
Index: src/parse/properties/list_style_image.c
===================================================================
--- src/parse/properties/list_style_image.c	(revision 11378)
+++ src/parse/properties/list_style_image.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * list_style_image:CSS_PROP_LIST_STYLE_IMAGE IDENT:( INHERIT: NONE:0,LIST_STYLE_IMAGE_NONE IDENT:) URI:LIST_STYLE_IMAGE_URI
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse list-style-image
+ * Parse list_style_image
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,40 +32,30 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_list_style_image(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_list_style_image(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size;
 	bool match;
-	lwc_string *uri = NULL;
 
-	/* URI | IDENT (none, inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_URI))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = LIST_STYLE_IMAGE_NONE;
+	if ((token->type == CSS_TOKEN_IDENT) && 
+		(lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_LIST_STYLE_IMAGE);
+	} else if ((token->type == CSS_TOKEN_IDENT) && 
+		(lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_LIST_STYLE_IMAGE, 0,LIST_STYLE_IMAGE_NONE);
 	} else if (token->type == CSS_TOKEN_URI) {
-		value = LIST_STYLE_IMAGE_URI;
+		lwc_string *uri = NULL;
+		uint32_t uri_snumber;
 
 		error = c->sheet->resolve(c->sheet->resolve_pw,
 				c->sheet->url,
@@ -69,31 +64,30 @@
 			*ctx = orig_ctx;
 			return error;
 		}
-	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
 
-	opv = buildOPV(CSS_PROP_LIST_STYLE_IMAGE, flags, value);
+		error = css_stylesheet_string_add(c->sheet, uri, &uri_snumber);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == LIST_STYLE_IMAGE_URI)
-		required_size += sizeof(lwc_string *);
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_LIST_STYLE_IMAGE,
+				0,
+				LIST_STYLE_IMAGE_URI);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_append(result, uri_snumber);
+	} else {
+		error = CSS_INVALID;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == LIST_STYLE_IMAGE_URI) {
-		/* Don't ref URI -- we want to pass ownership to the bytecode */
-		memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
-				&uri, sizeof(lwc_string *));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/border_style.c
===================================================================
--- src/parse/properties/border_style.c	(revision 11378)
+++ src/parse/properties/border_style.c	(working copy)
@@ -29,236 +29,123 @@
  */
 css_error parse_border_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t num_sides = 0;
-	uint32_t required_size;
+	uint16_t side_val[4];
+	uint32_t side_count = 0;
 	bool match;
 	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			4 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_STYLE);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_RIGHT_STYLE);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_STYLE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_RIGHT_STYLE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_LEFT_STYLE,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_STYLE);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_STYLE);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
 	/* Attempt to parse up to 4 styles */
 	do {
 		prev_ctx = *ctx;
-		error = CSS_OK;
 
-		/* Ensure that we're not about to parse another inherit */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
+		if ((token != NULL) && is_css_inherit(c, token)) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
 		}
 
-		if (top == NULL &&
-				(error = parse_border_side_style(c, vector, 
-				ctx, CSS_PROP_BORDER_TOP_STYLE, &top)) == 
-				CSS_OK) {
-			num_sides = 1;
-		} else if (right == NULL &&
-				(error = parse_border_side_style(c, vector, 
-				ctx, CSS_PROP_BORDER_RIGHT_STYLE, &right)) == 
-				CSS_OK) {
-			num_sides = 2;
-		} else if (bottom == NULL &&
-				(error = parse_border_side_style(c, vector, 
-				ctx, CSS_PROP_BORDER_BOTTOM_STYLE, &bottom)) == 
-				CSS_OK) {
-			num_sides = 3;
-		} else if (left == NULL &&
-				(error = parse_border_side_style(c, vector, 
-				ctx, CSS_PROP_BORDER_LEFT_STYLE, &left)) == 
-				CSS_OK) {
-			num_sides = 4;
-		}
+		if (token->type != CSS_TOKEN_IDENT) 
+			break;
 
-		if (error == CSS_OK) {
-			consumeWhitespace(vector, ctx);
-
-			token = parserutils_vector_peek(vector, *ctx);
+		if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_NONE;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_HIDDEN;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DOTTED], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_DOTTED;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DASHED], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_DASHED;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[SOLID], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_SOLID;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_DOUBLE], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_DOUBLE;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[GROOVE], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_GROOVE;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIDGE], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_RIDGE;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[INSET], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_INSET;
+		} else if ((lwc_string_caseless_isequal(token->idata, c->strings[OUTSET], &match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_STYLE_OUTSET;
 		} else {
-			/* Forcibly cause loop to exit */
-			token = NULL;
+			break;
 		}
-	} while (*ctx != prev_ctx && token != NULL);
 
-	if (num_sides == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
-	}
+		side_count++;
+				
+		parserutils_vector_iterate(vector, ctx);
+		
+		consumeWhitespace(vector, ctx);
 
-	/* Calculate size of resultant style */
-	if (num_sides == 1) {
-		required_size = 4 * top->length;
-	} else if (num_sides == 2) {
-		required_size = 2 * top->length + 2 * right->length;
-	} else if (num_sides == 3) {
-		required_size = top->length + 2 * right->length + 
-				bottom->length;
-	} else {
-		required_size = top->length + right->length +
-				bottom->length + left->length;
-	}
+		token = parserutils_vector_peek(vector, *ctx);
+	} while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
 
-	required_size = 0;
+#define SIDE_APPEND(OP,NUM)								\
+	error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]);	\
+	if (error != CSS_OK)								\
+		break 
 
-	if (num_sides == 1) {
-		uint32_t *opv = ((uint32_t *) top->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
+	switch (side_count) {
+	case 1:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 0);
+		break;
+	case 2:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1);
+		break;
+	case 3:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1);
+		break;
+	case 4:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 3);
+		break;
 
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_RIGHT_STYLE, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-	} else if (num_sides == 2) {
-		uint32_t *vopv = ((uint32_t *) top->bytecode);
-		uint32_t *hopv = ((uint32_t *) right->bytecode);
-		uint8_t vflags = getFlags(*vopv);
-		uint8_t hflags = getFlags(*hopv);
-		uint16_t vvalue = getValue(*vopv);
-		uint16_t hvalue = getValue(*hopv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		*vopv = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE, vflags, vvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*hopv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, hflags, hvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else if (num_sides == 3) {
-		uint32_t *opv = ((uint32_t *) right->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				left->bytecode, left->length);
-		required_size += left->length;
+	default:
+		error = CSS_INVALID;
+		break;
 	}
 
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/border_top_width.c
===================================================================
--- src/parse/properties/border_top_width.c	(revision 11378)
+++ src/parse/properties/border_top_width.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_top_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_width(c, vector, ctx, 
-			CSS_PROP_BORDER_TOP_WIDTH, result);
+	return parse_border_side_width(c, vector, ctx, result, CSS_PROP_BORDER_TOP_WIDTH);
 }
Index: src/parse/properties/border_top.c
===================================================================
--- src/parse/properties/border_top.c	(revision 11378)
+++ src/parse/properties/border_top.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_border_top(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side(c, vector, ctx, BORDER_SIDE_TOP, result);
+	return parse_border_side(c, vector, ctx, result, BORDER_SIDE_TOP);
 }
Index: src/parse/properties/font_size.c
===================================================================
--- src/parse/properties/font_size.c	(revision 11378)
+++ src/parse/properties/font_size.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_font_size(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(xx-small, x-small, small, medium,
@@ -132,26 +130,22 @@
 		value = FONT_SIZE_DIMENSION;
 	}
 
-	opv = buildOPV(CSS_PROP_FONT_SIZE, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == FONT_SIZE_DIMENSION)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, 
+					       CSS_PROP_FONT_SIZE, 
+					       flags, 
+					       value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == FONT_SIZE_DIMENSION) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && 
+	    (value == FONT_SIZE_DIMENSION)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/margin_bottom.c
===================================================================
--- src/parse/properties/margin_bottom.c	(revision 11378)
+++ src/parse/properties/margin_bottom.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * margin_bottom:CSS_PROP_MARGIN_BOTTOM WRAP:parse_margin_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse margin-bottom
+ * Parse margin_bottom
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_margin_bottom(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_margin_bottom(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_margin_side(c, vector, ctx, 
-			CSS_PROP_MARGIN_BOTTOM, result);
+	return parse_margin_side(c, vector, ctx, result, CSS_PROP_MARGIN_BOTTOM);
 }
Index: src/parse/properties/page_break_after.c
===================================================================
--- src/parse/properties/page_break_after.c	(revision 11378)
+++ src/parse/properties/page_break_after.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * page_break_after:CSS_PROP_PAGE_BREAK_AFTER IDENT:( INHERIT: AUTO:0,PAGE_BREAK_AFTER_AUTO ALWAYS:0,PAGE_BREAK_AFTER_ALWAYS AVOID:0,PAGE_BREAK_AFTER_AVOID LEFT:0,PAGE_BREAK_AFTER_LEFT RIGHT:0,PAGE_BREAK_AFTER_RIGHT IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,78 +19,53 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse page-break-after
+ * Parse page_break_after
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_page_break_after(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_page_break_after(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (auto, always, avoid, left, right, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_AFTER_AUTO;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ALWAYS],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_AFTER_ALWAYS;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AVOID],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_AFTER_AVOID;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LEFT],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_AFTER_LEFT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RIGHT],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_AFTER_RIGHT;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PAGE_BREAK_AFTER);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_AFTER, 0,PAGE_BREAK_AFTER_AUTO);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[ALWAYS], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_AFTER, 0,PAGE_BREAK_AFTER_ALWAYS);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AVOID], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_AFTER, 0,PAGE_BREAK_AFTER_AVOID);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LEFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_AFTER, 0,PAGE_BREAK_AFTER_LEFT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIGHT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_AFTER, 0,PAGE_BREAK_AFTER_RIGHT);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_PAGE_BREAK_AFTER, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/overflow.c
===================================================================
--- src/parse/properties/overflow.c	(revision 11378)
+++ src/parse/properties/overflow.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * overflow:CSS_PROP_OVERFLOW IDENT:( INHERIT: VISIBLE:0,OVERFLOW_VISIBLE HIDDEN:0,OVERFLOW_HIDDEN SCROLL:0,OVERFLOW_SCROLL AUTO:0,OVERFLOW_AUTO  IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,72 +21,49 @@
 /**
  * Parse overflow
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_overflow(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_overflow(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (visible, hidden, scroll, auto, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[VISIBLE],
-			&match) == lwc_error_ok && match)) {
-		value = OVERFLOW_VISIBLE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[HIDDEN],
-			&match) == lwc_error_ok && match)) {
-		value = OVERFLOW_HIDDEN;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[SCROLL],
-			&match) == lwc_error_ok && match)) {
-		value = OVERFLOW_SCROLL;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = OVERFLOW_AUTO;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_OVERFLOW);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[VISIBLE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OVERFLOW, 0,OVERFLOW_VISIBLE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OVERFLOW, 0,OVERFLOW_HIDDEN);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[SCROLL], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OVERFLOW, 0,OVERFLOW_SCROLL);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OVERFLOW, 0,OVERFLOW_AUTO);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_OVERFLOW, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/background_position.c
===================================================================
--- src/parse/properties/background_position.c	(revision 11378)
+++ src/parse/properties/background_position.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_background_position(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
-	uint32_t opv;
 	uint16_t value[2] = { 0 };
 	css_fixed length[2] = { 0 };
 	uint32_t unit[2] = { 0 };
-	uint32_t required_size;
 	bool match;
 
 	/* [length | percentage | IDENT(left, right, top, bottom, center)]{1,2}
@@ -185,38 +183,23 @@
 		}
 	}
 
-	opv = buildOPV(CSS_PROP_BACKGROUND_POSITION, flags, 
-			value[0] | value[1]);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false) { 
-		if (value[0] == BACKGROUND_POSITION_HORZ_SET)
-			required_size += sizeof(length[0]) + sizeof(unit[0]);
-		if (value[1] == BACKGROUND_POSITION_VERT_SET)
-			required_size += sizeof(length[1]) + sizeof(unit[1]);
-	}
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, 
+					       CSS_PROP_BACKGROUND_POSITION, 
+					       flags, 
+					       value[0] | value[1]);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
 	if ((flags & FLAG_INHERIT) == false) {
-		uint8_t *ptr = ((uint8_t *) (*result)->bytecode) + sizeof(opv);
 		if (value[0] == BACKGROUND_POSITION_HORZ_SET) {
-			memcpy(ptr, &length[0], sizeof(length[0]));
-			ptr += sizeof(length[0]);
-			memcpy(ptr, &unit[0], sizeof(unit[0]));
-			ptr += sizeof(unit[0]);
+			css_stylesheet_style_append(result, length[0]);
+			css_stylesheet_style_append(result, unit[0]);
 		}
 		if (value[1] == BACKGROUND_POSITION_VERT_SET) {
-			memcpy(ptr, &length[1], sizeof(length[1]));
-			ptr += sizeof(length[1]);
-			memcpy(ptr, &unit[1], sizeof(unit[1]));
+			css_stylesheet_style_append(result, length[1]);
+			css_stylesheet_style_append(result, unit[1]);
 		}
 	}
 
Index: src/parse/properties/voice_family.c
===================================================================
--- src/parse/properties/voice_family.c	(revision 11378)
+++ src/parse/properties/voice_family.c	(working copy)
@@ -42,7 +42,7 @@
  * \param token	 Token to consider
  * \return Bytecode value
  */
-static uint16_t voice_family_value(css_language *c, const css_token *token)
+static css_code_t voice_family_value(css_language *c, const css_token *token, bool first)
 {
 	uint16_t value;
 	bool match;
@@ -66,7 +66,7 @@
 		value = VOICE_FAMILY_STRING;
 	}
 
-	return value;
+	return first ? buildOPV(CSS_PROP_VOICE_FAMILY, 0, value) : value;
 }
 
 /**
@@ -85,17 +85,11 @@
  */
 css_error parse_voice_family(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
 	bool match;
 
 	/* [ IDENT+ | STRING ] [ ',' [ IDENT+ | STRING ] ]* | IDENT(inherit)
@@ -104,8 +98,7 @@
 	 * a single space
 	 */
 
-	/* Pass 1: validate input and calculate space */
-	token = parserutils_vector_iterate(vector, &temp_ctx);
+	token = parserutils_vector_iterate(vector, ctx);
 	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
 			token->type != CSS_TOKEN_STRING)) {
 		*ctx = orig_ctx;
@@ -116,67 +109,25 @@
 			(lwc_string_caseless_isequal(
 			token->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_VOICE_FAMILY);
 	} else {
-		uint32_t list_size;
+		*ctx = orig_ctx;
 
-		value = voice_family_value(c, token);
-
-		error = comma_list_length(c, vector, &temp_ctx, 
-				token, voice_family_reserved, &list_size);
+		error = comma_list_to_style(c, vector, ctx,
+				voice_family_reserved, voice_family_value,
+				result);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		required_size += list_size;
+		error = css_stylesheet_style_append(result, VOICE_FAMILY_END);
 	}
 
-	opv = buildOPV(CSS_PROP_VOICE_FAMILY, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
-
-	/* Pass 2: populate bytecode */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_STRING)) {
-		css_stylesheet_style_destroy(c->sheet, *result, true);
-		*result = NULL;
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		/* Nothing to do */
-	} else {
-		error = comma_list_to_bytecode(c, vector, ctx, token, 
-				voice_family_reserved, voice_family_value,
-				&ptr);
-		if (error != CSS_OK) {
-			css_stylesheet_style_destroy(c->sheet, *result, true);
-			*result = NULL;
-			*ctx = orig_ctx;
-			return error;
-		}
-
-		/* Write terminator */
-		opv = VOICE_FAMILY_END;
-		memcpy(ptr, &opv, sizeof(opv));
-		ptr += sizeof(opv);
-	}
-
 	return CSS_OK;
 }
Index: src/parse/properties/pitch.c
===================================================================
--- src/parse/properties/pitch.c	(revision 11378)
+++ src/parse/properties/pitch.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * pitch:CSS_PROP_PITCH IDENT:( INHERIT: X_LOW:0,PITCH_X_LOW LOW:0,PITCH_LOW MEDIUM:0,PITCH_MEDIUM HIGH:0,PITCH_HIGH X_HIGH:0,PITCH_X_HIGH IDENT:) LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW:UNIT_FREQ RANGE:<0 UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -19,7 +24,7 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,107 +32,65 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_pitch(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_pitch(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* frequency | IDENT(x-low, low, medium, high, x-high, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_LOW],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = PITCH_X_LOW;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[LOW],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = PITCH_LOW;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[MEDIUM],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = PITCH_MEDIUM;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[HIGH],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = PITCH_HIGH;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_HIGH],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = PITCH_X_HIGH;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PITCH);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_LOW], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0,PITCH_X_LOW);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[LOW], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0,PITCH_LOW);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MEDIUM], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0,PITCH_MEDIUM);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[HIGH], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0,PITCH_HIGH);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_HIGH], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0,PITCH_X_HIGH);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_HZ,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_HZ, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
-
 		if ((unit & UNIT_FREQ) == false) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		/* Negative values are invalid */
-		if (length < 0) {
+		if (length <0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = PITCH_FREQUENCY;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH, 0, PITCH_FREQUENCY);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_PITCH, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == PITCH_FREQUENCY)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == PITCH_FREQUENCY) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/height.c
===================================================================
--- src/parse/properties/height.c	(revision 11378)
+++ src/parse/properties/height.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_height(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(auto, inherit) */
@@ -83,26 +81,18 @@
 		value = HEIGHT_SET;
 	}
 
-	opv = buildOPV(CSS_PROP_HEIGHT, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == HEIGHT_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_HEIGHT, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == HEIGHT_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == HEIGHT_SET)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/border_right.c
===================================================================
--- src/parse/properties/border_right.c	(revision 11378)
+++ src/parse/properties/border_right.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_border_right(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side(c, vector, ctx, BORDER_SIDE_RIGHT, result);
+	return parse_border_side(c, vector, ctx, result, BORDER_SIDE_RIGHT);
 }
Index: src/parse/properties/content.c
===================================================================
--- src/parse/properties/content.c	(revision 11378)
+++ src/parse/properties/content.c	(working copy)
@@ -13,6 +13,7 @@
 #include "parse/properties/properties.h"
 #include "parse/properties/utils.h"
 
+
 /**
  * Parse content
  *
@@ -27,108 +28,398 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_content(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_content(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
 	bool match;
 
-	/* IDENT(normal, none, inherit) |
-	 * [
-	 *	IDENT(open-quote, close-quote, no-open-quote, no-close-quote) |
-	 *	STRING | URI |
-	 *	FUNCTION(attr) IDENT ')' |
-	 *	FUNCTION(counter) IDENT IDENT? ')' |
-	 *	FUNCTION(counters) IDENT STRING IDENT? ')'
-	 * ]+
-	 */
-
-	/* Pass 1: Calculate required size & validate input */
-	token = parserutils_vector_peek(vector, temp_ctx);
+	/* IDENT(normal, none, inherit) | [ ... ]+ */
+	token = parserutils_vector_iterate(vector, ctx);
 	if (token == NULL) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
-		parserutils_vector_iterate(vector, &temp_ctx);
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			 (lwc_string_caseless_isequal(
-			token->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		value = CONTENT_NORMAL;
-		parserutils_vector_iterate(vector, &temp_ctx);
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			 (lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = CONTENT_NONE;
-		parserutils_vector_iterate(vector, &temp_ctx);
+
+	if ((token->type == CSS_TOKEN_IDENT) &&
+	    (lwc_string_caseless_isequal(token->idata,
+					 c->strings[INHERIT],
+					 &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_CONTENT);
+	} else if ((token->type == CSS_TOKEN_IDENT) &&
+		   (lwc_string_caseless_isequal(token->idata,
+						c->strings[NORMAL],
+						&match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_CONTENT, 0, CONTENT_NORMAL);
+	} else if ((token->type == CSS_TOKEN_IDENT) &&
+		   (lwc_string_caseless_isequal(token->idata,
+						c->strings[NONE],
+						&match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_CONTENT, 0, CONTENT_NONE);
 	} else {
-		uint32_t len;
 
-		error = parse_content_list(c, vector, &temp_ctx, &value,
-				NULL, &len);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
+/* Macro to output the value marker, awkward because we need to check
+ * first to determine how the value is constructed.
+ */
+#define CSS_APPEND(CSSVAL) css_stylesheet_style_append(result, first?buildOPV(CSS_PROP_CONTENT, 0, CSSVAL):CSSVAL)
 
-		required_size += len;
-	}
+		bool first = true;
+		int prev_ctx = orig_ctx;
 
-	opv = buildOPV(CSS_PROP_CONTENT, flags, value);
+		/* [
+		 *   IDENT(open-quote, close-quote, no-open-quote,
+		 *         no-close-quote) |
+		 *   STRING |
+		 *   URI |
+		 *   FUNCTION(attr) IDENT ')' |
+		 *   FUNCTION(counter) IDENT IDENT? ')' |
+		 *   FUNCTION(counters) IDENT STRING IDENT? ')'
+		 * ]+
+		 */
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
+		while (token != NULL) {
+			if ((token->type == CSS_TOKEN_IDENT) &&
+			    (lwc_string_caseless_isequal(
+				    token->idata, c->strings[OPEN_QUOTE],
+				    &match) == lwc_error_ok && match)) {
 
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
+				error = CSS_APPEND(CONTENT_OPEN_QUOTE);
 
-	/* Pass 2: construct bytecode */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
+			} else if (token->type == CSS_TOKEN_IDENT &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[CLOSE_QUOTE],
+					   &match) == lwc_error_ok && match)) {
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match) ||
-			 (lwc_string_caseless_isequal(
-			token->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match) ||
-			 (lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match))) {
-		parserutils_vector_iterate(vector, ctx);
-	} else {
-		error = parse_content_list(c, vector, ctx, NULL, ptr, NULL);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
+				error = CSS_APPEND(CONTENT_CLOSE_QUOTE);
+			} else if (token->type == CSS_TOKEN_IDENT &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[NO_OPEN_QUOTE],
+					   &match) == lwc_error_ok && match)) {
+				error = CSS_APPEND(CONTENT_NO_OPEN_QUOTE);
+			} else if (token->type == CSS_TOKEN_IDENT &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[NO_CLOSE_QUOTE],
+					   &match) == lwc_error_ok && match)) {
+				error = CSS_APPEND(CONTENT_NO_CLOSE_QUOTE);
+			} else if (token->type == CSS_TOKEN_STRING) {
+				uint32_t snumber;
+
+				error = css_stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = CSS_APPEND(CONTENT_STRING);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, snumber);
+			} else if (token->type == CSS_TOKEN_URI) {
+				lwc_string *uri;
+				uint32_t uri_snumber;
+
+				error = c->sheet->resolve(c->sheet->resolve_pw,
+							  c->sheet->url,
+							  token->idata, 
+							  &uri);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_string_add(c->sheet, 
+								  uri, 
+								  &uri_snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = CSS_APPEND(CONTENT_URI);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, uri_snumber);
+			} else if (token->type == CSS_TOKEN_FUNCTION &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[ATTR],
+					   &match) == lwc_error_ok && match)) {
+				uint32_t snumber;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect IDENT */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || token->type != CSS_TOKEN_IDENT) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				error = css_stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = CSS_APPEND(CONTENT_ATTR);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, snumber);
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect ')' */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || tokenIsChar(token, ')') == false) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+			} else if (token->type == CSS_TOKEN_FUNCTION &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[COUNTER],
+					   &match) == lwc_error_ok && match)) {
+				lwc_string *name;
+				uint32_t snumber;
+				uint32_t opv;
+
+				opv = CONTENT_COUNTER;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect IDENT */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || token->type != CSS_TOKEN_IDENT) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				name = token->idata;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Possible ',' */
+				token = parserutils_vector_peek(vector, *ctx);
+				if (token == NULL ||
+				    (tokenIsChar(token, ',') == false &&
+				     tokenIsChar(token, ')') == false)) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				if (tokenIsChar(token, ',')) {
+					uint16_t v;
+
+					parserutils_vector_iterate(vector, ctx);
+
+					consumeWhitespace(vector, ctx);
+
+					/* Expect IDENT */
+					token = parserutils_vector_peek(vector, *ctx);
+					if (token == NULL || token->type !=
+					    CSS_TOKEN_IDENT) {
+						*ctx = orig_ctx;
+						return CSS_INVALID;
+					}
+
+					error = parse_list_style_type_value(c, token, &v);
+					if (error != CSS_OK) {
+						*ctx = orig_ctx;
+						return error;
+					}
+
+					opv |= v << CONTENT_COUNTER_STYLE_SHIFT;
+
+					parserutils_vector_iterate(vector, ctx);
+
+					consumeWhitespace(vector, ctx);
+				} else {
+					opv |= LIST_STYLE_TYPE_DECIMAL <<
+						CONTENT_COUNTER_STYLE_SHIFT;
+				}
+
+				/* Expect ')' */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || tokenIsChar(token,	')') == false) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+
+				error = css_stylesheet_string_add(c->sheet, lwc_string_ref(name), &snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = CSS_APPEND(opv);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, snumber);
+			} else if (token->type == CSS_TOKEN_FUNCTION &&
+				   (lwc_string_caseless_isequal(
+					   token->idata, c->strings[COUNTERS],
+					   &match) == lwc_error_ok && match)) {
+				lwc_string *name;
+				lwc_string *sep;
+				uint32_t name_snumber;
+				uint32_t sep_snumber;
+				uint32_t opv;
+
+				opv = CONTENT_COUNTERS;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect IDENT */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || token->type != CSS_TOKEN_IDENT) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				name = token->idata;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect ',' */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || tokenIsChar(token, ',') == false) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				consumeWhitespace(vector, ctx);
+
+				/* Expect STRING */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || token->type != CSS_TOKEN_STRING) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				sep = token->idata;
+
+				consumeWhitespace(vector, ctx);
+
+				/* Possible ',' */
+				token = parserutils_vector_peek(vector, *ctx);
+				if (token == NULL ||
+				    (tokenIsChar(token, ',') == false &&
+				     tokenIsChar(token, ')') == false)) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				if (tokenIsChar(token, ',')) {
+					uint16_t v;
+
+					parserutils_vector_iterate(vector, ctx);
+
+					consumeWhitespace(vector, ctx);
+
+					/* Expect IDENT */
+					token = parserutils_vector_peek(vector, *ctx);
+					if (token == NULL || token->type !=
+					    CSS_TOKEN_IDENT) {
+						*ctx = orig_ctx;
+						return CSS_INVALID;
+					}
+
+					error = parse_list_style_type_value(c,
+									    token, &v);
+					if (error != CSS_OK) {
+						*ctx = orig_ctx;
+						return error;
+					}
+
+					opv |= v << CONTENT_COUNTERS_STYLE_SHIFT;
+
+					parserutils_vector_iterate(vector, ctx);
+
+					consumeWhitespace(vector, ctx);
+				} else {
+					opv |= LIST_STYLE_TYPE_DECIMAL <<
+						CONTENT_COUNTERS_STYLE_SHIFT;
+				}
+
+				/* Expect ')' */
+				token = parserutils_vector_iterate(vector, ctx);
+				if (token == NULL || tokenIsChar(token, ')') == false) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+
+				error = css_stylesheet_string_add(c->sheet, lwc_string_ref(name), &name_snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_string_add(c->sheet, lwc_string_ref(sep), &sep_snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = CSS_APPEND(opv);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, name_snumber);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+
+				error = css_stylesheet_style_append(result, sep_snumber);
+			} else if (first) {
+				/* Invalid if this is the first iteration */
+				error = CSS_INVALID;
+			} else {
+				/* Give up, ensuring current token is reprocessed */
+				*ctx = prev_ctx;
+				error = CSS_OK;
+				break;
+			}
+
+			/* if there was an error bail */
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			first = false;
+
+			consumeWhitespace(vector, ctx);
+
+			prev_ctx = *ctx;
+			token = parserutils_vector_iterate(vector, ctx);
+		} /* while */
+
+		/* Write list terminator */
+		css_stylesheet_style_append(result, CONTENT_NORMAL);
 	}
 
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+
+	return error;
 }
+
Index: src/parse/properties/page_break_inside.c
===================================================================
--- src/parse/properties/page_break_inside.c	(revision 11378)
+++ src/parse/properties/page_break_inside.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * page_break_inside:CSS_PROP_PAGE_BREAK_INSIDE IDENT:( INHERIT: AUTO:0,PAGE_BREAK_INSIDE_AUTO AVOID:0,PAGE_BREAK_INSIDE_AVOID IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,66 +19,47 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse page-break-inside
+ * Parse page_break_inside
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_page_break_inside(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_page_break_inside(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (auto, avoid, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_INSIDE_AUTO;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AVOID],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_INSIDE_AVOID;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PAGE_BREAK_INSIDE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_INSIDE, 0,PAGE_BREAK_INSIDE_AUTO);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AVOID], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_INSIDE, 0,PAGE_BREAK_INSIDE_AVOID);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_PAGE_BREAK_INSIDE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/min_height.c
===================================================================
--- src/parse/properties/min_height.c	(revision 11378)
+++ src/parse/properties/min_height.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_min_height(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(inherit) */
@@ -77,26 +75,18 @@
 		value = MIN_HEIGHT_SET;
 	}
 
-	opv = buildOPV(CSS_PROP_MIN_HEIGHT, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == MIN_HEIGHT_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_MIN_HEIGHT, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == MIN_HEIGHT_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == MIN_HEIGHT_SET)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/widows.c
===================================================================
--- src/parse/properties/widows.c	(revision 11378)
+++ src/parse/properties/widows.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * widows:CSS_PROP_WIDOWS IDENT:INHERIT NUMBER:( true:WIDOWS_SET RANGE:num<0 NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,83 +21,63 @@
 /**
  * Parse widows
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_widows(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_widows(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* <integer> | IDENT (inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_WIDOWS);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, true, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Negative values are nonsensical */
-		if (num < 0) {
+		if (num<0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = WIDOWS_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_WIDOWS, 0, WIDOWS_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_WIDOWS, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == WIDOWS_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == WIDOWS_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/cue.c
===================================================================
--- src/parse/properties/cue.c	(revision 11378)
+++ src/parse/properties/cue.c	(working copy)
@@ -14,134 +14,6 @@
 #include "parse/properties/utils.h"
 
 /**
- * Common parser for cue-after and cue-before
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param op	  Opcode to parse for
- * \param result  Pointer to location to receive resulting style
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-static css_error parse_cue_common(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		uint16_t op, css_style **result)
-{
-	int orig_ctx = *ctx;
-	css_error error;
-	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size;
-	lwc_string *uri = NULL;
-	bool match;
-
-	/* URI | IDENT (none, inherit) */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = CUE_AFTER_NONE;
-	} else if (token->type == CSS_TOKEN_URI) {
-		value = CUE_AFTER_URI;
-
-		error = c->sheet->resolve(c->sheet->resolve_pw,
-				c->sheet->url,
-				token->idata, &uri);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
-	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	opv = buildOPV(op, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == CUE_AFTER_URI)
-		required_size += sizeof(lwc_string *);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == CUE_AFTER_URI) {
-		/* Don't ref URI -- we want to pass ownership to the bytecode */
-		memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
-				&uri, sizeof(lwc_string *));
-	}
-	
-	return CSS_OK;
-}
-
-/**
- * Parse cue-after
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-css_error parse_cue_after(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
-{
-	return parse_cue_common(c, vector, ctx, CSS_PROP_CUE_AFTER, result);
-}
-
-/**
- * Parse cue-before
- *
- * \param c	  Parsing context
- * \param vector  Vector of tokens to process
- * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
- * \return CSS_OK on success,
- *	   CSS_NOMEM on memory exhaustion,
- *	   CSS_INVALID if the input is not valid
- *
- * Post condition: \a *ctx is updated with the next token to process
- *		   If the input is invalid, then \a *ctx remains unchanged.
- */
-css_error parse_cue_before(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
-{
-	return parse_cue_common(c, vector, ctx, CSS_PROP_CUE_BEFORE, result);
-}
-
-/**
  * Parse cue shorthand
  *
  * \param c	  Parsing context
@@ -157,140 +29,56 @@
  */
 css_error parse_cue(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
-	const css_token *token;
-	css_style *before = NULL;
-	css_style *after = NULL;
-	css_style *ret = NULL;
-	int num_read = 0;
-	int prev_ctx;
-	uint32_t required_size;
-	bool match;
 	css_error error;
+	const css_token *first_token;
+	const css_token *token;
 
-	/* Deal with inherit */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
+	/* one or two tokens follow:
+	 *  if one emit for both BEFORE and AFTER
+	 *  if two first is before second is after
+	 *  tokens are either IDENT:none or URI
+	 */
 
-		error = css_stylesheet_style_create(c->sheet,
-				2 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
+	first_token = parserutils_vector_peek(vector, *ctx);
 
-		bytecode = (uint32_t *) ret->bytecode;
+	error = parse_cue_before(c, vector, ctx, result);
+	if (error == CSS_OK) {
+		/* first token parsed */
+		
+		consumeWhitespace(vector, ctx);
 
-		*(bytecode++) = buildOPV(CSS_PROP_CUE_BEFORE, FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_CUE_AFTER, FLAG_INHERIT, 0);
-
-		parserutils_vector_iterate(vector, ctx);
-
-		*result = ret;
-
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	/* Attempt to read 1 or 2 cues */
-	do {
-		prev_ctx = *ctx;
-		error = CSS_OK;
-
-		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
-		}
-
-		if (before == NULL && (error = parse_cue_before(c, vector, ctx, 
-				&before)) == CSS_OK) {
-			num_read = 1;
-		} else if (after == NULL &&
-				(error = parse_cue_after(c, vector, ctx, 
-				&after)) == CSS_OK) {
-			num_read = 2;
-		}
-
-		if (error == CSS_OK) {
-			consumeWhitespace(vector, ctx);
-
-			token = parserutils_vector_peek(vector, *ctx);
+		if (token == NULL)  {
+			/* no second token, re-parse the first */
+			*ctx = orig_ctx;
+			error = parse_cue_after(c, vector, ctx, result);
 		} else {
-			token = NULL;
+			/* second token - might be useful */
+			if (is_css_inherit(c, token)) {
+				/* another inherit which is bogus */
+				error = CSS_INVALID;
+			} else {
+				error = parse_cue_after(c, vector, ctx, result);
+				if (error == CSS_OK) { 
+					/* second token parsed */
+					if (is_css_inherit(c, first_token)) {
+						/* valid second token after inherit */
+						error = CSS_INVALID;
+					}
+				} else {
+					/* second token appears to be junk re-try with first */
+					*ctx = orig_ctx;
+					error = parse_cue_after(c, vector, ctx, result);
+				}
+			}
 		}
-	} while (*ctx != prev_ctx && token != NULL);
-
-	if (num_read == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
 	}
 
-	/* Calculate size of resultant style */
-	if (num_read == 1)
-		required_size = 2 * before->length;
-	else
-		required_size = before->length + after->length;
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
 	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_read == 1) {
-		uint32_t *opv = ((uint32_t *) before->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-
-		*opv = buildOPV(CSS_PROP_CUE_AFTER, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				after->bytecode, after->length);
-		required_size += after->length;
-	}
-
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (before)
-		css_stylesheet_style_destroy(c->sheet, before, error == CSS_OK);
-	if (after)
-		css_stylesheet_style_destroy(c->sheet, after, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
-	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
Index: src/parse/properties/cursor.c
===================================================================
--- src/parse/properties/cursor.c	(revision 11378)
+++ src/parse/properties/cursor.c	(working copy)
@@ -28,17 +28,11 @@
  */
 css_error parse_cursor(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
 	bool match;
 
 	/* [ (URI ',')* IDENT(auto, crosshair, default, pointer, move, e-resize,
@@ -46,224 +40,61 @@
 	 *              s-resize, w-resize, text, wait, help, progress) ] 
 	 * | IDENT(inherit) 
 	 */
-
-	/* Pass 1: validate input and calculate bytecode size */
-	token = parserutils_vector_iterate(vector, &temp_ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || 
+	    (token->type != CSS_TOKEN_IDENT &&
+	     token->type != CSS_TOKEN_URI)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) &&
+	    (lwc_string_caseless_isequal(token->idata,
+					 c->strings[INHERIT],
+					 &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_CURSOR);
 	} else {
 		bool first = true;
 
+/* Macro to output the value marker, awkward because we need to check
+ * first to determine how the value is constructed.
+ */
+#define CSS_APPEND(CSSVAL) css_stylesheet_style_append(result, first?buildOPV(CSS_PROP_CURSOR, 0, CSSVAL):CSSVAL)
+
+
 		/* URI* */
 		while (token != NULL && token->type == CSS_TOKEN_URI) {
-			lwc_string *uri = token->idata;
+			lwc_string *uri;
+			uint32_t uri_snumber;
 
-			if (first == false) {
-				required_size += sizeof(opv);
-			} else {
-				value = CURSOR_URI;
-			}
-			required_size += sizeof(uri);
-
-			consumeWhitespace(vector, &temp_ctx);
-
-			/* Expect ',' */
-			token = parserutils_vector_iterate(vector, &temp_ctx);
-			if (token == NULL || tokenIsChar(token, ',') == false) {
+			error = c->sheet->resolve(c->sheet->resolve_pw,
+					c->sheet->url,
+					token->idata, &uri);
+			if (error != CSS_OK) {
 				*ctx = orig_ctx;
-				return CSS_INVALID;
+				return error;
 			}
 
-			consumeWhitespace(vector, &temp_ctx);
-
-			/* Expect either URI or IDENT */
-			token = parserutils_vector_iterate(vector, &temp_ctx);
-			if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-					token->type != CSS_TOKEN_URI)) {
+			error = css_stylesheet_string_add(c->sheet, 
+							  uri, 
+							  &uri_snumber);
+			if (error != CSS_OK) {
 				*ctx = orig_ctx;
-				return CSS_INVALID;
+				return error;
 			}
 
-			first = false;
-		}
-
-		/* IDENT */
-		if (token != NULL && token->type == CSS_TOKEN_IDENT) {
-			if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[AUTO],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_AUTO;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[CROSSHAIR],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_CROSSHAIR;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[DEFAULT],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_DEFAULT;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[POINTER],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_POINTER;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[MOVE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_MOVE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[E_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_E_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[NE_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_NE_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[NW_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_NW_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[N_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_N_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[SE_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_SE_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[SW_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_SW_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[S_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_S_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[W_RESIZE],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_W_RESIZE;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[LIBCSS_TEXT],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_TEXT;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[WAIT],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_WAIT;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[HELP],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_HELP;
-				}
-			} else if ((lwc_string_caseless_isequal(
-					token->idata, c->strings[PROGRESS],
-					&match) == lwc_error_ok && match)) {
-				if (first) {
-					value = CURSOR_PROGRESS;
-				}
-			} else {
+			error = CSS_APPEND(CURSOR_URI);
+			if (error != CSS_OK) {
 				*ctx = orig_ctx;
-				return CSS_INVALID;
+				return error;
 			}
 
-			if (first == false) {
-				required_size += sizeof(opv);
-			}
-		}
-	}
-
-	opv = buildOPV(CSS_PROP_CURSOR, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
-
-	/* Pass 2: construct bytecode */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		/* Nothing to do */
-	} else {
-		bool first = true;
-
-		/* URI* */
-		while (token != NULL && token->type == CSS_TOKEN_URI) {
-			lwc_string *uri;
-
-			error = c->sheet->resolve(c->sheet->resolve_pw,
-					c->sheet->url,
-					token->idata, &uri);
+			error = css_stylesheet_style_append(result, uri_snumber);
 			if (error != CSS_OK) {
 				*ctx = orig_ctx;
 				return error;
 			}
 
-			if (first == false) {
-				opv = CURSOR_URI;
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
-                        
- 			/* Don't ref URI -- we want to pass ownership to the 
-			 * bytecode */
-			memcpy(ptr, &uri, sizeof(uri));
-			ptr += sizeof(uri);
-
 			consumeWhitespace(vector, ctx);
 
 			/* Expect ',' */
@@ -291,83 +122,81 @@
 			if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[AUTO],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_AUTO;
+				error=CSS_APPEND(CURSOR_AUTO);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[CROSSHAIR],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_CROSSHAIR;
+				error=CSS_APPEND(CURSOR_CROSSHAIR);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[DEFAULT],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_DEFAULT;
+				error=CSS_APPEND(CURSOR_DEFAULT);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[POINTER],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_POINTER;
+				error=CSS_APPEND(CURSOR_POINTER);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[MOVE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_MOVE;
+				error=CSS_APPEND(CURSOR_MOVE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[E_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_E_RESIZE;
+				error=CSS_APPEND(CURSOR_E_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[NE_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_NE_RESIZE;
+				error=CSS_APPEND(CURSOR_NE_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[NW_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_NW_RESIZE;
+				error=CSS_APPEND(CURSOR_NW_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[N_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_N_RESIZE;
+				error=CSS_APPEND(CURSOR_N_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[SE_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_SE_RESIZE;
+				error=CSS_APPEND(CURSOR_SE_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[SW_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_SW_RESIZE;
+				error=CSS_APPEND(CURSOR_SW_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[S_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_S_RESIZE;
+				error=CSS_APPEND(CURSOR_S_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[W_RESIZE],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_W_RESIZE;
+				error=CSS_APPEND(CURSOR_W_RESIZE);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[LIBCSS_TEXT],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_TEXT;
+				error=CSS_APPEND(CURSOR_TEXT);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[WAIT],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_WAIT;
+				error=CSS_APPEND(CURSOR_WAIT);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[HELP],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_HELP;
+				error=CSS_APPEND(CURSOR_HELP);
 			} else if ((lwc_string_caseless_isequal(
 					token->idata, c->strings[PROGRESS],
 					&match) == lwc_error_ok && match)) {
-				opv = CURSOR_PROGRESS;
+				error=CSS_APPEND(CURSOR_PROGRESS);
 			} else {
-				*ctx = orig_ctx;
-				return CSS_INVALID;
+				error =  CSS_INVALID;
 			}
-
-			if (first == false) {
-				memcpy(ptr, &opv, sizeof(opv));
-				ptr += sizeof(opv);
-			}
 		}
+
 	}
 
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+
+	return error;
 }
 
Index: src/parse/properties/richness.c
===================================================================
--- src/parse/properties/richness.c	(revision 11378)
+++ src/parse/properties/richness.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * richness:CSS_PROP_RICHNESS IDENT:INHERIT NUMBER:( false:RICHNESS_SET RANGE:num<0||num>F_100 NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -19,7 +24,7 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,72 +32,52 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_richness(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_richness(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* number | IDENT (inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_RICHNESS);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, false, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Must be between 0 and 100 */
-		if (num < 0 || num > F_100) {
+		if (num<0||num>F_100) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = RICHNESS_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_RICHNESS, 0, RICHNESS_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_RICHNESS, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == RICHNESS_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == RICHNESS_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/outline_width.c
===================================================================
--- src/parse/properties/outline_width.c	(revision 11378)
+++ src/parse/properties/outline_width.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * outline_width:CSS_PROP_OUTLINE_WIDTH WRAP:parse_border_side_width
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse outline-width
+ * Parse outline_width
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,11 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_outline_width(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_outline_width(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	/* Parse as border width */
-	return parse_border_side_width(c, vector, ctx, 
-			CSS_PROP_OUTLINE_WIDTH, result);
+	return parse_border_side_width(c, vector, ctx, result, CSS_PROP_OUTLINE_WIDTH);
 }
Index: src/parse/properties/color.c
===================================================================
--- src/parse/properties/color.c	(revision 11378)
+++ src/parse/properties/color.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * color:CSS_PROP_COLOR IDENT:INHERIT COLOR:COLOR_SET
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,73 +21,56 @@
 /**
  * Parse color
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_color(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_color(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t colour = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* colour | IDENT (inherit) */
-	token= parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_COLOR);
 	} else {
-		error = parse_colour_specifier(c, vector, ctx, &colour);
+		uint32_t color = 0;
+		*ctx = orig_ctx;
+
+		error = parse_colour_specifier(c, vector, ctx, &color);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		value = COLOR_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_COLOR, 0, COLOR_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_COLOR, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == COLOR_SET)
-		required_size += sizeof(colour);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_append(result, color);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == COLOR_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&colour, sizeof(colour));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/text_transform.c
===================================================================
--- src/parse/properties/text_transform.c	(revision 11378)
+++ src/parse/properties/text_transform.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * text_transform:CSS_PROP_TEXT_TRANSFORM IDENT:( INHERIT: CAPITALIZE:0,TEXT_TRANSFORM_CAPITALIZE UPPERCASE:0,TEXT_TRANSFORM_UPPERCASE LOWERCASE:0,TEXT_TRANSFORM_LOWERCASE NONE:0,TEXT_TRANSFORM_NONE IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,74 +19,51 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse text-transform
+ * Parse text_transform
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_text_transform(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_text_transform(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (capitalize, uppercase, lowercase, none, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[CAPITALIZE],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_TRANSFORM_CAPITALIZE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[UPPERCASE],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_TRANSFORM_UPPERCASE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LOWERCASE],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_TRANSFORM_LOWERCASE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_TRANSFORM_NONE;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_TEXT_TRANSFORM);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[CAPITALIZE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_TRANSFORM, 0,TEXT_TRANSFORM_CAPITALIZE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[UPPERCASE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_TRANSFORM, 0,TEXT_TRANSFORM_UPPERCASE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LOWERCASE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_TRANSFORM, 0,TEXT_TRANSFORM_LOWERCASE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_TRANSFORM, 0,TEXT_TRANSFORM_NONE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_TEXT_TRANSFORM, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/outline.c
===================================================================
--- src/parse/properties/outline.c	(revision 11378)
+++ src/parse/properties/outline.c	(working copy)
@@ -29,79 +29,84 @@
  */
 css_error parse_outline(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *color = NULL;
-	css_style *style = NULL;
-	css_style *width = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
-	bool match;
 	css_error error;
+	bool color = true;
+	bool style = true;
+	bool width = true;
+	css_style *color_style;
+	css_style *style_style;
+	css_style *width_style;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			3 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_OUTLINE_COLOR);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_OUTLINE_STYLE);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_OUTLINE_COLOR,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_OUTLINE_STYLE,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_OUTLINE_WIDTH,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_OUTLINE_WIDTH);
 
-		parserutils_vector_iterate(vector, ctx);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+	/* allocate styles */
+	error = css_stylesheet_style_create(c->sheet, &color_style);
+	if (error != CSS_OK) 
+		return error;
+
+	error = css_stylesheet_style_create(c->sheet, &style_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(color_style, true);
+		return error;
 	}
 
-	/* Attempt to parse individual properties */
+	error = css_stylesheet_style_create(c->sheet, &width_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(color_style, true);
+		css_stylesheet_style_destroy(style_style, true);
+		return error;
+	}
+
+	/* Attempt to parse the various longhand properties */
 	do {
 		prev_ctx = *ctx;
 		error = CSS_OK;
 
 		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
+		if (token != NULL && is_css_inherit(c, token)) {
 			error = CSS_INVALID;
-			goto cleanup;
+			goto parse_outline_cleanup;
 		}
 
-		if (color == NULL &&
-				(error = parse_outline_color(c, vector, 
-				ctx, &color)) == CSS_OK) {
-		} else if (style == NULL &&
-				(error = parse_outline_style(c, vector, 
-				ctx, &style)) == CSS_OK) {
-		} else if (width == NULL &&
-				(error = parse_outline_width(c, vector, 
-				ctx, &width)) == CSS_OK) {
-		}
+		if ((color) && 
+			   (error = parse_outline_color(c, vector, ctx,
+				color_style)) == CSS_OK) {
+			color = false;
+		} else if ((style) && 
+			   (error = parse_outline_style(c, vector, 
+				ctx, style_style)) == CSS_OK) {
+			style = false;
+		} else if ((width) && 
+		    (error = parse_outline_width(c, vector,
+				ctx, width_style)) == CSS_OK) {
+			width = false;
+		} 
 
 		if (error == CSS_OK) {
 			consumeWhitespace(vector, ctx);
@@ -113,83 +118,44 @@
 		}
 	} while (*ctx != prev_ctx && token != NULL);
 
-	/* Calculate size of resultant style */
-	required_size = 0;
-	if (color)
-		required_size += color->length;
-	else
-		required_size += sizeof(uint32_t);
 
-	if (style)
-		required_size += style->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (width)
-		required_size += width->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
+	/* defaults */
 	if (color) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				color->bytecode, color->length);
-		required_size += color->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_OUTLINE_COLOR,
+		error = css_stylesheet_style_appendOPV(color_style, 
+			       CSS_PROP_OUTLINE_COLOR,
 				0, OUTLINE_COLOR_INVERT);
-		required_size += sizeof(uint32_t);
 	}
 
 	if (style) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				style->bytecode, style->length);
-		required_size += style->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_OUTLINE_STYLE,
+		error = css_stylesheet_style_appendOPV(style_style, 
+			       CSS_PROP_OUTLINE_STYLE,
 				0, OUTLINE_STYLE_NONE);
-		required_size += sizeof(uint32_t);
 	}
 
 	if (width) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				width->bytecode, width->length);
-		required_size += width->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_OUTLINE_WIDTH,
+		error = css_stylesheet_style_appendOPV(width_style, 
+			       CSS_PROP_OUTLINE_WIDTH,
 				0, OUTLINE_WIDTH_MEDIUM);
-		required_size += sizeof(uint32_t);
 	}
 
-	assert(required_size == ret->length);
 
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
+	error = css_stylesheet_merge_style(result, color_style);
+	if (error != CSS_OK)
+		goto parse_outline_cleanup;
 
-	/* Clean up after ourselves */
-cleanup:
-	if (color)
-		css_stylesheet_style_destroy(c->sheet, color, error == CSS_OK);
-	if (style)
-		css_stylesheet_style_destroy(c->sheet, style, error == CSS_OK);
-	if (width)
-		css_stylesheet_style_destroy(c->sheet, width, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
+	error = css_stylesheet_merge_style(result, style_style);
+	if (error != CSS_OK)
+		goto parse_outline_cleanup;
 
+	error = css_stylesheet_merge_style(result, width_style);
+
+
+parse_outline_cleanup:
+
+	css_stylesheet_style_destroy(width_style, true);
+	css_stylesheet_style_destroy(style_style, true);
+	css_stylesheet_style_destroy(color_style, true);
+
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/line_height.c
===================================================================
--- src/parse/properties/line_height.c	(revision 11378)
+++ src/parse/properties/line_height.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_line_height(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* number | length | percentage | IDENT(normal, inherit) */
@@ -99,31 +97,30 @@
 		value = LINE_HEIGHT_DIMENSION;
 	}
 
-	opv = buildOPV(CSS_PROP_LINE_HEIGHT, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == LINE_HEIGHT_NUMBER)
-		required_size += sizeof(length);
-	else if ((flags & FLAG_INHERIT) == false && 
-			value == LINE_HEIGHT_DIMENSION)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_LINE_HEIGHT, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && (value == LINE_HEIGHT_NUMBER || 
-			value == LINE_HEIGHT_DIMENSION))
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-	if ((flags & FLAG_INHERIT) == false && value == LINE_HEIGHT_DIMENSION)
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && 
+	    ((value == LINE_HEIGHT_NUMBER) || 
+	     (value == LINE_HEIGHT_DIMENSION))) {
+		error = css_stylesheet_style_append(result, length);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+	}
 
+	if (((flags & FLAG_INHERIT) == false) && 
+	    (value == LINE_HEIGHT_DIMENSION)) {
+		error = css_stylesheet_style_append(result, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+	}
+
 	return CSS_OK;
 }
Index: src/parse/properties/border_spacing.c
===================================================================
--- src/parse/properties/border_spacing.c	(revision 11378)
+++ src/parse/properties/border_spacing.c	(working copy)
@@ -29,17 +29,13 @@
  */
 css_error parse_border_spacing(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length[2] = { 0 };
 	uint32_t unit[2] = { 0 };
-	uint32_t required_size;
 	bool match;
 
 	/* length length? | IDENT(inherit) */
@@ -54,7 +50,11 @@
 			token->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
 		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
+		/* inherit */
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BORDER_SPACING,
+						       FLAG_INHERIT,
+						       0);
 	} else {
 		int num_lengths = 0;
 
@@ -109,35 +109,29 @@
 			return CSS_INVALID;
 		}
 
-		value = BORDER_SPACING_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BORDER_SPACING,
+						       0,
+						       BORDER_SPACING_SET);
 
-	opv = buildOPV(CSS_PROP_BORDER_SPACING, flags, value);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_SPACING_SET)
-		required_size += 2 * (sizeof(length[0]) + sizeof(unit[0]));
+		error = css_stylesheet_style_vappend(result, 
+						     4, 
+						     length[0], 
+						     unit[0], 
+						     length[1], 
+						     unit[1]);
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	}
+
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BORDER_SPACING_SET) {
-		uint8_t *ptr = ((uint8_t *) (*result)->bytecode) + sizeof(opv);
-
-		memcpy(ptr, &length[0], sizeof(length[0]));
-		ptr += sizeof(length[0]);
-		memcpy(ptr, &unit[0], sizeof(unit[0]));
-		ptr += sizeof(unit[0]);
-		memcpy(ptr, &length[1], sizeof(length[1]));
-		ptr += sizeof(length[1]);
-		memcpy(ptr, &unit[1], sizeof(unit[1]));
-	}
-
 	return CSS_OK;
 }
Index: src/parse/properties/border_bottom_style.c
===================================================================
--- src/parse/properties/border_bottom_style.c	(revision 11378)
+++ src/parse/properties/border_bottom_style.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_bottom_style(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_style(c, vector, ctx, 
-			CSS_PROP_BORDER_BOTTOM_STYLE, result);
+	return parse_border_side_style(c, vector, ctx, result, CSS_PROP_BORDER_BOTTOM_STYLE);
 }
Index: src/parse/properties/stress.c
===================================================================
--- src/parse/properties/stress.c	(revision 11378)
+++ src/parse/properties/stress.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * stress:CSS_PROP_STRESS IDENT:INHERIT NUMBER:( false:STRESS_SET RANGE:num<0||num>INTTOFIX(100) NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -19,7 +24,7 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,71 +32,52 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_stress(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_stress(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* number | IDENT (inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_STRESS);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, false, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		if (num < 0 || num > INTTOFIX(100)) {
+		if (num<0||num>INTTOFIX(100)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = STRESS_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_STRESS, 0, STRESS_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_STRESS, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == STRESS_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == STRESS_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/pitch_range.c
===================================================================
--- src/parse/properties/pitch_range.c	(revision 11378)
+++ src/parse/properties/pitch_range.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * pitch_range:CSS_PROP_PITCH_RANGE IDENT:INHERIT NUMBER:( false:PITCH_RANGE_SET RANGE:num<0||num>F_100 NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse pitch-range
+ * Parse pitch_range
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,72 +32,52 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_pitch_range(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_pitch_range(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* number | IDENT (inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PITCH_RANGE);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, false, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Must be between 0 and 100 */
-		if (num < 0 || num > F_100) {
+		if (num<0||num>F_100) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = PITCH_RANGE_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_PITCH_RANGE, 0, PITCH_RANGE_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_PITCH_RANGE, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == PITCH_RANGE_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == PITCH_RANGE_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/border_left_width.c
===================================================================
--- src/parse/properties/border_left_width.c	(revision 11378)
+++ src/parse/properties/border_left_width.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_left_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_width(c, vector, ctx, 
-			CSS_PROP_BORDER_LEFT_WIDTH, result);
+	return parse_border_side_width(c, vector, ctx, result, CSS_PROP_BORDER_LEFT_WIDTH);
 }
Index: src/parse/properties/visibility.c
===================================================================
--- src/parse/properties/visibility.c	(revision 11378)
+++ src/parse/properties/visibility.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * visibility:CSS_PROP_VISIBILITY IDENT:( INHERIT: VISIBLE:0,VISIBILITY_VISIBLE HIDDEN:0,VISIBILITY_HIDDEN COLLAPSE:0,VISIBILITY_COLLAPSE IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,68 +21,47 @@
 /**
  * Parse visibility
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_visibility(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_visibility(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (visible, hidden, collapse, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[VISIBLE],
-			&match) == lwc_error_ok && match)) {
-		value = VISIBILITY_VISIBLE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[HIDDEN],
-			&match) == lwc_error_ok && match)) {
-		value = VISIBILITY_HIDDEN;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[COLLAPSE],
-			&match) == lwc_error_ok && match)) {
-		value = VISIBILITY_COLLAPSE;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_VISIBILITY);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[VISIBLE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VISIBILITY, 0,VISIBILITY_VISIBLE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VISIBILITY, 0,VISIBILITY_HIDDEN);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[COLLAPSE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_VISIBILITY, 0,VISIBILITY_COLLAPSE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_VISIBILITY, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/border_left.c
===================================================================
--- src/parse/properties/border_left.c	(revision 11378)
+++ src/parse/properties/border_left.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_border_left(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side(c, vector, ctx, BORDER_SIDE_LEFT, result);
+	return parse_border_side(c, vector, ctx, result, BORDER_SIDE_LEFT);
 }
Index: src/parse/properties/clip.c
===================================================================
--- src/parse/properties/clip.c	(revision 11378)
+++ src/parse/properties/clip.c	(working copy)
@@ -29,18 +29,14 @@
  */
 css_error parse_clip(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	int num_lengths = 0;
 	css_fixed length[4] = { 0 };
 	uint32_t unit[4] = { 0 };
-	uint32_t required_size;
 	bool match;
 
 	/* FUNCTION(rect) [ [ IDENT(auto) | length ] CHAR(,)? ]{3} 
@@ -52,22 +48,28 @@
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = CLIP_AUTO;
-	} else if (token->type == CSS_TOKEN_FUNCTION &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[RECT],
-			&match) == lwc_error_ok && match)) {
+	if ((token->type == CSS_TOKEN_IDENT) &&
+	    (lwc_string_caseless_isequal(
+		    token->idata, c->strings[INHERIT],
+		    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLIP,
+						       FLAG_INHERIT,
+						       0);
+	} else if ((token->type == CSS_TOKEN_IDENT) &&
+		   (lwc_string_caseless_isequal(
+			   token->idata, c->strings[AUTO],
+			   &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLIP,
+						       0,
+						       CLIP_AUTO);
+	} else if ((token->type == CSS_TOKEN_FUNCTION) &&
+		   (lwc_string_caseless_isequal(
+			   token->idata, c->strings[RECT],
+			   &match) == lwc_error_ok && match)) {
 		int i;
-		value = CLIP_SHAPE_RECT;
+		uint16_t value = CLIP_SHAPE_RECT;
 
 		for (i = 0; i < 4; i++) {
 			consumeWhitespace(vector, ctx);
@@ -136,41 +138,34 @@
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
 
-	opv = buildOPV(CSS_PROP_CLIP, flags, value);
+                /* output bytecode */
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLIP,
+						       0,
+						       value);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && 
-			(value & CLIP_SHAPE_MASK) == CLIP_SHAPE_RECT) {
-		required_size += 
-			num_lengths * (sizeof(length[0]) + sizeof(unit[0]));
+		for (i = 0; i < num_lengths; i++) {
+			error = css_stylesheet_style_vappend(result, 
+							     2, 
+							     length[i], 
+							     unit[i]);
+			if (error != CSS_OK) 
+				break;
+		}
+
+
+	} else {
+		error = CSS_INVALID;
 	}
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
-		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && 
-			(value & CLIP_SHAPE_MASK) == CLIP_SHAPE_RECT) {
-		int i;
-		uint8_t *ptr = ((uint8_t *) (*result)->bytecode) + sizeof(opv);
-
-		for (i = 0; i < num_lengths; i++) {
-			memcpy(ptr, &length[i], sizeof(length[i]));
-			ptr += sizeof(length[i]);
-			memcpy(ptr, &unit[i], sizeof(unit[i]));
-			ptr += sizeof(unit[i]);
-		}
-	}
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/padding_top.c
===================================================================
--- src/parse/properties/padding_top.c	(revision 11378)
+++ src/parse/properties/padding_top.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * padding_top:CSS_PROP_PADDING_TOP WRAP:parse_padding_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse padding-top
+ * Parse padding_top
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_padding_top(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_padding_top(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_padding_side(c, vector, ctx, 
-			CSS_PROP_PADDING_TOP, result);
+	return parse_padding_side(c, vector, ctx, result, CSS_PROP_PADDING_TOP);
 }
Index: src/parse/properties/left.c
===================================================================
--- src/parse/properties/left.c	(revision 11378)
+++ src/parse/properties/left.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_left(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_side(c, vector, ctx, CSS_PROP_LEFT, result);
+	return parse_side(c, vector, ctx, result, CSS_PROP_LEFT);
 }
Index: src/parse/properties/text_decoration.c
===================================================================
--- src/parse/properties/text_decoration.c	(revision 11378)
+++ src/parse/properties/text_decoration.c	(working copy)
@@ -29,36 +29,35 @@
  */
 css_error parse_text_decoration(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
-	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	css_error error = CSS_INVALID;
+	const css_token *token;
 	bool match;
 
 	/* IDENT([ underline || overline || line-through || blink ])
 	 * | IDENT (none, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || (token->type != CSS_TOKEN_IDENT) ) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_DECORATION_NONE;
+	if (lwc_string_caseless_isequal(token->idata,
+			c->strings[INHERIT],
+			&match) == lwc_error_ok && match) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_TEXT_DECORATION);
+	} else if (lwc_string_caseless_isequal(token->idata,
+				c->strings[NONE],
+				&match) == lwc_error_ok && match) {
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_TEXT_DECORATION, 0, TEXT_DECORATION_NONE);
 	} else {
-		while (ident != NULL) {
+		uint16_t value = 0;
+		while (token != NULL) {
 			if ((lwc_string_caseless_isequal(
-					ident->idata, c->strings[UNDERLINE],
+					token->idata, c->strings[UNDERLINE],
 					&match) == lwc_error_ok && match)) {
 				if ((value & TEXT_DECORATION_UNDERLINE) == 0)
 					value |= TEXT_DECORATION_UNDERLINE;
@@ -67,7 +66,7 @@
 					return CSS_INVALID;
 				}
 			} else if ((lwc_string_caseless_isequal(
-					ident->idata, c->strings[OVERLINE],
+					token->idata, c->strings[OVERLINE],
 					&match) == lwc_error_ok && match)) {
 				if ((value & TEXT_DECORATION_OVERLINE) == 0)
 					value |= TEXT_DECORATION_OVERLINE;
@@ -76,7 +75,7 @@
 					return CSS_INVALID;
 				}
 			} else if ((lwc_string_caseless_isequal(
-					ident->idata, c->strings[LINE_THROUGH],
+					token->idata, c->strings[LINE_THROUGH],
 					&match) == lwc_error_ok && match)) {
 				if ((value & TEXT_DECORATION_LINE_THROUGH) == 0)
 					value |= TEXT_DECORATION_LINE_THROUGH;
@@ -85,7 +84,7 @@
 					return CSS_INVALID;
 				}
 			} else if ((lwc_string_caseless_isequal(
-					ident->idata, c->strings[BLINK],
+					token->idata, c->strings[BLINK],
 					&match) == lwc_error_ok && match)) {
 				if ((value & TEXT_DECORATION_BLINK) == 0)
 					value |= TEXT_DECORATION_BLINK;
@@ -100,24 +99,17 @@
 
 			consumeWhitespace(vector, ctx);
 
-			ident = parserutils_vector_peek(vector, *ctx);
-			if (ident != NULL && ident->type != CSS_TOKEN_IDENT)
+			token = parserutils_vector_peek(vector, *ctx);
+			if (token != NULL && token->type != CSS_TOKEN_IDENT)
 				break;
-			ident = parserutils_vector_iterate(vector, ctx);
+			token = parserutils_vector_iterate(vector, ctx);
 		}
+		error = css_stylesheet_style_appendOPV(result,
+				CSS_PROP_TEXT_DECORATION, 0, value);
 	}
 
-	opv = buildOPV(CSS_PROP_TEXT_DECORATION, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/speak_punctuation.c
===================================================================
--- src/parse/properties/speak_punctuation.c	(revision 11378)
+++ src/parse/properties/speak_punctuation.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * speak_punctuation:CSS_PROP_SPEAK_PUNCTUATION IDENT:( INHERIT: CODE:0,SPEAK_PUNCTUATION_CODE NONE:0,SPEAK_PUNCTUATION_NONE IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse speak-punctuation
+ * Parse speak_punctuation
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,53 +32,34 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_speak_punctuation(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_speak_punctuation(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (code, none, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[CODE],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_PUNCTUATION_CODE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_PUNCTUATION_NONE;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_SPEAK_PUNCTUATION);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[CODE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_PUNCTUATION, 0,SPEAK_PUNCTUATION_CODE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_PUNCTUATION, 0,SPEAK_PUNCTUATION_NONE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_SPEAK_PUNCTUATION, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/text_align.c
===================================================================
--- src/parse/properties/text_align.c	(revision 11378)
+++ src/parse/properties/text_align.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * text_align:CSS_PROP_TEXT_ALIGN IDENT:( INHERIT: LEFT:0,TEXT_ALIGN_LEFT RIGHT:0,TEXT_ALIGN_RIGHT CENTER:0,TEXT_ALIGN_CENTER JUSTIFY:0,TEXT_ALIGN_JUSTIFY LIBCSS_LEFT:0,TEXT_ALIGN_LIBCSS_LEFT LIBCSS_CENTER:0,TEXT_ALIGN_LIBCSS_CENTER LIBCSS_RIGHT:0,TEXT_ALIGN_LIBCSS_RIGHT IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,87 +19,57 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse text-align
+ * Parse text_align
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_text_align(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_text_align(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (left, right, center, justify, -libcss-left, -libcss-center, 
-	 *        -libcss-right, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LEFT],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_LEFT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RIGHT],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_RIGHT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[CENTER],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_CENTER;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[JUSTIFY],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_JUSTIFY;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LIBCSS_LEFT],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_LIBCSS_LEFT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LIBCSS_CENTER],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_LIBCSS_CENTER;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LIBCSS_RIGHT],
-			&match) == lwc_error_ok && match)) {
-		value = TEXT_ALIGN_LIBCSS_RIGHT;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_TEXT_ALIGN);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LEFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_LEFT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIGHT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_RIGHT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[CENTER], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_CENTER);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[JUSTIFY], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_JUSTIFY);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_LEFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_LIBCSS_LEFT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_CENTER], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_LIBCSS_CENTER);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_RIGHT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_ALIGN, 0,TEXT_ALIGN_LIBCSS_RIGHT);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_TEXT_ALIGN, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/margin_top.c
===================================================================
--- src/parse/properties/margin_top.c	(revision 11378)
+++ src/parse/properties/margin_top.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * margin_top:CSS_PROP_MARGIN_TOP WRAP:parse_margin_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse margin-top
+ * Parse margin_top
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,9 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_margin_top(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_margin_top(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_margin_side(c, vector, ctx, CSS_PROP_MARGIN_TOP, result);
+	return parse_margin_side(c, vector, ctx, result, CSS_PROP_MARGIN_TOP);
 }
Index: src/parse/properties/pause_before.c
===================================================================
--- src/parse/properties/pause_before.c	(revision 11378)
+++ src/parse/properties/pause_before.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * pause_before:CSS_PROP_PAUSE_BEFORE IDENT:INHERIT LENGTH_UNIT:( UNIT_S:PAUSE_BEFORE_SET DISALLOW:(unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false RANGE:<0 LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse pause-before
+ * Parse pause_before
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,56 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_pause_before(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_pause_before(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_pause_common(c, vector, ctx, 
-			CSS_PROP_PAUSE_BEFORE, result);
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PAUSE_BEFORE);
+	} else {
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_S, &length, &unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		if ((unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
+		}
+
+		if (length <0) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
+		}
+
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAUSE_BEFORE, 0, PAUSE_BEFORE_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+	}
+
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/z_index.c
===================================================================
--- src/parse/properties/z_index.c	(revision 11378)
+++ src/parse/properties/z_index.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * z_index:CSS_PROP_Z_INDEX IDENT:( INHERIT: AUTO:0,Z_INDEX_AUTO IDENT:) NUMBER:( true:Z_INDEX_SET NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,85 +19,62 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse z-index
+ * Parse z_index
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_z_index(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_z_index(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* <integer> | IDENT (auto, inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = Z_INDEX_AUTO;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_Z_INDEX);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_Z_INDEX, 0,Z_INDEX_AUTO);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, true, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_Z_INDEX, 0, Z_INDEX_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-		value = Z_INDEX_SET;
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_Z_INDEX, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == Z_INDEX_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == Z_INDEX_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/top.c
===================================================================
--- src/parse/properties/top.c	(revision 11378)
+++ src/parse/properties/top.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_top(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_side(c, vector, ctx, CSS_PROP_TOP, result);
+	return parse_side(c, vector, ctx, result, CSS_PROP_TOP);
 }
Index: src/parse/properties/letter_spacing.c
===================================================================
--- src/parse/properties/letter_spacing.c	(revision 11378)
+++ src/parse/properties/letter_spacing.c	(working copy)
@@ -29,17 +29,13 @@
  */
 css_error parse_letter_spacing(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | IDENT(normal, inherit) */
@@ -54,13 +50,17 @@
 			token->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
 		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
+		error = css_stylesheet_style_inherit(result, 
+						     CSS_PROP_LETTER_SPACING);
 	} else if (token->type == CSS_TOKEN_IDENT &&
 			(lwc_string_caseless_isequal(
 			token->idata, c->strings[NORMAL],
 			&match) == lwc_error_ok && match)) {
 		parserutils_vector_iterate(vector, ctx);
-		value = LETTER_SPACING_NORMAL;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_LETTER_SPACING,
+						       0,
+						       LETTER_SPACING_NORMAL);
 	} else {
 		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
 				&length, &unit);
@@ -69,36 +69,30 @@
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ ||
-				unit & UNIT_PCT) {
+		if ((unit & UNIT_ANGLE) || 
+		    (unit & UNIT_TIME) || 
+		    (unit & UNIT_FREQ) ||
+		    (unit & UNIT_PCT)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = LETTER_SPACING_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_LETTER_SPACING,
+						       0,
+						       LETTER_SPACING_SET);
 
-	opv = buildOPV(CSS_PROP_LETTER_SPACING, flags, value);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == LETTER_SPACING_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == LETTER_SPACING_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
 
-	return CSS_OK;
+	if (error != CSS_OK) 
+		*ctx = orig_ctx;
+	
+	return error;
 }
Index: src/parse/properties/speak.c
===================================================================
--- src/parse/properties/speak.c	(revision 11378)
+++ src/parse/properties/speak.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * speak:CSS_PROP_SPEAK IDENT:( INHERIT: NORMAL:0,SPEAK_NORMAL NONE:0,SPEAK_NONE SPELL_OUT:0,SPEAK_SPELL_OUT  IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -19,7 +24,7 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,57 +32,36 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_speak(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_speak(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (normal, none, spell-out, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_NORMAL;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_NONE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[SPELL_OUT],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_SPELL_OUT;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_SPEAK);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK, 0,SPEAK_NORMAL);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK, 0,SPEAK_NONE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[SPELL_OUT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK, 0,SPEAK_SPELL_OUT);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_SPEAK, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/bottom.c
===================================================================
--- src/parse/properties/bottom.c	(revision 11378)
+++ src/parse/properties/bottom.c	(working copy)
@@ -29,7 +29,7 @@
  */
 css_error parse_bottom(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_side(c, vector, ctx, CSS_PROP_BOTTOM, result);
+	return parse_side(c, vector, ctx, result, CSS_PROP_BOTTOM);
 }
Index: src/parse/properties/position.c
===================================================================
--- src/parse/properties/position.c	(revision 11378)
+++ src/parse/properties/position.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * position:CSS_PROP_POSITION IDENT:( INHERIT: LIBCSS_STATIC:0,POSITION_STATIC RELATIVE:0,POSITION_RELATIVE ABSOLUTE:0,POSITION_ABSOLUTE FIXED:0,POSITION_FIXED IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,72 +21,49 @@
 /**
  * Parse position
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_position(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_position(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (static, relative, absolute, fixed, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LIBCSS_STATIC],
-			&match) == lwc_error_ok && match)) {
-		value = POSITION_STATIC;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RELATIVE],
-			&match) == lwc_error_ok && match)) {
-		value = POSITION_RELATIVE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ABSOLUTE],
-			&match) == lwc_error_ok && match)) {
-		value = POSITION_ABSOLUTE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[FIXED],
-			&match) == lwc_error_ok && match)) {
-		value = POSITION_FIXED;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_POSITION);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_STATIC], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_POSITION, 0,POSITION_STATIC);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RELATIVE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_POSITION, 0,POSITION_RELATIVE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[ABSOLUTE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_POSITION, 0,POSITION_ABSOLUTE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[FIXED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_POSITION, 0,POSITION_FIXED);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_POSITION, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/float.c
===================================================================
--- src/parse/properties/float.c	(revision 11378)
+++ src/parse/properties/float.c	(working copy)
@@ -27,16 +27,13 @@
  * Post condition: \a *ctx is updated with the next token to process
  *                 If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_float(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_float(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (left, right, none, inherit) */
@@ -47,37 +44,40 @@
 	}
 
 	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		     ident->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FLOAT,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LEFT],
-			&match) == lwc_error_ok && match)) {
-		value = FLOAT_LEFT;
+			    ident->idata, c->strings[LEFT],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FLOAT,
+						       0,
+						       FLOAT_LEFT);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RIGHT],
-			&match) == lwc_error_ok && match)) {
-		value = FLOAT_RIGHT;
+			    ident->idata, c->strings[RIGHT],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FLOAT,
+						       0,
+						       FLOAT_RIGHT);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = FLOAT_NONE;
+			    ident->idata, c->strings[NONE],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FLOAT,
+						       0,
+						       FLOAT_NONE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_FLOAT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
 
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/border_right_color.c
===================================================================
--- src/parse/properties/border_right_color.c	(revision 11378)
+++ src/parse/properties/border_right_color.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_right_color(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_color(c, vector, ctx, 
-			CSS_PROP_BORDER_RIGHT_COLOR, result);
+	return parse_border_side_color(c, vector, ctx, result, CSS_PROP_BORDER_RIGHT_COLOR);
 }
Index: src/parse/properties/margin_right.c
===================================================================
--- src/parse/properties/margin_right.c	(revision 11378)
+++ src/parse/properties/margin_right.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * margin_right:CSS_PROP_MARGIN_RIGHT WRAP:parse_margin_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse margin-right
+ * Parse margin_right
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,9 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_margin_right(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_margin_right(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_margin_side(c, vector, ctx, CSS_PROP_MARGIN_RIGHT, result);
+	return parse_margin_side(c, vector, ctx, result, CSS_PROP_MARGIN_RIGHT);
 }
Index: src/parse/properties/border_color.c
===================================================================
--- src/parse/properties/border_color.c	(revision 11378)
+++ src/parse/properties/border_color.c	(working copy)
@@ -29,96 +29,66 @@
  */
 css_error parse_border_color(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t num_sides = 0;
-	uint32_t required_size;
+	uint16_t side_val[4];
+	uint32_t side_color[4];
+	uint32_t side_count = 0;
 	bool match;
 	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			4 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_COLOR);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_RIGHT_COLOR);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_COLOR,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_RIGHT_COLOR,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_BOTTOM_COLOR,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_LEFT_COLOR,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_COLOR);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_COLOR);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
 	/* Attempt to parse up to 4 colours */
 	do {
 		prev_ctx = *ctx;
-		error = CSS_OK;
 
-		/* Ensure that we're not about to parse another inherit */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
+		if ((token != NULL) && is_css_inherit(c, token)) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
 		}
 
-		if (top == NULL &&
-				(error = parse_border_side_color(c, vector, 
-				ctx, CSS_PROP_BORDER_TOP_COLOR, &top)) == 
-				CSS_OK) {
-			num_sides = 1;
-		} else if (right == NULL &&
-				(error = parse_border_side_color(c, vector, 
-				ctx, CSS_PROP_BORDER_RIGHT_COLOR, &right)) == 
-				CSS_OK) {
-			num_sides = 2;
-		} else if (bottom == NULL &&
-				(error = parse_border_side_color(c, vector, 
-				ctx, CSS_PROP_BORDER_BOTTOM_COLOR, &bottom)) == 
-				CSS_OK) {
-			num_sides = 3;
-		} else if (left == NULL &&
-				(error = parse_border_side_color(c, vector, 
-				ctx, CSS_PROP_BORDER_LEFT_COLOR, &left)) == 
-				CSS_OK) {
-			num_sides = 4;
+		if ((token->type == CSS_TOKEN_IDENT) && 
+		   (lwc_string_caseless_isequal(token->idata, 
+				c->strings[TRANSPARENT], 
+				&match) == lwc_error_ok && match)) {
+			side_val[side_count] = BORDER_COLOR_TRANSPARENT;
+			parserutils_vector_iterate(vector, ctx);
+			error = CSS_OK;
+		} else {
+			side_val[side_count] = BORDER_COLOR_SET;
+			error = parse_colour_specifier(c, vector, ctx, &side_color[side_count]);
 		}
 
 		if (error == CSS_OK) {
+			side_count++;
+
 			consumeWhitespace(vector, ctx);
 
 			token = parserutils_vector_peek(vector, *ctx);
@@ -126,139 +96,48 @@
 			/* Forcibly cause loop to exit */
 			token = NULL;
 		}
-	} while (*ctx != prev_ctx && token != NULL);
+	} while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
 
-	if (num_sides == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
-	}
 
-	/* Calculate size of resultant style */
-	if (num_sides == 1) {
-		required_size = 4 * top->length;
-	} else if (num_sides == 2) {
-		required_size = 2 * top->length + 2 * right->length;
-	} else if (num_sides == 3) {
-		required_size = top->length + 2 * right->length + 
-				bottom->length;
-	} else {
-		required_size = top->length + right->length +
-				bottom->length + left->length;
-	}
+#define SIDE_APPEND(OP,NUM)								\
+	error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]);	\
+	if (error != CSS_OK)								\
+		break;									\
+	if (side_val[(NUM)] == BORDER_COLOR_SET)					\
+		error = css_stylesheet_style_append(result, side_color[(NUM)]);		\
+	if (error != CSS_OK)								\
+		break;
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_sides == 1) {
-		uint32_t *opv = ((uint32_t *) top->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_RIGHT_COLOR, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_BOTTOM_COLOR, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_COLOR, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-	} else if (num_sides == 2) {
-		uint32_t *vopv = ((uint32_t *) top->bytecode);
-		uint32_t *hopv = ((uint32_t *) right->bytecode);
-		uint8_t vflags = getFlags(*vopv);
-		uint8_t hflags = getFlags(*hopv);
-		uint16_t vvalue = getValue(*vopv);
-		uint16_t hvalue = getValue(*hopv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		*vopv = buildOPV(CSS_PROP_BORDER_BOTTOM_COLOR, vflags, vvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*hopv = buildOPV(CSS_PROP_BORDER_LEFT_COLOR, hflags, hvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else if (num_sides == 3) {
-		uint32_t *opv = ((uint32_t *) right->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_COLOR, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				left->bytecode, left->length);
-		required_size += left->length;
+	switch (side_count) {
+	case 1:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_COLOR, 0);
+		break;
+	case 2:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_COLOR, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_COLOR, 1);
+		break;
+	case 3:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_COLOR, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_COLOR, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_COLOR, 1);
+		break;
+	case 4:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_COLOR, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_COLOR, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_COLOR, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_COLOR, 3);
+		break;
+	default:
+		error = CSS_INVALID;
+		break;
 	}
 
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/speak_header.c
===================================================================
--- src/parse/properties/speak_header.c	(revision 11378)
+++ src/parse/properties/speak_header.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * speak_header:CSS_PROP_SPEAK_HEADER IDENT:( INHERIT: ONCE:0,SPEAK_HEADER_ONCE ALWAYS:0,SPEAK_HEADER_ALWAYS IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse speak-header
+ * Parse speak_header
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,53 +32,34 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_speak_header(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_speak_header(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (once, always, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ONCE],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_HEADER_ONCE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ALWAYS],
-			&match) == lwc_error_ok && match)) {
-		value = SPEAK_HEADER_ALWAYS;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_SPEAK_HEADER);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[ONCE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_HEADER, 0,SPEAK_HEADER_ONCE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[ALWAYS], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEAK_HEADER, 0,SPEAK_HEADER_ALWAYS);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_SPEAK_HEADER, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/play_during.c
===================================================================
--- src/parse/properties/play_during.c	(revision 11378)
+++ src/parse/properties/play_during.c	(working copy)
@@ -29,22 +29,22 @@
  */
 css_error parse_play_during(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size;
 	lwc_string *uri;
 	bool match;
+	uint32_t uri_snumber;
 
 	/* URI [ IDENT(mix) || IDENT(repeat) ]? | IDENT(auto,none,inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
+	if ((token == NULL) || 
+	    ((token->type != CSS_TOKEN_IDENT) &&
+	     (token->type != CSS_TOKEN_URI))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
@@ -79,6 +79,15 @@
 			return error;
 		}
 
+		error = css_stylesheet_string_add(c->sheet, 
+						  uri, 
+						  &uri_snumber);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+
 		for (modifiers = 0; modifiers < 2; modifiers++) {
 			consumeWhitespace(vector, ctx);
 
@@ -115,28 +124,19 @@
 		}
 	}
 
-	opv = buildOPV(CSS_PROP_PLAY_DURING, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && 
-			(value & PLAY_DURING_TYPE_MASK) == PLAY_DURING_URI)
-		required_size += sizeof(lwc_string *);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_PLAY_DURING, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
 	if ((flags & FLAG_INHERIT) == false && 
-			(value & PLAY_DURING_TYPE_MASK)	 == PLAY_DURING_URI) {
-		/* Don't ref URI -- we want to pass ownership to the bytecode */
-		memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
-				&uri, sizeof(lwc_string *));
+	    (value & PLAY_DURING_TYPE_MASK) == PLAY_DURING_URI) {
+		error = css_stylesheet_style_append(result, uri_snumber);
 	}
 
-	return CSS_OK;
+	if (error != CSS_OK) 
+		*ctx = orig_ctx;
+
+	return error;
 }
Index: src/parse/properties/background_repeat.c
===================================================================
--- src/parse/properties/background_repeat.c	(revision 11378)
+++ src/parse/properties/background_repeat.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_background_repeat(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (no-repeat, repeat-x, repeat-y, repeat, inherit) */
@@ -47,41 +44,49 @@
 	}
 
 	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		     ident->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+		/* inherit */
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_REPEAT,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NO_REPEAT],
-			&match) == lwc_error_ok && match)) {
-		value = BACKGROUND_REPEAT_NO_REPEAT;
+			    ident->idata, c->strings[NO_REPEAT],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_REPEAT,
+						       0,
+						       BACKGROUND_REPEAT_NO_REPEAT);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[REPEAT_X],
-			&match) == lwc_error_ok && match)) {
-		value = BACKGROUND_REPEAT_REPEAT_X;
+			    ident->idata, c->strings[REPEAT_X],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_REPEAT,
+						       0,
+						       BACKGROUND_REPEAT_REPEAT_X);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[REPEAT_Y],
-			&match) == lwc_error_ok && match)) {
-		value = BACKGROUND_REPEAT_REPEAT_Y;
+			    ident->idata, c->strings[REPEAT_Y],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_REPEAT,
+						       0,
+						       BACKGROUND_REPEAT_REPEAT_Y);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[REPEAT],
-			&match) == lwc_error_ok && match)) {
-		value = BACKGROUND_REPEAT_REPEAT;
+			    ident->idata, c->strings[REPEAT],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_REPEAT,
+						       0,
+						       BACKGROUND_REPEAT_REPEAT);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_BACKGROUND_REPEAT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
 	return CSS_OK;
 }
Index: src/parse/properties/border_top_style.c
===================================================================
--- src/parse/properties/border_top_style.c	(revision 11378)
+++ src/parse/properties/border_top_style.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_top_style(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_style(c, vector, ctx, 
-			CSS_PROP_BORDER_TOP_STYLE, result);
+	return parse_border_side_style(c, vector, ctx, result, CSS_PROP_BORDER_TOP_STYLE);
 }
Index: src/parse/properties/width.c
===================================================================
--- src/parse/properties/width.c	(revision 11378)
+++ src/parse/properties/width.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * width:CSS_PROP_WIDTH IDENT:( INHERIT: AUTO:0,WIDTH_AUTO IDENT:) LENGTH_UNIT:( UNIT_PX:WIDTH_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -16,94 +21,69 @@
 /**
  * Parse width
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_width(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_width(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(auto, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = WIDTH_AUTO;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_WIDTH);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WIDTH, 0,WIDTH_AUTO);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		/* Must be positive */
-		if (length < 0) {
+		if (length <0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = WIDTH_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_WIDTH, 0, WIDTH_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_WIDTH, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == WIDTH_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == WIDTH_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/background_image.c
===================================================================
--- src/parse/properties/background_image.c	(revision 11378)
+++ src/parse/properties/background_image.c	(working copy)
@@ -27,73 +27,77 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_background_image(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_background_image(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size;
 	bool match;
-	lwc_string *uri = NULL;
 
 	/* URI | IDENT (none, inherit) */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_URI)) {
+	if ((token == NULL) ||
+	    (token->type != CSS_TOKEN_IDENT &&
+	     token->type != CSS_TOKEN_URI)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[NONE],
-			&match) == lwc_error_ok && match)) {
-		value = BACKGROUND_IMAGE_NONE;
+	if ((token->type == CSS_TOKEN_IDENT) &&
+	    (lwc_string_caseless_isequal(
+		    token->idata, c->strings[INHERIT],
+		    &match) == lwc_error_ok && match)) {
+		/* inherit */
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_IMAGE);
+	} else if ((token->type == CSS_TOKEN_IDENT) &&
+		   (lwc_string_caseless_isequal(
+			   token->idata, c->strings[NONE],
+			   &match) == lwc_error_ok && match)) {
+		/* background image none */
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_IMAGE,
+						       0,
+						       BACKGROUND_IMAGE_NONE);
 	} else if (token->type == CSS_TOKEN_URI) {
-		value = BACKGROUND_IMAGE_URI;
+		/* background image with uri */
+		lwc_string *uri = NULL;
+		uint32_t uri_snumber;
 
 		error = c->sheet->resolve(c->sheet->resolve_pw,
-				c->sheet->url,
-				token->idata, &uri);
+					  c->sheet->url,
+					  token->idata,
+					  &uri);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
-	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
 
-	opv = buildOPV(CSS_PROP_BACKGROUND_IMAGE, flags, value);
+		error = css_stylesheet_string_add(c->sheet, uri, &uri_snumber);
 
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_IMAGE_URI)
-		required_size += sizeof(lwc_string *);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
-	}
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_BACKGROUND_IMAGE,
+						       0,
+						       BACKGROUND_IMAGE_URI);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_IMAGE_URI) {
-		/* Don't ref URI -- we want to pass ownership to the bytecode */
-		memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
-				&uri, sizeof(lwc_string *));
+		error = css_stylesheet_style_append(result, uri_snumber);
+
+	} else {
+		error = CSS_INVALID;
 	}
 
-	return CSS_OK;
+	if (error != CSS_OK) 
+		*ctx = orig_ctx;
+	
+	return error;
 }
Index: src/parse/properties/margin_left.c
===================================================================
--- src/parse/properties/margin_left.c	(revision 11378)
+++ src/parse/properties/margin_left.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * margin_left:CSS_PROP_MARGIN_LEFT WRAP:parse_margin_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse margin-left
+ * Parse margin_left
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,9 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_margin_left(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_margin_left(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_margin_side(c, vector, ctx, CSS_PROP_MARGIN_LEFT, result);
+	return parse_margin_side(c, vector, ctx, result, CSS_PROP_MARGIN_LEFT);
 }
Index: src/parse/properties/list_style.c
===================================================================
--- src/parse/properties/list_style.c	(revision 11378)
+++ src/parse/properties/list_style.c	(working copy)
@@ -29,54 +29,59 @@
  */
 css_error parse_list_style(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *image = NULL;
-	css_style *position = NULL;
-	css_style *type = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
-	bool match;
 	css_error error;
+	bool image = true;
+	bool position = true;
+	bool type = true;
+	css_style *image_style;
+	css_style *position_style;
+	css_style *type_style;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet, 
-				3 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_LIST_STYLE_IMAGE);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_LIST_STYLE_POSITION);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_IMAGE, 
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_POSITION,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_TYPE,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_LIST_STYLE_TYPE);
 
-		parserutils_vector_iterate(vector, ctx);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+	/* allocate styles */
+	error = css_stylesheet_style_create(c->sheet, &image_style);
+	if (error != CSS_OK) 
+		return error;
+
+	error = css_stylesheet_style_create(c->sheet, &position_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(image_style, true);
+		return error;
 	}
 
+	error = css_stylesheet_style_create(c->sheet, &type_style);
+	if (error != CSS_OK) {
+		css_stylesheet_style_destroy(image_style, true);
+		css_stylesheet_style_destroy(position_style, true);
+		return error;
+	}
+
 	/* Attempt to parse the various longhand properties */
 	do {
 		prev_ctx = *ctx;
@@ -84,22 +89,23 @@
 
 		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
+		if (token != NULL && is_css_inherit(c, token)) {
 			error = CSS_INVALID;
-			goto cleanup;
+			goto parse_list_style_cleanup;
 		}
 
-		if (type == NULL && (error = parse_list_style_type(c, vector,
-				ctx, &type)) == CSS_OK) {
-		} else if (position == NULL && 
-				(error = parse_list_style_position(c, vector, 
-				ctx, &position)) == CSS_OK) {
-		} else if (image == NULL && 
-				(error = parse_list_style_image(c, vector, ctx,
-				&image)) == CSS_OK) {
+		if ((type) && 
+		    (error = parse_list_style_type(c, vector,
+				ctx, type_style)) == CSS_OK) {
+			type = false;
+		} else if ((position) && 
+			   (error = parse_list_style_position(c, vector, 
+				ctx, position_style)) == CSS_OK) {
+			position = false;
+		} else if ((image) && 
+			   (error = parse_list_style_image(c, vector, ctx,
+				image_style)) == CSS_OK) {
+			image = false;
 		}
 
 		if (error == CSS_OK) {
@@ -112,88 +118,47 @@
 		}
 	} while (*ctx != prev_ctx && token != NULL);
 
-	/* Calculate the required size of the resultant style,
-	 * defaulting the unspecified properties to their initial values */
-	required_size = 0;
 
-	if (image)
-		required_size += image->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (position)
-		required_size += position->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	if (type)
-		required_size += type->length;
-	else
-		required_size += sizeof(uint32_t);
-
-	/* Create and populate it */
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
+	/* defaults */
 	if (image) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				image->bytecode, image->length);
-		required_size += image->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_IMAGE,
+		error = css_stylesheet_style_appendOPV(image_style, 
+			       CSS_PROP_LIST_STYLE_IMAGE,
 				0, LIST_STYLE_IMAGE_NONE);
-		required_size += sizeof(uint32_t);
 	}
 
 	if (position) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				position->bytecode, position->length);
-		required_size += position->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_POSITION,
+		error = css_stylesheet_style_appendOPV(position_style, 
+			       CSS_PROP_LIST_STYLE_POSITION,
 				0, LIST_STYLE_POSITION_OUTSIDE);
-		required_size += sizeof(uint32_t);
 	}
 
 	if (type) {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				type->bytecode, type->length);
-		required_size += type->length;
-	} else {
-		void *bc = ((uint8_t *) ret->bytecode) + required_size;
-
-		*((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_TYPE,
+		error = css_stylesheet_style_appendOPV(type_style, 
+			       CSS_PROP_LIST_STYLE_TYPE,
 				0, LIST_STYLE_TYPE_DISC);
-		required_size += sizeof(uint32_t);
 	}
 
-	assert(required_size == ret->length);
 
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
+	error = css_stylesheet_merge_style(result, image_style);
+	if (error != CSS_OK)
+		goto parse_list_style_cleanup;
 
-	/* Clean up after ourselves */
-cleanup:
-	if (image)
-		css_stylesheet_style_destroy(c->sheet, image, error == CSS_OK);
-	if (position)
-		css_stylesheet_style_destroy(c->sheet, position, error == CSS_OK);
-	if (type)
-		css_stylesheet_style_destroy(c->sheet, type, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
+	error = css_stylesheet_merge_style(result, position_style);
+	if (error != CSS_OK)
+		goto parse_list_style_cleanup;
 
+	error = css_stylesheet_merge_style(result, type_style);
+
+
+parse_list_style_cleanup:
+
+	css_stylesheet_style_destroy(type_style, true);
+	css_stylesheet_style_destroy(position_style, true);
+	css_stylesheet_style_destroy(image_style, true);
+
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
+
 }
Index: src/parse/properties/white_space.c
===================================================================
--- src/parse/properties/white_space.c	(revision 11378)
+++ src/parse/properties/white_space.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * white_space:CSS_PROP_WHITE_SPACE IDENT:( INHERIT: NORMAL:0,WHITE_SPACE_NORMAL PRE:0,WHITE_SPACE_PRE NOWRAP:0,WHITE_SPACE_NOWRAP PRE_WRAP:0,WHITE_SPACE_PRE_WRAP PRE_LINE:0,WHITE_SPACE_PRE_LINE  IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,78 +19,53 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse white-space
+ * Parse white_space
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_white_space(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_white_space(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (normal, pre, nowrap, pre-wrap, pre-line, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		value = WHITE_SPACE_NORMAL;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[PRE],
-			&match) == lwc_error_ok && match)) {
-		value = WHITE_SPACE_PRE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NOWRAP],
-			&match) == lwc_error_ok && match)) {
-		value = WHITE_SPACE_NOWRAP;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[PRE_WRAP],
-			&match) == lwc_error_ok && match)) {
-		value = WHITE_SPACE_PRE_WRAP;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[PRE_LINE],
-			&match) == lwc_error_ok && match)) {
-		value = WHITE_SPACE_PRE_LINE;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_WHITE_SPACE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WHITE_SPACE, 0,WHITE_SPACE_NORMAL);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[PRE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WHITE_SPACE, 0,WHITE_SPACE_PRE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NOWRAP], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WHITE_SPACE, 0,WHITE_SPACE_NOWRAP);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[PRE_WRAP], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WHITE_SPACE, 0,WHITE_SPACE_PRE_WRAP);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[PRE_LINE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WHITE_SPACE, 0,WHITE_SPACE_PRE_LINE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_WHITE_SPACE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/pause_after.c
===================================================================
--- src/parse/properties/pause_after.c	(revision 11378)
+++ src/parse/properties/pause_after.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * pause_after:CSS_PROP_PAUSE_AFTER IDENT:INHERIT LENGTH_UNIT:( UNIT_S:PAUSE_AFTER_SET DISALLOW:(unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false RANGE:<0 LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse pause-after
+ * Parse pause_after
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,9 +32,56 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_pause_after(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_pause_after(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_pause_common(c, vector, ctx, CSS_PROP_PAUSE_AFTER, result);
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PAUSE_AFTER);
+	} else {
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_S, &length, &unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		if ((unit&UNIT_TIME)==false&&(unit&UNIT_PCT)==false) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
+		}
+
+		if (length <0) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
+		}
+
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAUSE_AFTER, 0, PAUSE_AFTER_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+	}
+
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/border_bottom_color.c
===================================================================
--- src/parse/properties/border_bottom_color.c	(revision 11378)
+++ src/parse/properties/border_bottom_color.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_bottom_color(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_color(c, vector, ctx, 
-			CSS_PROP_BORDER_BOTTOM_COLOR, result);
+	return parse_border_side_color(c, vector, ctx, result, CSS_PROP_BORDER_BOTTOM_COLOR);
 }
Index: src/parse/properties/outline_style.c
===================================================================
--- src/parse/properties/outline_style.c	(revision 11378)
+++ src/parse/properties/outline_style.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * outline_style:CSS_PROP_OUTLINE_STYLE IDENT:( INHERIT: NONE:0,BORDER_STYLE_NONE DOTTED:0,BORDER_STYLE_DOTTED DASHED:0,BORDER_STYLE_DASHED SOLID:0,BORDER_STYLE_SOLID LIBCSS_DOUBLE:0,BORDER_STYLE_DOUBLE GROOVE:0,BORDER_STYLE_GROOVE RIDGE:0,BORDER_STYLE_RIDGE INSET:0,BORDER_STYLE_INSET OUTSET:0,BORDER_STYLE_OUTSET IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse outline-style
+ * Parse outline_style
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,32 +32,48 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_outline_style(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_outline_style(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	uint32_t opv;
-	uint16_t value;
+	const css_token *token;
+	bool match;
 
-	/* Parse as a border style  */
-	error = parse_border_side_style(c, vector, ctx, 
-			CSS_PROP_OUTLINE_STYLE, result);
-	if (error != CSS_OK) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
-		return error;
+		return CSS_INVALID;
 	}
 
-	opv = *((uint32_t *) (*result)->bytecode);
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_OUTLINE_STYLE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_NONE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DOTTED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_DOTTED);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[DASHED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_DASHED);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[SOLID], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_SOLID);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_DOUBLE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_DOUBLE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[GROOVE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_GROOVE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIDGE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_RIDGE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[INSET], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_INSET);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[OUTSET], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_OUTLINE_STYLE, 0,BORDER_STYLE_OUTSET);
+	} else {
+		error = CSS_INVALID;
+	}
 
-	value = getValue(opv);
-
-	/* Hidden is invalid */
-	if (value == BORDER_STYLE_HIDDEN) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
+	
+	return error;
+}
 
-	return CSS_OK;
-}
Index: src/parse/properties/caption_side.c
===================================================================
--- src/parse/properties/caption_side.c	(revision 11378)
+++ src/parse/properties/caption_side.c	(working copy)
@@ -29,51 +29,48 @@
  */
 css_error parse_caption_side(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (top, bottom, inherit) */
 	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	if ((ident == NULL) || (ident->type != CSS_TOKEN_IDENT)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
 	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		     ident->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CAPTION_SIDE,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[TOP],
-			&match) == lwc_error_ok && match)) {
-		value = CAPTION_SIDE_TOP;
+			    ident->idata, c->strings[TOP],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CAPTION_SIDE,
+						       0,
+						       CAPTION_SIDE_TOP);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[BOTTOM],
-			&match) == lwc_error_ok && match)) {
-		value = CAPTION_SIDE_BOTTOM;
+			    ident->idata, c->strings[BOTTOM],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CAPTION_SIDE,
+						       0,
+						       CAPTION_SIDE_BOTTOM);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_CAPTION_SIDE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
-		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/page_break_before.c
===================================================================
--- src/parse/properties/page_break_before.c	(revision 11378)
+++ src/parse/properties/page_break_before.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * page_break_before:CSS_PROP_PAGE_BREAK_BEFORE IDENT:( INHERIT: AUTO:0,PAGE_BREAK_BEFORE_AUTO ALWAYS:0,PAGE_BREAK_BEFORE_ALWAYS AVOID:0,PAGE_BREAK_BEFORE_AVOID LEFT:0,PAGE_BREAK_BEFORE_LEFT RIGHT:0,PAGE_BREAK_BEFORE_RIGHT IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,78 +19,53 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse page-break-before
+ * Parse page_break_before
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_page_break_before(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_page_break_before(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (auto, always, avoid, left, right, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_BEFORE_AUTO;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ALWAYS],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_BEFORE_ALWAYS;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AVOID],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_BEFORE_AVOID;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[LEFT],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_BEFORE_LEFT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[RIGHT],
-			&match) == lwc_error_ok && match)) {
-		value = PAGE_BREAK_BEFORE_RIGHT;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_PAGE_BREAK_BEFORE);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_BEFORE, 0,PAGE_BREAK_BEFORE_AUTO);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[ALWAYS], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_BEFORE, 0,PAGE_BREAK_BEFORE_ALWAYS);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AVOID], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_BEFORE, 0,PAGE_BREAK_BEFORE_AVOID);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[LEFT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_BEFORE, 0,PAGE_BREAK_BEFORE_LEFT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIGHT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_PAGE_BREAK_BEFORE, 0,PAGE_BREAK_BEFORE_RIGHT);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_PAGE_BREAK_BEFORE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/font_family.c
===================================================================
--- src/parse/properties/font_family.c	(revision 11378)
+++ src/parse/properties/font_family.c	(working copy)
@@ -46,9 +46,10 @@
  *
  * \param c	 Parsing context
  * \param token	 Token to consider
+ * \param first  Whether the token is the first
  * \return Bytecode value
  */
-static uint16_t font_family_value(css_language *c, const css_token *token)
+static css_code_t font_family_value(css_language *c, const css_token *token, bool first)
 {
 	uint16_t value;
 	bool match;
@@ -80,7 +81,7 @@
 		value = FONT_FAMILY_STRING;
 	}
 
-	return value;
+	return first ? buildOPV(CSS_PROP_FONT_FAMILY, 0, value) : value;
 }
 
 /**
@@ -99,17 +100,11 @@
  */
 css_error parse_font_family(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t required_size = sizeof(opv);
-	int temp_ctx = *ctx;
-	uint8_t *ptr;
 	bool match;
 
 	/* [ IDENT+ | STRING ] [ ',' [ IDENT+ | STRING ] ]* | IDENT(inherit)
@@ -121,8 +116,7 @@
 	 * Perhaps this is a quirk we should inherit?
 	 */
 
-	/* Pass 1: validate input and calculate space */
-	token = parserutils_vector_iterate(vector, &temp_ctx);
+	token = parserutils_vector_iterate(vector, ctx);
 	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
 			token->type != CSS_TOKEN_STRING)) {
 		*ctx = orig_ctx;
@@ -133,67 +127,25 @@
 			(lwc_string_caseless_isequal(
 			token->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags = FLAG_INHERIT;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_FAMILY);
 	} else {
-		uint32_t list_size;
+		*ctx = orig_ctx;
 
-		value = font_family_value(c, token);
-
-		error = comma_list_length(c, vector, &temp_ctx,
-				token, font_family_reserved, &list_size);
+		error = comma_list_to_style(c, vector, ctx,
+				font_family_reserved, font_family_value,
+				result);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		required_size += list_size;
+		error = css_stylesheet_style_append(result, FONT_FAMILY_END);
 	}
 
-	opv = buildOPV(CSS_PROP_FONT_FAMILY, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy OPV to bytecode */
-	ptr = (*result)->bytecode;
-	memcpy(ptr, &opv, sizeof(opv));
-	ptr += sizeof(opv);
-
-	/* Pass 2: populate bytecode */
-	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_STRING)) {
-		css_stylesheet_style_destroy(c->sheet, *result, false);
-		*result = NULL;
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		/* Nothing to do */
-	} else {
-		error = comma_list_to_bytecode(c, vector, ctx, token,
-				font_family_reserved, font_family_value,
-				&ptr);
-		if (error != CSS_OK) {
-			css_stylesheet_style_destroy(c->sheet, *result, false);
-			*result = NULL;
-			*ctx = orig_ctx;
-			return error;
-		}
-
-		/* Write terminator */
-		opv = FONT_FAMILY_END;
-		memcpy(ptr, &opv, sizeof(opv));
-		ptr += sizeof(opv);
-	}
-
 	return CSS_OK;
 }
Index: src/parse/properties/border_left_style.c
===================================================================
--- src/parse/properties/border_left_style.c	(revision 11378)
+++ src/parse/properties/border_left_style.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_left_style(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_style(c, vector, ctx, 
-			CSS_PROP_BORDER_LEFT_STYLE, result);
+	return parse_border_side_style(c, vector, ctx, result, CSS_PROP_BORDER_LEFT_STYLE);
 }
Index: src/parse/properties/border_right_width.c
===================================================================
--- src/parse/properties/border_right_width.c	(revision 11378)
+++ src/parse/properties/border_right_width.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_right_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_width(c, vector, ctx, 
-			CSS_PROP_BORDER_RIGHT_WIDTH, result);
+	return parse_border_side_width(c, vector, ctx, result, CSS_PROP_BORDER_RIGHT_WIDTH);
 }
Index: src/parse/properties/border_width.c
===================================================================
--- src/parse/properties/border_width.c	(revision 11378)
+++ src/parse/properties/border_width.c	(working copy)
@@ -29,96 +29,87 @@
  */
 css_error parse_border_width(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	int prev_ctx;
 	const css_token *token;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t num_sides = 0;
-	uint32_t required_size;
+	uint16_t side_val[4];
+	css_fixed side_length[4];
+	uint32_t side_unit[4];
+	uint32_t side_count = 0;
 	bool match;
 	css_error error;
 
 	/* Firstly, handle inherit */
 	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
-
-		error = css_stylesheet_style_create(c->sheet,
-			4 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
+	if (token == NULL) 
+		return CSS_INVALID;
+		
+	if (is_css_inherit(c, token)) {
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_WIDTH);
+		if (error != CSS_OK) 
 			return error;
-		}
 
-		bytecode = (uint32_t *) ret->bytecode;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_RIGHT_WIDTH);
+		if (error != CSS_OK) 
+			return error;		
 
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_WIDTH,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_RIGHT_WIDTH,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_BOTTOM_WIDTH,
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_BORDER_LEFT_WIDTH,
-				FLAG_INHERIT, 0);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_WIDTH);
+		if (error != CSS_OK) 
+			return error;
 
-		parserutils_vector_iterate(vector, ctx);
+		error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_WIDTH);
+		if (error == CSS_OK) 
+			parserutils_vector_iterate(vector, ctx);
 
-		*result = ret;
+		return error;
+	} 
 
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
 	/* Attempt to parse up to 4 widths */
 	do {
 		prev_ctx = *ctx;
-		error = CSS_OK;
 
-		/* Ensure that we're not about to parse another inherit */
-		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-				(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
+		if ((token != NULL) && is_css_inherit(c, token)) {
+			*ctx = orig_ctx;
+			return CSS_INVALID;
 		}
 
-		if (top == NULL &&
-				(error = parse_border_side_width(c, vector, 
-				ctx, CSS_PROP_BORDER_TOP_WIDTH, &top)) == 
-				CSS_OK) {
-			num_sides = 1;
-		} else if (right == NULL &&
-				(error = parse_border_side_width(c, vector, 
-				ctx, CSS_PROP_BORDER_RIGHT_WIDTH, &right)) == 
-				CSS_OK) {
-			num_sides = 2;
-		} else if (bottom == NULL &&
-				(error = parse_border_side_width(c, vector, 
-				ctx, CSS_PROP_BORDER_BOTTOM_WIDTH, &bottom)) == 
-				CSS_OK) {
-			num_sides = 3;
-		} else if (left == NULL &&
-				(error = parse_border_side_width(c, vector, 
-				ctx, CSS_PROP_BORDER_LEFT_WIDTH, &left)) == 
-				CSS_OK) {
-			num_sides = 4;
+		if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[THIN], &match) == lwc_error_ok && match)) {
+			side_val[side_count] =  BORDER_WIDTH_THIN;
+			parserutils_vector_iterate(vector, ctx);
+			error = CSS_OK;
+		} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MEDIUM], &match) == lwc_error_ok && match)) {
+			side_val[side_count] =  BORDER_WIDTH_MEDIUM;
+			parserutils_vector_iterate(vector, ctx);
+			error = CSS_OK;
+		} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[THICK], &match) == lwc_error_ok && match)) {
+			parserutils_vector_iterate(vector, ctx);
+			error = CSS_OK;
+			side_val[side_count] =  BORDER_WIDTH_THICK;
+		} else {
+			side_val[side_count] = BORDER_WIDTH_SET;
+
+			error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &side_length[side_count], &side_unit[side_count]);
+			if (error == CSS_OK) {
+				if (side_unit[side_count] == UNIT_PCT ||
+				    side_unit[side_count] & UNIT_ANGLE ||
+				    side_unit[side_count] & UNIT_TIME ||
+				    side_unit[side_count] & UNIT_FREQ) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+
+				if (side_length[side_count] < 0) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+			}
 		}
 
 		if (error == CSS_OK) {
+			side_count++;
+
 			consumeWhitespace(vector, ctx);
 
 			token = parserutils_vector_peek(vector, *ctx);
@@ -126,139 +117,52 @@
 			/* Forcibly cause loop to exit */
 			token = NULL;
 		}
-	} while (*ctx != prev_ctx && token != NULL);
+	} while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
 
-	if (num_sides == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
-	}
 
-	/* Calculate size of resultant style */
-	if (num_sides == 1) {
-		required_size = 4 * top->length;
-	} else if (num_sides == 2) {
-		required_size = 2 * top->length + 2 * right->length;
-	} else if (num_sides == 3) {
-		required_size = top->length + 2 * right->length + 
-				bottom->length;
-	} else {
-		required_size = top->length + right->length +
-				bottom->length + left->length;
+#define SIDE_APPEND(OP,NUM)								\
+	error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]);	\
+	if (error != CSS_OK)								\
+		break;									\
+	if (side_val[(NUM)] == BORDER_WIDTH_SET) {					\
+		error = css_stylesheet_style_append(result, side_length[(NUM)]);	\
+		if (error != CSS_OK)							\
+			break;								\
+		error = css_stylesheet_style_append(result, side_unit[(NUM)]);		\
+		if (error != CSS_OK)							\
+			break;								\
 	}
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_sides == 1) {
-		uint32_t *opv = ((uint32_t *) top->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_RIGHT_WIDTH, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_BOTTOM_WIDTH, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_WIDTH, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-	} else if (num_sides == 2) {
-		uint32_t *vopv = ((uint32_t *) top->bytecode);
-		uint32_t *hopv = ((uint32_t *) right->bytecode);
-		uint8_t vflags = getFlags(*vopv);
-		uint8_t hflags = getFlags(*hopv);
-		uint16_t vvalue = getValue(*vopv);
-		uint16_t hvalue = getValue(*hopv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		*vopv = buildOPV(CSS_PROP_BORDER_BOTTOM_WIDTH, vflags, vvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		*hopv = buildOPV(CSS_PROP_BORDER_LEFT_WIDTH, hflags, hvalue);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else if (num_sides == 3) {
-		uint32_t *opv = ((uint32_t *) right->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		*opv = buildOPV(CSS_PROP_BORDER_LEFT_WIDTH, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				top->bytecode, top->length);
-		required_size += top->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				right->bytecode, right->length);
-		required_size += right->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				bottom->bytecode, bottom->length);
-		required_size += bottom->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				left->bytecode, left->length);
-		required_size += left->length;
+	switch (side_count) {
+	case 1:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_WIDTH, 0);
+		break;
+	case 2:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_WIDTH, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_WIDTH, 1);
+		break;
+	case 3:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_WIDTH, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_WIDTH, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_WIDTH, 1);
+		break;
+	case 4:
+		SIDE_APPEND(CSS_PROP_BORDER_TOP_WIDTH, 0);
+		SIDE_APPEND(CSS_PROP_BORDER_RIGHT_WIDTH, 1);
+		SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_WIDTH, 2);
+		SIDE_APPEND(CSS_PROP_BORDER_LEFT_WIDTH, 3);
+		break;
+	default:
+		error = CSS_INVALID;
+		break;
 	}
 
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret, so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
 	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
Index: src/parse/properties/border.c
===================================================================
--- src/parse/properties/border.c	(revision 11378)
+++ src/parse/properties/border.c	(working copy)
@@ -29,81 +29,36 @@
  */
 css_error parse_border(css_language *c,
 		const parserutils_vector *vector, int *ctx,
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
-	css_style *top = NULL;
-	css_style *right = NULL;
-	css_style *bottom = NULL;
-	css_style *left = NULL;
-	css_style *ret = NULL;
-	uint32_t required_size;
 	css_error error;
 
-	error = parse_border_side(c, vector, ctx, BORDER_SIDE_TOP, &top);
-	if (error != CSS_OK)
-		goto cleanup;
+	error = parse_border_side(c, vector, ctx, result, BORDER_SIDE_TOP);
+	if (error != CSS_OK) {
+		*ctx = orig_ctx;
+		return error;
+	}
 
 	*ctx = orig_ctx;
-	error = parse_border_side(c, vector, ctx, BORDER_SIDE_RIGHT, &right);
-	if (error != CSS_OK)
-		goto cleanup;
+	error = parse_border_side(c, vector, ctx, result, BORDER_SIDE_RIGHT);
+	if (error != CSS_OK) {
+		*ctx = orig_ctx;
+		return error;
+	}
 
 	*ctx = orig_ctx;
-	error = parse_border_side(c, vector, ctx, BORDER_SIDE_BOTTOM, &bottom);
-	if (error != CSS_OK)
-		goto cleanup;
+	error = parse_border_side(c, vector, ctx, result, BORDER_SIDE_BOTTOM);
+	if (error != CSS_OK) {
+		*ctx = orig_ctx;
+		return error;
+	}
 
 	*ctx = orig_ctx;
-	error = parse_border_side(c, vector, ctx, BORDER_SIDE_LEFT, &left);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = top->length + right->length + 
-			bottom->length + left->length;
-
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
-	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	memcpy(((uint8_t *) ret->bytecode) + required_size, 
-			top->bytecode, top->length);
-	required_size += top->length;
-
-	memcpy(((uint8_t *) ret->bytecode) + required_size, 
-			right->bytecode, right->length);
-	required_size += right->length;
-
-	memcpy(((uint8_t *) ret->bytecode) + required_size, 
-			bottom->bytecode, bottom->length);
-	required_size += bottom->length;
-
-	memcpy(((uint8_t *) ret->bytecode) + required_size, 
-			left->bytecode, left->length);
-	required_size += left->length;
-
-	assert(required_size == ret->length);
-
-	*result = ret;
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (top)
-		css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK);
-	if (right)
-		css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK);
-	if (bottom)
-		css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK);
-	if (left)
-		css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
-	if (error != CSS_OK)
+	error = parse_border_side(c, vector, ctx, result, BORDER_SIDE_LEFT);
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-
+	
 	return error;
+		
 }
Index: src/parse/properties/background_color.c
===================================================================
--- src/parse/properties/background_color.c	(revision 11378)
+++ src/parse/properties/background_color.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * background_color:CSS_PROP_BACKGROUND_COLOR IDENT:( INHERIT: TRANSPARENT:0,BACKGROUND_COLOR_TRANSPARENT IDENT:) COLOR:BACKGROUND_COLOR_SET
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse background-color
+ * Parse background_color
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,68 +32,47 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_background_color(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_background_color(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	uint32_t colour = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* colour | IDENT (transparent, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT && 
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[TRANSPARENT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = BACKGROUND_COLOR_TRANSPARENT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_COLOR);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[TRANSPARENT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_BACKGROUND_COLOR, 0,BACKGROUND_COLOR_TRANSPARENT);
 	} else {
-		error = parse_colour_specifier(c, vector, ctx, &colour);
+		uint32_t color = 0;
+		*ctx = orig_ctx;
+
+		error = parse_colour_specifier(c, vector, ctx, &color);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		value = BACKGROUND_COLOR_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_BACKGROUND_COLOR, 0, BACKGROUND_COLOR_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_BACKGROUND_COLOR, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_COLOR_SET)
-		required_size += sizeof(colour);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_append(result, color);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_COLOR_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&colour, sizeof(colour));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/max_height.c
===================================================================
--- src/parse/properties/max_height.c	(revision 11378)
+++ src/parse/properties/max_height.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_max_height(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(none, inherit) */
@@ -83,26 +81,18 @@
 		value = MAX_HEIGHT_SET;
 	}
 
-	opv = buildOPV(CSS_PROP_MAX_HEIGHT, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == MAX_HEIGHT_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_MAX_HEIGHT, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == MAX_HEIGHT_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == MAX_HEIGHT_SET)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/pause.c
===================================================================
--- src/parse/properties/pause.c	(revision 11378)
+++ src/parse/properties/pause.c	(working copy)
@@ -27,146 +27,59 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_pause(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_pause(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
-	const css_token *token;
-	css_style *before = NULL;
-	css_style *after = NULL;
-	css_style *ret = NULL;
-	int num_read = 0;
-	int prev_ctx;
-	uint32_t required_size;
-	bool match;
 	css_error error;
+	const css_token *first_token;
+	const css_token *token;
 
-	/* Deal with inherit */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-		(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		uint32_t *bytecode;
+	/* one or two tokens follow:
+	 *  if one emit for both BEFORE and AFTER
+	 *  if two first is before second is after
+	 *  tokens are either IDENT:none or URI
+	 */
 
-		error = css_stylesheet_style_create(c->sheet,
-				2 * sizeof(uint32_t), &ret);
-		if (error != CSS_OK) {
-			*ctx = orig_ctx;
-			return error;
-		}
+	first_token = parserutils_vector_peek(vector, *ctx);
 
-		bytecode = (uint32_t *) ret->bytecode;
+	error = parse_pause_before(c, vector, ctx, result);
+	if (error == CSS_OK) {
+		/* first token parsed */
 
-		*(bytecode++) = buildOPV(CSS_PROP_PAUSE_BEFORE, 
-				FLAG_INHERIT, 0);
-		*(bytecode++) = buildOPV(CSS_PROP_PAUSE_AFTER, 
-				FLAG_INHERIT, 0);
+		consumeWhitespace(vector, ctx);
 
-		parserutils_vector_iterate(vector, ctx);
-
-		*result = ret;
-
-		return CSS_OK;
-	} else if (token == NULL) {
-		/* No tokens -- clearly garbage */
-		*ctx = orig_ctx;
-		return CSS_INVALID;
-	}
-
-	/* Attempt to read 1 or 2 pauses */
-	do {
-		prev_ctx = *ctx;
-		error = CSS_OK;
-
-		/* Ensure that we're not about to parse another inherit */
 		token = parserutils_vector_peek(vector, *ctx);
-		if (token != NULL && token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-				token->idata, c->strings[INHERIT],
-				&match) == lwc_error_ok && match)) {
-			error = CSS_INVALID;
-			goto cleanup;
-		}
-
-		if (before == NULL && (error = parse_pause_before(c, vector, 
-				ctx, &before)) == CSS_OK) {
-			num_read = 1;
-		} else if (after == NULL && 
-				(error = parse_pause_after(c, vector, ctx, 
-				&after)) == CSS_OK) {
-			num_read = 2;
-		}
-
-		if (error == CSS_OK) {
-			consumeWhitespace(vector, ctx);
-
-			token = parserutils_vector_peek(vector, *ctx);
+		if (token == NULL)  {
+			/* no second token, re-parse the first */
+			*ctx = orig_ctx;
+			error = parse_pause_after(c, vector, ctx, result);
 		} else {
-			token = NULL;
+			/* second token - might be useful */
+			if (is_css_inherit(c, token)) {
+				/* another bogus inherit */
+				error = CSS_INVALID;
+			} else {
+				error = parse_pause_after(c, vector, ctx, result);
+				if (error == CSS_OK) { 
+					/* second token parsed */
+					if (is_css_inherit(c, first_token)) {
+						/* valid second token after inherit */
+						error = CSS_INVALID;
+					}
+				} else {
+					/* second token appears to be junk re-try with first */
+					*ctx = orig_ctx;
+					error = parse_pause_after(c, vector, ctx, result);
+				}
+			}
 		}
-	} while (*ctx != prev_ctx && token != NULL);
-
-	if (num_read == 0) {
-		error = CSS_INVALID;
-		goto cleanup;
 	}
 
-	/* Calculate size of resultant style */
-	if (num_read == 1)
-		required_size = 2 * before->length;
-	else
-		required_size = before->length + after->length;
 
-	error = css_stylesheet_style_create(c->sheet, required_size, &ret);
 	if (error != CSS_OK)
-		goto cleanup;
-
-	required_size = 0;
-
-	if (num_read == 1) {
-		uint32_t *opv = ((uint32_t *) before->bytecode);
-		uint8_t flags = getFlags(*opv);
-		uint16_t value = getValue(*opv);
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-
-		*opv = buildOPV(CSS_PROP_PAUSE_AFTER, flags, value);
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-	} else {
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				before->bytecode, before->length);
-		required_size += before->length;
-
-		memcpy(((uint8_t *) ret->bytecode) + required_size,
-				after->bytecode, after->length);
-		required_size += after->length;
-	}
-
-	assert(required_size == ret->length);
-
-	/* Write the result */
-	*result = ret;
-	/* Invalidate ret so that cleanup doesn't destroy it */
-	ret = NULL;
-
-	/* Clean up after ourselves */
-cleanup:
-	if (before)
-		css_stylesheet_style_destroy(c->sheet, before, error == CSS_OK);
-	if (after)
-		css_stylesheet_style_destroy(c->sheet, after, error == CSS_OK);
-	if (ret)
-		css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK);
-
-	if (error != CSS_OK)
 		*ctx = orig_ctx;
 
 	return error;
 }
-
Index: src/parse/properties/unicode_bidi.c
===================================================================
--- src/parse/properties/unicode_bidi.c	(revision 11378)
+++ src/parse/properties/unicode_bidi.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * unicode_bidi:CSS_PROP_UNICODE_BIDI IDENT:( INHERIT: NORMAL:0,UNICODE_BIDI_NORMAL EMBED:0,UNICODE_BIDI_EMBED BIDI_OVERRIDE:0,UNICODE_BIDI_BIDI_OVERRIDE IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,70 +19,49 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse unicode-bidi
+ * Parse unicode_bidi
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_unicode_bidi(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_unicode_bidi(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (normal, embed, bidi-override, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		value = UNICODE_BIDI_NORMAL;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[EMBED],
-			&match) == lwc_error_ok && match)) {
-		value = UNICODE_BIDI_EMBED;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[BIDI_OVERRIDE],
-			&match) == lwc_error_ok && match)) {
-		value = UNICODE_BIDI_BIDI_OVERRIDE;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_UNICODE_BIDI);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_UNICODE_BIDI, 0,UNICODE_BIDI_NORMAL);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[EMBED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_UNICODE_BIDI, 0,UNICODE_BIDI_EMBED);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[BIDI_OVERRIDE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_UNICODE_BIDI, 0,UNICODE_BIDI_BIDI_OVERRIDE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_UNICODE_BIDI, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/list_style_position.c
===================================================================
--- src/parse/properties/list_style_position.c	(revision 11378)
+++ src/parse/properties/list_style_position.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * list_style_position:CSS_PROP_LIST_STYLE_POSITION IDENT:( INHERIT: INSIDE:0,LIST_STYLE_POSITION_INSIDE OUTSIDE:0,LIST_STYLE_POSITION_OUTSIDE IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse list-style-position
+ * Parse list_style_position
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,53 +32,43 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_list_style_position(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_list_style_position(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (inside, outside, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INSIDE],
-			&match) == lwc_error_ok && match)) {
-		value = LIST_STYLE_POSITION_INSIDE;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[OUTSIDE],
-			&match) == lwc_error_ok && match)) {
-		value = LIST_STYLE_POSITION_OUTSIDE;
+ if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(
+		     token->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_LIST_STYLE_POSITION);
+	} else  if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(
+		     token->idata, c->strings[INSIDE],
+		     &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_LIST_STYLE_POSITION, 0,LIST_STYLE_POSITION_INSIDE);
+	} else  if ((token->type == CSS_TOKEN_IDENT) && 
+	    (lwc_string_caseless_isequal(
+		     token->idata, c->strings[OUTSIDE],
+		     &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_LIST_STYLE_POSITION, 0,LIST_STYLE_POSITION_OUTSIDE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_LIST_STYLE_POSITION, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/word_spacing.c
===================================================================
--- src/parse/properties/word_spacing.c	(revision 11378)
+++ src/parse/properties/word_spacing.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * word_spacing:CSS_PROP_WORD_SPACING IDENT:( INHERIT: NORMAL:0,WORD_SPACING_NORMAL IDENT:) LENGTH_UNIT:( UNIT_PX:WORD_SPACING_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ||unit&UNIT_PCT LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,91 +19,66 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse word-spacing
+ * Parse word_spacing
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_word_spacing(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_word_spacing(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | IDENT(normal, inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		value = WORD_SPACING_NORMAL;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_WORD_SPACING);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_WORD_SPACING, 0,WORD_SPACING_NORMAL);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ ||
-				unit & UNIT_PCT) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ||unit&UNIT_PCT) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = WORD_SPACING_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_WORD_SPACING, 0, WORD_SPACING_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_WORD_SPACING, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == WORD_SPACING_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == WORD_SPACING_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/direction.c
===================================================================
--- src/parse/properties/direction.c	(revision 11378)
+++ src/parse/properties/direction.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_direction(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (ltr, rtl, inherit) */
@@ -49,31 +46,30 @@
 	if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_DIRECTION,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[LTR],
 			&match) == lwc_error_ok && match)) {
-		value = DIRECTION_LTR;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_DIRECTION,
+						       0,
+						       DIRECTION_LTR);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[RTL],
 			&match) == lwc_error_ok && match)) {
-		value = DIRECTION_RTL;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_DIRECTION,
+						       0,
+						       DIRECTION_RTL);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_DIRECTION, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/padding_left.c
===================================================================
--- src/parse/properties/padding_left.c	(revision 11378)
+++ src/parse/properties/padding_left.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * padding_left:CSS_PROP_PADDING_LEFT WRAP:parse_padding_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse padding-left
+ * Parse padding_left
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_padding_left(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_padding_left(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_padding_side(c, vector, ctx, 
-			CSS_PROP_PADDING_LEFT, result);
+	return parse_padding_side(c, vector, ctx, result, CSS_PROP_PADDING_LEFT);
 }
Index: src/parse/properties/azimuth.c
===================================================================
--- src/parse/properties/azimuth.c	(revision 11378)
+++ src/parse/properties/azimuth.c	(working copy)
@@ -19,7 +19,7 @@
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  style to place resulting bytcode in
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -29,17 +29,15 @@
  */
 css_error parse_azimuth(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* angle | [ IDENT(left-side, far-left, left, center-left, center, 
@@ -219,26 +217,18 @@
 		value = AZIMUTH_ANGLE;
 	}
 
-	opv = buildOPV(CSS_PROP_AZIMUTH, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == AZIMUTH_ANGLE)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_AZIMUTH, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == AZIMUTH_ANGLE) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == AZIMUTH_ANGLE)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/min_width.c
===================================================================
--- src/parse/properties/min_width.c	(revision 11378)
+++ src/parse/properties/min_width.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_min_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(inherit) */
@@ -77,26 +75,18 @@
 		value = MIN_WIDTH_SET;
 	}
 
-	opv = buildOPV(CSS_PROP_MIN_WIDTH, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == MIN_WIDTH_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_MIN_WIDTH, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == MIN_WIDTH_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == MIN_WIDTH_SET)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/speech_rate.c
===================================================================
--- src/parse/properties/speech_rate.c	(revision 11378)
+++ src/parse/properties/speech_rate.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * speech_rate:CSS_PROP_SPEECH_RATE IDENT:( INHERIT: X_SLOW:0,SPEECH_RATE_X_SLOW SLOW:0,SPEECH_RATE_SLOW MEDIUM:0,SPEECH_RATE_MEDIUM FAST:0,SPEECH_RATE_FAST X_FAST:0,SPEECH_RATE_X_FAST FASTER:0,SPEECH_RATE_FASTER SLOWER:0,SPEECH_RATE_SLOWER IDENT:) NUMBER:( false:SPEECH_RATE_SET RANGE:num<0 NUMBER:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse speech-rate
+ * Parse speech_rate
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,110 +32,66 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_speech_rate(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_speech_rate(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed num = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* number | IDENT (x-slow, slow, medium, fast, x-fast, faster, slower, 
-	 *		 inherit)
-	 */
 	token = parserutils_vector_iterate(vector, ctx);
-	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
-			token->type != CSS_TOKEN_NUMBER)) {
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_SLOW],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_X_SLOW;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SLOW],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_SLOW;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[MEDIUM],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_MEDIUM;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[FAST],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_FAST;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[X_FAST],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_X_FAST;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[FASTER],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_FASTER;
-	} else if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[SLOWER],
-			&match) == lwc_error_ok && match)) {
-		value = SPEECH_RATE_SLOWER;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_SPEECH_RATE);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_SLOW], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_X_SLOW);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SLOW], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_SLOW);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[MEDIUM], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_MEDIUM);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[FAST], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_FAST);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[X_FAST], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_X_FAST);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[FASTER], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_FASTER);
+	} else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[SLOWER], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0,SPEECH_RATE_SLOWER);
 	} else if (token->type == CSS_TOKEN_NUMBER) {
+		css_fixed num = 0;
 		size_t consumed = 0;
+
 		num = number_from_lwc_string(token->idata, false, &consumed);
 		/* Invalid if there are trailing characters */
 		if (consumed != lwc_string_length(token->idata)) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
-
-		/* Make negative values invalid */
-		if (num < 0) {
+		if (num<0) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = SPEECH_RATE_SET;
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_SPEECH_RATE, 0, SPEECH_RATE_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		error = css_stylesheet_style_append(result, num);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_SPEECH_RATE, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == SPEECH_RATE_SET)
-		required_size += sizeof(num);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == SPEECH_RATE_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), 
-				&num, sizeof(num));
-	}
-
-	return CSS_OK;
+	
+	return error;
 }
+
Index: src/parse/properties/counter_increment.c
===================================================================
--- src/parse/properties/counter_increment.c	(revision 11378)
+++ src/parse/properties/counter_increment.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * counter_increment:CSS_PROP_COUNTER_INCREMENT IDENT:( INHERIT: NONE:0,COUNTER_INCREMENT_NONE IDENT:) IDENT_LIST:( STRING_OPTNUM:COUNTER_INCREMENT_NAMED 1:COUNTER_INCREMENT_NONE IDENT_LIST:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse counter-increment
+ * Parse counter_increment
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,95 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_counter_increment(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_counter_increment(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_counter_common(c, vector, ctx, 
-			CSS_PROP_COUNTER_INCREMENT, result);
+	int orig_ctx = *ctx;
+	css_error error;
+	const css_token *token;
+	bool match;
+
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
+		*ctx = orig_ctx;
+		return CSS_INVALID;
+	}
+
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_COUNTER_INCREMENT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_COUNTER_INCREMENT, 0,COUNTER_INCREMENT_NONE);
+	} else {
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_COUNTER_INCREMENT, 0, COUNTER_INCREMENT_NAMED);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
+
+		while ((token != NULL) && (token->type == CSS_TOKEN_IDENT)) {
+			uint32_t snumber;
+			css_fixed num;
+			int pctx;
+
+			error = css_stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &snumber);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			error = css_stylesheet_style_append(result, snumber);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			consumeWhitespace(vector, ctx);
+
+			pctx = *ctx;
+			token = parserutils_vector_iterate(vector, ctx);
+			if ((token != NULL) && (token->type == CSS_TOKEN_NUMBER)) {
+				size_t consumed = 0;
+
+				num = number_from_lwc_string(token->idata, true, &consumed);
+				if (consumed != lwc_string_length(token->idata)) {
+					*ctx = orig_ctx;
+					return CSS_INVALID;
+				}
+				consumeWhitespace(vector, ctx);
+
+				pctx = *ctx;
+				token = parserutils_vector_iterate(vector, ctx);
+			} else {
+				num = INTTOFIX(1);
+			}
+
+			error = css_stylesheet_style_append(result, num);
+			if (error != CSS_OK) {
+				*ctx = orig_ctx;
+				return error;
+			}
+
+			if (token == NULL)
+				break;
+
+			if (token->type == CSS_TOKEN_IDENT) {
+				error = css_stylesheet_style_append(result, COUNTER_INCREMENT_NAMED);
+				if (error != CSS_OK) {
+					*ctx = orig_ctx;
+					return error;
+				}
+			} else {
+				*ctx = pctx; /* rewind one token back */
+			}
+		}
+
+		error = css_stylesheet_style_append(result, COUNTER_INCREMENT_NONE);
+	}
+
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/max_width.c
===================================================================
--- src/parse/properties/max_width.c	(revision 11378)
+++ src/parse/properties/max_width.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_max_width(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* length | percentage | IDENT(none, inherit) */
@@ -83,26 +81,18 @@
 		value = MAX_WIDTH_SET;
 	}
 
-	opv = buildOPV(CSS_PROP_MAX_WIDTH, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == MAX_WIDTH_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_MAX_WIDTH, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == MAX_WIDTH_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == MAX_WIDTH_SET)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/table_layout.c
===================================================================
--- src/parse/properties/table_layout.c	(revision 11378)
+++ src/parse/properties/table_layout.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * table_layout:CSS_PROP_TABLE_LAYOUT IDENT:( INHERIT: AUTO:0,TABLE_LAYOUT_AUTO FIXED:0,TABLE_LAYOUT_FIXED IDENT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,67 +19,47 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse table-layout
+ * Parse table_layout
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_table_layout(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_table_layout(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
-	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
+	const css_token *token;
 	bool match;
 
-	/* IDENT (auto, fixed, inherit) */
-	ident = parserutils_vector_iterate(vector, ctx);
-	if (ident == NULL || ident->type != CSS_TOKEN_IDENT) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[AUTO],
-			&match) == lwc_error_ok && match)) {
-		value = TABLE_LAYOUT_AUTO;
-	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[FIXED],
-			&match) == lwc_error_ok && match)) {
-		value = TABLE_LAYOUT_FIXED;
+	if ((lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_TABLE_LAYOUT);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[AUTO], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TABLE_LAYOUT, 0,TABLE_LAYOUT_AUTO);
+	} else if ((lwc_string_caseless_isequal(token->idata, c->strings[FIXED], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_appendOPV(result, CSS_PROP_TABLE_LAYOUT, 0,TABLE_LAYOUT_FIXED);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_TABLE_LAYOUT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
 
Index: src/parse/properties/text_indent.c
===================================================================
--- src/parse/properties/text_indent.c	(revision 11378)
+++ src/parse/properties/text_indent.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * text_indent:CSS_PROP_TEXT_INDENT IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:TEXT_INDENT_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ LENGTH_UNIT:)
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,84 +19,64 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse text-indent
+ * Parse text_indent
  *
- * \param c       Parsing context
+ * \param c	  Parsing context
  * \param vector  Vector of tokens to process
- * \param ctx     Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param ctx	  Pointer to vector iteration context
+ * \param result  resulting style
  * \return CSS_OK on success,
- *         CSS_NOMEM on memory exhaustion,
- *         CSS_INVALID if the input is not valid
+ *	   CSS_NOMEM on memory exhaustion,
+ *	   CSS_INVALID if the input is not valid
  *
  * Post condition: \a *ctx is updated with the next token to process
- *                 If the input is invalid, then \a *ctx remains unchanged.
+ *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_text_indent(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_text_indent(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
-	css_fixed length = 0;
-	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
-	/* length | percentage | IDENT(inherit) */
-	token = parserutils_vector_peek(vector, *ctx);
-	if (token == NULL) {
+	token = parserutils_vector_iterate(vector, ctx);
+	if ((token == NULL)) {
 		*ctx = orig_ctx;
 		return CSS_INVALID;
 	}
 
-	if (token->type == CSS_TOKEN_IDENT &&
-			(lwc_string_caseless_isequal(
-			token->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		parserutils_vector_iterate(vector, ctx);
-		flags = FLAG_INHERIT;
+	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
+			error = css_stylesheet_style_inherit(result, CSS_PROP_TEXT_INDENT);
 	} else {
-		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
-				&length, &unit);
+		css_fixed length = 0;
+		uint32_t unit = 0;
+		*ctx = orig_ctx;
+
+		error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &length, &unit);
 		if (error != CSS_OK) {
 			*ctx = orig_ctx;
 			return error;
 		}
 
-		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
+		if (unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ) {
 			*ctx = orig_ctx;
 			return CSS_INVALID;
 		}
 
-		value = TEXT_INDENT_SET;
-	}
+		error = css_stylesheet_style_appendOPV(result, CSS_PROP_TEXT_INDENT, 0, TEXT_INDENT_SET);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 
-	opv = buildOPV(CSS_PROP_TEXT_INDENT, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == TEXT_INDENT_SET)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
-	if (error != CSS_OK) {
-		*ctx = orig_ctx;
-		return error;
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == TEXT_INDENT_SET) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
-	}
-
-	return CSS_OK;
+	if (error != CSS_OK)
+		*ctx = orig_ctx;
+	
+	return error;
 }
+
Index: src/parse/properties/font_style.c
===================================================================
--- src/parse/properties/font_style.c	(revision 11378)
+++ src/parse/properties/font_style.c	(working copy)
@@ -27,16 +27,13 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_font_style(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_font_style(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (normal, italic, oblique, inherit) */
@@ -47,37 +44,40 @@
 	}
 
 	if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[INHERIT],
-			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		     ident->idata, c->strings[INHERIT],
+		     &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_STYLE,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[NORMAL],
-			&match) == lwc_error_ok && match)) {
-		value = FONT_STYLE_NORMAL;
+			    ident->idata, c->strings[NORMAL],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_STYLE,
+						       0,
+						       FONT_STYLE_NORMAL);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[ITALIC],
-			&match) == lwc_error_ok && match)) {
-		value = FONT_STYLE_ITALIC;
+			    ident->idata, c->strings[ITALIC],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_STYLE,
+						       0,
+						       FONT_STYLE_ITALIC);
 	} else if ((lwc_string_caseless_isequal(
-			ident->idata, c->strings[OBLIQUE],
-			&match) == lwc_error_ok && match)) {
-		value = FONT_STYLE_OBLIQUE;
+			    ident->idata, c->strings[OBLIQUE],
+			    &match) == lwc_error_ok && match)) {
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_STYLE,
+						       0,
+						       FONT_STYLE_OBLIQUE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_FONT_STYLE, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK)
 		*ctx = orig_ctx;
-		return error;
-	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
 
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/elevation.c
===================================================================
--- src/parse/properties/elevation.c	(revision 11378)
+++ src/parse/properties/elevation.c	(working copy)
@@ -29,17 +29,15 @@
  */
 css_error parse_elevation(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *token;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	css_fixed length = 0;
 	uint32_t unit = 0;
-	uint32_t required_size;
 	bool match;
 
 	/* angle | IDENT(below, level, above, higher, lower, inherit) */
@@ -119,26 +117,18 @@
 		value = ELEVATION_ANGLE;
 	}
 
-	opv = buildOPV(CSS_PROP_ELEVATION, flags, value);
-
-	required_size = sizeof(opv);
-	if ((flags & FLAG_INHERIT) == false && value == ELEVATION_ANGLE)
-		required_size += sizeof(length) + sizeof(unit);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, required_size, result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_ELEVATION, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-	if ((flags & FLAG_INHERIT) == false && value == ELEVATION_ANGLE) {
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
-				&length, sizeof(length));
-		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
-				sizeof(length), &unit, sizeof(unit));
+	if (((flags & FLAG_INHERIT) == false) && (value == ELEVATION_ANGLE)) {
+		error = css_stylesheet_style_vappend(result, 2, length, unit);
+		if (error != CSS_OK) {
+			*ctx = orig_ctx;
+			return error;
+		}
 	}
 
 	return CSS_OK;
Index: src/parse/properties/clear.c
===================================================================
--- src/parse/properties/clear.c	(revision 11378)
+++ src/parse/properties/clear.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_clear(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (left, right, both, none, inherit) */
@@ -49,39 +46,45 @@
 	if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLEAR,
+						       FLAG_INHERIT,
+						       0);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[RIGHT],
 			&match) == lwc_error_ok && match)) {
-		value = CLEAR_RIGHT;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLEAR,
+						       0,
+						       CLEAR_RIGHT);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[LEFT],
 			&match) == lwc_error_ok && match)) {
-		value = CLEAR_LEFT;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLEAR,
+						       0,
+						       CLEAR_LEFT);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[BOTH],
 			&match) == lwc_error_ok && match)) {
-		value = CLEAR_BOTH;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLEAR,
+						       0,
+						       CLEAR_BOTH);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[NONE],
 			&match) == lwc_error_ok && match)) {
-		value = CLEAR_NONE;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_CLEAR,
+						       0,
+						       CLEAR_NONE);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_CLEAR, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
-		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	return error;
 }
Index: src/parse/properties/background_attachment.c
===================================================================
--- src/parse/properties/background_attachment.c	(revision 11378)
+++ src/parse/properties/background_attachment.c	(working copy)
@@ -29,14 +29,13 @@
  */
 css_error parse_background_attachment(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (fixed, scroll, inherit) */
@@ -63,17 +62,11 @@
 		return CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_BACKGROUND_ATTACHMENT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_BACKGROUND_ATTACHMENT, flags, value);
 	if (error != CSS_OK) {
 		*ctx = orig_ctx;
 		return error;
 	}
 
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
 	return CSS_OK;
 }
Index: src/parse/properties/font_variant.c
===================================================================
--- src/parse/properties/font_variant.c	(revision 11378)
+++ src/parse/properties/font_variant.c	(working copy)
@@ -29,14 +29,11 @@
  */
 css_error parse_font_variant(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
-	uint8_t flags = 0;
-	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (normal, small-caps, inherit) */
@@ -49,31 +46,27 @@
 	if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[INHERIT],
 			&match) == lwc_error_ok && match)) {
-		flags |= FLAG_INHERIT;
+		error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_VARIANT);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[NORMAL],
 			&match) == lwc_error_ok && match)) {
-		value = FONT_VARIANT_NORMAL;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_VARIANT,
+						       0,
+						       FONT_VARIANT_NORMAL);
 	} else if ((lwc_string_caseless_isequal(
 			ident->idata, c->strings[SMALL_CAPS],
 			&match) == lwc_error_ok && match)) {
-		value = FONT_VARIANT_SMALL_CAPS;
+		error = css_stylesheet_style_appendOPV(result,
+						       CSS_PROP_FONT_VARIANT,
+						       0,
+						       FONT_VARIANT_SMALL_CAPS);
 	} else {
-		*ctx = orig_ctx;
-		return CSS_INVALID;
+		error = CSS_INVALID;
 	}
 
-	opv = buildOPV(CSS_PROP_FONT_VARIANT, flags, value);
-
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
Index: src/parse/properties/padding_bottom.c
===================================================================
--- src/parse/properties/padding_bottom.c	(revision 11378)
+++ src/parse/properties/padding_bottom.c	(working copy)
@@ -1,5 +1,10 @@
 /*
- * This file is part of LibCSS.
+ * This file was generated by LibCSS gen_parser 
+ * 
+ * Generated from:
+ *
+ * padding_bottom:CSS_PROP_PADDING_BOTTOM WRAP:parse_padding_side
+ * 
  * Licensed under the MIT License,
  *		  http://www.opensource.org/licenses/mit-license.php
  * Copyright 2009 John-Mark Bell <jmb at netsurf-browser.org>
@@ -14,12 +19,12 @@
 #include "parse/properties/utils.h"
 
 /**
- * Parse padding-bottom
+ * Parse padding_bottom
  *
  * \param c	  Parsing context
  * \param vector  Vector of tokens to process
  * \param ctx	  Pointer to vector iteration context
- * \param result  Pointer to location to receive resulting style
+ * \param result  resulting style
  * \return CSS_OK on success,
  *	   CSS_NOMEM on memory exhaustion,
  *	   CSS_INVALID if the input is not valid
@@ -27,10 +32,9 @@
  * Post condition: \a *ctx is updated with the next token to process
  *		   If the input is invalid, then \a *ctx remains unchanged.
  */
-css_error parse_padding_bottom(css_language *c, 
-		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+css_error parse_padding_bottom(css_language *c,
+		const parserutils_vector *vector, int *ctx,
+		css_style *result)
 {
-	return parse_padding_side(c, vector, ctx, 
-			CSS_PROP_PADDING_BOTTOM, result);
+	return parse_padding_side(c, vector, ctx, result, CSS_PROP_PADDING_BOTTOM);
 }
Index: src/parse/properties/list_style_type.c
===================================================================
--- src/parse/properties/list_style_type.c	(revision 11378)
+++ src/parse/properties/list_style_type.c	(working copy)
@@ -29,14 +29,13 @@
  */
 css_error parse_list_style_type(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
 	int orig_ctx = *ctx;
 	css_error error;
 	const css_token *ident;
 	uint8_t flags = 0;
 	uint16_t value = 0;
-	uint32_t opv;
 	bool match;
 
 	/* IDENT (disc, circle, square, decimal, decimal-leading-zero,
@@ -62,17 +61,10 @@
 		}
 	}
 
-	opv = buildOPV(CSS_PROP_LIST_STYLE_TYPE, flags, value);
+	error = css_stylesheet_style_appendOPV(result, CSS_PROP_LIST_STYLE_TYPE, flags, value);
 
-	/* Allocate result */
-	error = css_stylesheet_style_create(c->sheet, sizeof(opv), result);
-	if (error != CSS_OK) {	
+	if (error != CSS_OK) 
 		*ctx = orig_ctx;
-		return error;
-	}
-
-	/* Copy the bytecode to it */
-	memcpy((*result)->bytecode, &opv, sizeof(opv));
-
-	return CSS_OK;
+	
+	return error;
 }
Index: src/parse/properties/border_top_color.c
===================================================================
--- src/parse/properties/border_top_color.c	(revision 11378)
+++ src/parse/properties/border_top_color.c	(working copy)
@@ -29,8 +29,7 @@
  */
 css_error parse_border_top_color(css_language *c, 
 		const parserutils_vector *vector, int *ctx, 
-		css_style **result)
+		css_style *result)
 {
-	return parse_border_side_color(c, vector, ctx, 
-			CSS_PROP_BORDER_TOP_COLOR, result);
+	return parse_border_side_color(c, vector, ctx, result, CSS_PROP_BORDER_TOP_COLOR);
 }
Index: src/parse/important.c
===================================================================
--- src/parse/important.c	(revision 11378)
+++ src/parse/important.c	(working copy)
@@ -66,20 +66,15 @@
  */
 void make_style_important(css_style *style)
 {
-	void *bytecode = style->bytecode;
-	size_t length = style->length;
+	css_code_t *bytecode = style->bytecode;
+	uint32_t length = style->used;
 	uint32_t offset = 0;
 
-#define ADVANCE(n) do {					\
-	offset += (n);					\
-	bytecode = ((uint8_t *) bytecode) + (n);	\
-} while(0)
-
 	while (offset < length) {
 		opcode_t op;
 		uint8_t flags;
 		uint32_t value;
-		uint32_t opv = *((uint32_t *) bytecode);
+		css_code_t opv = bytecode[offset];
 
 		/* Extract opv components, setting important flag */
 		op = getOpcode(opv);
@@ -87,20 +82,18 @@
 		value = getValue(opv);
 
 		/* Write OPV back to bytecode */
-		*((uint32_t *) bytecode) = buildOPV(op, flags, value);
+		bytecode[offset] = buildOPV(op, flags, value);
 
-		ADVANCE(sizeof(opv));
+		offset++;
 
 		/* Advance past any property-specific data */
 		if (isInherit(opv) == false) {
 			switch (op) {
 			case CSS_PROP_AZIMUTH:
-				if ((value & ~AZIMUTH_BEHIND) == 
-						AZIMUTH_ANGLE) {
-					ADVANCE(sizeof(css_fixed) + 
-							sizeof(uint32_t));
-				}
+				if ((value & ~AZIMUTH_BEHIND) == AZIMUTH_ANGLE)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_BORDER_TOP_COLOR:
 			case CSS_PROP_BORDER_RIGHT_COLOR:
 			case CSS_PROP_BORDER_BOTTOM_COLOR:
@@ -109,10 +102,10 @@
 				assert(BACKGROUND_COLOR_SET == 
 						BORDER_COLOR_SET);
 
-				if (value == BACKGROUND_COLOR_SET) {
-					ADVANCE(sizeof(uint32_t));
-				}
+				if (value == BACKGROUND_COLOR_SET)
+					offset++; /* colour */
 				break;
+
 			case CSS_PROP_BACKGROUND_IMAGE:
 			case CSS_PROP_CUE_AFTER:
 			case CSS_PROP_CUE_BEFORE:
@@ -122,28 +115,23 @@
 				assert(BACKGROUND_IMAGE_URI ==
 						LIST_STYLE_IMAGE_URI);
 
-				if (value == BACKGROUND_IMAGE_URI) {
-					ADVANCE(sizeof(lwc_string *));
-				}
+				if (value == BACKGROUND_IMAGE_URI) 
+					offset++; /* string table entry */
 				break;
+
 			case CSS_PROP_BACKGROUND_POSITION:
-				if ((value & 0xf0) ==
-						BACKGROUND_POSITION_HORZ_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
-				if ((value & 0x0f) ==
-						BACKGROUND_POSITION_VERT_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if ((value & 0xf0) == BACKGROUND_POSITION_HORZ_SET)
+					offset += 2; /* length + units */
+
+				if ((value & 0x0f) == BACKGROUND_POSITION_VERT_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_BORDER_SPACING:
-				if (value == BORDER_SPACING_SET) {
-					ADVANCE(2 * sizeof(css_fixed) +
-							2 * sizeof(uint32_t));
-				}
+				if (value == BORDER_SPACING_SET)
+					offset += 4; /* two length + units */
 				break;
+
 			case CSS_PROP_BORDER_TOP_WIDTH:
 			case CSS_PROP_BORDER_RIGHT_WIDTH:
 			case CSS_PROP_BORDER_BOTTOM_WIDTH:
@@ -151,11 +139,10 @@
 			case CSS_PROP_OUTLINE_WIDTH:
 				assert(BORDER_WIDTH_SET == OUTLINE_WIDTH_SET);
 
-				if (value == BORDER_WIDTH_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == BORDER_WIDTH_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_MARGIN_TOP:
 			case CSS_PROP_MARGIN_RIGHT:
 			case CSS_PROP_MARGIN_BOTTOM:
@@ -173,40 +160,32 @@
 				assert(BOTTOM_SET == MARGIN_SET);
 				assert(BOTTOM_SET == WIDTH_SET);
 
-				if (value == BOTTOM_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == BOTTOM_SET) 
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_CLIP:
-				if ((value & CLIP_SHAPE_MASK) == 
-						CLIP_SHAPE_RECT) {
-					if ((value & CLIP_RECT_TOP_AUTO) == 0) {
-						ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-					}
-					if ((value & CLIP_RECT_RIGHT_AUTO) == 
-							0) {
-						ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-					}
-					if ((value & CLIP_RECT_BOTTOM_AUTO) == 
-							0) {
-						ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-					}
-					if ((value & CLIP_RECT_LEFT_AUTO) == 
-							0) {
-						ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-					}
+				if ((value & CLIP_SHAPE_MASK) == CLIP_SHAPE_RECT) {
+					if ((value & CLIP_RECT_TOP_AUTO) == 0)
+						offset += 2; /* length + units */
+
+					if ((value & CLIP_RECT_RIGHT_AUTO) == 0)
+						offset += 2; /* length + units */
+
+					if ((value & CLIP_RECT_BOTTOM_AUTO) == 0)
+						offset += 2; /* length + units */
+
+					if ((value & CLIP_RECT_LEFT_AUTO) == 0)
+						offset += 2; /* length + units */
+
 				}
 				break;
+
 			case CSS_PROP_COLOR:
-				if (value == COLOR_SET) {
-					ADVANCE(sizeof(uint32_t));
-				}	
+				if (value == COLOR_SET)
+					offset++; /* colour */
 				break;
+
 			case CSS_PROP_CONTENT:
 				while (value != CONTENT_NORMAL &&
 						value != CONTENT_NONE) {
@@ -215,12 +194,13 @@
 					case CONTENT_URI:
 					case CONTENT_ATTR:
 					case CONTENT_STRING:
-						ADVANCE(sizeof(lwc_string *));
+						offset++; /* string table entry */
 						break;
+
 					case CONTENT_COUNTERS:
-						ADVANCE(2 * 
-							sizeof(lwc_string *));
+						offset+=2; /* two string entries */
 						break;
+
 					case CONTENT_OPEN_QUOTE:
 					case CONTENT_CLOSE_QUOTE:
 					case CONTENT_NO_OPEN_QUOTE:
@@ -228,85 +208,85 @@
 						break;
 					}
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_COUNTER_INCREMENT:
 			case CSS_PROP_COUNTER_RESET:
 				assert(COUNTER_INCREMENT_NONE == 
 						COUNTER_RESET_NONE);
 
 				while (value != COUNTER_INCREMENT_NONE) {
-					ADVANCE(sizeof(lwc_string *) +
-							sizeof(css_fixed));
+					offset+=2; /* string + integer */
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_CURSOR:
 				while (value == CURSOR_URI) {
-					ADVANCE(sizeof(lwc_string *));
+					offset++; /* string table entry */
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_ELEVATION:
-				if (value == ELEVATION_ANGLE) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == ELEVATION_ANGLE)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_FONT_FAMILY:
 				while (value != FONT_FAMILY_END) {
 					switch (value) {
 					case FONT_FAMILY_STRING:
 					case FONT_FAMILY_IDENT_LIST:
-						ADVANCE(sizeof(lwc_string *));
+						offset++; /* string table entry */
 						break;
 					}
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_FONT_SIZE:
-				if (value == FONT_SIZE_DIMENSION) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == FONT_SIZE_DIMENSION) 
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_LETTER_SPACING:
 			case CSS_PROP_WORD_SPACING:
 				assert(LETTER_SPACING_SET == WORD_SPACING_SET);
 
-				if (value == LETTER_SPACING_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == LETTER_SPACING_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_LINE_HEIGHT:
 				switch (value) {
 				case LINE_HEIGHT_NUMBER:
-					ADVANCE(sizeof(css_fixed));
+					offset++; /* value */
 					break;
+
 				case LINE_HEIGHT_DIMENSION:
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
+					offset += 2; /* length + units */
 					break;
 				}
 				break;
+
 			case CSS_PROP_MAX_HEIGHT:
 			case CSS_PROP_MAX_WIDTH:
 				assert(MAX_HEIGHT_SET == MAX_WIDTH_SET);
 
-				if (value == MAX_HEIGHT_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == MAX_HEIGHT_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_PADDING_TOP:
 			case CSS_PROP_PADDING_RIGHT:
 			case CSS_PROP_PADDING_BOTTOM:
@@ -322,11 +302,10 @@
 				assert(MIN_HEIGHT_SET == PAUSE_BEFORE_SET);
 				assert(MIN_HEIGHT_SET == TEXT_INDENT_SET);
 
-				if (value == MIN_HEIGHT_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == MIN_HEIGHT_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_ORPHANS:
 			case CSS_PROP_PITCH_RANGE:
 			case CSS_PROP_RICHNESS:
@@ -337,81 +316,80 @@
 				assert(ORPHANS_SET == STRESS_SET);
 				assert(ORPHANS_SET == WIDOWS_SET);
 
-				if (value == ORPHANS_SET) {
-					ADVANCE(sizeof(css_fixed));
-				}
+				if (value == ORPHANS_SET)
+					offset++; /* value */
 				break;
+
 			case CSS_PROP_OUTLINE_COLOR:
-				if (value == OUTLINE_COLOR_SET) {
-					ADVANCE(sizeof(uint32_t));
-				}
+				if (value == OUTLINE_COLOR_SET)
+					offset++; /* color */
 				break;
+
 			case CSS_PROP_PITCH:
-				if (value == PITCH_FREQUENCY) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == PITCH_FREQUENCY)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_PLAY_DURING:
-				if (value == PLAY_DURING_URI) {
-					ADVANCE(sizeof(lwc_string *));
-				}
+				if (value == PLAY_DURING_URI)
+					offset++; /* string table entry */
 				break;
+
 			case CSS_PROP_QUOTES:
 				while (value != QUOTES_NONE) {
-					ADVANCE(2 * sizeof(lwc_string *));
+					offset += 2; /* two string table entries */
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_SPEECH_RATE:
-				if (value == SPEECH_RATE_SET) {
-					ADVANCE(sizeof(css_fixed));
-				}
+				if (value == SPEECH_RATE_SET) 
+					offset++; /* rate */
 				break;
+
 			case CSS_PROP_VERTICAL_ALIGN:
-				if (value == VERTICAL_ALIGN_SET) {
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
-				}
+				if (value == VERTICAL_ALIGN_SET)
+					offset += 2; /* length + units */
 				break;
+
 			case CSS_PROP_VOICE_FAMILY:
 				while (value != VOICE_FAMILY_END) {
 					switch (value) {
 					case VOICE_FAMILY_STRING:
 					case VOICE_FAMILY_IDENT_LIST:
-						ADVANCE(sizeof(lwc_string *));
+						offset++; /* string table entry */
 						break;
 					}
 
-					value = *((uint32_t *) bytecode);
-					ADVANCE(sizeof(value));
+					value = bytecode[offset];
+				        offset++;
 				}
 				break;
+
 			case CSS_PROP_VOLUME:
 				switch (value) {
 				case VOLUME_NUMBER:
-					ADVANCE(sizeof(css_fixed));
+					offset++; /* value */
 					break;
+
 				case VOLUME_DIMENSION:
-					ADVANCE(sizeof(css_fixed) +
-							sizeof(uint32_t));
+					offset += 2; /* value + units */
 					break;
 				}
 				break;
+
 			case CSS_PROP_Z_INDEX:
-				if (value == Z_INDEX_SET) {
-					ADVANCE(sizeof(css_fixed));
-				}
+				if (value == Z_INDEX_SET)
+					offset++; /* z index */
 				break;
+
 			default:
 				break;
 			}
 		}
 	}
 
-#undef ADVANCE
-
 }
 
Index: src/stylesheet.c
===================================================================
--- src/stylesheet.c	(revision 11378)
+++ src/stylesheet.c	(working copy)
@@ -7,6 +7,7 @@
 
 #include <assert.h>
 #include <string.h>
+#include <stdarg.h>
 
 #include "stylesheet.h"
 #include "bytecode/bytecode.h"
@@ -20,15 +21,17 @@
 static size_t _rule_size(const css_rule *rule);
 
 /**
- * Add a string to a stylesheets string vector.
+ * Add a string to a stylesheet's string vector.
  *
  * \param sheet The stylesheet to add string to.
  * \param string The string to add.
- * \param string_number Pointer to location to recive string number.
+ * \param string_number Pointer to location to receive string number.
  * \return CSS_OK on success,
  *	   CSS_BADPARM on bad parameters,
  *	   CSS_NOMEM on memory exhaustion
  *
+ * \post Ownership of \a string reference is passed to the stylesheet (even on failure)
+ * \note The returned string number is guaranteed to be non-zero
  */
 css_error css_stylesheet_string_add(css_stylesheet *sheet, lwc_string *string, uint32_t *string_number)
 {
@@ -43,9 +46,15 @@
 		res = lwc_string_isequal(string, 
 					 sheet->string_vector[new_string_number], 
 					 &isequal);
+
+		if (res != lwc_error_ok) {
+			lwc_string_unref(string);			
+			return css_error_from_lwc_error(res);
+		}
+
 		if (isequal) {
 			lwc_string_unref(string);			
-			*string_number = new_string_number;
+			*string_number = (new_string_number + 1);
 			return CSS_OK;
 		}
 		 
@@ -64,6 +73,7 @@
 		new_vector = sheet->alloc(sheet->string_vector, new_vector_len * sizeof(lwc_string *), sheet->pw);
 
 		if (new_vector == NULL) {
+			lwc_string_unref(string);			
 			return CSS_NOMEM;
 		}
 		sheet->string_vector = new_vector;
@@ -72,21 +82,25 @@
 
 	sheet->string_vector_c++;
 	sheet->string_vector[new_string_number] = string;
-	*string_number = new_string_number;
+	*string_number = (new_string_number + 1);
+
 	return CSS_OK;
 }
 
 /**
- * Get a string from a stylesheets string vector.
+ * Get a string from a stylesheet's string vector.
  *
  * \param sheet The stylesheet to retrive string from.
  * \param string_number The string number to retrive.
- * \param string Pointer to location to recive string.
+ * \param string Pointer to location to receive string.
  * \return CSS_OK on success,
  *	   CSS_BADPARM on bad parameters,
  */
 css_error css_stylesheet_string_get(css_stylesheet *sheet, uint32_t string_number, lwc_string **string)
 {
+	/* External string numbers = index into vector + 1 */
+	string_number--;
+
 	if (string_number > sheet->string_vector_c) {
 		return CSS_BADPARM;
 	}
@@ -238,7 +252,6 @@
 css_error css_stylesheet_destroy(css_stylesheet *sheet)
 {
 	uint32_t string_index;
-	uint32_t bucket;
 	css_rule *r, *s;
 
 	if (sheet == NULL)
@@ -262,17 +275,6 @@
 
 	css_selector_hash_destroy(sheet->selectors);
 
-	/* Release cached free styles */
-	for (bucket = 0; bucket != N_ELEMENTS(sheet->free_styles); bucket++) {
-		while (sheet->free_styles[bucket] != NULL) {
-			css_style *s = sheet->free_styles[bucket];
-
-			sheet->free_styles[bucket] = s->bytecode;
-
-			sheet->alloc(s, 0, sheet->pw);
-		}
-	}
-
 	/* These two may have been destroyed when parsing completed */
 	if (sheet->parser_frontend != NULL)
 		css_language_destroy(sheet->parser_frontend);
@@ -326,7 +328,6 @@
 css_error css_stylesheet_data_done(css_stylesheet *sheet)
 {
 	const css_rule *r;
-	uint32_t bucket;
 	css_error error;
 
 	if (sheet == NULL)
@@ -346,17 +347,6 @@
 	sheet->parser_frontend = NULL;
 	sheet->parser = NULL;
 
-	/* Release cached free styles */
-	for (bucket = 0; bucket != N_ELEMENTS(sheet->free_styles); bucket++) {
-		while (sheet->free_styles[bucket] != NULL) {
-			css_style *s = sheet->free_styles[bucket];
-
-			sheet->free_styles[bucket] = s->bytecode;
-
-			sheet->alloc(s, 0, sheet->pw);
-		}
-	}
-
 	/* Determine if there are any pending imports */
 	for (r = sheet->rule_list; r != NULL; r = r->next) {
 		const css_rule_import *i = (const css_rule_import *) r;
@@ -623,6 +613,7 @@
 /******************************************************************************
  * Library-private API below here					      *
  ******************************************************************************/
+#define CSS_STYLE_DEFAULT_SIZE 16
 
 /**
  * Create a style
@@ -634,35 +625,107 @@
  *	   CSS_BADPARM on bad parameters,
  *	   CSS_NOMEM on memory exhaustion
  */
-css_error css_stylesheet_style_create(css_stylesheet *sheet, uint32_t len,
-		css_style **style)
+css_error css_stylesheet_style_create(css_stylesheet *sheet, css_style **style)
 {
 	css_style *s;
-	const uint32_t alloclen = ((len + 15) & ~15);
-	const uint32_t bucket = (alloclen / N_ELEMENTS(sheet->free_styles)) - 1;
 
-	if (sheet == NULL || len == 0 || style == NULL)
+	if (sheet == NULL)
 		return CSS_BADPARM;
 
-	if (bucket < N_ELEMENTS(sheet->free_styles) &&
-			sheet->free_styles[bucket] != NULL) {
-		s = sheet->free_styles[bucket];
-		sheet->free_styles[bucket] = s->bytecode;
-	} else {
-		s = sheet->alloc(NULL, sizeof(css_style) + alloclen, sheet->pw);
-		if (s == NULL)
-			return CSS_NOMEM;
+	s = sheet->alloc(NULL, sizeof(css_style), sheet->pw);
+	if (s == NULL)
+		return CSS_NOMEM;
+
+	s->bytecode = sheet->alloc(NULL, sizeof(css_code_t) * CSS_STYLE_DEFAULT_SIZE, sheet->pw);
+
+	if (s->bytecode == NULL) {
+		sheet->alloc(s, 0, sheet->pw); /* do not leak */
+	
+		return CSS_NOMEM;
 	}
+	s->allocated = CSS_STYLE_DEFAULT_SIZE;
+	s->used = 0;
+	s->sheet = sheet;
 
-	/* DIY variable-sized data member */
-	s->bytecode = ((uint8_t *) s + sizeof(css_style));
-	s->length = len;
-
 	*style = s;
 
 	return CSS_OK;
 }
 
+css_error css_stylesheet_merge_style(css_style *target, css_style *style)
+{
+	css_code_t *newcode;
+	uint32_t newcode_len;
+	css_stylesheet *sheet;
+
+	if (target == NULL || style == NULL)
+		return CSS_BADPARM;
+
+	sheet = target->sheet;
+	newcode_len = target->allocated + style->used ;
+
+	newcode = sheet->alloc(target->bytecode, newcode_len * sizeof(css_code_t), sheet->pw);
+
+	if (newcode == NULL)
+		return CSS_NOMEM;
+
+	target->bytecode = newcode;
+	target->allocated = newcode_len;
+
+	memcpy(target->bytecode + target->used, style->bytecode, style->used * sizeof(css_code_t));
+
+	target->used += style->used;
+
+	return CSS_OK;
+
+}
+
+/** append one or more css code entries to a style */ 
+css_error css_stylesheet_style_vappend(css_style *style, uint32_t style_count, ...)
+{
+	va_list ap;
+	css_error error = CSS_OK;
+	css_code_t css_code;
+
+	va_start(ap, style_count);
+	while (style_count > 0) {
+		css_code = va_arg(ap, css_code_t);
+		error = css_stylesheet_style_append(style, css_code);
+		if (error != CSS_OK)
+			break;
+		style_count--;
+	}
+	va_end(ap);
+	return error;
+}
+
+/** append a css code entry to a style */ 
+css_error css_stylesheet_style_append(css_style *style, css_code_t css_code)
+{
+	css_stylesheet *sheet;
+
+	if (style == NULL)
+		return CSS_BADPARM;
+
+	sheet = style->sheet;
+
+	if (style->allocated == style->used) {
+		/* space not available to append, extend allocation */
+		css_code_t *newcode;
+		uint32_t newcode_len = style->allocated * 2;
+		newcode = sheet->alloc(style->bytecode, sizeof(css_code_t) * newcode_len, sheet->pw);
+		if (newcode == NULL)
+			return CSS_NOMEM;
+		style->bytecode = newcode;
+		style->allocated = newcode_len;
+	}
+
+	style->bytecode[style->used] = css_code;
+	style->used++;
+
+	return CSS_OK;
+}
+
 /**
  * Destroy a style
  *
@@ -673,35 +736,27 @@
  *				    etc.
  * \return CSS_OK on success, appropriate error otherwise
  */
-css_error css_stylesheet_style_destroy(css_stylesheet *sheet, css_style *style,
+css_error css_stylesheet_style_destroy(css_style *style,
 				       bool suppress_bytecode_cleanup)
 {
-	uint32_t alloclen, bucket;
-	void *bptr, *eptr;
+	css_stylesheet *sheet;
 
-	if (sheet == NULL || style == NULL)
+	if (style == NULL)
 		return CSS_BADPARM;
+
+	sheet = style->sheet;
 	
 	if (suppress_bytecode_cleanup == false) {
-		bptr = style->bytecode;
-		eptr = (uint8_t *) bptr + style->length;
-		while (bptr != eptr) {
-			uint32_t opcode = getOpcode(*((uint32_t*)bptr));
-			uint32_t skip = prop_dispatch[opcode].destroy(bptr);
-			bptr = (uint8_t *) bptr + skip;
+                /* run style destructor */
+		uint32_t pcounter = 0;
+		while (pcounter < style->used) {
+			pcounter += (prop_dispatch[getOpcode(style->bytecode[pcounter])].destroy(style->bytecode + pcounter) / sizeof(css_code_t));
 		}
 	}
 	
-	alloclen = ((style->length + 15) & ~15);
-	bucket = (alloclen / N_ELEMENTS(sheet->free_styles)) - 1;
+	sheet->alloc(style->bytecode, 0, sheet->pw);
+	sheet->alloc(style, 0, sheet->pw);
 
-	if (bucket < N_ELEMENTS(sheet->free_styles)) {
-		style->bytecode = sheet->free_styles[bucket];
-		sheet->free_styles[bucket] = style;
-	} else {
-		sheet->alloc(style, 0, sheet->pw);
-	}
-
 	return CSS_OK;
 }
 
@@ -1041,7 +1096,7 @@
 			sheet->alloc(s->selectors, 0, sheet->pw);
 
 		if (s->style != NULL)
-			css_stylesheet_style_destroy(sheet, s->style, false);
+			css_stylesheet_style_destroy(s->style, false);
 	}
 		break;
 	case CSS_RULE_CHARSET:
@@ -1081,7 +1136,7 @@
 		css_rule_font_face *font_face = (css_rule_font_face *) rule;
 
 		if (font_face->style != NULL)
-			css_stylesheet_style_destroy(sheet, font_face->style, false);
+			css_stylesheet_style_destroy(font_face->style, false);
 	}
 		break;
 	case CSS_RULE_PAGE:
@@ -1094,7 +1149,7 @@
 		}
 
 		if (page->style != NULL)
-			css_stylesheet_style_destroy(sheet, page->style, false);
+			css_stylesheet_style_destroy(page->style, false);
 	}
 		break;
 	}
@@ -1142,6 +1197,7 @@
 	return CSS_OK;
 }
 
+
 /**
  * Append a style to a CSS rule
  *
@@ -1153,7 +1209,8 @@
 css_error css_stylesheet_rule_append_style(css_stylesheet *sheet,
 		css_rule *rule, css_style *style)
 {
-	css_style *cur;
+	css_style *current_style;
+	css_error error;
 
 	if (sheet == NULL || rule == NULL || style == NULL)
 		return CSS_BADPARM;
@@ -1161,56 +1218,30 @@
 	assert(rule->type == CSS_RULE_SELECTOR || rule->type == CSS_RULE_PAGE);
 
 	if (rule->type == CSS_RULE_SELECTOR)
-		cur = ((css_rule_selector *) rule)->style;
+		current_style = ((css_rule_selector *) rule)->style;
 	else
-		cur = ((css_rule_page *) rule)->style;
+		current_style = ((css_rule_page *) rule)->style;
 
-	if (cur != NULL) {
-		/* Already have a style, so append to the end of the bytecode */
-		const uint32_t reqlen = cur->length + style->length;
-		const uint32_t curlen = ((cur->length + 15) & ~15);
+	if (current_style != NULL) {
+		error = css_stylesheet_merge_style(current_style, style);
 
-		if (curlen < reqlen) {
-			css_style *temp;
-			css_error error;
+		if (error != CSS_OK)
+			return error;
 
-			error = css_stylesheet_style_create(sheet, 
-					reqlen, &temp);
-			if (error != CSS_OK)
-				return error;
-
-			memcpy((uint8_t *) temp->bytecode, cur->bytecode, 
-					cur->length);
-			temp->length = cur->length;
-
-			css_stylesheet_style_destroy(sheet, cur, true);
-
-			cur = temp;
-		}
-
-		/** \todo Can we optimise the bytecode here? */
-		memcpy((uint8_t *) cur->bytecode + cur->length, 
-				style->bytecode, style->length);
-
-		cur->length += style->length;
-
-		/* Add this to the sheet's size */
-		sheet->size += style->length;
-
 		/* Done with style */
-		css_stylesheet_style_destroy(sheet, style, true);
+		css_stylesheet_style_destroy(style, true);
 	} else {
 		/* No current style, so use this one */
-		cur = style;
+		current_style = style;
 
 		/* Add to the sheet's size */
-		sheet->size += style->length;
+		sheet->size += (style->used * sizeof(css_code_t));
 	}
 
 	if (rule->type == CSS_RULE_SELECTOR)
-		((css_rule_selector *) rule)->style = cur;
+		((css_rule_selector *) rule)->style = current_style;
 	else
-		((css_rule_page *) rule)->style = cur;
+		((css_rule_page *) rule)->style = current_style;
 
 	return CSS_OK;
 }
@@ -1594,7 +1625,7 @@
 		}
 
 		if (rs->style != NULL)
-			bytes += rs->style->length;
+			bytes += (rs->style->used * sizeof(css_code_t));
 	} else if (r->type == CSS_RULE_CHARSET) {
 		bytes += sizeof(css_rule_charset);
 	} else if (r->type == CSS_RULE_IMPORT) {
@@ -1614,7 +1645,7 @@
 		bytes += sizeof(css_rule_font_face);
 
 		if (rf->style != NULL)
-			bytes += rf->style->length;
+			bytes += (rf->style->used * sizeof(css_code_t));
 	} else if (r->type == CSS_RULE_PAGE) {
 		const css_rule_page *rp = (const css_rule_page *) r;
 		const css_selector *s = rp->selector;
@@ -1634,7 +1665,7 @@
 		}
 
 		if (rp->style != NULL)
-			bytes += rp->style->length;
+			bytes += (rp->style->used * sizeof(css_code_t));
 	}
 
 	return bytes;
Index: src/bytecode/bytecode.h
===================================================================
--- src/bytecode/bytecode.h	(revision 11378)
+++ src/bytecode/bytecode.h	(working copy)
@@ -14,6 +14,8 @@
 #include <libcss/types.h>
 #include <libcss/properties.h>
 
+typedef uint32_t css_code_t; 
+
 typedef enum css_properties_e opcode_t;
 
 enum flag {
@@ -53,32 +55,32 @@
 	SHAPE_RECT = 0
 } shape;
 
-static inline uint32_t buildOPV(opcode_t opcode, uint8_t flags, uint16_t value)
+static inline css_code_t buildOPV(opcode_t opcode, uint8_t flags, uint16_t value)
 {
 	return (opcode & 0x3ff) | (flags << 10) | ((value & 0x3fff) << 18);
 }
 
-static inline opcode_t getOpcode(uint32_t OPV)
+static inline opcode_t getOpcode(css_code_t OPV)
 {
 	return (OPV & 0x3ff);
 }
 
-static inline uint8_t getFlags(uint32_t OPV)
+static inline uint8_t getFlags(css_code_t OPV)
 {
 	return ((OPV >> 10) & 0xff);
 }
 
-static inline uint16_t getValue(uint32_t OPV)
+static inline uint16_t getValue(css_code_t OPV)
 {
 	return (OPV >> 18);
 }
 
-static inline bool isImportant(uint32_t OPV)
+static inline bool isImportant(css_code_t OPV)
 {
 	return getFlags(OPV) & 0x1;
 }
 
-static inline bool isInherit(uint32_t OPV)
+static inline bool isInherit(css_code_t OPV)
 {
 	return getFlags(OPV) & 0x2;
 }


Conflicted files




Removed files


 src/parse/properties/conter_reset.c



More information about the netsurf-dev mailing list