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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/Rakefile +8 -2
  4. data/lib/leptris/version.rb +1 -1
  5. data/lib/leptris/xml/document.rb +25 -0
  6. data/lib/leptris/xml/dtd.rb +113 -0
  7. data/lib/leptris/xml/ffi.rb +75 -0
  8. data/lib/leptris/xml.rb +1 -0
  9. data/lib/libleptris.so +0 -0
  10. data/vendor-src/libleptris/CHANGELOG.md +79 -0
  11. data/vendor-src/libleptris/CLAUDE.md +1 -1
  12. data/vendor-src/libleptris/CMakeLists.txt +1 -1
  13. data/vendor-src/libleptris/README.adoc +26 -0
  14. data/vendor-src/libleptris/TODO.max-perf/2-3-oneshot-tokenizer-design.md +98 -0
  15. data/vendor-src/libleptris/cli/commands/validate.c +4 -2
  16. data/vendor-src/libleptris/docs/guide/parsing.md +30 -0
  17. data/vendor-src/libleptris/scripts/check_export_surface.py +20 -0
  18. data/vendor-src/libleptris/src/CMakeLists.txt +44 -1
  19. data/vendor-src/libleptris/src/include/leptris/descriptor.h +7 -1
  20. data/vendor-src/libleptris/src/include/leptris/dom/document.h +7 -1
  21. data/vendor-src/libleptris/src/include/leptris/dom/element.h +7 -1
  22. data/vendor-src/libleptris/src/include/leptris/dom/serialize.h +7 -1
  23. data/vendor-src/libleptris/src/include/leptris/dtd.h +46 -9
  24. data/vendor-src/libleptris/src/include/leptris/error.h +63 -1
  25. data/vendor-src/libleptris/src/include/leptris/html.h +79 -0
  26. data/vendor-src/libleptris/src/include/leptris/sax/sax.h +20 -1
  27. data/vendor-src/libleptris/src/include/leptris/types.h +29 -1
  28. data/vendor-src/libleptris/src/include/leptris/xpath/xpath.h +7 -1
  29. data/vendor-src/libleptris/src/include/leptris.h +59 -37
  30. data/vendor-src/libleptris/src/leptris/core.c +28 -0
  31. data/vendor-src/libleptris/src/leptris/dom/diag.h +2 -13
  32. data/vendor-src/libleptris/src/leptris/dom/digest.c +5 -1
  33. data/vendor-src/libleptris/src/leptris/dom/doctype.c +27 -0
  34. data/vendor-src/libleptris/src/leptris/dom/element.c +54 -9
  35. data/vendor-src/libleptris/src/leptris/dom/element.h +5 -0
  36. data/vendor-src/libleptris/src/leptris/dom/element_modify.c +46 -6
  37. data/vendor-src/libleptris/src/leptris/dtd/model.h +6 -0
  38. data/vendor-src/libleptris/src/leptris/dtd/parser.c +49 -12
  39. data/vendor-src/libleptris/src/leptris/error.c +22 -0
  40. data/vendor-src/libleptris/src/leptris/flat/direct_parse.c +61 -6
  41. data/vendor-src/libleptris/src/leptris/html/html_parse.c +156 -42
  42. data/vendor-src/libleptris/src/leptris/leptris.c +11 -2
  43. data/vendor-src/libleptris/src/leptris/leptris_internal.h +23 -1
  44. data/vendor-src/libleptris/src/leptris/sax/pull.c +62 -18
  45. data/vendor-src/libleptris/src/leptris/sax/sax_internal.h +7 -0
  46. data/vendor-src/libleptris/src/leptris/sax/streaming.c +155 -4
  47. data/vendor-src/libleptris/src/leptris/xpath/evaluator.c +19 -2
  48. data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +126 -0
  49. data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +653 -151
  50. data/vendor-src/libleptris/src/leptris/xpath/parser.c +4 -2
  51. data/vendor-src/libleptris/src/leptris/xslt/xslt_functions.c +9 -5
  52. data/vendor-src/libleptris/test/dom/test_digest.cpp +36 -0
  53. data/vendor-src/libleptris/test/dom/test_dom.cpp +24 -0
  54. data/vendor-src/libleptris/test/dom/test_node_surface_parity.cpp +81 -0
  55. data/vendor-src/libleptris/test/dtd/test_dtd_validate.cpp +113 -0
  56. data/vendor-src/libleptris/test/html/test_html.cpp +51 -0
  57. data/vendor-src/libleptris/test/parser/test_parser.cpp +43 -0
  58. data/vendor-src/libleptris/test/sax/test_pull.cpp +32 -0
  59. data/vendor-src/libleptris/test/xquery/qt3/fn/replace.xml +865 -0
  60. data/vendor-src/libleptris/test/xquery/qt3/fn/string-join.xml +449 -0
  61. data/vendor-src/libleptris/test/xquery/qt3/fn/tokenize.xml +639 -0
  62. data/vendor-src/libleptris/test/xquery/test_qt3.cpp +74 -6
  63. data/vendor-src/libleptris/vcpkg.json +1 -1
  64. 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
- file(APPEND "${LEPTRIS_AMALGAMATED_C}" "#include \"${_src}\"\n")
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
- #define LEPTRIS_API __attribute__((visibility("default")))
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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 malloc'd (or calloc'd) buffer in *out_len
116
- * bytes, which the parser consumes and frees; return NULL for
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, LeptrisDTDError* error);
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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
- # define LEPTRIS_API __attribute__((visibility("default")))
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