Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Respect "ignore" return value from recover script in case of END_EVENT, enabling to get further recover calls for other missing mandantory content particle of the current content model. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | wip |
Files: | files | file ages | folders |
SHA3-256: |
42c54de7e79319352b81b9bd2a21cfd3 |
User & Date: | rolf 2020-07-30 13:16:46 |
Context
2020-07-30
| ||
14:33 | Integrated further improvements and features to recovering. check-in: 0e98933aa6 user: rolf tags: schema | |
13:16 | Respect "ignore" return value from recover script in case of END_EVENT, enabling to get further recover calls for other missing mandantory content particle of the current content model. Closed-Leaf check-in: 42c54de7e7 user: rolf tags: wip | |
2020-07-23
| ||
23:50 | Merged from schema. check-in: 227e773285 user: rolf tags: wip | |
Changes
Changes to generic/schema.c.
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 ... 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 .... 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 .... 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 .... 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 .... 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 .... 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 .... 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 |
ac += + 1; \ hm = 0; \ } \ #define updateStack(sdata,se,ac) \ if (!(sdata->recoverFlags & RECOVER_FLAG_REWIND)) { \ se->activeChild = ac; \ se->hasMatched = 1; \ } \ #ifndef TCL_THREADS SchemaData * tdomGetSchemadata (Tcl_Interp *interp) { ................................................................................ static void pushToStack ( SchemaData *sdata, SchemaCP *pattern ) { SchemaValidationStack *se, *nextse; DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern)); if (pattern->type == SCHEMA_CTYPE_NAME && sdata->lastMatchse) { se = sdata->lastMatchse; while (se) { nextse = se->down; repoolStackElement (sdata, se); se = nextse; ................................................................................ if (reqAttr != cp->numReqAttr) { SetResult ("Missing mandatory attribute(s)"); return TCL_ERROR; } return TCL_OK; } static int checkElementEnd ( Tcl_Interp *interp, SchemaData *sdata ) { SchemaValidationStack *se; SchemaCP *cp, *ic; ................................................................................ if (ac < cp->nc && (hasMatched (cp->quants[ac], hm))) { DBG(fprintf (stderr, "ac %d has matched, skiping to next ac\n", ac)); ac++; hm = 0; } while (ac < cp->nc) { DBG(fprintf (stderr, "ac %d hm %d mayMiss: %d\n", ac, hm, mayMiss (cp->quants[ac]))); if (se->interleaveState) { if (se->interleaveState[ac]) { ac++; continue; } } if (mayMiss (cp->quants[ac])) { ac++; continue; } switch (cp->content[ac]->type) { case SCHEMA_CTYPE_KEYSPACE_END: /* Don't happen as INTERLEAVE child */ ................................................................................ if (recursivePattern (se, ic)) { thismayskip = 1; break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, ic); if (checkElementEnd (interp, sdata)) { thismayskip = 1; } popStack (sdata); break; case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: ................................................................................ if (thismayskip) break; } if (thismayskip) break; if (!recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { return 0; } break; case SCHEMA_CTYPE_VIRTUAL: if (evalVirtual (interp, sdata, ac)) break; else return 0; case SCHEMA_CTYPE_PATTERN: ................................................................................ if (recursivePattern (se, cp->content[ac])) { break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, cp->content[ac]); rc = checkElementEnd (interp, sdata); popStack (sdata); if (rc) break; if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { break; } return 0; case SCHEMA_CTYPE_ANY: case SCHEMA_CTYPE_NAME: if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { break; } return 0; } ac++; } if (se->interleaveState) { ................................................................................ SetResult ("No validation started"); return TCL_ERROR; } if (sdata->validationState == VALIDATION_ERROR) { return TCL_ERROR; } rc = checkElementEnd (interp, sdata); while (rc == -1) { popStack (sdata); rc = checkElementEnd (interp, sdata); } sdata->recoverFlags &= ~RECOVER_FLAG_DONT_REPORT; if (rc) { popStack (sdata); if (sdata->stack == NULL) { /* End of the first pattern (the tree root) without error. */ /* Check for unknown ID references */ if (!checkDocKeys (interp, sdata)) { return TCL_ERROR; } /* We have successfully finished validation */ sdata->validationState = VALIDATION_FINISHED; } DBG( fprintf(stderr, "probeElementEnd: _CAN_ end here.\n"); serializeStack (sdata); ); return TCL_OK; } SetResultV ("Missing mandatory content"); sdata->validationState = VALIDATION_ERROR; DBG( fprintf(stderr, "probeElementEnd: CAN'T end here.\n"); serializeStack (sdata); ); |
| | < > > > > > > > > > > > > > > > | < | < | > > > > > | < > > > | | > > > > > | | > | > > > > > > > > > > > > | | | | | | | > > > > | | | | | | | | | | | | | | | > > |
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 ... 976 977 978 979 980 981 982 983 984 985 986 987 988 989 .... 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 .... 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 .... 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 .... 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 .... 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 .... 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 |
ac += + 1; \ hm = 0; \ } \ #define updateStack(sdata,se,ac) \ if (!(sdata->recoverFlags & RECOVER_FLAG_REWIND)) { \ se->activeChild = ac; \ se->hasMatched = 1; \ } \ #ifndef TCL_THREADS SchemaData * tdomGetSchemadata (Tcl_Interp *interp) { ................................................................................ static void pushToStack ( SchemaData *sdata, SchemaCP *pattern ) { SchemaValidationStack *se, *nextse; DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern)); if (pattern->type == SCHEMA_CTYPE_NAME && sdata->lastMatchse) { se = sdata->lastMatchse; while (se) { nextse = se->down; repoolStackElement (sdata, se); se = nextse; ................................................................................ if (reqAttr != cp->numReqAttr) { SetResult ("Missing mandatory attribute(s)"); return TCL_ERROR; } return TCL_OK; } /* Returns either -1, 0, 1, 2 -1 means a pattern or an interleave ended may end, look further at parents next sibling. 0 means rewind with validation error. 1 means element content may end here. 2 means recovering requested further error reporting about missing childs in the current element. To be able to to answer a [info expected] on the occasion of the next error, we update the stack in this case and let probeElementEnd restart checkElementEnd again with this stack state. */ static int checkElementEnd ( Tcl_Interp *interp, SchemaData *sdata ) { SchemaValidationStack *se; SchemaCP *cp, *ic; ................................................................................ if (ac < cp->nc && (hasMatched (cp->quants[ac], hm))) { DBG(fprintf (stderr, "ac %d has matched, skiping to next ac\n", ac)); ac++; hm = 0; } while (ac < cp->nc) { DBG(fprintf (stderr, "ac %d hm %d mayMiss: %d\n", ac, hm, mayMiss (cp->quants[ac]))); if (se->interleaveState && se->interleaveState[ac]) { ac++; continue; } if (mayMiss (cp->quants[ac])) { ac++; continue; } switch (cp->content[ac]->type) { case SCHEMA_CTYPE_KEYSPACE_END: /* Don't happen as INTERLEAVE child */ ................................................................................ if (recursivePattern (se, ic)) { thismayskip = 1; break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, ic); if (checkElementEnd (interp, sdata) == -1) { thismayskip = 1; } popStack (sdata); break; case SCHEMA_CTYPE_KEYSPACE_END: case SCHEMA_CTYPE_KEYSPACE: ................................................................................ if (thismayskip) break; } if (thismayskip) break; if (!recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { return 0; } if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; case SCHEMA_CTYPE_VIRTUAL: if (evalVirtual (interp, sdata, ac)) break; else return 0; case SCHEMA_CTYPE_PATTERN: ................................................................................ if (recursivePattern (se, cp->content[ac])) { break; } /* fall throu */ case SCHEMA_CTYPE_INTERLEAVE: pushToStack (sdata, cp->content[ac]); rc = checkElementEnd (interp, sdata); if (rc == 0) { popStack (sdata); if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME || sdata->stack->activeChild || sdata->stack->hasMatched) { if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; } } return 0; } if (rc == 2) { updateStack (sdata, se, ac); return 2; } popStack (sdata); break; case SCHEMA_CTYPE_ANY: case SCHEMA_CTYPE_NAME: if (recover (interp, sdata, MISSING_ELEMENT_MATCH_END, NULL, NULL, NULL, 0)) { if (sdata->recoverFlags & RECOVER_FLAG_MATCH_END_CONTINUE) { updateStack (sdata, se, ac); return 2; } break; } return 0; } ac++; } if (se->interleaveState) { ................................................................................ SetResult ("No validation started"); return TCL_ERROR; } if (sdata->validationState == VALIDATION_ERROR) { return TCL_ERROR; } while (1) { rc = checkElementEnd (interp, sdata); while (rc == -1) { popStack (sdata); rc = checkElementEnd (interp, sdata); } sdata->recoverFlags &= ~RECOVER_FLAG_DONT_REPORT; if (rc == 2) { sdata->recoverFlags &= ~RECOVER_FLAG_MATCH_END_CONTINUE; continue; } if (rc == 1) { popStack (sdata); if (sdata->stack == NULL) { /* End of the first pattern (the tree root) without error. */ /* Check for unknown ID references */ if (!checkDocKeys (interp, sdata)) { return TCL_ERROR; } /* We have successfully finished validation */ sdata->validationState = VALIDATION_FINISHED; } DBG( fprintf(stderr, "probeElementEnd: _CAN_ end here.\n"); serializeStack (sdata); ); return TCL_OK; } break; } SetResultV ("Missing mandatory content"); sdata->validationState = VALIDATION_ERROR; DBG( fprintf(stderr, "probeElementEnd: CAN'T end here.\n"); serializeStack (sdata); ); |
Changes to tests/schema.test.
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
....
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
|
} s delete incr defnr } set result } {0/0: 1 {END_EVENT expecting a} 0/1: 1 {END_EVENT expecting b} 0/2: 1 {matching b} {expecting a} {END_EVENT expecting c} 0/3: 1 {matching c} {expecting a} {matching c} {expecting b} 0/4: 1 {END_EVENT expecting c} 0/5: 1 {matching c} {expecting b} 0/6: 1 {matching b} {expecting a} 0/7: 1 {matching unknown} {expecting a} {matching unknown} {expecting b} {matching unknown} {expecting c} {matching unknown} {expecting {<elementend> {}}} 0/8: 1 {matching unknown} {expecting b} {matching unknown} {expecting c} {matching unknown} {expecting {<elementend> {}}}} test schema-17.22a {return "ignore" from recover script for MISSING_ELEMENT_MATCH_START} { set defs { { interleave { element a element b element c } element d ? } } set xmlinput { <doc/> <doc><a/><d/></doc> <doc><b/><d/></doc> <doc><c/><d/>/doc> <doc><a/><b/><d/></doc> <doc><a/><c/><d/></doc> <doc><c/><b/><d/></doc> <doc><unknown/></doc> <doc><a/><unknown/></doc> } set result [list] set defnr 0 foreach def $defs { tdom::schema s s defelement doc $def s reportcmd schema-17.22 set xmlnr 0 foreach xml $xmlinput { set fromReportCmd "" lappend result $defnr/$xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete incr defnr } set result } {} proc schema-17.23 {scmd errorInfo} { global fromReportCmd if {[$scmd info vaction] eq "MATCH_ELEMENT_START"} { lappend fromReportCmd "matching [$scmd info vaction name]" "expecting [lsort [$scmd info expected]]" if {$errorInfo in {"MISSING_ELEMENT" "UNEXPECTED_ELEMENT"}} { return vanish } ................................................................................ } test schema-17.26 {return "ignore" from recover handler for element end event} { tdom::schema s s define { defelement doc { element a ref b element d ? } defpattern b { element b ref c } defpattern c { element c + } } s reportcmd schema-17.26 set result "" set xmlnr 0 foreach xml { <doc/> } { set ::fromReportCmd "" lappend result $defnr/$xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete set result } {0: 1 a b c {c d} d} proc schema-18 {args} { lappend ::result {*}$args } test schema-18.1 {reportcmd} { tdom::schema s s define { defelement doc { |
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
....
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
|
} s delete incr defnr } set result } {0/0: 1 {END_EVENT expecting a} 0/1: 1 {END_EVENT expecting b} 0/2: 1 {matching b} {expecting a} {END_EVENT expecting c} 0/3: 1 {matching c} {expecting a} {matching c} {expecting b} 0/4: 1 {END_EVENT expecting c} 0/5: 1 {matching c} {expecting b} 0/6: 1 {matching b} {expecting a} 0/7: 1 {matching unknown} {expecting a} {matching unknown} {expecting b} {matching unknown} {expecting c} {matching unknown} {expecting {<elementend> {}}} 0/8: 1 {matching unknown} {expecting b} {matching unknown} {expecting c} {matching unknown} {expecting {<elementend> {}}}} proc schema-17.23 {scmd errorInfo} { global fromReportCmd if {[$scmd info vaction] eq "MATCH_ELEMENT_START"} { lappend fromReportCmd "matching [$scmd info vaction name]" "expecting [lsort [$scmd info expected]]" if {$errorInfo in {"MISSING_ELEMENT" "UNEXPECTED_ELEMENT"}} { return vanish } ................................................................................ } test schema-17.26 {return "ignore" from recover handler for element end event} { tdom::schema s s define { defelement doc { element a ref bpat element d } defpattern bpat { element b ref c } defpattern c { element c + } } s reportcmd schema-17.26 set result "" set xmlnr 0 foreach xml { <doc/> <doc><a/></doc> <doc><a/><b/></doc> <doc><a/><b/><d/></doc> <doc><a/><b/><c/><d/></doc> <doc><a/><b/><c/><c/><c/><d/></doc> } { set ::fromReportCmd "" lappend result $xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete set result } {0: 1 {END_EVENT doc} {expecting a} {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting d} 1: 1 {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting d} 2: 1 {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 3: 1 {MATCH_ELEMENT_START expecting c} 4: 1 5: 1} test schema-17.27 {return "ignore" from recover handler for element end event} { tdom::schema s s define { defelement doc { element a element b element c element d } } s reportcmd schema-17.26 set result "" set xmlnr 0 foreach xml { <doc/> <doc><a/></doc> <doc><a/><b/></doc> <doc><a/><b/><d/></doc> <doc><a/><b/><c/><d/></doc> <doc><a/><b/><c/><c/><c/><d/></doc> } { set ::fromReportCmd "" lappend result $xmlnr: [s validate $xml errMsg] lappend result {*}$fromReportCmd incr xmlnr } s delete set result } {0: 1 {END_EVENT doc} {expecting a} {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 1: 1 {END_EVENT doc} {expecting b} {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 2: 1 {END_EVENT doc} {expecting c} {END_EVENT doc} {expecting d} 3: 1 {MATCH_ELEMENT_START expecting c} 4: 1 5: 1 {MATCH_ELEMENT_START expecting d}} proc schema-18 {args} { lappend ::result {*}$args } test schema-18.1 {reportcmd} { tdom::schema s s define { defelement doc { |