From 6a50bef84ae6a0a67e03ac1356f8d85d15fe09d6 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 19 Jan 2011 23:12:37 +0000 Subject: Merge parser autogeneration and string handling refactor branch r=jmb,kinnison,vince svn path=/trunk/libcss/; revision=11408 --- src/bytecode/bytecode.h | 14 +- src/parse/important.c | 256 ++-- src/parse/language.c | 19 +- src/parse/properties/Makefile | 176 +-- src/parse/properties/azimuth.c | 28 +- src/parse/properties/background.c | 297 ++-- src/parse/properties/background_attachment.c | 79 - src/parse/properties/background_color.c | 94 -- src/parse/properties/background_image.c | 99 -- src/parse/properties/background_position.c | 35 +- src/parse/properties/background_repeat.c | 87 -- src/parse/properties/border.c | 85 +- src/parse/properties/border_bottom.c | 35 - src/parse/properties/border_bottom_color.c | 36 - src/parse/properties/border_bottom_style.c | 36 - src/parse/properties/border_bottom_width.c | 36 - src/parse/properties/border_collapse.c | 79 - src/parse/properties/border_color.c | 271 +--- src/parse/properties/border_left.c | 35 - src/parse/properties/border_left_color.c | 36 - src/parse/properties/border_left_style.c | 36 - src/parse/properties/border_left_width.c | 36 - src/parse/properties/border_right.c | 35 - src/parse/properties/border_right_color.c | 36 - src/parse/properties/border_right_style.c | 36 - src/parse/properties/border_right_width.c | 36 - src/parse/properties/border_spacing.c | 50 +- src/parse/properties/border_style.c | 293 ++-- src/parse/properties/border_top.c | 35 - src/parse/properties/border_top_color.c | 36 - src/parse/properties/border_top_style.c | 36 - src/parse/properties/border_top_width.c | 36 - src/parse/properties/border_width.c | 294 ++-- src/parse/properties/bottom.c | 35 - src/parse/properties/caption_side.c | 79 - src/parse/properties/clear.c | 87 -- src/parse/properties/clip.c | 93 +- src/parse/properties/color.c | 88 -- src/parse/properties/content.c | 457 ++++-- src/parse/properties/conter_reset.c | 36 - src/parse/properties/counter_increment.c | 36 - src/parse/properties/css_property_parser_gen.c | 613 ++++++++ src/parse/properties/cue.c | 284 +--- src/parse/properties/cursor.c | 281 +--- src/parse/properties/direction.c | 79 - src/parse/properties/display.c | 138 -- src/parse/properties/elevation.c | 26 +- src/parse/properties/empty_cells.c | 79 - src/parse/properties/float.c | 83 -- src/parse/properties/font.c | 351 +++-- src/parse/properties/font_family.c | 70 +- src/parse/properties/font_size.c | 158 -- src/parse/properties/font_style.c | 83 -- src/parse/properties/font_variant.c | 79 - src/parse/properties/font_weight.c | 21 +- src/parse/properties/height.c | 109 -- src/parse/properties/left.c | 35 - src/parse/properties/letter_spacing.c | 104 -- src/parse/properties/line_height.c | 129 -- src/parse/properties/list_style.c | 183 +-- src/parse/properties/list_style_image.c | 99 -- src/parse/properties/list_style_position.c | 79 - src/parse/properties/list_style_type.c | 18 +- src/parse/properties/margin.c | 280 ++-- src/parse/properties/margin_bottom.c | 36 - src/parse/properties/margin_left.c | 35 - src/parse/properties/margin_right.c | 35 - src/parse/properties/margin_top.c | 35 - src/parse/properties/max_height.c | 109 -- src/parse/properties/max_width.c | 109 -- src/parse/properties/min_height.c | 103 -- src/parse/properties/min_width.c | 103 -- src/parse/properties/orphans.c | 98 -- src/parse/properties/outline.c | 188 +-- src/parse/properties/outline_color.c | 94 -- src/parse/properties/outline_style.c | 58 - src/parse/properties/outline_width.c | 37 - src/parse/properties/overflow.c | 87 -- src/parse/properties/padding.c | 274 +--- src/parse/properties/padding_bottom.c | 36 - src/parse/properties/padding_left.c | 36 - src/parse/properties/padding_right.c | 36 - src/parse/properties/padding_top.c | 36 - src/parse/properties/page_break_after.c | 91 -- src/parse/properties/page_break_before.c | 91 -- src/parse/properties/page_break_inside.c | 79 - src/parse/properties/pause.c | 161 +-- src/parse/properties/pause_after.c | 35 - src/parse/properties/pause_before.c | 36 - src/parse/properties/pitch.c | 133 -- src/parse/properties/pitch_range.c | 98 -- src/parse/properties/play_during.c | 42 +- src/parse/properties/position.c | 87 -- src/parse/properties/properties.gen | 190 +++ src/parse/properties/properties.h | 232 +-- src/parse/properties/quotes.c | 181 +-- src/parse/properties/richness.c | 98 -- src/parse/properties/right.c | 35 - src/parse/properties/speak.c | 83 -- src/parse/properties/speak_header.c | 79 - src/parse/properties/speak_numeral.c | 79 - src/parse/properties/speak_punctuation.c | 79 - src/parse/properties/speech_rate.c | 136 -- src/parse/properties/stress.c | 97 -- src/parse/properties/table_layout.c | 80 - src/parse/properties/text_align.c | 100 -- src/parse/properties/text_decoration.c | 62 +- src/parse/properties/text_indent.c | 97 -- src/parse/properties/text_transform.c | 87 -- src/parse/properties/top.c | 35 - src/parse/properties/unicode_bidi.c | 83 -- src/parse/properties/utils.c | 1851 +++--------------------- src/parse/properties/utils.h | 174 ++- src/parse/properties/vertical_align.c | 147 -- src/parse/properties/visibility.c | 83 -- src/parse/properties/voice_family.c | 69 +- src/parse/properties/volume.c | 161 --- src/parse/properties/white_space.c | 91 -- src/parse/properties/widows.c | 98 -- src/parse/properties/width.c | 109 -- src/parse/properties/word_spacing.c | 104 -- src/parse/properties/z_index.c | 98 -- src/select/dispatch.c | 3 +- src/select/dispatch.h | 1 - src/select/properties/azimuth.c | 7 - src/select/properties/background_attachment.c | 6 - src/select/properties/background_color.c | 4 - src/select/properties/background_image.c | 4 - src/select/properties/background_position.c | 13 - src/select/properties/background_repeat.c | 6 - src/select/properties/border_bottom_color.c | 4 - src/select/properties/border_bottom_style.c | 6 - src/select/properties/border_bottom_width.c | 4 - src/select/properties/border_collapse.c | 6 - src/select/properties/border_left_color.c | 4 - src/select/properties/border_left_style.c | 6 - src/select/properties/border_left_width.c | 4 - src/select/properties/border_right_color.c | 4 - src/select/properties/border_right_style.c | 6 - src/select/properties/border_right_width.c | 4 - src/select/properties/border_spacing.c | 6 - src/select/properties/border_top_color.c | 4 - src/select/properties/border_top_style.c | 6 - src/select/properties/border_top_width.c | 4 - src/select/properties/bottom.c | 4 - src/select/properties/caption_side.c | 6 - src/select/properties/clear.c | 6 - src/select/properties/clip.c | 19 - src/select/properties/color.c | 4 - src/select/properties/content.c | 53 +- src/select/properties/counter_increment.c | 21 - src/select/properties/counter_reset.c | 22 - src/select/properties/cue_after.c | 4 - src/select/properties/cue_before.c | 4 - src/select/properties/cursor.c | 19 - src/select/properties/direction.c | 6 - src/select/properties/display.c | 6 - src/select/properties/elevation.c | 4 - src/select/properties/empty_cells.c | 6 - src/select/properties/float.c | 6 - src/select/properties/font_family.c | 26 +- src/select/properties/font_size.c | 4 - src/select/properties/font_style.c | 6 - src/select/properties/font_variant.c | 6 - src/select/properties/font_weight.c | 6 - src/select/properties/height.c | 4 - src/select/properties/helpers.c | 42 +- src/select/properties/left.c | 4 - src/select/properties/letter_spacing.c | 4 - src/select/properties/line_height.c | 8 - src/select/properties/list_style_image.c | 4 - src/select/properties/list_style_position.c | 6 - src/select/properties/list_style_type.c | 6 - src/select/properties/margin_bottom.c | 4 - src/select/properties/margin_left.c | 4 - src/select/properties/margin_right.c | 4 - src/select/properties/margin_top.c | 4 - src/select/properties/max_height.c | 4 - src/select/properties/max_width.c | 4 - src/select/properties/min_height.c | 4 - src/select/properties/min_width.c | 4 - src/select/properties/orphans.c | 4 - src/select/properties/outline_color.c | 4 - src/select/properties/outline_style.c | 6 - src/select/properties/outline_width.c | 4 - src/select/properties/overflow.c | 6 - src/select/properties/padding_bottom.c | 4 - src/select/properties/padding_left.c | 4 - src/select/properties/padding_right.c | 4 - src/select/properties/padding_top.c | 4 - src/select/properties/page_break_after.c | 6 - src/select/properties/page_break_before.c | 6 - src/select/properties/page_break_inside.c | 6 - src/select/properties/pause_after.c | 4 - src/select/properties/pause_before.c | 4 - src/select/properties/pitch.c | 4 - src/select/properties/pitch_range.c | 4 - src/select/properties/play_during.c | 4 - src/select/properties/position.c | 6 - src/select/properties/quotes.c | 28 +- src/select/properties/richness.c | 4 - src/select/properties/right.c | 4 - src/select/properties/speach_rate.c | 4 - src/select/properties/speak.c | 6 - src/select/properties/speak_header.c | 6 - src/select/properties/speak_numeral.c | 6 - src/select/properties/speak_punctuation.c | 6 - src/select/properties/stress.c | 4 - src/select/properties/table_layout.c | 6 - src/select/properties/text_align.c | 6 - src/select/properties/text_decoration.c | 6 - src/select/properties/text_indent.c | 4 - src/select/properties/text_transform.c | 6 - src/select/properties/top.c | 4 - src/select/properties/unicode_bidi.c | 6 - src/select/properties/vertical_align.c | 4 - src/select/properties/visibility.c | 6 - src/select/properties/voice_family.c | 26 +- src/select/properties/volume.c | 11 - src/select/properties/white_space.c | 6 - src/select/properties/width.c | 4 - src/select/properties/windows.c | 4 - src/select/properties/word_spacing.c | 4 - src/select/properties/z_index.c | 4 - src/select/select.c | 4 +- src/select/select.h | 4 +- src/stylesheet.c | 288 ++-- src/stylesheet.h | 37 +- 228 files changed, 3357 insertions(+), 12031 deletions(-) delete mode 100644 src/parse/properties/background_attachment.c delete mode 100644 src/parse/properties/background_color.c delete mode 100644 src/parse/properties/background_image.c delete mode 100644 src/parse/properties/background_repeat.c delete mode 100644 src/parse/properties/border_bottom.c delete mode 100644 src/parse/properties/border_bottom_color.c delete mode 100644 src/parse/properties/border_bottom_style.c delete mode 100644 src/parse/properties/border_bottom_width.c delete mode 100644 src/parse/properties/border_collapse.c delete mode 100644 src/parse/properties/border_left.c delete mode 100644 src/parse/properties/border_left_color.c delete mode 100644 src/parse/properties/border_left_style.c delete mode 100644 src/parse/properties/border_left_width.c delete mode 100644 src/parse/properties/border_right.c delete mode 100644 src/parse/properties/border_right_color.c delete mode 100644 src/parse/properties/border_right_style.c delete mode 100644 src/parse/properties/border_right_width.c delete mode 100644 src/parse/properties/border_top.c delete mode 100644 src/parse/properties/border_top_color.c delete mode 100644 src/parse/properties/border_top_style.c delete mode 100644 src/parse/properties/border_top_width.c delete mode 100644 src/parse/properties/bottom.c delete mode 100644 src/parse/properties/caption_side.c delete mode 100644 src/parse/properties/clear.c delete mode 100644 src/parse/properties/color.c delete mode 100644 src/parse/properties/conter_reset.c delete mode 100644 src/parse/properties/counter_increment.c create mode 100644 src/parse/properties/css_property_parser_gen.c delete mode 100644 src/parse/properties/direction.c delete mode 100644 src/parse/properties/display.c delete mode 100644 src/parse/properties/empty_cells.c delete mode 100644 src/parse/properties/float.c delete mode 100644 src/parse/properties/font_size.c delete mode 100644 src/parse/properties/font_style.c delete mode 100644 src/parse/properties/font_variant.c delete mode 100644 src/parse/properties/height.c delete mode 100644 src/parse/properties/left.c delete mode 100644 src/parse/properties/letter_spacing.c delete mode 100644 src/parse/properties/line_height.c delete mode 100644 src/parse/properties/list_style_image.c delete mode 100644 src/parse/properties/list_style_position.c delete mode 100644 src/parse/properties/margin_bottom.c delete mode 100644 src/parse/properties/margin_left.c delete mode 100644 src/parse/properties/margin_right.c delete mode 100644 src/parse/properties/margin_top.c delete mode 100644 src/parse/properties/max_height.c delete mode 100644 src/parse/properties/max_width.c delete mode 100644 src/parse/properties/min_height.c delete mode 100644 src/parse/properties/min_width.c delete mode 100644 src/parse/properties/orphans.c delete mode 100644 src/parse/properties/outline_color.c delete mode 100644 src/parse/properties/outline_style.c delete mode 100644 src/parse/properties/outline_width.c delete mode 100644 src/parse/properties/overflow.c delete mode 100644 src/parse/properties/padding_bottom.c delete mode 100644 src/parse/properties/padding_left.c delete mode 100644 src/parse/properties/padding_right.c delete mode 100644 src/parse/properties/padding_top.c delete mode 100644 src/parse/properties/page_break_after.c delete mode 100644 src/parse/properties/page_break_before.c delete mode 100644 src/parse/properties/page_break_inside.c delete mode 100644 src/parse/properties/pause_after.c delete mode 100644 src/parse/properties/pause_before.c delete mode 100644 src/parse/properties/pitch.c delete mode 100644 src/parse/properties/pitch_range.c delete mode 100644 src/parse/properties/position.c create mode 100644 src/parse/properties/properties.gen delete mode 100644 src/parse/properties/richness.c delete mode 100644 src/parse/properties/right.c delete mode 100644 src/parse/properties/speak.c delete mode 100644 src/parse/properties/speak_header.c delete mode 100644 src/parse/properties/speak_numeral.c delete mode 100644 src/parse/properties/speak_punctuation.c delete mode 100644 src/parse/properties/speech_rate.c delete mode 100644 src/parse/properties/stress.c delete mode 100644 src/parse/properties/table_layout.c delete mode 100644 src/parse/properties/text_align.c delete mode 100644 src/parse/properties/text_indent.c delete mode 100644 src/parse/properties/text_transform.c delete mode 100644 src/parse/properties/top.c delete mode 100644 src/parse/properties/unicode_bidi.c delete mode 100644 src/parse/properties/vertical_align.c delete mode 100644 src/parse/properties/visibility.c delete mode 100644 src/parse/properties/volume.c delete mode 100644 src/parse/properties/white_space.c delete mode 100644 src/parse/properties/widows.c delete mode 100644 src/parse/properties/width.c delete mode 100644 src/parse/properties/word_spacing.c delete mode 100644 src/parse/properties/z_index.c (limited to 'src') diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h index f378585..4ac3dfb 100644 --- a/src/bytecode/bytecode.h +++ b/src/bytecode/bytecode.h @@ -14,6 +14,8 @@ #include #include +typedef uint32_t css_code_t; + typedef enum css_properties_e opcode_t; enum flag { @@ -53,32 +55,32 @@ typedef enum shape { 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; } diff --git a/src/parse/important.c b/src/parse/important.c index 5790122..062074a 100644 --- a/src/parse/important.c +++ b/src/parse/important.c @@ -66,20 +66,15 @@ css_error parse_important(css_language *c, */ 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 @@ void make_style_important(css_style *style) 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 - } diff --git a/src/parse/language.c b/src/parse/language.c index 739eba5..f8df2f1 100644 --- a/src/parse/language.c +++ b/src/parse/language.c @@ -1273,17 +1273,24 @@ css_error parseProperty(css_language *c, const css_token *property, handler = property_handlers[i - FIRST_PROP]; assert(handler != NULL); - /* Call it */ - error = handler(c, vector, ctx, &style); - if (error != CSS_OK) + /* allocate style */ + error = css_stylesheet_style_create(c->sheet, &style); + if (error != CSS_OK) return error; assert (style != NULL); + /* Call the handler */ + error = handler(c, vector, ctx, style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(style); + return error; + } + /* 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); return error; } @@ -1292,7 +1299,7 @@ css_error parseProperty(css_language *c, const css_token *property, 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); return CSS_INVALID; } @@ -1303,7 +1310,7 @@ css_error parseProperty(css_language *c, const css_token *property, /* 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); return error; } diff --git a/src/parse/properties/Makefile b/src/parse/properties/Makefile index 9a76d48..43a2cf1 100644 --- a/src/parse/properties/Makefile +++ b/src/parse/properties/Makefile @@ -1,117 +1,65 @@ # Sources -DIR_SOURCES := utils.c properties.c \ - azimuth.c \ - background_attachment.c \ - background.c \ - background_color.c \ - background_image.c \ - background_position.c \ - background_repeat.c \ - border_bottom.c \ - border_bottom_color.c \ - border_bottom_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_increment.c \ - cue.c \ - cursor.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 \ - font_weight.c \ - height.c \ - 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 \ - max_height.c \ - max_width.c \ - 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 \ - page_break_after.c \ - page_break_before.c \ - 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 \ - speak_header.c \ - speak_numeral.c \ - speak_punctuation.c \ - speech_rate.c \ - 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 +# 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 + +AUTOGEN_PARSERS=$(shell perl -pe'$$_="" unless /^([^\#][^:]+):/;$$_=$$1 . " "' $(DIR)properties.gen) + +# Dodgy use of define/eval to bypass DIR changing +define build_gen_parser + +$(BUILDDIR)/gen_parser: $(DIR)css_property_parser_gen.c + $$(VQ)$$(ECHO) $$(ECHOFLAGS) " PREPARE: $$@" + $$(Q)$$(HOST_CC) -o $$@ $$^ + +endef + +$(eval $(build_gen_parser)) + +define gen_prop_parser + +$(DIR)autogenerated_$1.c: $(DIR)properties.gen $(BUILDDIR)/gen_parser + $$(VQ)$$(ECHO) $$(ECHOFLAGS) "GENERATE: $$@" + $$(Q)$$(BUILDDIR)/gen_parser -o $$@ '$(shell grep "^$1:" $(DIR)properties.gen)' + +AUTOGEN_SOURCES := $$(AUTOGEN_SOURCES) autogenerated_$1.c + +endef + +AUTOGEN_SOURCES := + +$(eval $(foreach PROP,$(AUTOGEN_PARSERS),$(call gen_prop_parser,$(PROP)))) + + + +DIR_SOURCES := azimuth.c text_decoration.c background.c utils.c \ + background_position.c border_spacing.c font.c outline.c \ + voice_family.c border_style.c cue.c \ + font_family.c list_style.c padding.c cursor.c \ + list_style_type.c pause.c border.c border_width.c margin.c \ + play_during.c clip.c properties.c border_color.c content.c \ + elevation.c font_weight.c quotes.c utils.c + +DIR_SOURCES := $(DIR_SOURCES) $(AUTOGEN_SOURCES) + +PRE_TARGETS := $(foreach AP,$(AUTOGEN_PARSERS),src/parse/properties/autogenerated_$(AP).c) + +DISTCLEAN_ITEMS := $(foreach AP,$(AUTOGEN_PARSERS),src/parse/properties/autogenerated_$(AP).c) include build/makefiles/Makefile.subdir diff --git a/src/parse/properties/azimuth.c b/src/parse/properties/azimuth.c index c5465bd..e6d28e6 100644 --- a/src/parse/properties/azimuth.c +++ b/src/parse/properties/azimuth.c @@ -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 @@ css_error parse_azimuth(css_language *c, 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; diff --git a/src/parse/properties/background.c b/src/parse/properties/background.c index 25c9315..f12fde7 100644 --- a/src/parse/properties/background.c +++ b/src/parse/properties/background.c @@ -29,58 +29,86 @@ */ 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; - - error = css_stylesheet_style_create(c->sheet, - 5 * 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_BACKGROUND_ATTACHMENT); + if (error != CSS_OK) return error; - } - bytecode = (uint32_t *) ret->bytecode; + error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_COLOR); + 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_IMAGE); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_POSITION); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_REPEAT); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; + return error; + } + + /* allocate styles */ + error = css_stylesheet_style_create(c->sheet, &attachment_style); + if (error != CSS_OK) + return error; + + error = css_stylesheet_style_create(c->sheet, &color_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(attachment_style); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &image_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(attachment_style); + css_stylesheet_style_destroy(color_style); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &position_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(attachment_style); + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(image_style); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &repeat_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(attachment_style); + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(image_style); + css_stylesheet_style_destroy(position_style); + return error; } /* Attempt to parse the various longhand properties */ @@ -88,26 +116,34 @@ css_error parse_background(css_language *c, 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 @@ css_error parse_background(css_language *c, } } 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); - - /* Write the result */ - *result = ret; - /* Invalidate ret, so that cleanup doesn't destroy it */ - ret = NULL; - - /* 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, attachment_style); + if (error != CSS_OK) + goto parse_background_cleanup; + + error = css_stylesheet_merge_style(result, color_style); + if (error != CSS_OK) + goto parse_background_cleanup; + + 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); + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(image_style); + css_stylesheet_style_destroy(position_style); + css_stylesheet_style_destroy(repeat_style); if (error != CSS_OK) *ctx = orig_ctx; return error; + + } diff --git a/src/parse/properties/background_attachment.c b/src/parse/properties/background_attachment.c deleted file mode 100644 index d1c6da4..0000000 --- a/src/parse/properties/background_attachment.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse background-attachment - * - * \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_background_attachment(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 (fixed, scroll, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[FIXED], - &match) == lwc_error_ok && match)) { - value = BACKGROUND_ATTACHMENT_FIXED; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[SCROLL], - &match) == lwc_error_ok && match)) { - value = BACKGROUND_ATTACHMENT_SCROLL; - } else { - *ctx = orig_ctx; - return CSS_INVALID; - } - - opv = buildOPV(CSS_PROP_BACKGROUND_ATTACHMENT, 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; -} diff --git a/src/parse/properties/background_color.c b/src/parse/properties/background_color.c deleted file mode 100644 index bf8d341..0000000 --- a/src/parse/properties/background_color.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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) { - *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; - } else { - error = parse_colour_specifier(c, vector, ctx, &colour); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - value = BACKGROUND_COLOR_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/background_image.c b/src/parse/properties/background_image.c deleted file mode 100644 index 52d3006..0000000 --- a/src/parse/properties/background_image.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse background-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 - * \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_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)) { - *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; - } else if (token->type == CSS_TOKEN_URI) { - value = BACKGROUND_IMAGE_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(CSS_PROP_BACKGROUND_IMAGE, flags, value); - - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_IMAGE_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 == 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 *)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/background_position.c b/src/parse/properties/background_position.c index 94bce82..e74072f 100644 --- a/src/parse/properties/background_position.c +++ b/src/parse/properties/background_position.c @@ -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 @@ css_error parse_background_position(css_language *c, } } - 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]); } } diff --git a/src/parse/properties/background_repeat.c b/src/parse/properties/background_repeat.c deleted file mode 100644 index 06b2e8d..0000000 --- a/src/parse/properties/background_repeat.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse background-repeat - * - * \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_background_repeat(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 (no-repeat, repeat-x, repeat-y, repeat, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NO_REPEAT], - &match) == lwc_error_ok && match)) { - value = 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[REPEAT_Y], - &match) == lwc_error_ok && match)) { - value = BACKGROUND_REPEAT_REPEAT_Y; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[REPEAT], - &match) == lwc_error_ok && match)) { - value = BACKGROUND_REPEAT_REPEAT; - } else { - *ctx = orig_ctx; - return 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; -} diff --git a/src/parse/properties/border.c b/src/parse/properties/border.c index b90ca66..e33aa40 100644 --- a/src/parse/properties/border.c +++ b/src/parse/properties/border.c @@ -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; + } diff --git a/src/parse/properties/border_bottom.c b/src/parse/properties/border_bottom.c deleted file mode 100644 index 0ac1ebc..0000000 --- a/src/parse/properties/border_bottom.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-bottom shorthand - * - * \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_border_bottom(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side(c, vector, ctx, BORDER_SIDE_BOTTOM, result); -} diff --git a/src/parse/properties/border_bottom_color.c b/src/parse/properties/border_bottom_color.c deleted file mode 100644 index acf417f..0000000 --- a/src/parse/properties/border_bottom_color.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-bottom-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 - * \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_bottom_color(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_color(c, vector, ctx, - CSS_PROP_BORDER_BOTTOM_COLOR, result); -} diff --git a/src/parse/properties/border_bottom_style.c b/src/parse/properties/border_bottom_style.c deleted file mode 100644 index 2c549fa..0000000 --- a/src/parse/properties/border_bottom_style.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-bottom-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 - * \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_bottom_style(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_style(c, vector, ctx, - CSS_PROP_BORDER_BOTTOM_STYLE, result); -} diff --git a/src/parse/properties/border_bottom_width.c b/src/parse/properties/border_bottom_width.c deleted file mode 100644 index 56769e8..0000000 --- a/src/parse/properties/border_bottom_width.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-bottom-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 - * \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_bottom_width(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_width(c, vector, ctx, - CSS_PROP_BORDER_BOTTOM_WIDTH, result); -} diff --git a/src/parse/properties/border_collapse.c b/src/parse/properties/border_collapse.c deleted file mode 100644 index 8926010..0000000 --- a/src/parse/properties/border_collapse.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-collapse - * - * \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_border_collapse(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 (collapse, separate, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[COLLAPSE], - &match) == lwc_error_ok && match)) { - value = BORDER_COLLAPSE_COLLAPSE; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[SEPARATE], - &match) == lwc_error_ok && match)) { - value = BORDER_COLLAPSE_SEPARATE; - } else { - *ctx = orig_ctx; - return 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; -} diff --git a/src/parse/properties/border_color.c b/src/parse/properties/border_color.c index 65f35f3..aa337ad 100644 --- a/src/parse/properties/border_color.c +++ b/src/parse/properties/border_color.c @@ -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; - *(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_RIGHT_COLOR); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_COLOR); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_COLOR); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* 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 @@ css_error parse_border_color(css_language *c, /* Forcibly cause loop to exit */ token = NULL; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + + +#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; + + 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; - 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; - } - - 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; + 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; diff --git a/src/parse/properties/border_left.c b/src/parse/properties/border_left.c deleted file mode 100644 index 6c395c9..0000000 --- a/src/parse/properties/border_left.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-left shorthand - * - * \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_border_left(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side(c, vector, ctx, BORDER_SIDE_LEFT, result); -} diff --git a/src/parse/properties/border_left_color.c b/src/parse/properties/border_left_color.c deleted file mode 100644 index 79cf187..0000000 --- a/src/parse/properties/border_left_color.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-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 - * \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_left_color(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_color(c, vector, ctx, - CSS_PROP_BORDER_LEFT_COLOR, result); -} diff --git a/src/parse/properties/border_left_style.c b/src/parse/properties/border_left_style.c deleted file mode 100644 index d1e31c4..0000000 --- a/src/parse/properties/border_left_style.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-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 - * \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_left_style(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_style(c, vector, ctx, - CSS_PROP_BORDER_LEFT_STYLE, result); -} diff --git a/src/parse/properties/border_left_width.c b/src/parse/properties/border_left_width.c deleted file mode 100644 index 6a78bb6..0000000 --- a/src/parse/properties/border_left_width.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-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 - * \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_left_width(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_width(c, vector, ctx, - CSS_PROP_BORDER_LEFT_WIDTH, result); -} diff --git a/src/parse/properties/border_right.c b/src/parse/properties/border_right.c deleted file mode 100644 index b8433f1..0000000 --- a/src/parse/properties/border_right.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-right shorthand - * - * \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_border_right(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side(c, vector, ctx, BORDER_SIDE_RIGHT, result); -} diff --git a/src/parse/properties/border_right_color.c b/src/parse/properties/border_right_color.c deleted file mode 100644 index dc1412c..0000000 --- a/src/parse/properties/border_right_color.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-right-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 - * \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_right_color(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_color(c, vector, ctx, - CSS_PROP_BORDER_RIGHT_COLOR, result); -} diff --git a/src/parse/properties/border_right_style.c b/src/parse/properties/border_right_style.c deleted file mode 100644 index eb33c4f..0000000 --- a/src/parse/properties/border_right_style.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-right-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 - * \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_right_style(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_style(c, vector, ctx, - CSS_PROP_BORDER_RIGHT_STYLE, result); -} diff --git a/src/parse/properties/border_right_width.c b/src/parse/properties/border_right_width.c deleted file mode 100644 index a4739fb..0000000 --- a/src/parse/properties/border_right_width.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-right-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 - * \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_right_width(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_width(c, vector, ctx, - CSS_PROP_BORDER_RIGHT_WIDTH, result); -} diff --git a/src/parse/properties/border_spacing.c b/src/parse/properties/border_spacing.c index 623f616..3d8f994 100644 --- a/src/parse/properties/border_spacing.c +++ b/src/parse/properties/border_spacing.c @@ -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 @@ css_error parse_border_spacing(css_language *c, 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 @@ css_error parse_border_spacing(css_language *c, 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; } diff --git a/src/parse/properties/border_style.c b/src/parse/properties/border_style.c index ed3a7ac..7ee6922 100644 --- a/src/parse/properties/border_style.c +++ b/src/parse/properties/border_style.c @@ -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; - *(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_RIGHT_STYLE); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_STYLE); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_STYLE); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* 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 (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 != NULL) && is_css_inherit(c, token)) { + *ctx = orig_ctx; + return CSS_INVALID; } - if (error == CSS_OK) { - consumeWhitespace(vector, ctx); - - token = parserutils_vector_peek(vector, *ctx); + if (token->type != CSS_TOKEN_IDENT) + break; + + 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; - } - - /* 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_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; + side_count++; + + parserutils_vector_iterate(vector, ctx); + + consumeWhitespace(vector, ctx); - memcpy(((uint8_t *) ret->bytecode) + required_size, - left->bytecode, left->length); - required_size += left->length; + token = parserutils_vector_peek(vector, *ctx); + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + + +#define SIDE_APPEND(OP,NUM) \ + error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]); \ + if (error != CSS_OK) \ + break + + 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; + + 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; diff --git a/src/parse/properties/border_top.c b/src/parse/properties/border_top.c deleted file mode 100644 index 01993d7..0000000 --- a/src/parse/properties/border_top.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-top shorthand - * - * \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_border_top(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side(c, vector, ctx, BORDER_SIDE_TOP, result); -} diff --git a/src/parse/properties/border_top_color.c b/src/parse/properties/border_top_color.c deleted file mode 100644 index 2d02451..0000000 --- a/src/parse/properties/border_top_color.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-top-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 - * \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_top_color(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_color(c, vector, ctx, - CSS_PROP_BORDER_TOP_COLOR, result); -} diff --git a/src/parse/properties/border_top_style.c b/src/parse/properties/border_top_style.c deleted file mode 100644 index f98b608..0000000 --- a/src/parse/properties/border_top_style.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-top-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 - * \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_top_style(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_style(c, vector, ctx, - CSS_PROP_BORDER_TOP_STYLE, result); -} diff --git a/src/parse/properties/border_top_width.c b/src/parse/properties/border_top_width.c deleted file mode 100644 index d71b39c..0000000 --- a/src/parse/properties/border_top_width.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse border-top-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 - * \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_top_width(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_border_side_width(c, vector, ctx, - CSS_PROP_BORDER_TOP_WIDTH, result); -} diff --git a/src/parse/properties/border_width.c b/src/parse/properties/border_width.c index 74d3ee8..de4845a 100644 --- a/src/parse/properties/border_width.c +++ b/src/parse/properties/border_width.c @@ -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; - *(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_RIGHT_WIDTH); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_WIDTH); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_WIDTH); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* 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 @@ css_error parse_border_width(css_language *c, /* Forcibly cause loop to exit */ token = NULL; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { - error = CSS_INVALID; - goto cleanup; + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + + +#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; \ } - /* 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_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; diff --git a/src/parse/properties/bottom.c b/src/parse/properties/bottom.c deleted file mode 100644 index d1e3dc8..0000000 --- a/src/parse/properties/bottom.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_bottom(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_side(c, vector, ctx, CSS_PROP_BOTTOM, result); -} diff --git a/src/parse/properties/caption_side.c b/src/parse/properties/caption_side.c deleted file mode 100644 index 69cc945..0000000 --- a/src/parse/properties/caption_side.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse caption-side - * - * \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_caption_side(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 (top, bottom, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TOP], - &match) == lwc_error_ok && match)) { - value = CAPTION_SIDE_TOP; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[BOTTOM], - &match) == lwc_error_ok && match)) { - value = CAPTION_SIDE_BOTTOM; - } else { - *ctx = orig_ctx; - return 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; -} diff --git a/src/parse/properties/clear.c b/src/parse/properties/clear.c deleted file mode 100644 index 8673557..0000000 --- a/src/parse/properties/clear.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse clear - * - * \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_clear(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, both, none, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[RIGHT], - &match) == lwc_error_ok && match)) { - value = CLEAR_RIGHT; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[LEFT], - &match) == lwc_error_ok && match)) { - value = CLEAR_LEFT; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[BOTH], - &match) == lwc_error_ok && match)) { - value = CLEAR_BOTH; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - value = CLEAR_NONE; - } else { - *ctx = orig_ctx; - return 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; -} diff --git a/src/parse/properties/clip.c b/src/parse/properties/clip.c index dce2915..8b0cda6 100644 --- a/src/parse/properties/clip.c +++ b/src/parse/properties/clip.c @@ -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 @@ css_error parse_clip(css_language *c, 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 @@ css_error parse_clip(css_language *c, *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; + } + + for (i = 0; i < num_lengths; i++) { + error = css_stylesheet_style_vappend(result, + 2, + length[i], + unit[i]); + if (error != CSS_OK) + break; + } - 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])); + + } 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; } diff --git a/src/parse/properties/color.c b/src/parse/properties/color.c deleted file mode 100644 index f809518..0000000 --- a/src/parse/properties/color.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_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) { - *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_colour_specifier(c, vector, ctx, &colour); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - value = COLOR_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/content.c b/src/parse/properties/content.c index 7f37400..9a3a425 100644 --- a/src/parse/properties/content.c +++ b/src/parse/properties/content.c @@ -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; } + diff --git a/src/parse/properties/conter_reset.c b/src/parse/properties/conter_reset.c deleted file mode 100644 index 74f8f36..0000000 --- a/src/parse/properties/conter_reset.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#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 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_reset(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_counter_common(c, vector, ctx, - CSS_PROP_COUNTER_RESET, result); -} diff --git a/src/parse/properties/counter_increment.c b/src/parse/properties/counter_increment.c deleted file mode 100644 index b5ea5e6..0000000 --- a/src/parse/properties/counter_increment.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/css_property_parser_gen.c b/src/parse/properties/css_property_parser_gen.c new file mode 100644 index 0000000..a348c6a --- /dev/null +++ b/src/parse/properties/css_property_parser_gen.c @@ -0,0 +1,613 @@ +/* + * This file generates parts of LibCSS. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2010 Vincent Sanders + */ + +#include +#include +#include +#include + +/* 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, bool is_generic) +{ + 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 2010 The NetSurf Browser Project.\n" + " */\n" + "\n" + "#include \n" + "#include \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" + "%s" + " * \\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%s)\n" + "{\n", + descriptor, + parser_id->key, + is_generic ? " * \\param op Bytecode OpCode for CSS property to encode\n" : "", + parser_id->key, + is_generic ? ", enum css_properties_e op" : ""); +} + + +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 *kvlist) +{ + struct keyval *ckv = kvlist->item[0]; + + 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, %s, 0, %s);\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 ", + parseid->val, + ckv->val); +} + +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 */ + bool is_generic = false; + + 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 ] \n", argv[0]); + return 1; + } + + if ((argv[1][0] == '-') && (argv[1][1] == 'o')) { + if (argc != 4) { + fprintf(stderr,"Usage: %s [-o ] \n", 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\n", 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 if (strcmp(rkv->key, "GENERIC") == 0) { + is_generic = true; + } else { + /* just append to current list */ + curlist->item[curlist->count++] = rkv; + } + } + + if (base.count != 1) { + fprintf(stderr,"Incorrect base element count (got %d expected 1)\n", base.count); + fclose(outputf); + return 3; + } + + + /* header */ +output_header(outputf, descriptor, base.item[0], is_generic); + + 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; +} diff --git a/src/parse/properties/cue.c b/src/parse/properties/cue.c index 982405f..096c121 100644 --- a/src/parse/properties/cue.c +++ b/src/parse/properties/cue.c @@ -13,134 +13,6 @@ #include "parse/properties/properties.h" #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 * @@ -157,138 +29,54 @@ css_error parse_cue_before(css_language *c, */ 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; - - error = css_stylesheet_style_create(c->sheet, - 2 * sizeof(uint32_t), &ret); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - bytecode = (uint32_t *) ret->bytecode; - - *(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; + /* 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 + */ - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + first_token = parserutils_vector_peek(vector, *ctx); - /* Attempt to read 1 or 2 cues */ - do { - prev_ctx = *ctx; - error = CSS_OK; + error = parse_cue_before(c, vector, ctx, result); + if (error == CSS_OK) { + /* first token parsed */ + + 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)) { - 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; diff --git a/src/parse/properties/cursor.c b/src/parse/properties/cursor.c index 725e7b7..e063a9b 100644 --- a/src/parse/properties/cursor.c +++ b/src/parse/properties/cursor.c @@ -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 @@ css_error parse_cursor(css_language *c, * 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; - /* URI* */ - while (token != NULL && token->type == CSS_TOKEN_URI) { - lwc_string *uri = token->idata; +/* 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) - if (first == false) { - required_size += sizeof(opv); - } else { - value = CURSOR_URI; - } - required_size += sizeof(uri); - consumeWhitespace(vector, &temp_ctx); + /* URI* */ + while (token != NULL && token->type == CSS_TOKEN_URI) { + lwc_string *uri; + uint32_t uri_snumber; - /* 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; - } - - if (first == false) { - required_size += sizeof(opv); + return error; } - } - } - 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 @@ css_error parse_cursor(css_language *c, 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; - } - - if (first == false) { - memcpy(ptr, &opv, sizeof(opv)); - ptr += sizeof(opv); + error = CSS_INVALID; } } + } - return CSS_OK; + if (error != CSS_OK) + *ctx = orig_ctx; + + return error; } diff --git a/src/parse/properties/direction.c b/src/parse/properties/direction.c deleted file mode 100644 index 2d9fc96..0000000 --- a/src/parse/properties/direction.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse direction - * - * \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_direction(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 (ltr, rtl, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[LTR], - &match) == lwc_error_ok && match)) { - value = DIRECTION_LTR; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[RTL], - &match) == lwc_error_ok && match)) { - value = DIRECTION_RTL; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/display.c b/src/parse/properties/display.c deleted file mode 100644 index b96b159..0000000 --- a/src/parse/properties/display.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse display - * - * \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_display(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 (inline, block, list-item, run-in, inline-block, table, - * inline-table, table-row-group, table-header-group, - * table-footer-group, table-row, table-column-group, table-column, - * table-cell, table-caption, none, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[INLINE], - &match) == lwc_error_ok && match)) { - value = DISPLAY_INLINE; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[BLOCK], - &match) == lwc_error_ok && match)) { - value = DISPLAY_BLOCK; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[LIST_ITEM], - &match) == lwc_error_ok && match)) { - value = DISPLAY_LIST_ITEM; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[RUN_IN], - &match) == lwc_error_ok && match)) { - value = DISPLAY_RUN_IN; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[INLINE_BLOCK], - &match) == lwc_error_ok && match)) { - value = DISPLAY_INLINE_BLOCK; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[INLINE_TABLE], - &match) == lwc_error_ok && match)) { - value = DISPLAY_INLINE_TABLE; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_ROW_GROUP], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_ROW_GROUP; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_HEADER_GROUP], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_HEADER_GROUP; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_FOOTER_GROUP], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_FOOTER_GROUP; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_ROW], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_ROW; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_COLUMN_GROUP], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_COLUMN_GROUP; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_COLUMN], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_COLUMN; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_CELL], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_CELL; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[TABLE_CAPTION], - &match) == lwc_error_ok && match)) { - value = DISPLAY_TABLE_CAPTION; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - value = DISPLAY_NONE; - } else { - *ctx = orig_ctx; - return CSS_INVALID; - } - - opv = buildOPV(CSS_PROP_DISPLAY, 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; -} diff --git a/src/parse/properties/elevation.c b/src/parse/properties/elevation.c index d29a9b7..d0c47d8 100644 --- a/src/parse/properties/elevation.c +++ b/src/parse/properties/elevation.c @@ -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 @@ css_error parse_elevation(css_language *c, 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; diff --git a/src/parse/properties/empty_cells.c b/src/parse/properties/empty_cells.c deleted file mode 100644 index ca3ddf4..0000000 --- a/src/parse/properties/empty_cells.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse empty-cells - * - * \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_empty_cells(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 (show, hide, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[SHOW], - &match) == lwc_error_ok && match)) { - value = EMPTY_CELLS_SHOW; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[HIDE], - &match) == lwc_error_ok && match)) { - value = EMPTY_CELLS_HIDE; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/float.c b/src/parse/properties/float.c deleted file mode 100644 index 78a33fe..0000000 --- a/src/parse/properties/float.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse float - * - * \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_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) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[LEFT], - &match) == lwc_error_ok && match)) { - value = FLOAT_LEFT; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[RIGHT], - &match) == lwc_error_ok && match)) { - value = FLOAT_RIGHT; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - value = FLOAT_NONE; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/font.c b/src/parse/properties/font.c index c759dde..93029a4 100644 --- a/src/parse/properties/font.c +++ b/src/parse/properties/font.c @@ -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; - - error = css_stylesheet_style_create(c->sheet, - 6 * 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_FONT_STYLE); + if (error != CSS_OK) return error; - } - bytecode = (uint32_t *) ret->bytecode; - - *(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_FONT_VARIANT); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_WEIGHT); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_SIZE); + 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_inherit(result, CSS_PROP_LINE_HEIGHT); + if (error != CSS_OK) + return error; + + error = css_stylesheet_style_inherit(result, CSS_PROP_FONT_FAMILY); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); + + return error; + } + + + /* 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); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &weight_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(variant_style); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &size_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(variant_style); + css_stylesheet_style_destroy(weight_style); + return error; } + error = css_stylesheet_style_create(c->sheet, &line_height_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(variant_style); + css_stylesheet_style_destroy(weight_style); + css_stylesheet_style_destroy(size_style); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &family_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(variant_style); + css_stylesheet_style_destroy(weight_style); + css_stylesheet_style_destroy(size_style); + css_stylesheet_style_destroy(line_height_style); + return error; + } + + /* Attempt to parse the optional style, variant, and weight */ for (svw = 0; svw < 3; svw++) { prev_ctx = *ctx; @@ -94,23 +136,23 @@ css_error parse_font(css_language *c, /* 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,178 +169,125 @@ css_error parse_font(css_language *c, /* 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); - - /* Calculate the required size of the resultant style, - * defaulting the unspecified properties to their initial values */ - required_size = 0; + assert(size != true); + assert(family != true); - 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; - - 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 (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); + /* merge final output */ + error = css_stylesheet_merge_style(result, style_style); + if (error != CSS_OK) + goto parse_font_cleanup; + + error = css_stylesheet_merge_style(result, variant_style); + if (error != CSS_OK) + goto parse_font_cleanup; + + error = css_stylesheet_merge_style(result, weight_style); + if (error != CSS_OK) + goto parse_font_cleanup; + + 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); + css_stylesheet_style_destroy(variant_style); + css_stylesheet_style_destroy(weight_style); + css_stylesheet_style_destroy(size_style); + css_stylesheet_style_destroy(line_height_style); + css_stylesheet_style_destroy(family_style); if (error != CSS_OK) *ctx = orig_ctx; diff --git a/src/parse/properties/font_family.c b/src/parse/properties/font_family.c index d551e5d..a2e9511 100644 --- a/src/parse/properties/font_family.c +++ b/src/parse/properties/font_family.c @@ -46,9 +46,10 @@ static bool font_family_reserved(css_language *c, const css_token *ident) * * \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 @@ static uint16_t font_family_value(css_language *c, const css_token *token) value = FONT_FAMILY_STRING; } - return value; + return first ? buildOPV(CSS_PROP_FONT_FAMILY, 0, value) : value; } /** @@ -99,17 +100,11 @@ static uint16_t font_family_value(css_language *c, const css_token *token) */ 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 @@ css_error parse_font_family(css_language *c, * 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 @@ css_error parse_font_family(css_language *c, (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; - - value = font_family_value(c, token); + *ctx = orig_ctx; - 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; } diff --git a/src/parse/properties/font_size.c b/src/parse/properties/font_size.c deleted file mode 100644 index 8b02362..0000000 --- a/src/parse/properties/font_size.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse font-size - * - * \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_font_size(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(xx-small, x-small, small, medium, - * large, x-large, xx-large, larger, smaller, 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 if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[XX_SMALL], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_XX_SMALL; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[X_SMALL], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_X_SMALL; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[SMALL], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_SMALL; - } 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 = FONT_SIZE_MEDIUM; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[LARGE], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_LARGE; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[X_LARGE], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_X_LARGE; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[XX_LARGE], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_XX_LARGE; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[LARGER], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_LARGER; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[SMALLER], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = FONT_SIZE_SMALLER; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are not permitted */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/font_style.c b/src/parse/properties/font_style.c deleted file mode 100644 index 1deeb83..0000000 --- a/src/parse/properties/font_style.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse font-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 - * \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_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) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NORMAL], - &match) == lwc_error_ok && match)) { - value = FONT_STYLE_NORMAL; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[ITALIC], - &match) == lwc_error_ok && match)) { - value = FONT_STYLE_ITALIC; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[OBLIQUE], - &match) == lwc_error_ok && match)) { - value = FONT_STYLE_OBLIQUE; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/font_variant.c b/src/parse/properties/font_variant.c deleted file mode 100644 index b350e86..0000000 --- a/src/parse/properties/font_variant.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse font-variant - * - * \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_font_variant(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, small-caps, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NORMAL], - &match) == lwc_error_ok && match)) { - value = 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/font_weight.c b/src/parse/properties/font_weight.c index df35c0d..03e6e51 100644 --- a/src/parse/properties/font_weight.c +++ b/src/parse/properties/font_weight.c @@ -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 @@ css_error parse_font_weight(css_language *c, 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; } diff --git a/src/parse/properties/height.c b/src/parse/properties/height.c deleted file mode 100644 index 1611651..0000000 --- a/src/parse/properties/height.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse height - * - * \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_height(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) { - *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 = HEIGHT_AUTO; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative height is illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/left.c b/src/parse/properties/left.c deleted file mode 100644 index dc04c40..0000000 --- a/src/parse/properties/left.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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_left(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_side(c, vector, ctx, CSS_PROP_LEFT, result); -} diff --git a/src/parse/properties/letter_spacing.c b/src/parse/properties/letter_spacing.c deleted file mode 100644 index c5566e2..0000000 --- a/src/parse/properties/letter_spacing.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse letter-spacing - * - * \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_letter_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) { - *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 = LETTER_SPACING_NORMAL; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = LETTER_SPACING_SET; - } - - opv = buildOPV(CSS_PROP_LETTER_SPACING, flags, value); - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/line_height.c b/src/parse/properties/line_height.c deleted file mode 100644 index 8b1c995..0000000 --- a/src/parse/properties/line_height.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse line-height - * - * \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_line_height(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 | length | percentage | IDENT(normal, 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 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 = LINE_HEIGHT_NORMAL; - } else if (token->type == CSS_TOKEN_NUMBER) { - size_t consumed = 0; - length = number_from_lwc_string(token->idata, false, &consumed); - if (consumed != lwc_string_length(token->idata)) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - parserutils_vector_iterate(vector, ctx); - value = LINE_HEIGHT_NUMBER; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - - return CSS_OK; -} diff --git a/src/parse/properties/list_style.c b/src/parse/properties/list_style.c index 4c2043e..b9406c1 100644 --- a/src/parse/properties/list_style.c +++ b/src/parse/properties/list_style.c @@ -29,52 +29,57 @@ */ 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); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &type_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(image_style); + css_stylesheet_style_destroy(position_style); + return error; } /* Attempt to parse the various longhand properties */ @@ -84,22 +89,23 @@ css_error parse_list_style(css_language *c, /* 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 @@ css_error parse_list_style(css_language *c, } } 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); + css_stylesheet_style_destroy(position_style); + css_stylesheet_style_destroy(image_style); if (error != CSS_OK) *ctx = orig_ctx; return error; + } diff --git a/src/parse/properties/list_style_image.c b/src/parse/properties/list_style_image.c deleted file mode 100644 index a200323..0000000 --- a/src/parse/properties/list_style_image.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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)) { - *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; - } else if (token->type == CSS_TOKEN_URI) { - value = LIST_STYLE_IMAGE_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(CSS_PROP_LIST_STYLE_IMAGE, flags, value); - - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == LIST_STYLE_IMAGE_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 == 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; -} diff --git a/src/parse/properties/list_style_position.c b/src/parse/properties/list_style_position.c deleted file mode 100644 index 7fc680d..0000000 --- a/src/parse/properties/list_style_position.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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; - bool match; - - /* IDENT (inside, outside, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/list_style_type.c b/src/parse/properties/list_style_type.c index 1d1fe42..3afab3a 100644 --- a/src/parse/properties/list_style_type.c +++ b/src/parse/properties/list_style_type.c @@ -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 @@ css_error parse_list_style_type(css_language *c, } } - 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; } diff --git a/src/parse/properties/margin.c b/src/parse/properties/margin.c index 5614024..b320e85 100644 --- a/src/parse/properties/margin.c +++ b/src/parse/properties/margin.c @@ -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 CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* 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 @@ css_error parse_margin(css_language *c, /* Forcibly cause loop to exit */ token = NULL; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { - error = CSS_INVALID; - goto cleanup; + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + + +#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; \ } - /* 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_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; } - - - - - diff --git a/src/parse/properties/margin_bottom.c b/src/parse/properties/margin_bottom.c deleted file mode 100644 index 1c922ea..0000000 --- a/src/parse/properties/margin_bottom.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/margin_left.c b/src/parse/properties/margin_left.c deleted file mode 100644 index 2fb4597..0000000 --- a/src/parse/properties/margin_left.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/margin_right.c b/src/parse/properties/margin_right.c deleted file mode 100644 index 4fe0363..0000000 --- a/src/parse/properties/margin_right.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/margin_top.c b/src/parse/properties/margin_top.c deleted file mode 100644 index 7bba06b..0000000 --- a/src/parse/properties/margin_top.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/max_height.c b/src/parse/properties/max_height.c deleted file mode 100644 index cbabf24..0000000 --- a/src/parse/properties/max_height.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse max-height - * - * \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_max_height(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(none, 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 if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = MAX_HEIGHT_NONE; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/max_width.c b/src/parse/properties/max_width.c deleted file mode 100644 index 4ee9572..0000000 --- a/src/parse/properties/max_width.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse max-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 - * \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_max_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(none, 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 if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - parserutils_vector_iterate(vector, ctx); - value = MAX_WIDTH_NONE; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/min_height.c b/src/parse/properties/min_height.c deleted file mode 100644 index 36adbd5..0000000 --- a/src/parse/properties/min_height.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse min-height - * - * \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_min_height(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) { - *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_PX, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/min_width.c b/src/parse/properties/min_width.c deleted file mode 100644 index fba6518..0000000 --- a/src/parse/properties/min_width.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse min-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 - * \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_min_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(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_PX, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - 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); - 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)); - } - - return CSS_OK; -} diff --git a/src/parse/properties/orphans.c b/src/parse/properties/orphans.c deleted file mode 100644 index 735db60..0000000 --- a/src/parse/properties/orphans.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse orphans - * - * \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_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; - - /* | IDENT (inherit) */ - token = parserutils_vector_iterate(vector, ctx); - 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; - } else if (token->type == CSS_TOKEN_NUMBER) { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = ORPHANS_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/outline.c b/src/parse/properties/outline.c index b262609..7af2cc3 100644 --- a/src/parse/properties/outline.c +++ b/src/parse/properties/outline.c @@ -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); + return error; + } + + error = css_stylesheet_style_create(c->sheet, &width_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(style_style); + return error; } - /* Attempt to parse individual properties */ + /* 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,82 +118,43 @@ css_error parse_outline(css_language *c, } } 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; - - /* 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, color_style); + if (error != CSS_OK) + goto parse_outline_cleanup; + + 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); + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(color_style); if (error != CSS_OK) *ctx = orig_ctx; diff --git a/src/parse/properties/outline_color.c b/src/parse/properties/outline_color.c deleted file mode 100644 index 402dee3..0000000 --- a/src/parse/properties/outline_color.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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) { - *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; - } else { - error = parse_colour_specifier(c, vector, ctx, &colour); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - value = OUTLINE_COLOR_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/outline_style.c b/src/parse/properties/outline_style.c deleted file mode 100644 index 0263d68..0000000 --- a/src/parse/properties/outline_style.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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; - - /* Parse as a border style */ - error = parse_border_side_style(c, vector, ctx, - CSS_PROP_OUTLINE_STYLE, result); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - opv = *((uint32_t *) (*result)->bytecode); - - value = getValue(opv); - - /* Hidden is invalid */ - if (value == BORDER_STYLE_HIDDEN) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - return CSS_OK; -} diff --git a/src/parse/properties/outline_width.c b/src/parse/properties/outline_width.c deleted file mode 100644 index 54a669a..0000000 --- a/src/parse/properties/outline_width.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/overflow.c b/src/parse/properties/overflow.c deleted file mode 100644 index 5d5ade0..0000000 --- a/src/parse/properties/overflow.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse overflow - * - * \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_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; - bool match; - - /* IDENT (visible, hidden, scroll, auto, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/padding.c b/src/parse/properties/padding.c index 753b530..263906d 100644 --- a/src/parse/properties/padding.c +++ b/src/parse/properties/padding.c @@ -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; - *(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_RIGHT); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_BOTTOM); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_LEFT); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* 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 (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; + if ((token != NULL) && is_css_inherit(c, token)) { + *ctx = orig_ctx; + return CSS_INVALID; } + 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,139 +96,49 @@ css_error parse_padding(css_language *c, /* Forcibly cause loop to exit */ token = NULL; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + +#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; - } - - /* 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; + 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_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; diff --git a/src/parse/properties/padding_bottom.c b/src/parse/properties/padding_bottom.c deleted file mode 100644 index 41ba95b..0000000 --- a/src/parse/properties/padding_bottom.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/padding_left.c b/src/parse/properties/padding_left.c deleted file mode 100644 index 6bb3cd4..0000000 --- a/src/parse/properties/padding_left.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/padding_right.c b/src/parse/properties/padding_right.c deleted file mode 100644 index 834e586..0000000 --- a/src/parse/properties/padding_right.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/padding_top.c b/src/parse/properties/padding_top.c deleted file mode 100644 index c93dd6b..0000000 --- a/src/parse/properties/padding_top.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/page_break_after.c b/src/parse/properties/page_break_after.c deleted file mode 100644 index 8b6fc79..0000000 --- a/src/parse/properties/page_break_after.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse page-break-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_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; - bool match; - - /* IDENT (auto, always, avoid, left, right, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/page_break_before.c b/src/parse/properties/page_break_before.c deleted file mode 100644 index 515412d..0000000 --- a/src/parse/properties/page_break_before.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse page-break-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_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; - bool match; - - /* IDENT (auto, always, avoid, left, right, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/page_break_inside.c b/src/parse/properties/page_break_inside.c deleted file mode 100644 index 0d11a19..0000000 --- a/src/parse/properties/page_break_inside.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse page-break-inside - * - * \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_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; - bool match; - - /* IDENT (auto, avoid, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/pause.c b/src/parse/properties/pause.c index 82a199e..c1612aa 100644 --- a/src/parse/properties/pause.c +++ b/src/parse/properties/pause.c @@ -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; - - error = css_stylesheet_style_create(c->sheet, - 2 * sizeof(uint32_t), &ret); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - bytecode = (uint32_t *) ret->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 + */ - *(bytecode++) = buildOPV(CSS_PROP_PAUSE_BEFORE, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_PAUSE_AFTER, - FLAG_INHERIT, 0); + first_token = parserutils_vector_peek(vector, *ctx); - parserutils_vector_iterate(vector, ctx); + error = parse_pause_before(c, vector, ctx, result); + if (error == CSS_OK) { + /* first token parsed */ - *result = ret; + consumeWhitespace(vector, ctx); - 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; } - diff --git a/src/parse/properties/pause_after.c b/src/parse/properties/pause_after.c deleted file mode 100644 index a627440..0000000 --- a/src/parse/properties/pause_after.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/pause_before.c b/src/parse/properties/pause_before.c deleted file mode 100644 index 0ced812..0000000 --- a/src/parse/properties/pause_before.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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); -} diff --git a/src/parse/properties/pitch.c b/src/parse/properties/pitch.c deleted file mode 100644 index f821adb..0000000 --- a/src/parse/properties/pitch.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse pitch - * - * \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_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) { - *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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = PITCH_FREQUENCY; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/pitch_range.c b/src/parse/properties/pitch_range.c deleted file mode 100644 index 1c3e590..0000000 --- a/src/parse/properties/pitch_range.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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)) { - *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 (token->type == CSS_TOKEN_NUMBER) { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = PITCH_RANGE_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/play_during.c b/src/parse/properties/play_during.c index f4b0ba4..d2f6521 100644 --- a/src/parse/properties/play_during.c +++ b/src/parse/properties/play_during.c @@ -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 @@ css_error parse_play_during(css_language *c, 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 @@ css_error parse_play_during(css_language *c, } } - 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; } diff --git a/src/parse/properties/position.c b/src/parse/properties/position.c deleted file mode 100644 index 563f0bd..0000000 --- a/src/parse/properties/position.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_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; - bool match; - - /* IDENT (static, relative, absolute, fixed, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/properties.gen b/src/parse/properties/properties.gen new file mode 100644 index 0000000..7666a3a --- /dev/null +++ b/src/parse/properties/properties.gen @@ -0,0 +1,190 @@ +##Common templates +# +#property:CSS_PROP_ENUM IDENT:( INHERIT: IDENT:) +#property:CSS_PROP_ENUM IDENT:INHERIT NUMBER:( false: RANGE: NUMBER:) +#property:CSS_PROP_ENUM IDENT:INHERIT LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW: DISALLOW: RANGE:<0 LENGTH_UNIT:) +#property:CSS_PROP_ENUM IDENT:( INHERIT: IDENT:) LENGTH_UNIT:( UNIT_HZ:PITCH_FREQUENCY ALLOW: DISALLOW: RANGE:<0 LENGTH_UNIT:) +#property:CSS_PROP_ENUM WRAP: + +background_repeat:CSS_PROP_BACKGROUND_REPEAT IDENT:( INHERIT: NO_REPEAT:0,BACKGROUND_REPEAT_NO_REPEAT REPEAT_X:0,BACKGROUND_REPEAT_REPEAT_X REPEAT_Y:0,BACKGROUND_REPEAT_REPEAT_Y REPEAT:0,BACKGROUND_REPEAT_REPEAT IDENT:) + +border_collapse:CSS_PROP_BORDER_COLLAPSE IDENT:( INHERIT: COLLAPSE:0,BORDER_COLLAPSE_COLLAPSE SEPARATE:0,BORDER_COLLAPSE_SEPARATE IDENT:) + +cue_after:CSS_PROP_CUE_AFTER IDENT:( INHERIT: NONE:0,CUE_AFTER_NONE IDENT:) URI:CUE_AFTER_URI + +cue_before:CSS_PROP_CUE_BEFORE IDENT:( INHERIT: NONE:0,CUE_BEFORE_NONE IDENT:) URI:CUE_BEFORE_URI + +direction:CSS_PROP_DIRECTION IDENT:( INHERIT: LTR:0,DIRECTION_LTR RTL:0,DIRECTION_RTL IDENT:) + +display:CSS_PROP_DISPLAY IDENT:( INHERIT: INLINE:0,DISPLAY_INLINE BLOCK:0,DISPLAY_BLOCK LIST_ITEM:0,DISPLAY_LIST_ITEM RUN_IN:0,DISPLAY_RUN_IN INLINE_BLOCK:0,DISPLAY_INLINE_BLOCK TABLE:0,DISPLAY_TABLE INLINE_TABLE:0,DISPLAY_INLINE_TABLE TABLE_ROW_GROUP:0,DISPLAY_TABLE_ROW_GROUP TABLE_HEADER_GROUP:0,DISPLAY_TABLE_HEADER_GROUP TABLE_FOOTER_GROUP:0,DISPLAY_TABLE_FOOTER_GROUP TABLE_ROW:0,DISPLAY_TABLE_ROW TABLE_COLUMN_GROUP:0,DISPLAY_TABLE_COLUMN_GROUP TABLE_COLUMN:0,DISPLAY_TABLE_COLUMN TABLE_CELL:0,DISPLAY_TABLE_CELL TABLE_CAPTION:0,DISPLAY_TABLE_CAPTION NONE:0,DISPLAY_NONE IDENT:) + +empty_cells:CSS_PROP_EMPTY_CELLS IDENT:( INHERIT: SHOW:0,EMPTY_CELLS_SHOW HIDE:0,EMPTY_CELLS_HIDE IDENT:) + +float:CSS_PROP_FLOAT IDENT:( INHERIT: LEFT:0,FLOAT_LEFT RIGHT:0,FLOAT_RIGHT NONE:0,FLOAT_NONE IDENT:) + +font_size:CSS_PROP_FONT_SIZE IDENT:( INHERIT: XX_SMALL:0,FONT_SIZE_XX_SMALL X_SMALL:0,FONT_SIZE_X_SMALL SMALL:0,FONT_SIZE_SMALL MEDIUM:0,FONT_SIZE_MEDIUM LARGE:0,FONT_SIZE_LARGE X_LARGE:0,FONT_SIZE_X_LARGE XX_LARGE:0,FONT_SIZE_XX_LARGE LARGER:0,FONT_SIZE_LARGER SMALLER:0,FONT_SIZE_SMALLER IDENT:) LENGTH_UNIT:( UNIT_PX:FONT_SIZE_DIMENSION DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +font_style:CSS_PROP_FONT_STYLE IDENT:( INHERIT: NORMAL:0,FONT_STYLE_NORMAL ITALIC:0,FONT_STYLE_ITALIC OBLIQUE:0,FONT_STYLE_OBLIQUE IDENT:) + +font_variant:CSS_PROP_FONT_VARIANT IDENT:( INHERIT: NORMAL:0,FONT_VARIANT_NORMAL SMALL_CAPS:0,FONT_VARIANT_SMALL_CAPS IDENT:) + +height:CSS_PROP_HEIGHT IDENT:( INHERIT: AUTO:0,HEIGHT_AUTO IDENT:) LENGTH_UNIT:( UNIT_PX:HEIGHT_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +letter_spacing:CSS_PROP_LETTER_SPACING IDENT:( INHERIT: NORMAL:0,LETTER_SPACING_NORMAL IDENT:) LENGTH_UNIT:( UNIT_PX:LETTER_SPACING_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ||unit&UNIT_PCT LENGTH_UNIT:) + +line_height:CSS_PROP_LINE_HEIGHT IDENT:( INHERIT: NORMAL:0,LINE_HEIGHT_NORMAL IDENT:) NUMBER:( false:LINE_HEIGHT_NUMBER RANGE:num<0 NUMBER:) LENGTH_UNIT:( UNIT_PX:LINE_HEIGHT_DIMENSION DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +border_top:BORDER_SIDE_TOP WRAP:parse_border_side +border_bottom:BORDER_SIDE_BOTTOM WRAP:parse_border_side +border_left:BORDER_SIDE_LEFT WRAP:parse_border_side +border_right:BORDER_SIDE_RIGHT WRAP:parse_border_side + +max_height:CSS_PROP_MAX_HEIGHT IDENT:( INHERIT: NONE:0,MAX_HEIGHT_NONE IDENT:) LENGTH_UNIT:( UNIT_PX:MAX_HEIGHT_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +max_width:CSS_PROP_MAX_WIDTH IDENT:( INHERIT: NONE:0,MAX_WIDTH_NONE IDENT:) LENGTH_UNIT:( UNIT_PX:MAX_WIDTH_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +min_height:CSS_PROP_MIN_HEIGHT IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:MIN_HEIGHT_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +min_width:CSS_PROP_MIN_WIDTH IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:MIN_WIDTH_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +color:CSS_PROP_COLOR IDENT:INHERIT COLOR:COLOR_SET + +#generic for padding_{top, bottom, left, right}.c +padding_side:op GENERIC: IDENT:INHERIT LENGTH_UNIT:( UNIT_PX:PADDING_SET DISALLOW:unit&UNIT_ANGLE||unit&UNIT_TIME||unit&UNIT_FREQ RANGE:<0 LENGTH_UNIT:) + +padding_bottom:CSS_PROP_PADDING_BOTTOM WRAP:parse_padding_side +padding_left:CSS_PROP_PADDING_LEFT WRAP:parse_padding_side +padding_top:CSS_PROP_PADDING_TOP WRAP:parse_padding_side +padding_right:CSS_PROP_PADDING_RIGHT WRAP:parse_padding_side + + +#generic for margin_{top, bottom, left, right}.c +margin_side:op GENERIC 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:) + +margin_top:CSS_PROP_MARGIN_TOP WRAP:parse_margin_side +margin_bottom:CSS_PROP_MARGIN_BOTTOM WRAP:parse_margin_side +margin_left:CSS_PROP_MARGIN_LEFT WRAP:parse_margin_side +margin_right:CSS_PROP_MARGIN_RIGHT WRAP:parse_margin_side + +#generic for {top, bottom, left, right}.c +side:op GENERIC: 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:) + +top:CSS_PROP_TOP WRAP:parse_side +bottom:CSS_PROP_BOTTOM WRAP:parse_side +left:CSS_PROP_LEFT WRAP:parse_side +right:CSS_PROP_RIGHT WRAP:parse_side + + +#generic for border_{top, bottom, left, right}_width.c +border_side_width:op GENERIC: 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:) + +border_top_width:CSS_PROP_BORDER_TOP_WIDTH WRAP:parse_border_side_width +border_bottom_width:CSS_PROP_BORDER_BOTTOM_WIDTH WRAP:parse_border_side_width +border_left_width:CSS_PROP_BORDER_LEFT_WIDTH WRAP:parse_border_side_width +border_right_width:CSS_PROP_BORDER_RIGHT_WIDTH WRAP:parse_border_side_width + + +#generic for border_{top, bottom, left, right}_style.c +border_side_style:op GENERIC: 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:) + +border_top_style:CSS_PROP_BORDER_TOP_STYLE WRAP:parse_border_side_style +border_bottom_style:CSS_PROP_BORDER_BOTTOM_STYLE WRAP:parse_border_side_style +border_left_style:CSS_PROP_BORDER_LEFT_STYLE WRAP:parse_border_side_style +border_right_style:CSS_PROP_BORDER_RIGHT_STYLE WRAP:parse_border_side_style + +#generic for border_{top, bottom, left, right}_color.c +border_side_color:op GENERIC: IDENT:( INHERIT: TRANSPARENT:0,BORDER_COLOR_TRANSPARENT IDENT:) COLOR:BORDER_COLOR_SET + +border_top_color:CSS_PROP_BORDER_TOP_COLOR WRAP:parse_border_side_color +border_bottom_color:CSS_PROP_BORDER_BOTTOM_COLOR WRAP:parse_border_side_color +border_left_color:CSS_PROP_BORDER_LEFT_COLOR WRAP:parse_border_side_color +border_right_color:CSS_PROP_BORDER_RIGHT_COLOR WRAP:parse_border_side_color + + +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:) + +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:) + + +background_attachment:CSS_PROP_BACKGROUND_ATTACHMENT IDENT:( INHERIT: FIXED:0,BACKGROUND_ATTACHMENT_FIXED SCROLL:0,BACKGROUND_ATTACHMENT_SCROLL IDENT:) + +background_color:CSS_PROP_BACKGROUND_COLOR IDENT:( INHERIT: TRANSPARENT:0,BACKGROUND_COLOR_TRANSPARENT IDENT:) COLOR:BACKGROUND_COLOR_SET + +caption_side:CSS_PROP_CAPTION_SIDE IDENT:( INHERIT: TOP:0,CAPTION_SIDE_TOP BOTTOM:0,CAPTION_SIDE_BOTTOM IDENT:) + +clear:CSS_PROP_CLEAR IDENT:( INHERIT: RIGHT:0,CLEAR_RIGHT LEFT:0,CLEAR_LEFT BOTH:0,CLEAR_BOTH NONE:0,CLEAR_NONE IDENT:) + +background_image:CSS_PROP_BACKGROUND_IMAGE IDENT:( INHERIT: NONE:0,BACKGROUND_IMAGE_NONE IDENT:) URI:BACKGROUND_IMAGE_URI + +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:) + +orphans:CSS_PROP_ORPHANS IDENT:INHERIT NUMBER:( true:ORPHANS_SET RANGE:num<0 NUMBER:) + +outline_color:CSS_PROP_OUTLINE_COLOR IDENT:( INHERIT: INVERT:0,OUTLINE_COLOR_INVERT IDENT:) COLOR:OUTLINE_COLOR_SET + + +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:) + +outline_width:CSS_PROP_OUTLINE_WIDTH WRAP:parse_border_side_width + +overflow:CSS_PROP_OVERFLOW IDENT:( INHERIT: VISIBLE:0,OVERFLOW_VISIBLE HIDDEN:0,OVERFLOW_HIDDEN SCROLL:0,OVERFLOW_SCROLL AUTO:0,OVERFLOW_AUTO IDENT:) + + +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:) + +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:) + +page_break_inside:CSS_PROP_PAGE_BREAK_INSIDE IDENT:( INHERIT: AUTO:0,PAGE_BREAK_INSIDE_AUTO AVOID:0,PAGE_BREAK_INSIDE_AVOID IDENT:) + +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:) + +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:) + +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:) + +pitch_range:CSS_PROP_PITCH_RANGE IDENT:INHERIT NUMBER:( false:PITCH_RANGE_SET RANGE:num<0||num>F_100 NUMBER:) + +position:CSS_PROP_POSITION IDENT:( INHERIT: LIBCSS_STATIC:0,POSITION_STATIC RELATIVE:0,POSITION_RELATIVE ABSOLUTE:0,POSITION_ABSOLUTE FIXED:0,POSITION_FIXED IDENT:) + +richness:CSS_PROP_RICHNESS IDENT:INHERIT NUMBER:( false:RICHNESS_SET RANGE:num<0||num>F_100 NUMBER:) + +speak:CSS_PROP_SPEAK IDENT:( INHERIT: NORMAL:0,SPEAK_NORMAL NONE:0,SPEAK_NONE SPELL_OUT:0,SPEAK_SPELL_OUT IDENT:) + +speak_header:CSS_PROP_SPEAK_HEADER IDENT:( INHERIT: ONCE:0,SPEAK_HEADER_ONCE ALWAYS:0,SPEAK_HEADER_ALWAYS IDENT:) + +speak_numeral:CSS_PROP_SPEAK_NUMERAL IDENT:( INHERIT: DIGITS:0,SPEAK_NUMERAL_DIGITS CONTINUOUS:0,SPEAK_NUMERAL_CONTINUOUS IDENT:) + +speak_punctuation:CSS_PROP_SPEAK_PUNCTUATION IDENT:( INHERIT: CODE:0,SPEAK_PUNCTUATION_CODE NONE:0,SPEAK_PUNCTUATION_NONE IDENT:) + +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:) + +stress:CSS_PROP_STRESS IDENT:INHERIT NUMBER:( false:STRESS_SET RANGE:num<0||num>INTTOFIX(100) NUMBER:) + +table_layout:CSS_PROP_TABLE_LAYOUT IDENT:( INHERIT: AUTO:0,TABLE_LAYOUT_AUTO FIXED:0,TABLE_LAYOUT_FIXED IDENT:) + +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:) + +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:) + +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:) + +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:) + +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:) + +visibility:CSS_PROP_VISIBILITY IDENT:( INHERIT: VISIBLE:0,VISIBILITY_VISIBLE HIDDEN:0,VISIBILITY_HIDDEN COLLAPSE:0,VISIBILITY_COLLAPSE IDENT:) + +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:) + +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:) + +widows:CSS_PROP_WIDOWS IDENT:INHERIT NUMBER:( true:WIDOWS_SET RANGE:num<0 NUMBER:) + + +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:) + +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:) + +z_index:CSS_PROP_Z_INDEX IDENT:( INHERIT: AUTO:0,Z_INDEX_AUTO IDENT:) NUMBER:( true:Z_INDEX_SET NUMBER:) diff --git a/src/parse/properties/properties.h b/src/parse/properties/properties.h index 0dc750a..6117387 100644 --- a/src/parse/properties/properties.h +++ b/src/parse/properties/properties.h @@ -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 diff --git a/src/parse/properties/quotes.c b/src/parse/properties/quotes.c index 0488660..423046a 100644 --- a/src/parse/properties/quotes.c +++ b/src/parse/properties/quotes.c @@ -27,144 +27,82 @@ * 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], - &match) == lwc_error_ok && match)) { - flags = FLAG_INHERIT; - } else if ((lwc_string_caseless_isequal( - token->idata, c->strings[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_QUOTES); + } else if ((token->type == CSS_TOKEN_IDENT) && + (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; - - consumeWhitespace(vector, &temp_ctx); - - token = parserutils_vector_peek(vector, temp_ctx); - if (token == NULL || token->type != CSS_TOKEN_STRING) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - close = token->idata; +/* 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) - parserutils_vector_iterate(vector, &temp_ctx); + /* [ STRING STRING ]+ */ + while ((token != NULL) && (token->type == CSS_TOKEN_STRING)) { + uint32_t open_snumber; + uint32_t close_snumber; + + error = css_stylesheet_string_add(c->sheet, + lwc_string_ref(token->idata), + &open_snumber); + if (error != CSS_OK) + break; - consumeWhitespace(vector, &temp_ctx); + consumeWhitespace(vector, 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; - } - - close = token->idata; - - parserutils_vector_iterate(vector, ctx); + error = CSS_FIRST_APPEND(QUOTES_STRING); + if (error != CSS_OK) + break; - consumeWhitespace(vector, ctx); + error = css_stylesheet_style_append(result, open_snumber); + if (error != CSS_OK) + break; - 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); + error = css_stylesheet_style_append(result, close_snumber); + if (error != CSS_OK) + break; first = false; @@ -174,11 +112,16 @@ css_error parse_quotes(css_language *c, 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; } diff --git a/src/parse/properties/richness.c b/src/parse/properties/richness.c deleted file mode 100644 index ff8504d..0000000 --- a/src/parse/properties/richness.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse richness - * - * \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_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)) { - *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 (token->type == CSS_TOKEN_NUMBER) { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = RICHNESS_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/right.c b/src/parse/properties/right.c deleted file mode 100644 index 903dac0..0000000 --- a/src/parse/properties/right.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_right(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_side(c, vector, ctx, CSS_PROP_RIGHT, result); -} diff --git a/src/parse/properties/speak.c b/src/parse/properties/speak.c deleted file mode 100644 index f62bffc..0000000 --- a/src/parse/properties/speak.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse speak - * - * \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_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; - bool match; - - /* IDENT (normal, none, spell-out, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/speak_header.c b/src/parse/properties/speak_header.c deleted file mode 100644 index b0c5f92..0000000 --- a/src/parse/properties/speak_header.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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; - bool match; - - /* IDENT (once, always, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/speak_numeral.c b/src/parse/properties/speak_numeral.c deleted file mode 100644 index 7d9f7f1..0000000 --- a/src/parse/properties/speak_numeral.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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; - bool match; - - /* IDENT (digits, continuous, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/speak_punctuation.c b/src/parse/properties/speak_punctuation.c deleted file mode 100644 index c4b9ec9..0000000 --- a/src/parse/properties/speak_punctuation.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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; - bool match; - - /* IDENT (code, none, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/speech_rate.c b/src/parse/properties/speech_rate.c deleted file mode 100644 index 616c182..0000000 --- a/src/parse/properties/speech_rate.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * 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 - * \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_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)) { - *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; - } else if (token->type == CSS_TOKEN_NUMBER) { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = SPEECH_RATE_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/stress.c b/src/parse/properties/stress.c deleted file mode 100644 index c04d22e..0000000 --- a/src/parse/properties/stress.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse stress - * - * \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_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)) { - *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 (token->type == CSS_TOKEN_NUMBER) { - 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)) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = STRESS_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/table_layout.c b/src/parse/properties/table_layout.c deleted file mode 100644 index 7bc34d5..0000000 --- a/src/parse/properties/table_layout.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse table-layout - * - * \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_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; - bool match; - - /* IDENT (auto, fixed, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} - diff --git a/src/parse/properties/text_align.c b/src/parse/properties/text_align.c deleted file mode 100644 index 0df4eab..0000000 --- a/src/parse/properties/text_align.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse text-align - * - * \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_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; - 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) { - *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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/text_decoration.c b/src/parse/properties/text_decoration.c index 0c63c39..c9a91d1 100644 --- a/src/parse/properties/text_decoration.c +++ b/src/parse/properties/text_decoration.c @@ -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 @@ css_error parse_text_decoration(css_language *c, 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 @@ css_error parse_text_decoration(css_language *c, 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 @@ css_error parse_text_decoration(css_language *c, 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 @@ css_error parse_text_decoration(css_language *c, 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; } diff --git a/src/parse/properties/text_indent.c b/src/parse/properties/text_indent.c deleted file mode 100644 index 4198cf6..0000000 --- a/src/parse/properties/text_indent.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse text-indent - * - * \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_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) { - *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_PX, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = TEXT_INDENT_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/text_transform.c b/src/parse/properties/text_transform.c deleted file mode 100644 index b727046..0000000 --- a/src/parse/properties/text_transform.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse text-transform - * - * \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_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; - bool match; - - /* IDENT (capitalize, uppercase, lowercase, none, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/top.c b/src/parse/properties/top.c deleted file mode 100644 index 7325a24..0000000 --- a/src/parse/properties/top.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_top(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_side(c, vector, ctx, CSS_PROP_TOP, result); -} diff --git a/src/parse/properties/unicode_bidi.c b/src/parse/properties/unicode_bidi.c deleted file mode 100644 index e960d5e..0000000 --- a/src/parse/properties/unicode_bidi.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse unicode-bidi - * - * \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_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; - bool match; - - /* IDENT (normal, embed, bidi-override, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c index f2447a7..34a5225 100644 --- a/src/parse/properties/utils.c +++ b/src/parse/properties/utils.c @@ -13,96 +13,8 @@ #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 @@ -169,1122 +81,35 @@ css_error parse_list_style_type_value(css_language *c, const css_token *ident, *value = LIST_STYLE_TYPE_ARMENIAN; } else if ((lwc_string_caseless_isequal( ident->idata, c->strings[GEORGIAN], - &match) == lwc_error_ok && match)) { - *value = LIST_STYLE_TYPE_GEORGIAN; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[LOWER_ALPHA], - &match) == lwc_error_ok && match)) { - *value = LIST_STYLE_TYPE_LOWER_ALPHA; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[UPPER_ALPHA], - &match) == lwc_error_ok && match)) { - *value = LIST_STYLE_TYPE_UPPER_ALPHA; - } else if ((lwc_string_caseless_isequal( - ident->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - *value = LIST_STYLE_TYPE_NONE; - } else - return CSS_INVALID; - - 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 ? ]+ | 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 - * \param vector Vector of tokens to process - * \param ctx Pointer to vector iteration context - * \param side The side we're parsing 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_border_side(css_language *c, - const parserutils_vector *vector, int *ctx, - uint32_t side, 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; - - /* 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; - return error; - } - - bytecode = (uint32_t *) ret->bytecode; - - *(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); - - 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 parse individual 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)) { - error = CSS_INVALID; - goto 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) { - } - - if (error == CSS_OK) { - consumeWhitespace(vector, ctx); - - token = parserutils_vector_peek(vector, *ctx); - } else { - /* Forcibly cause loop to exit */ - token = NULL; - } - } 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; - - if (color) { - memcpy(((uint8_t *) ret->bytecode) + required_size, - color->bytecode, color->length); - required_size += color->length; - } - - 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); - } - - 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, - 0, BORDER_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; - - /* 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); - - if (error != CSS_OK) - *ctx = orig_ctx; - - return error; -} - -/** - * 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 op Opcode to parse for (encodes side) - * \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_border_side_color(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; - 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) { - *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; - } else { - error = parse_colour_specifier(c, vector, ctx, &colour); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - value = BORDER_COLOR_SET; - } - - 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; - } - - /* 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; -} - -/** - * 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 op Opcode to parse for (encodes side) - * \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_border_side_style(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 *ident; - uint8_t flags = 0; - uint16_t value = 0; - uint32_t opv; - 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) { - *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; - } else { - *ctx = orig_ctx; - return CSS_INVALID; - } - - opv = buildOPV(op, 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; -} - -/** - * 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 op Opcode to parse for (encodes side) - * \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_border_side_width(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; - - /* length | IDENT(thin, medium, thick, 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 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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Length must be positive */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = BORDER_WIDTH_SET; - } - - 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; - } - - /* 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)); - } + &match) == lwc_error_ok && match)) { + *value = LIST_STYLE_TYPE_GEORGIAN; + } else if ((lwc_string_caseless_isequal( + ident->idata, c->strings[LOWER_ALPHA], + &match) == lwc_error_ok && match)) { + *value = LIST_STYLE_TYPE_LOWER_ALPHA; + } else if ((lwc_string_caseless_isequal( + ident->idata, c->strings[UPPER_ALPHA], + &match) == lwc_error_ok && match)) { + *value = LIST_STYLE_TYPE_UPPER_ALPHA; + } else if ((lwc_string_caseless_isequal( + ident->idata, c->strings[NONE], + &match) == lwc_error_ok && match)) { + *value = LIST_STYLE_TYPE_NONE; + } else + return CSS_INVALID; return CSS_OK; } + + /** - * Parse margin-{top,right,bottom,left} + * 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 side The side we're parsing for * \param result Pointer to location to receive resulting style * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion, @@ -1293,258 +118,134 @@ css_error parse_border_side_width(css_language *c, * 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, +css_error parse_border_side(css_language *c, const parserutils_vector *vector, int *ctx, - uint16_t op, css_style **result) + css_style *result, enum border_side_e side) { int orig_ctx = *ctx; - css_error error; + int prev_ctx; 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; + 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; - /* length | percentage | IDENT(auto, inherit) */ + /* Firstly, handle inherit */ token = parserutils_vector_peek(vector, *ctx); - if (token == NULL) { - *ctx = orig_ctx; + if (token == NULL) 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; - } else { - error = parse_unit_specifier(c, vector, ctx, UNIT_PX, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; + + if (is_css_inherit(c, token)) { + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_COLOR + side); + if (error != CSS_OK) return error; - } - if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) { - *ctx = orig_ctx; - return CSS_INVALID; - } + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_STYLE + side); + if (error != CSS_OK) + return error; - value = MARGIN_SET; - } + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_WIDTH + side); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - opv = buildOPV(op, flags, value); + return error; + } - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == MARGIN_SET) - required_size += sizeof(length) + sizeof(unit); + /* allocate styles */ + error = css_stylesheet_style_create(c->sheet, &color_style); + if (error != CSS_OK) + return error; - /* Allocate result */ - error = css_stylesheet_style_create(c->sheet, required_size, result); + error = css_stylesheet_style_create(c->sheet, &style_style); if (error != CSS_OK) { - *ctx = orig_ctx; + css_stylesheet_style_destroy(color_style); return error; } - /* 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; -} - -/** - * 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) -{ - 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) { - *ctx = orig_ctx; - return CSS_INVALID; + error = css_stylesheet_style_create(c->sheet, &width_style); + if (error != CSS_OK) { + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(width_style); + return error; } - 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_PX, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) { - *ctx = orig_ctx; - return CSS_INVALID; - } + /* Attempt to parse the various longhand properties */ + do { + prev_ctx = *ctx; + error = CSS_OK; - /* Negative lengths are invalid */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; + /* Ensure that we're not about to parse another inherit */ + token = parserutils_vector_peek(vector, *ctx); + if (token != NULL && is_css_inherit(c, token)) { + error = CSS_INVALID; + goto parse_border_side_cleanup; } - value = PADDING_SET; - } - - opv = buildOPV(op, flags, value); + /* 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; + } - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == PADDING_SET) - required_size += sizeof(length) + sizeof(unit); + if (error == CSS_OK) { + consumeWhitespace(vector, ctx); - /* Allocate result */ - error = css_stylesheet_style_create(c->sheet, required_size, result); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } + token = parserutils_vector_peek(vector, *ctx); + } else { + /* Forcibly cause loop to exit */ + token = NULL; + } + } while (*ctx != prev_ctx && token != NULL); - /* 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)); + if (style) { + 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; } - return CSS_OK; -} - -/** - * 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) -{ - 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) { - *ctx = orig_ctx; - return CSS_INVALID; + if (width) { + error = css_stylesheet_style_appendOPV(width_style, + CSS_PROP_BORDER_TOP_WIDTH + side, + 0, BORDER_WIDTH_MEDIUM); + if (error != CSS_OK) + goto parse_border_side_cleanup; } - 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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } + error = css_stylesheet_merge_style(result, color_style); + if (error != CSS_OK) + goto parse_border_side_cleanup; - value = BOTTOM_SET; - } + error = css_stylesheet_merge_style(result, style_style); + if (error != CSS_OK) + goto parse_border_side_cleanup; - opv = buildOPV(op, flags, value); + error = css_stylesheet_merge_style(result, width_style); - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == BOTTOM_SET) - required_size += sizeof(length) + sizeof(unit); +parse_border_side_cleanup: + css_stylesheet_style_destroy(color_style); + css_stylesheet_style_destroy(style_style); + css_stylesheet_style_destroy(width_style); - /* 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 == 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; + return error; } /** @@ -2113,108 +814,92 @@ css_error parse_unit_keyword(const char *ptr, size_t len, css_unit *unit) } /** - * 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; - - while (token != NULL) { - if (token->type == CSS_TOKEN_IDENT) { - /* IDENT+ */ - required_size += first ? 0 : sizeof(opv); - - if (reserved(c, token) == false) { - required_size += sizeof(lwc_string *); + const css_token *token; + css_error error = CSS_OK; + parserutils_buffer *buffer; + parserutils_error perror; + lwc_string *interned; + lwc_error lerror; - /* 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; - } + perror = parserutils_buffer_create((parserutils_alloc) c->alloc, + c->pw, &buffer); + if (perror != PARSERUTILS_OK) + return css_error_from_parserutils_error(perror); - /* Idents must not be reserved */ - if (token != NULL && token->type == - CSS_TOKEN_IDENT && - reserved(c, token)) { - *ctx = orig_ctx; - return CSS_INVALID; - } + /* We know this token exists, and is an IDENT */ + token = parserutils_vector_iterate(vector, ctx); - 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); - - /* 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); + if (perror != PARSERUTILS_OK) { + error = css_error_from_parserutils_error(perror); + goto cleanup; + } - consumeWhitespace(vector, ctx); + token = parserutils_vector_iterate(vector, ctx); + } - /* 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; - } + /* Rewind context by one step if we consumed an unacceptable token */ + if (token != NULL) + *ctx = *ctx - 1; - /* Flag that this is no longer the first pass */ - first = false; + /* Strip trailing whitespace */ + while (buffer->length > 0 && buffer->data[buffer->length - 1] == ' ') + buffer->length--; - /* 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 +908,84 @@ css_error comma_list_length(css_language *c, * \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; - - opv = get_value(c, token); - - if (first == false) { - memcpy(ptr, &opv, sizeof(opv)); - ptr += sizeof(opv); - } + css_code_t value = get_value(c, token, first); 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; - - /* 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; - } + lwc_string *str = NULL; + uint32_t snumber; - if (temp_token != NULL && - temp_token->type == - CSS_TOKEN_IDENT) { - len += lwc_string_length( - temp_token->idata); - } else if (temp_token != NULL) { - len += 1; - } - - temp_token = parserutils_vector_iterate( - vector, &temp_ctx); - } - - 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; + *ctx = prev_ctx; - /* 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 = ident_list_to_string(c, vector, ctx, + reserved, &str); + if (error != CSS_OK) goto cleanup; - } - if (newname == name) { - lwc_string_unref(newname); - } - - name = newname; + error = css_stylesheet_string_add(c->sheet, + str, &snumber); + if (error != CSS_OK) + goto cleanup; - /* 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); - } + error = css_stylesheet_style_append(result, + value); + if (error != CSS_OK) + goto cleanup; - 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 +1011,12 @@ css_error comma_list_to_bytecode(css_language *c, 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; diff --git a/src/parse/properties/utils.h b/src/parse/properties/utils.h index c5bef1c..66b706d 100644 --- a/src/parse/properties/utils.h +++ b/src/parse/properties/utils.h @@ -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); - -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); +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)); +} +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, - 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, +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); #endif diff --git a/src/parse/properties/vertical_align.c b/src/parse/properties/vertical_align.c deleted file mode 100644 index 46e83c3..0000000 --- a/src/parse/properties/vertical_align.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse vertical-align - * - * \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_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) { - *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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = VERTICAL_ALIGN_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/visibility.c b/src/parse/properties/visibility.c deleted file mode 100644 index b6b6c11..0000000 --- a/src/parse/properties/visibility.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse visibility - * - * \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_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; - bool match; - - /* IDENT (visible, hidden, collapse, inherit) */ - ident = parserutils_vector_iterate(vector, ctx); - 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; - } 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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/voice_family.c b/src/parse/properties/voice_family.c index beca662..339d470 100644 --- a/src/parse/properties/voice_family.c +++ b/src/parse/properties/voice_family.c @@ -42,7 +42,7 @@ static bool voice_family_reserved(css_language *c, const css_token *ident) * \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 @@ static uint16_t voice_family_value(css_language *c, const css_token *token) value = VOICE_FAMILY_STRING; } - return value; + return first ? buildOPV(CSS_PROP_VOICE_FAMILY, 0, value) : value; } /** @@ -85,17 +85,11 @@ static uint16_t voice_family_value(css_language *c, const css_token *token) */ 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 @@ css_error parse_voice_family(css_language *c, * 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 @@ css_error parse_voice_family(css_language *c, (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; - - value = voice_family_value(c, token); + *ctx = orig_ctx; - 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; } diff --git a/src/parse/properties/volume.c b/src/parse/properties/volume.c deleted file mode 100644 index 2d4c90e..0000000 --- a/src/parse/properties/volume.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse volume - * - * \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_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) { - *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; - } else if (token->type == CSS_TOKEN_NUMBER) { - size_t consumed = 0; - length = number_from_lwc_string(token->idata, false, &consumed); - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - parserutils_vector_iterate(vector, ctx); - value = VOLUME_NUMBER; - } else { - /* Yes, really UNIT_PX -- percentages MUST have a % sign */ - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Must be positive */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = VOLUME_DIMENSION; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/white_space.c b/src/parse/properties/white_space.c deleted file mode 100644 index 3d57586..0000000 --- a/src/parse/properties/white_space.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse white-space - * - * \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_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; - 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) { - *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; - } else { - *ctx = orig_ctx; - return 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) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - - return CSS_OK; -} diff --git a/src/parse/properties/widows.c b/src/parse/properties/widows.c deleted file mode 100644 index 21101ce..0000000 --- a/src/parse/properties/widows.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse widows - * - * \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_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; - - /* | IDENT (inherit) */ - token = parserutils_vector_iterate(vector, ctx); - 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; - } else if (token->type == CSS_TOKEN_NUMBER) { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = WIDOWS_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/parse/properties/width.c b/src/parse/properties/width.c deleted file mode 100644 index 233a7e8..0000000 --- a/src/parse/properties/width.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse 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 - * \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_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) { - *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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Must be positive */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = WIDTH_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/word_spacing.c b/src/parse/properties/word_spacing.c deleted file mode 100644 index 8466c7f..0000000 --- a/src/parse/properties/word_spacing.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse word-spacing - * - * \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_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) { - *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; - } else { - 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) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = WORD_SPACING_SET; - } - - 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; - } - - /* 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; -} diff --git a/src/parse/properties/z_index.c b/src/parse/properties/z_index.c deleted file mode 100644 index 340626e..0000000 --- a/src/parse/properties/z_index.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of LibCSS. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2009 John-Mark Bell - */ - -#include -#include - -#include "bytecode/bytecode.h" -#include "bytecode/opcodes.h" -#include "parse/properties/properties.h" -#include "parse/properties/utils.h" - -/** - * Parse z-index - * - * \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_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; - - /* | IDENT (auto, inherit) */ - token = parserutils_vector_iterate(vector, ctx); - 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; - } else if (token->type == CSS_TOKEN_NUMBER) { - 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; - } - - value = Z_INDEX_SET; - } else { - *ctx = orig_ctx; - return 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) { - *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; -} diff --git a/src/select/dispatch.c b/src/select/dispatch.c index aee6175..f6172c6 100644 --- a/src/select/dispatch.c +++ b/src/select/dispatch.c @@ -15,8 +15,7 @@ cascade_##pname, \ set_##pname##_from_hint, \ initial_##pname, \ - compose_##pname, \ - destroy_##pname + compose_##pname struct prop_table prop_dispatch[CSS_N_PROPERTIES] = { { diff --git a/src/select/dispatch.h b/src/select/dispatch.h index 6aa61ab..2fcb739 100644 --- a/src/select/dispatch.h +++ b/src/select/dispatch.h @@ -36,7 +36,6 @@ extern struct prop_table { css_error (*compose)(const css_computed_style *parent, const css_computed_style *child, css_computed_style *result); - uint32_t (*destroy)(void *bytecode); unsigned int inherited; unsigned int group; } prop_dispatch[CSS_N_PROPERTIES]; diff --git a/src/select/properties/azimuth.c b/src/select/properties/azimuth.c index ed48a70..2d1c0ed 100644 --- a/src/select/properties/azimuth.c +++ b/src/select/properties/azimuth.c @@ -84,10 +84,3 @@ css_error compose_azimuth(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_azimuth(void *bytecode) -{ - bool has_angle = (((getValue(*(uint32_t*)bytecode) & (1<<7)) != 0)); - uint32_t extra_size = has_angle ? (sizeof(css_fixed) + sizeof(uint32_t)) : 0; - - return sizeof(uint32_t) + extra_size; -} diff --git a/src/select/properties/background_attachment.c b/src/select/properties/background_attachment.c index b5bf732..d2b56f8 100644 --- a/src/select/properties/background_attachment.c +++ b/src/select/properties/background_attachment.c @@ -65,9 +65,3 @@ css_error compose_background_attachment(const css_computed_style *parent, return set_background_attachment(result, type); } -uint32_t destroy_background_attachment(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/background_color.c b/src/select/properties/background_color.c index 0867ce2..ca4c015 100644 --- a/src/select/properties/background_color.c +++ b/src/select/properties/background_color.c @@ -46,7 +46,3 @@ css_error compose_background_color(const css_computed_style *parent, return set_background_color(result, type, color); } -uint32_t destroy_background_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/background_image.c b/src/select/properties/background_image.c index 501f4fe..6a63ce9 100644 --- a/src/select/properties/background_image.c +++ b/src/select/properties/background_image.c @@ -53,7 +53,3 @@ css_error compose_background_image(const css_computed_style *parent, return set_background_image(result, type, url); } -uint32_t destroy_background_image(void *bytecode) -{ - return generic_destroy_uri(bytecode); -} diff --git a/src/select/properties/background_position.c b/src/select/properties/background_position.c index 6bcaa7f..9eda573 100644 --- a/src/select/properties/background_position.c +++ b/src/select/properties/background_position.c @@ -114,16 +114,3 @@ css_error compose_background_position(const css_computed_style *parent, vlength, vunit); } - -uint32_t destroy_background_position(void *bytecode) -{ - uint32_t value = getValue(*((uint32_t*)bytecode)); - uint32_t extra_size = 0; - - if ((value & 0x0f) == BACKGROUND_POSITION_VERT_SET) - extra_size += sizeof(css_fixed) + sizeof(uint32_t); - if ((value & 0xf0) == BACKGROUND_POSITION_HORZ_SET) - extra_size += sizeof(css_fixed) + sizeof(uint32_t); - - return sizeof(uint32_t) + extra_size; -} diff --git a/src/select/properties/background_repeat.c b/src/select/properties/background_repeat.c index c700730..95ff660 100644 --- a/src/select/properties/background_repeat.c +++ b/src/select/properties/background_repeat.c @@ -71,9 +71,3 @@ css_error compose_background_repeat(const css_computed_style *parent, return set_background_repeat(result, type); } -uint32_t destroy_background_repeat(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_bottom_color.c b/src/select/properties/border_bottom_color.c index e2cc535..c5b7633 100644 --- a/src/select/properties/border_bottom_color.c +++ b/src/select/properties/border_bottom_color.c @@ -47,7 +47,3 @@ css_error compose_border_bottom_color(const css_computed_style *parent, return set_border_bottom_color(result, type, color); } -uint32_t destroy_border_bottom_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/border_bottom_style.c b/src/select/properties/border_bottom_style.c index 6857630..2f022c3 100644 --- a/src/select/properties/border_bottom_style.c +++ b/src/select/properties/border_bottom_style.c @@ -44,9 +44,3 @@ css_error compose_border_bottom_style(const css_computed_style *parent, return set_border_bottom_style(result, type); } -uint32_t destroy_border_bottom_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_bottom_width.c b/src/select/properties/border_bottom_width.c index b65ed5e..27f5b05 100644 --- a/src/select/properties/border_bottom_width.c +++ b/src/select/properties/border_bottom_width.c @@ -48,7 +48,3 @@ css_error compose_border_bottom_width(const css_computed_style *parent, return set_border_bottom_width(result, type, length, unit); } -uint32_t destroy_border_bottom_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/border_collapse.c b/src/select/properties/border_collapse.c index 108caa7..7b69847 100644 --- a/src/select/properties/border_collapse.c +++ b/src/select/properties/border_collapse.c @@ -64,9 +64,3 @@ css_error compose_border_collapse(const css_computed_style *parent, return set_border_collapse(result, type); } -uint32_t destroy_border_collapse(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_left_color.c b/src/select/properties/border_left_color.c index b745553..7c2e670 100644 --- a/src/select/properties/border_left_color.c +++ b/src/select/properties/border_left_color.c @@ -47,7 +47,3 @@ css_error compose_border_left_color(const css_computed_style *parent, return set_border_left_color(result, type, color); } -uint32_t destroy_border_left_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/border_left_style.c b/src/select/properties/border_left_style.c index 18e8604..74ee138 100644 --- a/src/select/properties/border_left_style.c +++ b/src/select/properties/border_left_style.c @@ -44,9 +44,3 @@ css_error compose_border_left_style(const css_computed_style *parent, return set_border_left_style(result, type); } -uint32_t destroy_border_left_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_left_width.c b/src/select/properties/border_left_width.c index 3247784..610d956 100644 --- a/src/select/properties/border_left_width.c +++ b/src/select/properties/border_left_width.c @@ -48,7 +48,3 @@ css_error compose_border_left_width(const css_computed_style *parent, return set_border_left_width(result, type, length, unit); } -uint32_t destroy_border_left_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/border_right_color.c b/src/select/properties/border_right_color.c index d2cd95d..41fe441 100644 --- a/src/select/properties/border_right_color.c +++ b/src/select/properties/border_right_color.c @@ -47,7 +47,3 @@ css_error compose_border_right_color(const css_computed_style *parent, return set_border_right_color(result, type, color); } -uint32_t destroy_border_right_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/border_right_style.c b/src/select/properties/border_right_style.c index c11b49a..2462b03 100644 --- a/src/select/properties/border_right_style.c +++ b/src/select/properties/border_right_style.c @@ -44,9 +44,3 @@ css_error compose_border_right_style(const css_computed_style *parent, return set_border_right_style(result, type); } -uint32_t destroy_border_right_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_right_width.c b/src/select/properties/border_right_width.c index e7fe775..477e74f 100644 --- a/src/select/properties/border_right_width.c +++ b/src/select/properties/border_right_width.c @@ -48,7 +48,3 @@ css_error compose_border_right_width(const css_computed_style *parent, return set_border_right_width(result, type, length, unit); } -uint32_t destroy_border_right_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/border_spacing.c b/src/select/properties/border_spacing.c index caf6f2e..745c423 100644 --- a/src/select/properties/border_spacing.c +++ b/src/select/properties/border_spacing.c @@ -87,9 +87,3 @@ css_error compose_border_spacing(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_border_spacing(void *bytecode) -{ - bool has_values = (getValue(*((uint32_t*)bytecode)) == BORDER_SPACING_SET); - - return sizeof(uint32_t) + (has_values ? (sizeof(css_fixed) + sizeof(uint32_t)) * 2 : 0); -} diff --git a/src/select/properties/border_top_color.c b/src/select/properties/border_top_color.c index f13df9e..6d3b7f3 100644 --- a/src/select/properties/border_top_color.c +++ b/src/select/properties/border_top_color.c @@ -45,7 +45,3 @@ css_error compose_border_top_color(const css_computed_style *parent, return set_border_top_color(result, type, color); } -uint32_t destroy_border_top_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/border_top_style.c b/src/select/properties/border_top_style.c index 7cdbf1b..6109cf3 100644 --- a/src/select/properties/border_top_style.c +++ b/src/select/properties/border_top_style.c @@ -44,9 +44,3 @@ css_error compose_border_top_style(const css_computed_style *parent, return set_border_top_style(result, type); } -uint32_t destroy_border_top_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/border_top_width.c b/src/select/properties/border_top_width.c index d8c4547..5884ab4 100644 --- a/src/select/properties/border_top_width.c +++ b/src/select/properties/border_top_width.c @@ -48,7 +48,3 @@ css_error compose_border_top_width(const css_computed_style *parent, return set_border_top_width(result, type, length, unit); } -uint32_t destroy_border_top_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/bottom.c b/src/select/properties/bottom.c index 455dca9..286d546 100644 --- a/src/select/properties/bottom.c +++ b/src/select/properties/bottom.c @@ -47,7 +47,3 @@ css_error compose_bottom(const css_computed_style *parent, return set_bottom(result, type, length, unit); } -uint32_t destroy_bottom(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/caption_side.c b/src/select/properties/caption_side.c index c751dba..cafbe2e 100644 --- a/src/select/properties/caption_side.c +++ b/src/select/properties/caption_side.c @@ -64,9 +64,3 @@ css_error compose_caption_side(const css_computed_style *parent, return set_caption_side(result, type); } -uint32_t destroy_caption_side(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/clear.c b/src/select/properties/clear.c index e29521b..27da0bd 100644 --- a/src/select/properties/clear.c +++ b/src/select/properties/clear.c @@ -70,9 +70,3 @@ css_error compose_clear(const css_computed_style *parent, return set_clear(result, type); } -uint32_t destroy_clear(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/clip.c b/src/select/properties/clip.c index b87da03..6daa204 100644 --- a/src/select/properties/clip.c +++ b/src/select/properties/clip.c @@ -115,22 +115,3 @@ css_error compose_clip(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_clip(void *bytecode) -{ - uint32_t value = getValue(*((uint32_t*)bytecode)); - bool has_rect = value & CLIP_SHAPE_RECT; - int nonautos = 0; - - if (has_rect) { - if ((value & CLIP_RECT_TOP_AUTO) == 0) - nonautos += 1; - if ((value & CLIP_RECT_RIGHT_AUTO) == 0) - nonautos += 1; - if ((value & CLIP_RECT_BOTTOM_AUTO) == 0) - nonautos += 1; - if ((value & CLIP_RECT_LEFT_AUTO) == 0) - nonautos += 1; - } - - return sizeof(uint32_t) + ((sizeof(css_fixed) + sizeof(uint32_t)) * nonautos); -} diff --git a/src/select/properties/color.c b/src/select/properties/color.c index f727b60..c246349 100644 --- a/src/select/properties/color.c +++ b/src/select/properties/color.c @@ -67,7 +67,3 @@ css_error compose_color(const css_computed_style *parent, return set_color(result, type, color); } -uint32_t destroy_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/content.c b/src/select/properties/content.c index 40fb018..f6e8452 100644 --- a/src/select/properties/content.c +++ b/src/select/properties/content.c @@ -32,8 +32,10 @@ css_error cascade_content(uint32_t opv, css_style *style, value = CSS_CONTENT_SET; while (v != CONTENT_NORMAL) { - lwc_string *he = *((lwc_string **) style->bytecode); + lwc_string *he; css_computed_content_item *temp; + + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &he); temp = state->computed->alloc(content, (n_contents + 1) * @@ -51,7 +53,7 @@ css_error cascade_content(uint32_t opv, css_style *style, 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 +64,10 @@ css_error cascade_content(uint32_t opv, css_style *style, { 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)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &sep); + advance_bytecode(style, sizeof(css_code_t)); content[n_contents].type = CSS_COMPUTED_CONTENT_COUNTERS; @@ -76,21 +77,21 @@ css_error cascade_content(uint32_t opv, css_style *style, } 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; @@ -245,37 +246,3 @@ css_error compose_content(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_content(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - - if (value == CONTENT_NONE || value == CONTENT_NORMAL) - return sizeof(uint32_t); - - 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 *); - } - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - - return consumed; -} diff --git a/src/select/properties/counter_increment.c b/src/select/properties/counter_increment.c index e17be9f..a0a0ae5 100644 --- a/src/select/properties/counter_increment.c +++ b/src/select/properties/counter_increment.c @@ -93,24 +93,3 @@ css_error compose_counter_increment(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_counter_increment(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - } - - return consumed; -} diff --git a/src/select/properties/counter_reset.c b/src/select/properties/counter_reset.c index 8bcd462..60b3939 100644 --- a/src/select/properties/counter_reset.c +++ b/src/select/properties/counter_reset.c @@ -91,25 +91,3 @@ css_error compose_counter_reset(const css_computed_style *parent, return CSS_OK; } - -uint32_t destroy_counter_reset(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - } - - return consumed; -} diff --git a/src/select/properties/cue_after.c b/src/select/properties/cue_after.c index 119a60b..1bdea51 100644 --- a/src/select/properties/cue_after.c +++ b/src/select/properties/cue_after.c @@ -48,7 +48,3 @@ css_error compose_cue_after(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_cue_after(void *bytecode) -{ - return generic_destroy_uri(bytecode); -} diff --git a/src/select/properties/cue_before.c b/src/select/properties/cue_before.c index b1d16ed..72f31dd 100644 --- a/src/select/properties/cue_before.c +++ b/src/select/properties/cue_before.c @@ -48,7 +48,3 @@ css_error compose_cue_before(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_cue_before(void *bytecode) -{ - return generic_destroy_uri(bytecode); -} diff --git a/src/select/properties/cursor.c b/src/select/properties/cursor.c index 249d8b4..5075fa4 100644 --- a/src/select/properties/cursor.c +++ b/src/select/properties/cursor.c @@ -210,22 +210,3 @@ css_error compose_cursor(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_cursor(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - - return consumed; -} diff --git a/src/select/properties/direction.c b/src/select/properties/direction.c index 2cc91c8..6878f02 100644 --- a/src/select/properties/direction.c +++ b/src/select/properties/direction.c @@ -64,9 +64,3 @@ css_error compose_direction(const css_computed_style *parent, return set_direction(result, type); } -uint32_t destroy_direction(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/display.c b/src/select/properties/display.c index 34f0b20..9c05f52 100644 --- a/src/select/properties/display.c +++ b/src/select/properties/display.c @@ -106,9 +106,3 @@ css_error compose_display(const css_computed_style *parent, return set_display(result, type); } -uint32_t destroy_display(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/elevation.c b/src/select/properties/elevation.c index 5586e0c..144d150 100644 --- a/src/select/properties/elevation.c +++ b/src/select/properties/elevation.c @@ -79,7 +79,3 @@ css_error compose_elevation(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_elevation(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/empty_cells.c b/src/select/properties/empty_cells.c index dc43f87..ae7d331 100644 --- a/src/select/properties/empty_cells.c +++ b/src/select/properties/empty_cells.c @@ -64,9 +64,3 @@ css_error compose_empty_cells(const css_computed_style *parent, return set_empty_cells(result, type); } -uint32_t destroy_empty_cells(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/float.c b/src/select/properties/float.c index 24377af..ff35f82 100644 --- a/src/select/properties/float.c +++ b/src/select/properties/float.c @@ -67,9 +67,3 @@ css_error compose_float(const css_computed_style *parent, return set_float(result, type); } -uint32_t destroy_float(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/font_family.c b/src/select/properties/font_family.c index a0c7609..c8b3789 100644 --- a/src/select/properties/font_family.c +++ b/src/select/properties/font_family.c @@ -31,9 +31,8 @@ css_error cascade_font_family(uint32_t opv, css_style *style, switch (v) { case FONT_FAMILY_STRING: case FONT_FAMILY_IDENT_LIST: - font = *((lwc_string **) - style->bytecode); - advance_bytecode(style, sizeof(font)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &font); + advance_bytecode(style, sizeof(css_code_t)); break; case FONT_FAMILY_SERIF: if (value == CSS_FONT_FAMILY_INHERIT) @@ -192,24 +191,3 @@ css_error compose_font_family(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_font_family(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - - 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); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - - return consumed; -} diff --git a/src/select/properties/font_size.c b/src/select/properties/font_size.c index 8b52626..3fbe9ea 100644 --- a/src/select/properties/font_size.c +++ b/src/select/properties/font_size.c @@ -100,7 +100,3 @@ css_error compose_font_size(const css_computed_style *parent, return set_font_size(result, type, size, unit); } -uint32_t destroy_font_size(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/font_style.c b/src/select/properties/font_style.c index 0683bfa..23aa119 100644 --- a/src/select/properties/font_style.c +++ b/src/select/properties/font_style.c @@ -67,9 +67,3 @@ css_error compose_font_style(const css_computed_style *parent, return set_font_style(result, type); } -uint32_t destroy_font_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/font_variant.c b/src/select/properties/font_variant.c index f1240cc..a5c9967 100644 --- a/src/select/properties/font_variant.c +++ b/src/select/properties/font_variant.c @@ -64,9 +64,3 @@ css_error compose_font_variant(const css_computed_style *parent, return set_font_variant(result, type); } -uint32_t destroy_font_variant(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/font_weight.c b/src/select/properties/font_weight.c index 39bb473..fa814f4 100644 --- a/src/select/properties/font_weight.c +++ b/src/select/properties/font_weight.c @@ -97,9 +97,3 @@ css_error compose_font_weight(const css_computed_style *parent, return set_font_weight(result, type); } -uint32_t destroy_font_weight(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/height.c b/src/select/properties/height.c index 6a0cfae..38b35c1 100644 --- a/src/select/properties/height.c +++ b/src/select/properties/height.c @@ -47,7 +47,3 @@ css_error compose_height(const css_computed_style *parent, return set_height(result, type, length, unit); } -uint32_t destroy_height(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/helpers.c b/src/select/properties/helpers.c index 8ce5fc6..3310502 100644 --- a/src/select/properties/helpers.c +++ b/src/select/properties/helpers.c @@ -16,41 +16,6 @@ #include "select/properties/helpers.h" -/* Generic destructors */ - -uint32_t generic_destroy_color(void *bytecode) -{ - return sizeof(uint32_t) + - ((getValue(*((uint32_t*)bytecode)) == BACKGROUND_COLOR_SET) ? sizeof(css_color) : 0); -} - -uint32_t generic_destroy_uri(void *bytecode) -{ - 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); -} - -uint32_t generic_destroy_length(void *bytecode) -{ - bool has_length = (getValue(*((uint32_t*)bytecode)) & BORDER_WIDTH_SET) == BORDER_WIDTH_SET; - - return sizeof(uint32_t) + (has_length ? sizeof(css_fixed) + sizeof(uint32_t) : 0); -} - -uint32_t generic_destroy_number(void *bytecode) -{ - uint32_t value = getValue(*((uint32_t*)bytecode)); - bool has_number = (value == ORPHANS_SET); - - return sizeof(uint32_t) + (has_number ? sizeof(css_fixed) : 0); -} - /* Useful helpers */ css_unit to_css_unit(uint32_t u) @@ -128,8 +93,8 @@ css_error cascade_uri_none(uint32_t opv, css_style *style, break; case BACKGROUND_IMAGE_URI: value = CSS_BACKGROUND_IMAGE_IMAGE; - uri = *((lwc_string **) style->bytecode); - advance_bytecode(style, sizeof(uri)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &uri); + advance_bytecode(style, sizeof(css_code_t)); break; } } @@ -437,8 +402,7 @@ css_error cascade_counter_increment_reset(uint32_t opv, css_style *style, lwc_string *name; css_fixed val = 0; - name = *((lwc_string **) - style->bytecode); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &name); advance_bytecode(style, sizeof(name)); val = *((css_fixed *) style->bytecode); diff --git a/src/select/properties/left.c b/src/select/properties/left.c index 5e0035d..4814b66 100644 --- a/src/select/properties/left.c +++ b/src/select/properties/left.c @@ -47,7 +47,3 @@ css_error compose_left(const css_computed_style *parent, return set_left(result, type, length, unit); } -uint32_t destroy_left(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/letter_spacing.c b/src/select/properties/letter_spacing.c index f466b69..ea30359 100644 --- a/src/select/properties/letter_spacing.c +++ b/src/select/properties/letter_spacing.c @@ -55,7 +55,3 @@ css_error compose_letter_spacing(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_letter_spacing(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/line_height.c b/src/select/properties/line_height.c index 8e20bd5..b52747d 100644 --- a/src/select/properties/line_height.c +++ b/src/select/properties/line_height.c @@ -79,11 +79,3 @@ css_error compose_line_height(const css_computed_style *parent, return set_line_height(result, type, length, unit); } -uint32_t destroy_line_height(void *bytecode) -{ - uint32_t value = getValue(*((uint32_t*)bytecode)); - if (value == LINE_HEIGHT_NUMBER) - return generic_destroy_number(bytecode); - else - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/list_style_image.c b/src/select/properties/list_style_image.c index 4ebfb28..bf2b213 100644 --- a/src/select/properties/list_style_image.c +++ b/src/select/properties/list_style_image.c @@ -53,7 +53,3 @@ css_error compose_list_style_image(const css_computed_style *parent, return set_list_style_image(result, type, url); } -uint32_t destroy_list_style_image(void *bytecode) -{ - return generic_destroy_uri(bytecode); -} diff --git a/src/select/properties/list_style_position.c b/src/select/properties/list_style_position.c index 17c5eed..b21abb5 100644 --- a/src/select/properties/list_style_position.c +++ b/src/select/properties/list_style_position.c @@ -65,9 +65,3 @@ css_error compose_list_style_position(const css_computed_style *parent, return set_list_style_position(result, type); } -uint32_t destroy_list_style_position(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/list_style_type.c b/src/select/properties/list_style_type.c index 37a2bad..2536f9c 100644 --- a/src/select/properties/list_style_type.c +++ b/src/select/properties/list_style_type.c @@ -103,9 +103,3 @@ css_error compose_list_style_type(const css_computed_style *parent, return set_list_style_type(result, type); } -uint32_t destroy_list_style_type(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/margin_bottom.c b/src/select/properties/margin_bottom.c index e1be53c..a80ae2d 100644 --- a/src/select/properties/margin_bottom.c +++ b/src/select/properties/margin_bottom.c @@ -47,7 +47,3 @@ css_error compose_margin_bottom(const css_computed_style *parent, return set_margin_bottom(result, type, length, unit); } -uint32_t destroy_margin_bottom(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/margin_left.c b/src/select/properties/margin_left.c index bd39871..1740169 100644 --- a/src/select/properties/margin_left.c +++ b/src/select/properties/margin_left.c @@ -47,7 +47,3 @@ css_error compose_margin_left(const css_computed_style *parent, return set_margin_left(result, type, length, unit); } -uint32_t destroy_margin_left(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/margin_right.c b/src/select/properties/margin_right.c index 8a03165..908652e 100644 --- a/src/select/properties/margin_right.c +++ b/src/select/properties/margin_right.c @@ -47,7 +47,3 @@ css_error compose_margin_right(const css_computed_style *parent, return set_margin_right(result, type, length, unit); } -uint32_t destroy_margin_right(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/margin_top.c b/src/select/properties/margin_top.c index 878cf27..ec13e11 100644 --- a/src/select/properties/margin_top.c +++ b/src/select/properties/margin_top.c @@ -47,7 +47,3 @@ css_error compose_margin_top(const css_computed_style *parent, return set_margin_top(result, type, length, unit); } -uint32_t destroy_margin_top(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/max_height.c b/src/select/properties/max_height.c index cdbc0a0..f527aa6 100644 --- a/src/select/properties/max_height.c +++ b/src/select/properties/max_height.c @@ -48,7 +48,3 @@ css_error compose_max_height(const css_computed_style *parent, return set_max_height(result, type, length, unit); } -uint32_t destroy_max_height(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/max_width.c b/src/select/properties/max_width.c index a8472aa..916288c 100644 --- a/src/select/properties/max_width.c +++ b/src/select/properties/max_width.c @@ -47,7 +47,3 @@ css_error compose_max_width(const css_computed_style *parent, return set_max_width(result, type, length, unit); } -uint32_t destroy_max_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/min_height.c b/src/select/properties/min_height.c index 8fb1f2b..087cc50 100644 --- a/src/select/properties/min_height.c +++ b/src/select/properties/min_height.c @@ -48,7 +48,3 @@ css_error compose_min_height(const css_computed_style *parent, return set_min_height(result, type, length, unit); } -uint32_t destroy_min_height(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/min_width.c b/src/select/properties/min_width.c index 9166fba..9cdcdea 100644 --- a/src/select/properties/min_width.c +++ b/src/select/properties/min_width.c @@ -47,7 +47,3 @@ css_error compose_min_width(const css_computed_style *parent, return set_min_width(result, type, length, unit); } -uint32_t destroy_min_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/orphans.c b/src/select/properties/orphans.c index b4da851..e723266 100644 --- a/src/select/properties/orphans.c +++ b/src/select/properties/orphans.c @@ -48,7 +48,3 @@ css_error compose_orphans(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_orphans(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/outline_color.c b/src/select/properties/outline_color.c index c444816..925376e 100644 --- a/src/select/properties/outline_color.c +++ b/src/select/properties/outline_color.c @@ -73,7 +73,3 @@ css_error compose_outline_color(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_outline_color(void *bytecode) -{ - return generic_destroy_color(bytecode); -} diff --git a/src/select/properties/outline_style.c b/src/select/properties/outline_style.c index 5e80a34..1bce2b8 100644 --- a/src/select/properties/outline_style.c +++ b/src/select/properties/outline_style.c @@ -44,9 +44,3 @@ css_error compose_outline_style(const css_computed_style *parent, return set_outline_style(result, type); } -uint32_t destroy_outline_style(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/outline_width.c b/src/select/properties/outline_width.c index 08b6945..acf8729 100644 --- a/src/select/properties/outline_width.c +++ b/src/select/properties/outline_width.c @@ -55,7 +55,3 @@ css_error compose_outline_width(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_outline_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/overflow.c b/src/select/properties/overflow.c index 6318d31..bf10d58 100644 --- a/src/select/properties/overflow.c +++ b/src/select/properties/overflow.c @@ -70,9 +70,3 @@ css_error compose_overflow(const css_computed_style *parent, return set_overflow(result, type); } -uint32_t destroy_overflow(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/padding_bottom.c b/src/select/properties/padding_bottom.c index cbc47d6..e529ecd 100644 --- a/src/select/properties/padding_bottom.c +++ b/src/select/properties/padding_bottom.c @@ -48,7 +48,3 @@ css_error compose_padding_bottom(const css_computed_style *parent, return set_padding_bottom(result, type, length, unit); } -uint32_t destroy_padding_bottom(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/padding_left.c b/src/select/properties/padding_left.c index 4a4e602..07acd03 100644 --- a/src/select/properties/padding_left.c +++ b/src/select/properties/padding_left.c @@ -47,7 +47,3 @@ css_error compose_padding_left(const css_computed_style *parent, return set_padding_left(result, type, length, unit); } -uint32_t destroy_padding_left(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/padding_right.c b/src/select/properties/padding_right.c index c9dbf07..bf3cfba 100644 --- a/src/select/properties/padding_right.c +++ b/src/select/properties/padding_right.c @@ -48,7 +48,3 @@ css_error compose_padding_right(const css_computed_style *parent, return set_padding_right(result, type, length, unit); } -uint32_t destroy_padding_right(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/padding_top.c b/src/select/properties/padding_top.c index 7ab62ae..bb7197d 100644 --- a/src/select/properties/padding_top.c +++ b/src/select/properties/padding_top.c @@ -47,7 +47,3 @@ css_error compose_padding_top(const css_computed_style *parent, return set_padding_top(result, type, length, unit); } -uint32_t destroy_padding_top(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/page_break_after.c b/src/select/properties/page_break_after.c index 61ad047..d0422e7 100644 --- a/src/select/properties/page_break_after.c +++ b/src/select/properties/page_break_after.c @@ -48,9 +48,3 @@ css_error compose_page_break_after(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_page_break_after(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/page_break_before.c b/src/select/properties/page_break_before.c index 7709fc0..7be98e0 100644 --- a/src/select/properties/page_break_before.c +++ b/src/select/properties/page_break_before.c @@ -48,9 +48,3 @@ css_error compose_page_break_before(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_page_break_before(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/page_break_inside.c b/src/select/properties/page_break_inside.c index 601ee81..cb960a9 100644 --- a/src/select/properties/page_break_inside.c +++ b/src/select/properties/page_break_inside.c @@ -66,9 +66,3 @@ css_error compose_page_break_inside(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_page_break_inside(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/pause_after.c b/src/select/properties/pause_after.c index ce3b2ca..d4a9b55 100644 --- a/src/select/properties/pause_after.c +++ b/src/select/properties/pause_after.c @@ -48,7 +48,3 @@ css_error compose_pause_after(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_pause_after(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/pause_before.c b/src/select/properties/pause_before.c index 8e66bd5..1621bbc 100644 --- a/src/select/properties/pause_before.c +++ b/src/select/properties/pause_before.c @@ -48,7 +48,3 @@ css_error compose_pause_before(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_pause_before(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/pitch.c b/src/select/properties/pitch.c index 786bafb..4301b25 100644 --- a/src/select/properties/pitch.c +++ b/src/select/properties/pitch.c @@ -78,7 +78,3 @@ css_error compose_pitch(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_pitch(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/pitch_range.c b/src/select/properties/pitch_range.c index 6f06f46..25b928f 100644 --- a/src/select/properties/pitch_range.c +++ b/src/select/properties/pitch_range.c @@ -48,7 +48,3 @@ css_error compose_pitch_range(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_pitch_range(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/play_during.c b/src/select/properties/play_during.c index 451ae57..d3f723c 100644 --- a/src/select/properties/play_during.c +++ b/src/select/properties/play_during.c @@ -72,7 +72,3 @@ css_error compose_play_during(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_play_during(void *bytecode) -{ - return generic_destroy_uri(bytecode); -} diff --git a/src/select/properties/position.c b/src/select/properties/position.c index 1bef4e3..03161ee 100644 --- a/src/select/properties/position.c +++ b/src/select/properties/position.c @@ -70,9 +70,3 @@ css_error compose_position(const css_computed_style *parent, return set_position(result, type); } -uint32_t destroy_position(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/quotes.c b/src/select/properties/quotes.c index 8d4fcbc..91ba76e 100644 --- a/src/select/properties/quotes.c +++ b/src/select/properties/quotes.c @@ -30,11 +30,11 @@ css_error cascade_quotes(uint32_t opv, css_style *style, lwc_string *open, *close; lwc_string **temp; - open = *((lwc_string **) style->bytecode); - advance_bytecode(style, sizeof(lwc_string *)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &open); + advance_bytecode(style, sizeof(css_code_t)); - close = *((lwc_string **) style->bytecode); - advance_bytecode(style, sizeof(lwc_string *)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &close); + advance_bytecode(style, sizeof(css_code_t)); temp = state->computed->alloc(quotes, (n_quotes + 2) * sizeof(lwc_string *), @@ -165,23 +165,3 @@ css_error compose_quotes(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_quotes(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - - return consumed; -} diff --git a/src/select/properties/richness.c b/src/select/properties/richness.c index acdbb1c..29971e9 100644 --- a/src/select/properties/richness.c +++ b/src/select/properties/richness.c @@ -48,7 +48,3 @@ css_error compose_richness(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_richness(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/right.c b/src/select/properties/right.c index 2dfdb2f..190db4d 100644 --- a/src/select/properties/right.c +++ b/src/select/properties/right.c @@ -47,7 +47,3 @@ css_error compose_right(const css_computed_style *parent, return set_right(result, type, length, unit); } -uint32_t destroy_right(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/speach_rate.c b/src/select/properties/speach_rate.c index b019529..e55d884 100644 --- a/src/select/properties/speach_rate.c +++ b/src/select/properties/speach_rate.c @@ -75,7 +75,3 @@ css_error compose_speech_rate(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_speech_rate(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/speak.c b/src/select/properties/speak.c index f291e1b..2f260ca 100644 --- a/src/select/properties/speak.c +++ b/src/select/properties/speak.c @@ -67,9 +67,3 @@ css_error compose_speak(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_speak(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/speak_header.c b/src/select/properties/speak_header.c index 58ebfbc..5ed68d4 100644 --- a/src/select/properties/speak_header.c +++ b/src/select/properties/speak_header.c @@ -66,9 +66,3 @@ css_error compose_speak_header(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_speak_header(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/speak_numeral.c b/src/select/properties/speak_numeral.c index 3fe8511..ec09410 100644 --- a/src/select/properties/speak_numeral.c +++ b/src/select/properties/speak_numeral.c @@ -66,9 +66,3 @@ css_error compose_speak_numeral(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_speak_numeral(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/speak_punctuation.c b/src/select/properties/speak_punctuation.c index eefdd07..fec4a30 100644 --- a/src/select/properties/speak_punctuation.c +++ b/src/select/properties/speak_punctuation.c @@ -66,9 +66,3 @@ css_error compose_speak_punctuation(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_speak_punctuation(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/stress.c b/src/select/properties/stress.c index 7d478bc..f2e0a2b 100644 --- a/src/select/properties/stress.c +++ b/src/select/properties/stress.c @@ -48,7 +48,3 @@ css_error compose_stress(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_stress(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/table_layout.c b/src/select/properties/table_layout.c index 7cc8792..1af8154 100644 --- a/src/select/properties/table_layout.c +++ b/src/select/properties/table_layout.c @@ -64,9 +64,3 @@ css_error compose_table_layout(const css_computed_style *parent, return set_table_layout(result, type); } -uint32_t destroy_table_layout(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/text_align.c b/src/select/properties/text_align.c index 2281079..780667e 100644 --- a/src/select/properties/text_align.c +++ b/src/select/properties/text_align.c @@ -90,9 +90,3 @@ css_error compose_text_align(const css_computed_style *parent, return set_text_align(result, type); } -uint32_t destroy_text_align(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/text_decoration.c b/src/select/properties/text_decoration.c index 96ce877..e8f976e 100644 --- a/src/select/properties/text_decoration.c +++ b/src/select/properties/text_decoration.c @@ -72,9 +72,3 @@ css_error compose_text_decoration(const css_computed_style *parent, return set_text_decoration(result, type); } -uint32_t destroy_text_decoration(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/text_indent.c b/src/select/properties/text_indent.c index 623f88d..d81b651 100644 --- a/src/select/properties/text_indent.c +++ b/src/select/properties/text_indent.c @@ -48,7 +48,3 @@ css_error compose_text_indent(const css_computed_style *parent, return set_text_indent(result, type, length, unit); } -uint32_t destroy_text_indent(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/text_transform.c b/src/select/properties/text_transform.c index 80ec86e..db4cd9f 100644 --- a/src/select/properties/text_transform.c +++ b/src/select/properties/text_transform.c @@ -70,9 +70,3 @@ css_error compose_text_transform(const css_computed_style *parent, return set_text_transform(result, type); } -uint32_t destroy_text_transform(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/top.c b/src/select/properties/top.c index f982fc9..9620d3f 100644 --- a/src/select/properties/top.c +++ b/src/select/properties/top.c @@ -47,7 +47,3 @@ css_error compose_top(const css_computed_style *parent, return set_top(result, type, length, unit); } -uint32_t destroy_top(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/unicode_bidi.c b/src/select/properties/unicode_bidi.c index d858b7f..38a4a97 100644 --- a/src/select/properties/unicode_bidi.c +++ b/src/select/properties/unicode_bidi.c @@ -67,9 +67,3 @@ css_error compose_unicode_bidi(const css_computed_style *parent, return set_unicode_bidi(result, type); } -uint32_t destroy_unicode_bidi(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/vertical_align.c b/src/select/properties/vertical_align.c index e26dee9..fb3b988 100644 --- a/src/select/properties/vertical_align.c +++ b/src/select/properties/vertical_align.c @@ -96,7 +96,3 @@ css_error compose_vertical_align(const css_computed_style *parent, return set_vertical_align(result, type, length, unit); } -uint32_t destroy_vertical_align(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/visibility.c b/src/select/properties/visibility.c index 9d5fd9a..2616c04 100644 --- a/src/select/properties/visibility.c +++ b/src/select/properties/visibility.c @@ -67,9 +67,3 @@ css_error compose_visibility(const css_computed_style *parent, return set_visibility(result, type); } -uint32_t destroy_visibility(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/voice_family.c b/src/select/properties/voice_family.c index cc1833c..395a778 100644 --- a/src/select/properties/voice_family.c +++ b/src/select/properties/voice_family.c @@ -31,9 +31,8 @@ css_error cascade_voice_family(uint32_t opv, css_style *style, switch (v) { case VOICE_FAMILY_STRING: case VOICE_FAMILY_IDENT_LIST: - voice = *((lwc_string **) - style->bytecode); - advance_bytecode(style, sizeof(voice)); + css_stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &voice); + advance_bytecode(style, sizeof(css_code_t)); break; case VOICE_FAMILY_MALE: if (value == 0) @@ -134,24 +133,3 @@ css_error compose_voice_family(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_voice_family(void *bytecode) -{ - uint32_t consumed = sizeof(uint32_t); - uint32_t value = getValue(*((uint32_t*)bytecode)); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - - 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(uint32_t); - value = *((uint32_t*)bytecode); - bytecode = ((uint8_t*)bytecode) + sizeof(uint32_t); - } - - return consumed; -} diff --git a/src/select/properties/volume.c b/src/select/properties/volume.c index b2b7b5e..aaa7d18 100644 --- a/src/select/properties/volume.c +++ b/src/select/properties/volume.c @@ -85,14 +85,3 @@ css_error compose_volume(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_volume(void *bytecode) -{ - uint32_t value = getValue(*((uint32_t*)bytecode)); - uint32_t additional = 0; - if (value == VOLUME_NUMBER) - additional = sizeof(css_fixed); - else if (value == VOLUME_DIMENSION) - additional = sizeof(css_fixed) + sizeof(uint32_t); - - return sizeof(uint32_t) + additional; -} diff --git a/src/select/properties/white_space.c b/src/select/properties/white_space.c index 4fb9caa..4657c6d 100644 --- a/src/select/properties/white_space.c +++ b/src/select/properties/white_space.c @@ -73,9 +73,3 @@ css_error compose_white_space(const css_computed_style *parent, return set_white_space(result, type); } -uint32_t destroy_white_space(void *bytecode) -{ - UNUSED(bytecode); - - return sizeof(uint32_t); -} diff --git a/src/select/properties/width.c b/src/select/properties/width.c index 68e27b3..8b05084 100644 --- a/src/select/properties/width.c +++ b/src/select/properties/width.c @@ -47,7 +47,3 @@ css_error compose_width(const css_computed_style *parent, return set_width(result, type, length, unit); } -uint32_t destroy_width(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/windows.c b/src/select/properties/windows.c index e48f71c..f9a153f 100644 --- a/src/select/properties/windows.c +++ b/src/select/properties/windows.c @@ -48,7 +48,3 @@ css_error compose_widows(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_widows(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/properties/word_spacing.c b/src/select/properties/word_spacing.c index 58a2674..e764198 100644 --- a/src/select/properties/word_spacing.c +++ b/src/select/properties/word_spacing.c @@ -55,7 +55,3 @@ css_error compose_word_spacing(const css_computed_style *parent, return CSS_OK; } -uint32_t destroy_word_spacing(void *bytecode) -{ - return generic_destroy_length(bytecode); -} diff --git a/src/select/properties/z_index.c b/src/select/properties/z_index.c index 343a3f3..189fe26 100644 --- a/src/select/properties/z_index.c +++ b/src/select/properties/z_index.c @@ -67,7 +67,3 @@ css_error compose_z_index(const css_computed_style *parent, return set_z_index(result, type, index); } -uint32_t destroy_z_index(void *bytecode) -{ - return generic_destroy_number(bytecode); -} diff --git a/src/select/select.c b/src/select/select.c index df5795f..e06bb33 100644 --- a/src/select/select.c +++ b/src/select/select.c @@ -1283,10 +1283,10 @@ css_error cascade_style(const css_style *style, css_select_state *state) { 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)); diff --git a/src/select/select.h b/src/select/select.h index e66743e..a5a4b64 100644 --- a/src/select/select.h +++ b/src/select/select.h @@ -60,8 +60,8 @@ typedef struct css_select_state { 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, diff --git a/src/stylesheet.c b/src/stylesheet.c index ac226ee..0847c77 100644 --- a/src/stylesheet.c +++ b/src/stylesheet.c @@ -7,6 +7,7 @@ #include #include +#include #include "stylesheet.h" #include "bytecode/bytecode.h" @@ -20,15 +21,17 @@ static css_error _remove_selectors(css_stylesheet *sheet, css_rule *rule); 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 @@ css_error css_stylesheet_string_add(css_stylesheet *sheet, lwc_string *string, u 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 @@ css_error css_stylesheet_string_add(css_stylesheet *sheet, lwc_string *string, u 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 @@ css_error css_stylesheet_string_add(css_stylesheet *sheet, lwc_string *string, u 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,17 +252,16 @@ css_error css_stylesheet_create(css_language_level level, css_error css_stylesheet_destroy(css_stylesheet *sheet) { uint32_t string_index; - uint32_t bucket; css_rule *r, *s; if (sheet == NULL) return CSS_BADPARM; - + if (sheet->title != NULL) sheet->alloc(sheet->title, 0, sheet->pw); sheet->alloc(sheet->url, 0, sheet->pw); - + for (r = sheet->rule_list; r != NULL; r = s) { s = r->next; @@ -262,24 +275,16 @@ css_error css_stylesheet_destroy(css_stylesheet *sheet) 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 */ + /* These three may have been destroyed when parsing completed */ if (sheet->parser_frontend != NULL) css_language_destroy(sheet->parser_frontend); if (sheet->parser != NULL) css_parser_destroy(sheet->parser); + if (sheet->cached_style != NULL) + css_stylesheet_style_destroy(sheet->cached_style); + /* destroy string vector */ for (string_index = 0; string_index < sheet->string_vector_c; @@ -326,7 +331,6 @@ css_error css_stylesheet_append_data(css_stylesheet *sheet, css_error css_stylesheet_data_done(css_stylesheet *sheet) { const css_rule *r; - uint32_t bucket; css_error error; if (sheet == NULL) @@ -345,16 +349,11 @@ css_error css_stylesheet_data_done(css_stylesheet *sheet) 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); - } + + /* If we have a cached style, drop it as we're done parsing. */ + if (sheet->cached_style != NULL) { + css_stylesheet_style_destroy(sheet->cached_style); + sheet->cached_style = NULL; } /* Determine if there are any pending imports */ @@ -623,6 +622,11 @@ css_error css_stylesheet_size(css_stylesheet *sheet, size_t *size) /****************************************************************************** * Library-private API below here * ******************************************************************************/ +/* Note, CSS_STYLE_DEFAULT_SIZE must be a power of 2 */ +/* With a test set of NetSurf's homepage, BBC news, wikipedia, CNN, Ars, Google and El-Reg, + * 16 seems to be a good medium between wastage and reallocs. + */ +#define CSS_STYLE_DEFAULT_SIZE 16 /** * Create a style @@ -634,31 +638,113 @@ css_error css_stylesheet_size(css_stylesheet *sheet, size_t *size) * 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 (sheet->cached_style != NULL) { + *style = sheet->cached_style; + sheet->cached_style = NULL; + return CSS_OK; + } + + 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; + + *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; - 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) + sheet = target->sheet; + newcode_len = target->used + style->used ; + + if (newcode_len > target->allocated) { + newcode_len += CSS_STYLE_DEFAULT_SIZE - 1; + newcode_len &= ~(CSS_STYLE_DEFAULT_SIZE - 1); + 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; } - /* DIY variable-sized data member */ - s->bytecode = ((uint8_t *) s + sizeof(css_style)); - s->length = len; + memcpy(target->bytecode + target->used, style->bytecode, style->used * sizeof(css_code_t)); - *style = s; + 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; } @@ -668,40 +754,30 @@ css_error css_stylesheet_style_create(css_stylesheet *sheet, uint32_t len, * * \param sheet The stylesheet context * \param style The style to destroy - * \param suppress_bytecode_cleanup Whether or not to prevent the - * bytecode from unreffing strings - * etc. * \return CSS_OK on success, appropriate error otherwise */ -css_error css_stylesheet_style_destroy(css_stylesheet *sheet, css_style *style, - bool suppress_bytecode_cleanup) +css_error css_stylesheet_style_destroy(css_style *style) { - uint32_t alloclen, bucket; - void *bptr, *eptr; - - if (sheet == NULL || style == NULL) - return CSS_BADPARM; - - 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; - } - } + css_stylesheet *sheet; - alloclen = ((style->length + 15) & ~15); - bucket = (alloclen / N_ELEMENTS(sheet->free_styles)) - 1; + if (style == NULL) + return CSS_BADPARM; + + sheet = style->sheet; - if (bucket < N_ELEMENTS(sheet->free_styles)) { - style->bytecode = sheet->free_styles[bucket]; - sheet->free_styles[bucket] = style; + if (sheet->cached_style == NULL) { + sheet->cached_style = style; + style->used = 0; + } else if (sheet->cached_style->allocated < style->allocated) { + sheet->alloc(sheet->cached_style->bytecode, 0, sheet->pw); + sheet->alloc(sheet->cached_style, 0, sheet->pw); + sheet->cached_style = style; + style->used = 0; } else { + sheet->alloc(style->bytecode, 0, sheet->pw); sheet->alloc(style, 0, sheet->pw); } - + return CSS_OK; } @@ -1041,7 +1117,7 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule) 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); } break; case CSS_RULE_CHARSET: @@ -1081,7 +1157,7 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule) 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); } break; case CSS_RULE_PAGE: @@ -1094,7 +1170,7 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule) } if (page->style != NULL) - css_stylesheet_style_destroy(sheet, page->style, false); + css_stylesheet_style_destroy(page->style); } break; } @@ -1142,6 +1218,7 @@ css_error css_stylesheet_rule_add_selector(css_stylesheet *sheet, return CSS_OK; } + /** * Append a style to a CSS rule * @@ -1153,7 +1230,8 @@ css_error css_stylesheet_rule_add_selector(css_stylesheet *sheet, 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 +1239,30 @@ css_error css_stylesheet_rule_append_style(css_stylesheet *sheet, 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; - - 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); + current_style = ((css_rule_page *) rule)->style; - if (curlen < reqlen) { - css_style *temp; - css_error error; + if (current_style != NULL) { + error = css_stylesheet_merge_style(current_style, style); - 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; + if (error != CSS_OK) + return error; /* Done with style */ - css_stylesheet_style_destroy(sheet, style, true); + css_stylesheet_style_destroy(style); } 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 +1646,7 @@ size_t _rule_size(const css_rule *r) } 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 +1666,7 @@ size_t _rule_size(const css_rule *r) 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 +1686,7 @@ size_t _rule_size(const css_rule *r) } if (rp->style != NULL) - bytes += rp->style->length; + bytes += (rp->style->used * sizeof(css_code_t)); } return bytes; diff --git a/src/stylesheet.h b/src/stylesheet.h index e8feea9..294f64a 100644 --- a/src/stylesheet.h +++ b/src/stylesheet.h @@ -18,6 +18,7 @@ #include #include +#include "bytecode/bytecode.h" #include "parse/parse.h" #include "select/hash.h" @@ -25,8 +26,10 @@ typedef struct css_rule css_rule; 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 @@ struct css_stylesheet { 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 */ @@ -178,16 +179,34 @@ struct css_stylesheet { css_allocator_fn alloc; /**< Allocation function */ void *pw; /**< Private word */ - + + css_style *cached_style; /**< Cache for style parsing */ + lwc_string **string_vector; /**< Bytecode string vector */ uint32_t string_vector_l; /**< The string vector allocated length in entries */ 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); +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); -- cgit v1.2.3