ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_extract_internal.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <stddef.h>
14#include <string.h>
15
16#include "ra8_attributes.h"
17
32RA8_INTERNAL static inline char internal_lc(char c)
33{
34 /* The conditional operator promotes both arms to int, so the cast belongs
35 * on the whole expression; both arms are already char-valued. */
36 return (char)(((c >= 'A') && (c <= 'Z')) ? (c + ('a' - 'A')) : c);
37}
38
53RA8_INTERNAL static inline bool internal_is_attr_boundary(char c)
54{
55 return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '"') || (c == '\'') ||
56 (c == '<');
57}
58
73RA8_INTERNAL static inline bool internal_is_name_end(char c)
74{
75 return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '>') || (c == '/');
76}
77
79RA8_INTERNAL static inline const char*
80internal_find_ci(const char* hay, size_t hay_len, const char* needle)
81{
82 const size_t nlen = strlen(needle);
83 if ((nlen == 0U) || (hay_len < nlen)) {
84 return nullptr;
85 }
86 for (size_t i = 0U; i + nlen <= hay_len; ++i) {
87 size_t j = 0U;
88 while ((j < nlen) && (internal_lc(hay[i + j]) == internal_lc(needle[j]))) {
89 ++j;
90 }
91 if (j == nlen) {
92 return hay + i;
93 }
94 }
95 return nullptr;
96}
97
114RA8_INTERNAL static inline size_t internal_skip_ws(const char* tag, size_t tag_len, size_t k)
115{
116 while ((k < tag_len) && ((tag[k] == ' ') || (tag[k] == '\t'))) {
117 ++k;
118 }
119 return k;
120}
121
142RA8_INTERNAL static inline bool
143internal_read_eq_value(const char* tag, size_t tag_len, size_t k, char* out, size_t out_cap)
144{
145 k = internal_skip_ws(tag, tag_len, k);
146 if (!((k < tag_len) && (tag[k] == '='))) {
147 return false;
148 }
149 k = internal_skip_ws(tag, tag_len, k + 1U);
150 if (!((k < tag_len) && ((tag[k] == '"') || (tag[k] == '\'')))) {
151 return false;
152 }
153 const char quote = tag[k];
154 ++k;
155 size_t n = 0U;
156 while ((k < tag_len) && (tag[k] != quote) && (n + 1U < out_cap)) {
157 out[n] = tag[k];
158 ++n;
159 ++k;
160 }
161 if ((k < tag_len) && (tag[k] == quote)) {
162 out[n] = '\0';
163 return true;
164 }
165 return false;
166}
167
188RA8_INTERNAL static inline bool internal_find_attr_value(const char* tag,
189 size_t tag_len,
190 const char* attr,
191 char* out,
192 size_t out_cap)
193{
194 const size_t alen = strlen(attr);
195 size_t pos = 0U;
196 while (pos + alen <= tag_len) {
197 const char* hit = internal_find_ci(tag + pos, tag_len - pos, attr);
198 if (hit == nullptr) {
199 return false;
200 }
201 const size_t idx = (size_t)(hit - tag);
202 const bool left_ok = (idx == 0U) || internal_is_attr_boundary(tag[idx - 1U]);
203 if (left_ok && internal_read_eq_value(tag, tag_len, idx + alen, out, out_cap)) {
204 return true;
205 }
206 pos = idx + alen;
207 }
208 return false;
209}
210
226RA8_INTERNAL static inline bool internal_contains_ok(const char* url, const char* needle)
227{
228 if ((needle == nullptr) || (needle[0] == '\0')) {
229 return true;
230 }
231 return strstr(url, needle) != nullptr;
232}
233
250RA8_INTERNAL static inline bool internal_copy_fits(char* out, size_t out_cap, const char* src)
251{
252 const size_t n = strlen(src);
253 if (n + 1U > out_cap) {
254 return false;
255 }
256 memcpy(out, src, n + 1U);
257 return true;
258}
static bool internal_read_eq_value(const char *tag, size_t tag_len, size_t k, char *out, size_t out_cap)
From position k just after an attr name, read ="value".
static bool internal_find_attr_value(const char *tag, size_t tag_len, const char *attr, char *out, size_t out_cap)
Read the value of attr inside one tag [tag, tag+tag_len).
static bool internal_copy_fits(char *out, size_t out_cap, const char *src)
Copy src into out if it fits (incl.
static bool internal_is_attr_boundary(char c)
True if c ends an HTML attribute token on its left side.
static const char * internal_find_ci(const char *hay, size_t hay_len, const char *needle)
Case-insensitive search for needle in [hay, hay+hay_len).
static size_t internal_skip_ws(const char *tag, size_t tag_len, size_t k)
Advance past spaces/tabs in [k, tag_len).
static bool internal_contains_ok(const char *url, const char *needle)
True if needle is empty/NULL or a substring of url.
static char internal_lc(char c)
ASCII lower-case (locale-independent).
static bool internal_is_name_end(char c)
True if c terminates a tag name (so "<a" != "<article").
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
char * strstr(const char *haystack, const char *needle)
Locate substring in string.