|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Content-CSS primitives + declaration-body parsing (#111). More...
#include "reflow_css.h"#include <stddef.h>#include <string.h>#include "ra8_attributes.h"#include "reflow.h"#include "reflow_css_internal.h"Go to the source code of this file.
Enumerations | |
| enum | priv_css_hex_t : uint8_t { k_priv_hex_base = 16U , k_priv_hex_a10 = 10U , k_priv_hex3_len = 3U , k_priv_hex6_len = 6U , k_priv_hex_nib = 4U , k_priv_hex_chan = 8U } |
| Hex-colour parsing constants (#rgb / #rrggbb). More... | |
| enum | priv_css_fs_t : uint16_t { k_priv_fs_dec = 10U , k_priv_fs_pct1 = 100U , k_priv_fs_frac = 2U , k_priv_fs_max = 9999U , k_priv_fs_ulen = 2U } |
| font-size parsing constants (decimal + unit scaling). More... | |
| enum | priv_css_color_t : uint32_t { k_priv_col_black = 0x000000U , k_priv_col_white = 0xFFFFFFU , k_priv_col_red = 0xFF0000U , k_priv_col_green = 0x008000U , k_priv_col_blue = 0x0000FFU , k_priv_col_gray = 0x808080U , k_priv_col_silver = 0xC0C0C0U , k_priv_col_maroon = 0x800000U , k_priv_col_navy = 0x000080U , k_priv_col_invalid = 0xFFFFFFFFU } |
| Common named CSS colours + the "not a colour" sentinel. More... | |
Functions | |
| bool | priv_reflow_css_is_ws (char c) |
| True for CSS whitespace (space / tab / newline / CR / FF). | |
| char | priv_reflow_css_lower (char c) |
| ASCII-fold one byte to lower case. | |
| bool | priv_reflow_css_ci_eq (const char *s, size_t len, const char *lit) |
Case-insensitive compare of span s[0..len) against NUL literal lit. | |
| static bool | internal_ci_contains (const char *s, size_t len, const char *sub) |
| Case-insensitive "span contains substring @p sub" (bounded scan). | |
| const char * | priv_reflow_css_trim (const char *s, size_t *len) |
Trim leading + trailing whitespace from s[0..*len); returns start. | |
| static uint8_t | internal_hex_val (char c) |
| Hex value of one ASCII digit, or k_priv_hex_base if not a hex digit. | |
| static uint32_t | internal_parse_hex_color (const char *s, size_t len) |
| Parse rgb / rrggbb hex digits (no #) to 0xRRGGBB, or invalid. | |
| static uint32_t | internal_parse_color (const char *s, size_t len) |
| Parse a CSS colour value (#rgb / #rrggbb / a named keyword). | |
| static uint32_t | internal_scan_hundredths (const char *s, size_t len, size_t *i, bool *any) |
| Scan a decimal number into hundredths (e.g. | |
| static uint16_t | internal_fs_whole (uint32_t hund) |
| Clamp a hundredths value to a whole number in [0, k_priv_fs_max]. | |
| static bool | internal_parse_fontsize (const char *s, size_t len, uint16_t *out_val, uint8_t *out_unit) |
| Parse Npx / N% / Nem (N may be fractional) into value + unit. | |
| static void | internal_set_emphasis (ra8_css_style_t *out, uint8_t setbit, uint8_t stylebit, bool on) |
Set or clear stylebit in out, marking setbit as present. | |
| static bool | internal_apply_emphasis (const char *prop, size_t plen, const char *val, size_t vlen, ra8_css_style_t *out) |
| Apply a boolean-emphasis property (font-weight/style/decoration); false if other. | |
| static void | internal_apply_align (const char *val, size_t vlen, ra8_css_style_t *out) |
Apply a parsed text-align value to out. | |
| static void | internal_apply_decl (const char *prop, size_t plen, const char *val, size_t vlen, ra8_css_style_t *out) |
Apply one trimmed prop:value pair to out, setting the matching bit. | |
| void | priv_reflow_css_parse_decls (const char *s, size_t len, ra8_css_style_t *out) |
Parse a prop:value; ... declaration body (no braces) into out. | |
| ra8_err_t | ra8_css_parse_inline (const char *decls, uint32_t len, ra8_css_style_t *out) |
| Parse an inline style="..." declaration body into one style. | |
Content-CSS primitives + declaration-body parsing (#111).
The string-classification primitives and the prop:value; declaration parser for the v1 CSS subset documented in reflow_css.h. This translation unit owns the small pure leaf helpers shared across the split (white-space test, ASCII case-fold, case-insensitive compare, span trim) and the declaration value parsers (colour, font-size, emphasis, align). It also implements the public inline-declaration entry point ra8_css_parse_inline. No MMIO, no heap; every buffer is a fixed-size field of the caller-owned ra8_css_sheet_t.
[Ring 4 / Reflow] {World: NS}
Definition in file reflow_css.c.
| enum priv_css_color_t : uint32_t |
Common named CSS colours + the "not a colour" sentinel.
Definition at line 66 of file reflow_css.c.
| enum priv_css_fs_t : uint16_t |
font-size parsing constants (decimal + unit scaling).
Definition at line 54 of file reflow_css.c.
| enum priv_css_hex_t : uint8_t |
Hex-colour parsing constants (#rgb / #rrggbb).
Definition at line 41 of file reflow_css.c.
|
static |
Apply a parsed text-align value to out.
Sets the k_ra8_css_set_align bit in out->set and assigns out->align to the matching reflow_align constant:
| [in] | val | Value span for the text-align property. |
| [in] | vlen | Length of val in bytes. |
| [in,out] | out | Style record to update; must not be NULL. |
val points to at least vlen readable bytes. out is non-NULL. out->set has k_ra8_css_set_align OR'd in. out->align holds the parsed alignment constant.out instances. Definition at line 673 of file reflow_css.c.
References ra8_css_style_t::align, k_ra8_css_set_align, k_reflow_align_center, k_reflow_align_justify, k_reflow_align_left, k_reflow_align_right, priv_reflow_css_ci_eq(), and ra8_css_style_t::set.
Referenced by internal_apply_decl().
|
static |
Apply one trimmed prop:value pair to out, setting the matching bit.
Routes a single CSS declaration to the appropriate handler:
| [in] | prop | Style property name span (not NUL-terminated). |
| [in] | plen | Length of prop in bytes. |
| [in] | val | Style value span (not NUL-terminated). |
| [in] | vlen | Length of val in bytes. |
| [in,out] | out | Style record to update; must not be NULL. |
prop points to at least plen readable bytes. val points to at least vlen readable bytes. out is non-NULL. out are updated when the property is recognised and the value parses successfully. prop and val are not modified.out instances. Definition at line 718 of file reflow_css.c.
References ra8_css_style_t::color, ra8_css_style_t::display, ra8_css_style_t::font_unit, ra8_css_style_t::font_val, internal_apply_align(), internal_apply_emphasis(), internal_parse_color(), internal_parse_fontsize(), k_priv_col_invalid, k_ra8_css_set_color, k_ra8_css_set_display, k_ra8_css_set_fontsize, priv_reflow_css_ci_eq(), and ra8_css_style_t::set.
Referenced by priv_reflow_css_parse_decls().
|
static |
Apply a boolean-emphasis property (font-weight/style/decoration); false if other.
Handles three CSS properties that map to on/off style bits:
| [in] | prop | Style property name span (not NUL-terminated). |
| [in] | plen | Length of prop in bytes. |
| [in] | val | Style value span (not NUL-terminated). |
| [in] | vlen | Length of val in bytes. |
| [in,out] | out | Style record to update on a match; must not be NULL. |
| true | prop was one of the handled emphasis properties; out updated. |
| false | prop was not an emphasis property; out is unchanged. |
prop points to at least plen readable bytes. val points to at least vlen readable bytes. out is non-NULL. prop and val are not modified. out have been updated.out instances. Definition at line 615 of file reflow_css.c.
References internal_ci_contains(), internal_set_emphasis(), k_ra8_css_set_bold, k_ra8_css_set_italic, k_ra8_css_set_underline, k_reflow_style_bold, k_reflow_style_italic, k_reflow_style_underline, and priv_reflow_css_ci_eq().
Referenced by internal_apply_decl().
|
static |
Case-insensitive "span contains substring @p sub" (bounded scan).
Slides a window of strlen(sub) bytes across s[0..len) and checks for a case-insensitive match at each position via priv_reflow_css_lower(). The outer loop is bounded by (len - sl + 1) windows; the inner loop is bounded by sl, the NUL-terminated substring length. Returns false immediately if s is NULL, sub is empty, or sub is longer than len.
| [in] | s | Byte span to search (need not be NUL-terminated). |
| [in] | len | Number of bytes in s. |
| [in] | sub | NUL-terminated substring to search for. |
| true | A case-insensitive occurrence of sub was found within s. |
| false | s is NULL, sub is empty, sub is longer than len, or no occurrence was found. |
sub is a valid NUL-terminated string (length determinable via strlen). len accurately reflects the number of valid bytes reachable via s. s and sub are not modified.Definition at line 203 of file reflow_css.c.
References priv_reflow_css_lower(), and strlen().
Referenced by internal_apply_emphasis().
|
static |
Clamp a hundredths value to a whole number in [0, k_priv_fs_max].
Divides hund by k_priv_fs_pct1 (100) to convert from hundredths back to whole units, then clamps the result to at most k_priv_fs_max (9999) to keep it representable in a uint16_t font-size field.
| [in] | hund | Value expressed in hundredths (e.g. 120 represents 1.20). |
| 0..k_priv_fs_max | The integer quotient of (hund / k_priv_fs_pct1), clamped to k_priv_fs_max. |
hund is a value previously produced by internal_scan_hundredths(). hund is not modified.Definition at line 486 of file reflow_css.c.
References k_priv_fs_max, and k_priv_fs_pct1.
Referenced by internal_parse_fontsize().
|
static |
Hex value of one ASCII digit, or k_priv_hex_base if not a hex digit.
Maps an ASCII hexadecimal character ('0'-'9', 'a'-'f', 'A'-'F') to its numeric value (0-15). The digit is first lower-cased via priv_reflow_css_lower() so 'A'-'F' and 'a'-'f' are treated identically. Any byte outside those ranges returns k_priv_hex_base (16) as a sentinel indicating "not a hex digit".
| [in] | c | ASCII character to convert. |
| 0..9 | For '0'..'9'. |
| 10..15 | For 'a'..'f' or 'A'..'F'. |
| k_priv_hex_base | (16) For any non-hex character. |
c; all byte values are valid inputs. c is not modified.Definition at line 271 of file reflow_css.c.
References k_priv_hex_a10, k_priv_hex_base, and priv_reflow_css_lower().
Referenced by internal_parse_hex_color().
|
static |
Parse a CSS colour value (#rgb / #rrggbb / a named keyword).
Accepts the following forms in s[0..len):
s is NULL, len is zero, the leading # is followed by an invalid hex span, or the keyword is unrecognised.| [in] | s | Pointer to the colour value span (need not be NUL-terminated). |
| [in] | len | Number of bytes in s. |
| 0x000000..0xFFFFFF | Parsed colour in 0xRRGGBB format. |
| k_priv_col_invalid | When s is NULL, len is 0, or parsing fails. |
s points to at least len readable bytes, or is NULL. len accurately reflects the span length. s is not modified.Definition at line 365 of file reflow_css.c.
References internal_parse_hex_color(), k_priv_col_black, k_priv_col_blue, k_priv_col_gray, k_priv_col_green, k_priv_col_invalid, k_priv_col_maroon, k_priv_col_navy, k_priv_col_red, k_priv_col_silver, k_priv_col_white, and priv_reflow_css_ci_eq().
Referenced by internal_apply_decl().
|
static |
Parse Npx / N% / Nem (N may be fractional) into value + unit.
Delegates numeric scanning to internal_scan_hundredths(), then classifies the trailing unit suffix:
*out_val and k_ra8_css_font_px to *out_unit.| [in] | s | Byte span containing the font-size value and unit. |
| [in] | len | Number of bytes in s. |
| [out] | out_val | Receives the parsed numeric value (valid only on true). |
| [out] | out_unit | Receives the unit constant (valid only on true). |
| true | The span was a recognised font-size token; *out_val and *out_unit have been written. |
| false | No digit was found, or the unit suffix was not px / % / em. |
s points to at least len readable bytes. out_val and out_unit are non-NULL. *out_val is in [0, k_priv_fs_max] and *out_unit is a valid ra8_css_font_unit value. *out_val and *out_unit are not written.Definition at line 524 of file reflow_css.c.
References internal_fs_whole(), internal_scan_hundredths(), k_priv_fs_max, k_priv_fs_ulen, k_ra8_css_font_pct, k_ra8_css_font_px, and priv_reflow_css_ci_eq().
Referenced by internal_apply_decl().
|
static |
Parse rgb / rrggbb hex digits (no #) to 0xRRGGBB, or invalid.
Accepts exactly k_priv_hex3_len (3) or k_priv_hex6_len (6) hex digits in s[0..len) with no leading #. For a 3-digit shorthand each nibble d is expanded to dd (i.e., channel = (d << 4) | d). For 6-digit form each pair is packed left-to-right into bits 23..0 of the result. Returns k_priv_col_invalid when any digit is non-hex or the length is neither 3 nor 6.
| [in] | s | Pointer to the hex digit span (no leading '#'). |
| [in] | len | Number of bytes in s (must equal 3 or 6 for a valid colour). |
| 0x000000..0xFFFFFF | Parsed colour in 0xRRGGBB format on success. |
| k_priv_col_invalid | When len is not 3 or 6, or a non-hex byte occurs. |
s points to at least len readable bytes. len equals k_priv_hex3_len or k_priv_hex6_len for a valid result. s is not modified.Definition at line 310 of file reflow_css.c.
References internal_hex_val(), k_priv_col_invalid, k_priv_hex3_len, k_priv_hex6_len, k_priv_hex_base, k_priv_hex_chan, and k_priv_hex_nib.
Referenced by internal_parse_color().
|
static |
Scan a decimal number into hundredths (e.g.
"1.2" -> 120); advance i.
Reads ASCII digits from s starting at *i, accumulating the integer part multiplied by k_priv_fs_pct1 (100). If a decimal point follows, up to k_priv_fs_frac (2) fractional digits are accumulated; further fractional digits are consumed and discarded so the cursor is always left past the number. Sets *any to true whenever at least one digit is consumed. On return *i points to the first byte after all consumed digits.
| [in] | s | Byte span containing the decimal number. |
| [in] | len | Total length of s. |
| [in,out] | i | Cursor into s; advanced past all consumed digit/dot bytes. |
| [in,out] | any | Set to true when any digit is consumed; never reset to false. |
| 0 | When no digit bytes are present at *i. |
| >0 | The integer value scaled to hundredths, including fractional part. |
s points to at least len readable bytes. i and any are non-NULL; *i <= len on entry. *i is in [*i_entry, len] on return. *any is unchanged if no digit was consumed, else it equals true.Definition at line 432 of file reflow_css.c.
References k_priv_fs_dec, k_priv_fs_frac, and k_priv_fs_pct1.
Referenced by internal_parse_fontsize().
|
static |
Set or clear stylebit in out, marking setbit as present.
Records that the emphasis property identified by setbit has been explicitly declared by setting that bit in out->set. If on is true the corresponding stylebit is OR'd into out->style; otherwise stylebit is cleared with a bitwise AND of the complement. This is the single mutation point for bold, italic, and underline state in the cascade.
| [in,out] | out | Style record to update; must not be NULL. |
| [in] | setbit | Bit in out->set that marks this property as set. |
| [in] | stylebit | Bit in out->style that carries the on/off value. |
| [in] | on | True to set stylebit, false to clear it. |
out is non-NULL. setbit and stylebit are single-bit masks valid for their fields. out->set has setbit OR'd in. out->style has stylebit set when on is true, cleared otherwise.out instances; not safe for concurrent writes to the same out. Definition at line 578 of file reflow_css.c.
References ra8_css_style_t::set, and ra8_css_style_t::style.
Referenced by internal_apply_emphasis().
| bool priv_reflow_css_ci_eq | ( | const char * | s, |
| size_t | len, | ||
| const char * | lit ) |
Case-insensitive compare of span s[0..len) against NUL literal lit.
Compares exactly len bytes of s against the NUL-terminated string lit using ASCII case folding via priv_reflow_css_lower(). Returns true only when the span and the literal have equal length and all bytes fold equal. Either null pointer causes an immediate false return without dereferencing.
| [in] | s | Pointer to the byte span (need not be NUL-terminated). |
| [in] | len | Number of bytes in s to compare. |
| [in] | lit | NUL-terminated reference string; must not be NULL for a true result. |
| true | s[0..len) equals lit case-insensitively and lengths match. |
| false | Lengths differ, any byte differs, or a null pointer was passed. |
len is the exact byte count of the span to compare (may be 0). lit is a valid NUL-terminated string pointer or NULL. s and lit are not modified.Definition at line 162 of file reflow_css.c.
References priv_reflow_css_lower().
Referenced by internal_apply_align(), internal_apply_decl(), internal_apply_emphasis(), internal_extract_url(), internal_face_apply(), internal_family_cb(), internal_is_bold_kw(), internal_is_italic_kw(), internal_parse_at_rule(), internal_parse_color(), and internal_parse_fontsize().
| bool priv_reflow_css_is_ws | ( | char | c | ) |
True for CSS whitespace (space / tab / newline / CR / FF).
Classifies a single byte as a CSS white-space character per the CSS specification: space (0x20), horizontal tab (0x09), newline (0x0A), carriage return (0x0D), and form feed (0x0C). Used throughout the parser to skip or trim tokens.
| [in] | c | Byte to classify (any value). |
| true | c is a CSS whitespace byte. |
| false | c is not a CSS whitespace byte. |
c; all byte values are valid inputs. c; no state is mutated. Definition at line 106 of file reflow_css.c.
Referenced by internal_class_list_has(), internal_split_compounds(), priv_reflow_css_trim(), and ra8_css_parse().
| char priv_reflow_css_lower | ( | char | c | ) |
ASCII-fold one byte to lower case.
Converts an ASCII upper-case letter ('A'-'Z') to its lower-case equivalent by adding the fixed offset between 'A' and 'a'. All other byte values are returned unchanged. This is used for case-insensitive CSS keyword and identifier comparisons throughout the parser.
| [in] | c | Byte to fold; may be any value. |
| c | + ('a' - 'A') When c is in the range 'A'..'Z'. |
| c | For all other byte values. |
c; all byte values are valid inputs. c only when c is an ASCII upper-case letter. Definition at line 133 of file reflow_css.c.
Referenced by internal_ci_contains(), internal_ci_eq_span(), internal_hex_val(), and priv_reflow_css_ci_eq().
| void priv_reflow_css_parse_decls | ( | const char * | s, |
| size_t | len, | ||
| ra8_css_style_t * | out ) |
Parse a prop:value; ... declaration body (no braces) into out.
Iterates over semicolon-delimited declarations in s[0..len). For each declaration, it locates the colon separator, trims whitespace from both property name and value, and delegates to internal_apply_decl(). Declarations with an empty property or value after trimming are skipped silently. The loop is bounded by len; each iteration advances past the next semicolon.
| [in] | s | Byte span of the declaration block (no surrounding braces). |
| [in] | len | Number of bytes in s. |
| [in,out] | out | Style record to accumulate parsed declarations into. |
s points to at least len readable bytes (may be NULL only when len == 0). out is non-NULL and zero-initialised or partially filled by the caller. out reflects all successfully parsed declarations from s. s is not modified.out instances. Definition at line 774 of file reflow_css.c.
References internal_apply_decl(), and priv_reflow_css_trim().
Referenced by priv_reflow_css_parse_one_block(), and ra8_css_parse_inline().
| const char * priv_reflow_css_trim | ( | const char * | s, |
| size_t * | len ) |
Trim leading + trailing whitespace from s[0..*len); returns start.
Advances past leading priv_reflow_css_is_ws() bytes and shrinks past trailing ones, writing the trimmed length back through len and returning a pointer to the first retained byte. Used to normalise property names, values, and selector spans before classification.
| [in] | s | Byte span to trim (need not be NUL-terminated). |
| [in,out] | len | On entry, the span length; on return, the trimmed length. |
s. | &s[a] | Pointer to the trimmed start; *len holds the trimmed length. |
s points to at least *len readable bytes. len is non-NULL. *len is in [0, *len_entry]; s contents are not modified. s, s + *len_entry].Definition at line 228 of file reflow_css.c.
References priv_reflow_css_is_ws().
Referenced by internal_extract_url(), internal_for_each_decl(), internal_parse_selector_list(), priv_reflow_css_parse_decls(), and priv_reflow_css_parse_one_block().
|
nodiscard |
Parse an inline style="..." declaration body into one style.
Same property grammar as ra8_css_parse but with no selector and no braces – just prop: value; prop: value. The result carries the inline declaration; the caller applies it at the highest specificity.
| [in] | decls | Declaration bytes (the style attribute value). |
| [in] | len | Length of decls, bytes. |
| [out] | out | Receives the parsed declaration (set == 0 if empty). |
| k_ra8_ok | Parsed (possibly empty). |
| k_ra8_err_null_ptr | decls or out is NULL. |
decls, out non-NULL. decls. out. Definition at line 805 of file reflow_css.c.
References k_ra8_err_null_ptr, k_ra8_ok, and priv_reflow_css_parse_decls().
Referenced by priv_reflow_tok_css_inline().