── Shared single-file battery: callable (dims 1-6) ──────────────────────── * * Adds defs-present (dim 5) and calls-extracted (dim 6) on top of the base * invariants. Used for the callable shells/scripting languages. Pass NULL for * expect_label when no def label is asserted alongside the call. Returns 0 on PASS. */
| 251 | * expect_label when no def label is asserted alongside the call. Returns 0 on PASS. |
| 252 | */ |
| 253 | static int sh_callable_battery(const char *lang_tag, const char *src, CBMLanguage lang, |
| 254 | const char *file, const char *expect_label, |
| 255 | const char *expect_label2, const char *callee) { |
| 256 | const char *RED = tf_red(); |
| 257 | const char *RST = tf_reset(); |
| 258 | |
| 259 | if (inv_extract_clean(src, lang, file) != 1) { |
| 260 | printf(" %sFAIL%s [%s] extract-clean: NULL result or has_error set\n", |
| 261 | RED, RST, lang_tag); |
| 262 | return 1; |
| 263 | } |
| 264 | |
| 265 | CBMFileResult *r = inv_rx(src, lang, file); |
| 266 | if (!r) { |
| 267 | printf(" %sFAIL%s [%s] inv_rx returned NULL after clean extract\n", |
| 268 | RED, RST, lang_tag); |
| 269 | return 1; |
| 270 | } |
| 271 | |
| 272 | int fails = 0; |
| 273 | |
| 274 | int bad_labels = inv_count_bad_labels(r); |
| 275 | if (bad_labels != 0) { |
| 276 | printf(" %sFAIL%s [%s] labels-valid: %d def(s) with invalid label\n", |
| 277 | RED, RST, lang_tag, bad_labels); |
| 278 | fails++; |
| 279 | } |
| 280 | |
| 281 | int bad_fqns = inv_count_bad_fqns(r); |
| 282 | if (bad_fqns != 0) { |
| 283 | printf(" %sFAIL%s [%s] fqn-wellformed: %d def(s) with malformed QN\n", |
| 284 | RED, RST, lang_tag, bad_fqns); |
| 285 | fails++; |
| 286 | } |
| 287 | |
| 288 | int bad_ranges = inv_count_bad_ranges(r); |
| 289 | if (bad_ranges != 0) { |
| 290 | printf(" %sFAIL%s [%s] ranges-valid: %d def(s) with invalid range\n", |
| 291 | RED, RST, lang_tag, bad_ranges); |
| 292 | fails++; |
| 293 | } |
| 294 | |
| 295 | /* 5. defs-present */ |
| 296 | if (expect_label && inv_count_label(r, expect_label) < 1) { |
| 297 | printf(" %sFAIL%s [%s] defs-present: no def labelled \"%s\"\n", |
| 298 | RED, RST, lang_tag, expect_label); |
| 299 | fails++; |
| 300 | } |
| 301 | if (expect_label2 && inv_count_label(r, expect_label2) < 1) { |
| 302 | printf(" %sFAIL%s [%s] defs-present: no def labelled \"%s\"\n", |
| 303 | RED, RST, lang_tag, expect_label2); |
| 304 | fails++; |
| 305 | } |
| 306 | |
| 307 | /* 6. calls-extracted */ |
| 308 | if (callee && inv_has_call(r, callee) != 1) { |
| 309 | printf(" %sFAIL%s [%s] calls-extracted: no call to \"%s\" found\n", |
| 310 | RED, RST, lang_tag, callee); |
no test coverage detected