20typedef enum : uint8_t {
50 const bool alpha = ((c >=
'A') && (c <=
'Z')) || ((c >=
'a') && (c <=
'z'));
51 const bool digit = (c >=
'0') && (c <=
'9');
52 const bool mark = (c ==
'-') || (c ==
'.') || (c ==
'_') || (c ==
'~');
53 return alpha || digit || mark;
71 static const char digits[] =
"0123456789ABCDEF";
77 if ((term ==
nullptr) || (out ==
nullptr) || (cap == 0U)) {
78 if ((out !=
nullptr) && (cap > 0U)) {
84 for (
size_t i = 0U; term[i] !=
'\0'; ++i) {
85 const unsigned char c = (
unsigned char)term[i];
87 if ((n + 1U) >= cap) {
110 if ((tmpl ==
nullptr) || (encoded_term ==
nullptr) || (out ==
nullptr) || (cap == 0U)) {
111 if ((out !=
nullptr) && (cap > 0U)) {
117 const size_t tlen =
strlen(encoded_term);
121 while (tmpl[i] !=
'\0') {
123 if ((n + tlen) >= cap) {
127 memcpy(out + n, encoded_term, tlen);
132 if ((n + 1U) >= cap) {
151 if (hits ==
nullptr) {
154 if (hits->
count > 0U) {
165 if ((hits ==
nullptr) || (chapter_marker ==
nullptr)) {
168 const size_t before = hits->
count;
170 for (
size_t i = 0U; i < before; ++i) {
173 if ((chapter_marker[0] !=
'\0') && (
strstr(candidate->
url, chapter_marker) !=
nullptr)) {
176 for (
size_t j = 0U; (!reject) && (j < kept); ++j) {
183 hits->
hits[kept] = *candidate;
188 hits->
count = (uint16_t)kept;
189 return before - kept;
const char * mdl_search_placeholder(void)
The {q} placeholder a search-URL template must contain.
mdl_search_const_t
Query-encoding constants.
@ k_triplet_len
Bytes a HH escape occupies.
@ k_hi_nibble_shift
Bits to shift for the high hex nibble.
static char internal_hex_digit(unsigned nibble)
Upper-case hex digit for a 0..15 nibble.
size_t mdl_search_filter_series_hits(mdl_hit_list_t *hits, const char *chapter_marker)
Remove chapter links and duplicate series URLs from discovery hits.
bool mdl_query_encode(const char *term, char *out, size_t cap)
Percent-encode a raw query term for safe inclusion in a URL.
mdl_search_outcome_t mdl_search_classify(const mdl_hit_list_t *hits)
Classify a parsed results page into an honest search outcome.
bool mdl_search_build_url(const char *tmpl, const char *encoded_term, char *out, size_t cap)
Expand a query-URL template by substituting the encoded term for {q}.
static bool internal_is_unreserved(unsigned char c)
True for an RFC 3986 unreserved byte (copied verbatim).
static const char s_placeholder[]
The {q} placeholder token, kept in one place.
Pure search/discovery policy: query encoding, URL templating, and the honest zero-vs-broken result cl...
mdl_search_outcome_t
The honest outcome of a parsed search/browse results page.
@ k_mdl_search_markup_changed
No links at all: the page could not be read.
@ k_mdl_search_have_results
One or more hits matched; print them.
@ k_mdl_search_zero_results
Links present, none matched: a real no-hit.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
int strncmp(const char *s1, const char *s2, size_t n)
Compare two strings up to a specified length.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
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.
@ k_nibble_mask
Nibble mask.
Bounded list of titled hits plus the raw anchor tally.
mdl_hit_t hits[k_mdl_max_hits]
Deduplicated titled hits.
size_t count
Number of valid hits.
size_t anchors_seen
Total resolvable <a href> anchors.
One discovery hit: a human-facing title paired with a series URL.
char url[k_mdl_url_max]
Absolute series URL, NUL-terminated.