leptris 1.9.201.4-arm-linux → 1.9.207.0-arm-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +69 -0
- data/Rakefile +8 -2
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/document.rb +25 -0
- data/lib/leptris/xml/dtd.rb +113 -0
- data/lib/leptris/xml/ffi.rb +75 -0
- data/lib/leptris/xml.rb +1 -0
- data/lib/libleptris.so +0 -0
- data/vendor-src/libleptris/CHANGELOG.md +79 -0
- data/vendor-src/libleptris/CLAUDE.md +1 -1
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/README.adoc +26 -0
- data/vendor-src/libleptris/TODO.max-perf/2-3-oneshot-tokenizer-design.md +98 -0
- data/vendor-src/libleptris/cli/commands/validate.c +4 -2
- data/vendor-src/libleptris/docs/guide/parsing.md +30 -0
- data/vendor-src/libleptris/scripts/check_export_surface.py +20 -0
- data/vendor-src/libleptris/src/CMakeLists.txt +44 -1
- data/vendor-src/libleptris/src/include/leptris/descriptor.h +7 -1
- data/vendor-src/libleptris/src/include/leptris/dom/document.h +7 -1
- data/vendor-src/libleptris/src/include/leptris/dom/element.h +7 -1
- data/vendor-src/libleptris/src/include/leptris/dom/serialize.h +7 -1
- data/vendor-src/libleptris/src/include/leptris/dtd.h +46 -9
- data/vendor-src/libleptris/src/include/leptris/error.h +63 -1
- data/vendor-src/libleptris/src/include/leptris/html.h +79 -0
- data/vendor-src/libleptris/src/include/leptris/sax/sax.h +20 -1
- data/vendor-src/libleptris/src/include/leptris/types.h +29 -1
- data/vendor-src/libleptris/src/include/leptris/xpath/xpath.h +7 -1
- data/vendor-src/libleptris/src/include/leptris.h +59 -37
- data/vendor-src/libleptris/src/leptris/core.c +28 -0
- data/vendor-src/libleptris/src/leptris/dom/diag.h +2 -13
- data/vendor-src/libleptris/src/leptris/dom/digest.c +5 -1
- data/vendor-src/libleptris/src/leptris/dom/doctype.c +27 -0
- data/vendor-src/libleptris/src/leptris/dom/element.c +54 -9
- data/vendor-src/libleptris/src/leptris/dom/element.h +5 -0
- data/vendor-src/libleptris/src/leptris/dom/element_modify.c +46 -6
- data/vendor-src/libleptris/src/leptris/dtd/model.h +6 -0
- data/vendor-src/libleptris/src/leptris/dtd/parser.c +49 -12
- data/vendor-src/libleptris/src/leptris/error.c +22 -0
- data/vendor-src/libleptris/src/leptris/flat/direct_parse.c +61 -6
- data/vendor-src/libleptris/src/leptris/html/html_parse.c +156 -42
- data/vendor-src/libleptris/src/leptris/leptris.c +11 -2
- data/vendor-src/libleptris/src/leptris/leptris_internal.h +23 -1
- data/vendor-src/libleptris/src/leptris/sax/pull.c +62 -18
- data/vendor-src/libleptris/src/leptris/sax/sax_internal.h +7 -0
- data/vendor-src/libleptris/src/leptris/sax/streaming.c +155 -4
- data/vendor-src/libleptris/src/leptris/xpath/evaluator.c +19 -2
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +126 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +653 -151
- data/vendor-src/libleptris/src/leptris/xpath/parser.c +4 -2
- data/vendor-src/libleptris/src/leptris/xslt/xslt_functions.c +9 -5
- data/vendor-src/libleptris/test/dom/test_digest.cpp +36 -0
- data/vendor-src/libleptris/test/dom/test_dom.cpp +24 -0
- data/vendor-src/libleptris/test/dom/test_node_surface_parity.cpp +81 -0
- data/vendor-src/libleptris/test/dtd/test_dtd_validate.cpp +113 -0
- data/vendor-src/libleptris/test/html/test_html.cpp +51 -0
- data/vendor-src/libleptris/test/parser/test_parser.cpp +43 -0
- data/vendor-src/libleptris/test/sax/test_pull.cpp +32 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/replace.xml +865 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/string-join.xml +449 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/tokenize.xml +639 -0
- data/vendor-src/libleptris/test/xquery/test_qt3.cpp +74 -6
- data/vendor-src/libleptris/vcpkg.json +1 -1
- metadata +7 -1
|
@@ -303,6 +303,36 @@ void find_by_attribute(LeptrisElement parent,
|
|
|
303
303
|
}
|
|
304
304
|
```
|
|
305
305
|
|
|
306
|
+
## Parsing HTML
|
|
307
|
+
|
|
308
|
+
HTML is a first-class input: the WHATWG-conformant tolerant parser
|
|
309
|
+
(`leptris_parse_html_string`) plus a libxml2/Nokogiri-compatibility
|
|
310
|
+
mode (`leptris_parse_html4_string`), both declared in
|
|
311
|
+
`leptris/html.h`:
|
|
312
|
+
|
|
313
|
+
```c
|
|
314
|
+
#include "leptris/html.h"
|
|
315
|
+
|
|
316
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
317
|
+
LeptrisDocument doc =
|
|
318
|
+
leptris_parse_html_string("<p>Hello <b>world", 18, &st);
|
|
319
|
+
/* Implied end tags, void elements, raw-text <script>/<style>,
|
|
320
|
+
* minimized + unquoted attribute values, case-insensitive names and
|
|
321
|
+
* the HTML named-entity table are all handled. Malformed input
|
|
322
|
+
* never fails the parse — it degrades to text. The result
|
|
323
|
+
* serializes and queries (XPath/XSLT) like any XML document. */
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Choose the mode by contract:
|
|
327
|
+
|
|
328
|
+
| Function | Mode | Shape |
|
|
329
|
+
|----------|------|-------|
|
|
330
|
+
| `leptris_parse_html_string` | WHATWG | full html5lib-conformant tree construction |
|
|
331
|
+
| `leptris_parse_html4_string` | libxml2/Nokogiri | fragment shape: no synthesized `<html>/<head>/<body>`, no implied `<tbody>`; leading `<script>/<style>` content stays in `<body>` |
|
|
332
|
+
|
|
333
|
+
Memory: identical to XML — `leptris_document_free` releases
|
|
334
|
+
everything; input must be valid UTF-8.
|
|
335
|
+
|
|
306
336
|
## Performance Tips
|
|
307
337
|
|
|
308
338
|
1. **Use in-place parsing** for string data when possible
|
|
@@ -31,6 +31,22 @@ def declared_public_symbols(root: Path):
|
|
|
31
31
|
return names
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
def unmarked_public_declarations(root: Path):
|
|
35
|
+
"""Public-header leptris_* function declarations WITHOUT
|
|
36
|
+
LEPTRIS_API: they link fine into the static lib (the CLI works)
|
|
37
|
+
but never export for FFI consumers — the dtd.h class caught by
|
|
38
|
+
the ruby binding (#1183)."""
|
|
39
|
+
pat = re.compile(
|
|
40
|
+
r"^(?!LEPTRIS_API|static|typedef|struct|#|//|\*|/\*)(?:const\s+|unsigned\s+|struct\s+)*"
|
|
41
|
+
r"[A-Za-z_][\w\s\*]*?\b(leptris_[a-z_0-9]+)\s*\(",
|
|
42
|
+
flags=re.M,
|
|
43
|
+
)
|
|
44
|
+
found = set()
|
|
45
|
+
for h in (root / "src" / "include").rglob("*.h"):
|
|
46
|
+
for m in pat.finditer(h.read_text()):
|
|
47
|
+
found.add(m.group(1))
|
|
48
|
+
return found
|
|
49
|
+
|
|
34
50
|
def exported_symbols(lib: Path):
|
|
35
51
|
out = subprocess.run(
|
|
36
52
|
["nm", "-gU", str(lib)], capture_output=True, text=True, check=True
|
|
@@ -65,11 +81,15 @@ def main():
|
|
|
65
81
|
undeclared = sorted(exported - declared)
|
|
66
82
|
missing = sorted(declared - exported)
|
|
67
83
|
|
|
84
|
+
unmarked = sorted(unmarked_public_declarations(root) - declared)
|
|
85
|
+
|
|
68
86
|
failures = []
|
|
69
87
|
for n in undeclared:
|
|
70
88
|
failures.append(f"UNDECLARED EXPORT {n}: exported but absent from src/include/")
|
|
71
89
|
for n in missing:
|
|
72
90
|
failures.append(f"MISSING EXPORT {n}: declared public but not exported")
|
|
91
|
+
for n in unmarked:
|
|
92
|
+
failures.append(f"UNMARKED PUBLIC {n}: declared in a public header without LEPTRIS_API")
|
|
73
93
|
|
|
74
94
|
if failures:
|
|
75
95
|
print("EXPORT SURFACE DRIFT:")
|
|
@@ -156,8 +156,51 @@ if(LEPTRIS_AMALGAMATED)
|
|
|
156
156
|
|
|
157
157
|
# Append #include for every source. Paths are relative to src/ so the
|
|
158
158
|
# file's own #include directives resolve identically to the per-file build.
|
|
159
|
+
#
|
|
160
|
+
# Static helpers with the same name in different TUs collide once
|
|
161
|
+
# everything is one TU (#1217). The generator renames those tokens
|
|
162
|
+
# per file via #define around the #include — the source files stay
|
|
163
|
+
# untouched. A new collision surfaces as a conflicting-types error
|
|
164
|
+
# in the amalgamated CI job; add a line here.
|
|
165
|
+
set(_amalg_renames
|
|
166
|
+
"leptris/xpath/functions_exslt.c:arg_number=exslt_arg_number"
|
|
167
|
+
"leptris/xpath/functions_exslt.c:arg_string=exslt_arg_string"
|
|
168
|
+
"leptris/common/format_number.c:parse_pattern=fmt_num_parse_pattern"
|
|
169
|
+
"leptris/sax/iterparse.c:set_error=iterparse_set_error"
|
|
170
|
+
"leptris/xpath/vm.c:xpath_context_document=vm_xpath_context_document"
|
|
171
|
+
"leptris/xpath/xpath_public.c:xslt_register_ufn_handlers=xslt_register_ufn_handlers_impl"
|
|
172
|
+
"leptris/xslt/xslt_functions.c:xslt_register_ufn_handlers=xslt_register_ufn_handlers_impl"
|
|
173
|
+
"leptris/xslt/xslt_exec.c:utf8_encode=xslt_utf8_encode"
|
|
174
|
+
"leptris/xslt/xslt_exec.c:ws_only=xslt_ws_only"
|
|
175
|
+
"leptris/rng/validate.c:match_seq=rng_match_seq"
|
|
176
|
+
"leptris/sax/pull.c:cb_start_document=pull_cb_start_document"
|
|
177
|
+
"leptris/sax/pull.c:cb_end_document=pull_cb_end_document"
|
|
178
|
+
"leptris/sax/pull.c:cb_start_element=pull_cb_start_element"
|
|
179
|
+
"leptris/sax/pull.c:cb_end_element=pull_cb_end_element"
|
|
180
|
+
"leptris/sax/pull.c:cb_characters=pull_cb_characters"
|
|
181
|
+
"leptris/sax/pull.c:cb_comment=pull_cb_comment"
|
|
182
|
+
"leptris/sax/pull.c:cb_cdata=pull_cb_cdata"
|
|
183
|
+
"leptris/sax/pull.c:cb_pi=pull_cb_pi"
|
|
184
|
+
"leptris/sax/pull.c:cb_start_prefix=pull_cb_start_prefix"
|
|
185
|
+
"leptris/sax/pull.c:cb_end_prefix=pull_cb_end_prefix"
|
|
186
|
+
"leptris/sax/pull.c:cb_error=pull_cb_error"
|
|
187
|
+
)
|
|
159
188
|
foreach(_src ${LEPTRIS_SOURCES})
|
|
160
|
-
|
|
189
|
+
set(_amalg_defs "")
|
|
190
|
+
set(_amalg_undefs "")
|
|
191
|
+
foreach(_r ${_amalg_renames})
|
|
192
|
+
string(REPLACE ":" ";" _rr "${_r}")
|
|
193
|
+
string(REPLACE "=" ";" _rr "${_rr}")
|
|
194
|
+
list(GET _rr 0 _rfile)
|
|
195
|
+
list(GET _rr 1 _rold)
|
|
196
|
+
list(GET _rr 2 _rnew)
|
|
197
|
+
if(_rfile STREQUAL _src)
|
|
198
|
+
string(APPEND _amalg_defs "#define ${_rold} ${_rnew}\n")
|
|
199
|
+
string(APPEND _amalg_undefs "#undef ${_rold}\n")
|
|
200
|
+
endif()
|
|
201
|
+
endforeach()
|
|
202
|
+
file(APPEND "${LEPTRIS_AMALGAMATED_C}"
|
|
203
|
+
"${_amalg_defs}#include \"${_src}\"\n${_amalg_undefs}\n")
|
|
161
204
|
endforeach()
|
|
162
205
|
|
|
163
206
|
# Replace the source list with the amalgamated file so the object
|
|
@@ -31,7 +31,13 @@
|
|
|
31
31
|
#ifdef _WIN32
|
|
32
32
|
#define LEPTRIS_API
|
|
33
33
|
#else
|
|
34
|
-
|
|
34
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
35
|
+
#if defined(__GNUC__) && !defined(__clang__)
|
|
36
|
+
#define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
37
|
+
externally_visible))
|
|
38
|
+
#else
|
|
39
|
+
#define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
40
|
+
#endif
|
|
35
41
|
#endif
|
|
36
42
|
#endif
|
|
37
43
|
|
|
@@ -32,7 +32,13 @@ extern "C" {
|
|
|
32
32
|
# define LEPTRIS_API
|
|
33
33
|
# endif
|
|
34
34
|
# else
|
|
35
|
-
|
|
35
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
36
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
37
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
38
|
+
externally_visible))
|
|
39
|
+
# else
|
|
40
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
41
|
+
# endif
|
|
36
42
|
# endif
|
|
37
43
|
#endif
|
|
38
44
|
|
|
@@ -32,7 +32,13 @@ extern "C" {
|
|
|
32
32
|
# define LEPTRIS_API
|
|
33
33
|
# endif
|
|
34
34
|
# else
|
|
35
|
-
|
|
35
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
36
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
37
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
38
|
+
externally_visible))
|
|
39
|
+
# else
|
|
40
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
41
|
+
# endif
|
|
36
42
|
# endif
|
|
37
43
|
#endif
|
|
38
44
|
|
|
@@ -31,7 +31,13 @@ extern "C" {
|
|
|
31
31
|
# define LEPTRIS_API
|
|
32
32
|
# endif
|
|
33
33
|
# else
|
|
34
|
-
|
|
34
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
35
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
36
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
37
|
+
externally_visible))
|
|
38
|
+
# else
|
|
39
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
40
|
+
# endif
|
|
35
41
|
# endif
|
|
36
42
|
#endif
|
|
37
43
|
|
|
@@ -10,6 +10,39 @@
|
|
|
10
10
|
|
|
11
11
|
#include <stddef.h>
|
|
12
12
|
|
|
13
|
+
/* Export macro: mirrors leptris.h/sax.h so dtd.h is includable
|
|
14
|
+
* standalone (bindings include sub-headers directly). See TODO 80. */
|
|
15
|
+
/* Export macro. Defined fully in leptris.h; sax.h allows standalone
|
|
16
|
+
* inclusion (leptris.h is not required) so we mirror the same logic.
|
|
17
|
+
* See TODO 80 (visibility preset) and TODO 122 (SAX surface). */
|
|
18
|
+
#ifndef LEPTRIS_API
|
|
19
|
+
# ifdef LEPTRIS_FOR_BINDGEN
|
|
20
|
+
# define LEPTRIS_API
|
|
21
|
+
# elif defined(_WIN32)
|
|
22
|
+
# ifdef LEPTRIS_BUILD_SHARED
|
|
23
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
24
|
+
# elif defined(LEPTRIS_BUILDING_DLL)
|
|
25
|
+
/* Mirrors leptris.h (issue #278): CMake defines
|
|
26
|
+
* LEPTRIS_BUILDING_DLL on the objects that build the DLL. */
|
|
27
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
28
|
+
# elif defined(LEPTRIS_USE_SHARED)
|
|
29
|
+
# define LEPTRIS_API __declspec(dllimport)
|
|
30
|
+
# else
|
|
31
|
+
# define LEPTRIS_API
|
|
32
|
+
# endif
|
|
33
|
+
# else
|
|
34
|
+
/* Mirrors leptris.h: GCC LTO needs externally_visible or it
|
|
35
|
+
* internalizes public symbols with no in-library caller
|
|
36
|
+
* (#1154/#1196/#1204 class). */
|
|
37
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
38
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
39
|
+
externally_visible))
|
|
40
|
+
# else
|
|
41
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
42
|
+
# endif
|
|
43
|
+
# endif
|
|
44
|
+
#endif
|
|
45
|
+
|
|
13
46
|
#ifdef __cplusplus
|
|
14
47
|
extern "C" {
|
|
15
48
|
#endif
|
|
@@ -57,7 +90,7 @@ typedef struct {
|
|
|
57
90
|
*
|
|
58
91
|
* Memory: Caller must free with leptris_dtd_free()
|
|
59
92
|
*/
|
|
60
|
-
LeptrisDTD* leptris_dtd_parse(const char* dtd_content, size_t len);
|
|
93
|
+
LEPTRIS_API LeptrisDTD* leptris_dtd_parse(const char* dtd_content, size_t len);
|
|
61
94
|
|
|
62
95
|
/**
|
|
63
96
|
* Get the document's DTD (the declarations parsed from the DOCTYPE
|
|
@@ -101,7 +134,7 @@ LEPTRIS_API LeptrisDTD* leptris_document_get_dtd(LeptrisDocument doc);
|
|
|
101
134
|
* leptris_dtd_parse_external_subset(dtd, buffer, len);
|
|
102
135
|
* int valid = leptris_dtd_validate(doc, dtd, &error);
|
|
103
136
|
*/
|
|
104
|
-
int leptris_dtd_parse_external_subset(LeptrisDTD* dtd, const char* content,
|
|
137
|
+
LEPTRIS_API int leptris_dtd_parse_external_subset(LeptrisDTD* dtd, const char* content,
|
|
105
138
|
size_t len);
|
|
106
139
|
|
|
107
140
|
/**
|
|
@@ -112,9 +145,12 @@ int leptris_dtd_parse_external_subset(LeptrisDTD* dtd, const char* content,
|
|
|
112
145
|
* this loader for the resource named by the system id. Same pattern
|
|
113
146
|
* as leptris_dtd_parse_external_subset: the library never does I/O.
|
|
114
147
|
*
|
|
115
|
-
* The loader returns a
|
|
116
|
-
*
|
|
117
|
-
* "unavailable" (the reference is then skipped, leniently).
|
|
148
|
+
* The loader returns a buffer in *out_len bytes, which the parser
|
|
149
|
+
* consumes and frees through the engine's allocator; return NULL
|
|
150
|
+
* for "unavailable" (the reference is then skipped, leniently).
|
|
151
|
+
* FFI loaders MUST allocate the buffer with leptris_alloc_buffer
|
|
152
|
+
* (#1219) so allocator/CRT mismatches cannot corrupt the heap —
|
|
153
|
+
* in-process C loaders may keep using plain malloc.
|
|
118
154
|
*
|
|
119
155
|
* The loader is consulted when DTD CONTENT IS PARSED — register it
|
|
120
156
|
* before leptris_dtd_parse_external_subset (or before parsing a
|
|
@@ -126,7 +162,7 @@ int leptris_dtd_parse_external_subset(LeptrisDTD* dtd, const char* content,
|
|
|
126
162
|
* @param loader Callback (NULL clears it)
|
|
127
163
|
* @param user_data Opaque pointer handed to the loader
|
|
128
164
|
*/
|
|
129
|
-
void leptris_dtd_set_pe_loader(LeptrisDTD* dtd,
|
|
165
|
+
LEPTRIS_API void leptris_dtd_set_pe_loader(LeptrisDTD* dtd,
|
|
130
166
|
char* (*loader)(void* user_data,
|
|
131
167
|
const char* system_id,
|
|
132
168
|
size_t* out_len),
|
|
@@ -153,14 +189,15 @@ void leptris_dtd_set_pe_loader(LeptrisDTD* dtd,
|
|
|
153
189
|
* leptris_dtd_error_free(&error);
|
|
154
190
|
* }
|
|
155
191
|
*/
|
|
156
|
-
int leptris_dtd_validate(LeptrisDocument doc, LeptrisDTD* dtd,
|
|
192
|
+
LEPTRIS_API int leptris_dtd_validate(LeptrisDocument doc, LeptrisDTD* dtd,
|
|
193
|
+
LeptrisDTDError* error);
|
|
157
194
|
|
|
158
195
|
/**
|
|
159
196
|
* Free DTD object
|
|
160
197
|
*
|
|
161
198
|
* @param dtd DTD to free (can be NULL)
|
|
162
199
|
*/
|
|
163
|
-
void leptris_dtd_free(LeptrisDTD* dtd);
|
|
200
|
+
LEPTRIS_API void leptris_dtd_free(LeptrisDTD* dtd);
|
|
164
201
|
|
|
165
202
|
/**
|
|
166
203
|
* Free DTD error
|
|
@@ -169,7 +206,7 @@ void leptris_dtd_free(LeptrisDTD* dtd);
|
|
|
169
206
|
*
|
|
170
207
|
* @param error Error to free (can be NULL)
|
|
171
208
|
*/
|
|
172
|
-
void leptris_dtd_error_free(LeptrisDTDError* error);
|
|
209
|
+
LEPTRIS_API void leptris_dtd_error_free(LeptrisDTDError* error);
|
|
173
210
|
|
|
174
211
|
#ifdef __cplusplus
|
|
175
212
|
}
|
|
@@ -19,7 +19,13 @@
|
|
|
19
19
|
# define LEPTRIS_API __declspec(dllimport)
|
|
20
20
|
# endif
|
|
21
21
|
# else
|
|
22
|
-
|
|
22
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
23
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
24
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
25
|
+
externally_visible))
|
|
26
|
+
# else
|
|
27
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
28
|
+
# endif
|
|
23
29
|
# endif
|
|
24
30
|
#endif
|
|
25
31
|
|
|
@@ -90,6 +96,62 @@ LEPTRIS_API void leptris_last_error_position(int* line, int* column);
|
|
|
90
96
|
*/
|
|
91
97
|
LEPTRIS_API const char* leptris_document_last_error(LeptrisDocument doc);
|
|
92
98
|
|
|
99
|
+
/* ============================================================================
|
|
100
|
+
* Parse diagnostics (#1200): recover-class events recorded on the
|
|
101
|
+
* DOM parse (duplicate attributes today) — the SAX lane's recover
|
|
102
|
+
* error list, unified engine-side so both lanes report the same
|
|
103
|
+
* surface. Documents stay usable; the diagnostics are advisory.
|
|
104
|
+
* ============================================================================ */
|
|
105
|
+
|
|
106
|
+
#ifndef LEPTRIS_API
|
|
107
|
+
# ifdef _WIN32
|
|
108
|
+
# ifdef LEPTRIS_BUILD_SHARED
|
|
109
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
110
|
+
# elif defined(LEPTRIS_BUILDING_DLL)
|
|
111
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
112
|
+
# elif defined(LEPTRIS_USE_SHARED)
|
|
113
|
+
# define LEPTRIS_API __declspec(dllimport)
|
|
114
|
+
# else
|
|
115
|
+
# define LEPTRIS_API
|
|
116
|
+
# endif
|
|
117
|
+
# else
|
|
118
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
119
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
120
|
+
externally_visible))
|
|
121
|
+
# else
|
|
122
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
123
|
+
# endif
|
|
124
|
+
# endif
|
|
125
|
+
#endif
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Number of recover-class diagnostics recorded during the
|
|
129
|
+
* document's parse.
|
|
130
|
+
*
|
|
131
|
+
* @param doc Document handle
|
|
132
|
+
* @return Diagnostic count (0 for NULL doc or a clean parse)
|
|
133
|
+
*/
|
|
134
|
+
LEPTRIS_API size_t leptris_document_parse_diag_count(LeptrisDocument doc);
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Read one parse diagnostic by index.
|
|
138
|
+
*
|
|
139
|
+
* @param doc Document handle
|
|
140
|
+
* @param index Diagnostic index (< leptris_document_parse_diag_count)
|
|
141
|
+
* @param kind Out: diagnostic kind (may be NULL)
|
|
142
|
+
* @param message Out: NUL-terminated message buffer (may be NULL)
|
|
143
|
+
* @param message_cap Capacity of message (ignored when message NULL)
|
|
144
|
+
* @return 1 on success; 0 for NULL doc or out-of-range index
|
|
145
|
+
*
|
|
146
|
+
* Memory: Message is copied into the caller's buffer; diagnostics
|
|
147
|
+
* are owned by the document until leptris_document_free.
|
|
148
|
+
*/
|
|
149
|
+
LEPTRIS_API int leptris_document_parse_diag(LeptrisDocument doc,
|
|
150
|
+
size_t index,
|
|
151
|
+
LeptrisDiagKind* kind,
|
|
152
|
+
char* message,
|
|
153
|
+
size_t message_cap);
|
|
154
|
+
|
|
93
155
|
#ifdef __cplusplus
|
|
94
156
|
}
|
|
95
157
|
#endif
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#ifndef LEPTRIS_HTML_H
|
|
2
|
+
#define LEPTRIS_HTML_H
|
|
3
|
+
|
|
4
|
+
/* ============================================================================
|
|
5
|
+
* HTML parsing (issue #659) — the WHATWG-conformant engine plus the
|
|
6
|
+
* libxml2/Nokogiri-compatibility mode. Split out of leptris.h so the
|
|
7
|
+
* HTML surface is discoverable as a subsystem (TODO 99 convention:
|
|
8
|
+
* headers split by subsystem; bindings include sub-headers directly).
|
|
9
|
+
* ============================================================================ */
|
|
10
|
+
|
|
11
|
+
#include <stddef.h>
|
|
12
|
+
#include "types.h"
|
|
13
|
+
|
|
14
|
+
/* Export macro: mirrors leptris.h/sax.h so html.h is includable
|
|
15
|
+
* standalone. See TODO 80 (visibility preset). */
|
|
16
|
+
#ifndef LEPTRIS_API
|
|
17
|
+
# ifdef LEPTRIS_FOR_BINDGEN
|
|
18
|
+
# define LEPTRIS_API
|
|
19
|
+
# elif defined(_WIN32)
|
|
20
|
+
# ifdef LEPTRIS_BUILD_SHARED
|
|
21
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
22
|
+
# elif defined(LEPTRIS_BUILDING_DLL)
|
|
23
|
+
# define LEPTRIS_API __declspec(dllexport)
|
|
24
|
+
# elif defined(LEPTRIS_USE_SHARED)
|
|
25
|
+
# define LEPTRIS_API __declspec(dllimport)
|
|
26
|
+
# else
|
|
27
|
+
# define LEPTRIS_API
|
|
28
|
+
# endif
|
|
29
|
+
# else
|
|
30
|
+
# define LEPTRIS_API __attribute__((visibility("default")))
|
|
31
|
+
# endif
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
#ifdef __cplusplus
|
|
35
|
+
extern "C" {
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parse an HTML string into a document (issue #659)
|
|
40
|
+
*
|
|
41
|
+
* Tolerant HTML4/5 parse into the standard DOM: implied end tags
|
|
42
|
+
* (p/li/td/tr/th/dt/dd/option/...), void elements, raw-text
|
|
43
|
+
* <script>/<style>, minimized + unquoted attribute values,
|
|
44
|
+
* case-insensitive tag/attribute names, and the HTML named-entity
|
|
45
|
+
* table. Behaviors follow libxml2's HTMLparser as exposed by
|
|
46
|
+
* Nokogiri (fragment shape: no synthesized <html>/<head>/<body>,
|
|
47
|
+
* no implied <tbody>). Malformed input never fails the parse — it
|
|
48
|
+
* degrades to text; a document with no nodes at all is an error.
|
|
49
|
+
* The result serializes and queries (XPath/XSLT) like any
|
|
50
|
+
* libleptris document.
|
|
51
|
+
*
|
|
52
|
+
* @param html HTML input (must be valid UTF-8)
|
|
53
|
+
* @param length Length of input in bytes
|
|
54
|
+
* @param status Output status code (can be NULL)
|
|
55
|
+
* @return Document handle or NULL on error
|
|
56
|
+
*
|
|
57
|
+
* Memory: Caller must call leptris_document_free() when done
|
|
58
|
+
* Thread safety: Not thread-safe. One document per thread.
|
|
59
|
+
*/
|
|
60
|
+
LEPTRIS_API LeptrisDocument leptris_parse_html_string(const char* html,
|
|
61
|
+
size_t length,
|
|
62
|
+
LeptrisStatus* status);
|
|
63
|
+
|
|
64
|
+
/* HTML4/libxml2-compatibility mode (#659): identical tolerant
|
|
65
|
+
* tokenizer and Nokogiri document shape, except leading
|
|
66
|
+
* script/style content stays in <body> (libxml2's shape —
|
|
67
|
+
* title/meta/link/base still lift into the implied head). Bindings
|
|
68
|
+
* that must match Nokogiri byte-for-byte pin this entry;
|
|
69
|
+
* leptris_parse_html_string is the WHATWG-conformant engine.
|
|
70
|
+
* Memory contract identical to leptris_parse_html_string. */
|
|
71
|
+
LEPTRIS_API LeptrisDocument leptris_parse_html4_string(const char* html,
|
|
72
|
+
size_t length,
|
|
73
|
+
LeptrisStatus* status);
|
|
74
|
+
|
|
75
|
+
#ifdef __cplusplus
|
|
76
|
+
}
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
#endif /* LEPTRIS_HTML_H */
|
|
@@ -31,7 +31,15 @@
|
|
|
31
31
|
# define LEPTRIS_API
|
|
32
32
|
# endif
|
|
33
33
|
# else
|
|
34
|
-
|
|
34
|
+
/* Mirrors leptris.h: GCC LTO needs externally_visible or it
|
|
35
|
+
* internalizes public symbols with no in-library caller
|
|
36
|
+
* (#1154/#1196/#1204 class). */
|
|
37
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
38
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
39
|
+
externally_visible))
|
|
40
|
+
# else
|
|
41
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
42
|
+
# endif
|
|
35
43
|
# endif
|
|
36
44
|
#endif
|
|
37
45
|
|
|
@@ -293,6 +301,17 @@ LEPTRIS_API void leptris_sax_parser_free(LeptrisSAXParser* parser);
|
|
|
293
301
|
*/
|
|
294
302
|
LEPTRIS_API int leptris_sax_parser_set_streaming(LeptrisSAXParser* parser, int streaming);
|
|
295
303
|
|
|
304
|
+
/**
|
|
305
|
+
* Mark the input as one-shot: the whole document arrives in a
|
|
306
|
+
* single feed() and stays alive for the parser's lifetime. The
|
|
307
|
+
* tokenizer then uses in-place scans with single-copy name storage
|
|
308
|
+
* instead of the chunk-safe carry paths. No effect on correctness
|
|
309
|
+
* for any conforming caller; only enable when the input truly is
|
|
310
|
+
* one-shot (leptris_pull_new does this for its memory source).
|
|
311
|
+
*/
|
|
312
|
+
LEPTRIS_API void leptris_sax_parser_set_one_shot(LeptrisSAXParser* parser,
|
|
313
|
+
int one_shot);
|
|
314
|
+
|
|
296
315
|
/* ============================================================================
|
|
297
316
|
* Pull (StAX-style) API — TODO.bindings/04, issue #510 Tier 2
|
|
298
317
|
* ============================================================================ */
|
|
@@ -246,6 +246,28 @@ typedef enum {
|
|
|
246
246
|
LEPTRIS_DIFF_IGNORE_WS_TEXT = 1u
|
|
247
247
|
} LeptrisDiffFlags;
|
|
248
248
|
|
|
249
|
+
/* Unified narration record kinds (#1126). One structured record
|
|
250
|
+
* per validation/recover event, shared by every validator (RNG
|
|
251
|
+
* today; XSD/Schematron follow) and the DOM parse's recover
|
|
252
|
+
* channel (#1200). The kind selects the reporting convention;
|
|
253
|
+
* append-only. */
|
|
254
|
+
typedef enum {
|
|
255
|
+
LEPTRIS_DIAG_INVALID = 0,
|
|
256
|
+
LEPTRIS_DIAG_NOT_ALLOWED_ANYWHERE, /* name never valid in model */
|
|
257
|
+
LEPTRIS_DIAG_NOT_ALLOWED_HERE, /* valid name, wrong position */
|
|
258
|
+
LEPTRIS_DIAG_NOT_ALLOWED_YET, /* later; missing required first */
|
|
259
|
+
LEPTRIS_DIAG_INCOMPLETE, /* content ends before required */
|
|
260
|
+
LEPTRIS_DIAG_MISSING_REQUIRED_ATTR,
|
|
261
|
+
LEPTRIS_DIAG_ATTR_NOT_ALLOWED,
|
|
262
|
+
LEPTRIS_DIAG_ATTR_VALUE_INVALID,
|
|
263
|
+
LEPTRIS_DIAG_CHAR_CONTENT_INVALID, /* data/value/list mismatch */
|
|
264
|
+
/* Recover-class parse event: the document is usable, the input
|
|
265
|
+
* was not conformant (duplicate attribute, ...). Not a model
|
|
266
|
+
* error; SAX-lane "recover" parity (#1200). */
|
|
267
|
+
LEPTRIS_DIAG_RECOVER,
|
|
268
|
+
LEPTRIS_DIAG_COUNT_
|
|
269
|
+
} LeptrisDiagKind;
|
|
270
|
+
|
|
249
271
|
/* Subtree digest flags (issue #869). The digest is content-defined
|
|
250
272
|
* (no pointers/addresses — stable across processes); equality
|
|
251
273
|
* implies subtree equivalence under the flag semantics. */
|
|
@@ -253,7 +275,13 @@ typedef enum {
|
|
|
253
275
|
LEPTRIS_DIGEST_DEFAULT = 0,
|
|
254
276
|
/* Skip whitespace-only text nodes entirely (comparator's
|
|
255
277
|
* strip-profile default). */
|
|
256
|
-
LEPTRIS_DIGEST_DROP_WS_TEXT = 1u
|
|
278
|
+
LEPTRIS_DIGEST_DROP_WS_TEXT = 1u,
|
|
279
|
+
/* Hash attributes in DOCUMENT order instead of the sorted
|
|
280
|
+
* canonical order — documents differing only in attribute
|
|
281
|
+
* order digest DIFFERENT under this flag (canon's verbose
|
|
282
|
+
* diff gate, #1200). Equality under this flag additionally
|
|
283
|
+
* implies attribute-order identity. */
|
|
284
|
+
LEPTRIS_DIGEST_ATTR_ORDER = 2u
|
|
257
285
|
} LeptrisDigestFlags;
|
|
258
286
|
|
|
259
287
|
typedef struct {
|
|
@@ -31,7 +31,13 @@ extern "C" {
|
|
|
31
31
|
# define LEPTRIS_API
|
|
32
32
|
# endif
|
|
33
33
|
# else
|
|
34
|
-
|
|
34
|
+
/* Mirrors leptris.h (GCC LTO externalization, #1204). */
|
|
35
|
+
# if defined(__GNUC__) && !defined(__clang__)
|
|
36
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used, \
|
|
37
|
+
externally_visible))
|
|
38
|
+
# else
|
|
39
|
+
# define LEPTRIS_API __attribute__((visibility("default"), used))
|
|
40
|
+
# endif
|
|
35
41
|
# endif
|
|
36
42
|
#endif
|
|
37
43
|
|