Skip to content

WIP: XML::Simple support - fix regex, parser, and matching bugs#432

Merged
fglock merged 4 commits into
masterfrom
feature/xml-simple-support
Apr 3, 2026
Merged

WIP: XML::Simple support - fix regex, parser, and matching bugs#432
fglock merged 4 commits into
masterfrom
feature/xml-simple-support

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 3, 2026

Summary

Investigation and fixes for ./jcpan -j 8 -t XML::Simple test failures (0/14 test files passing).

Bugs Identified

  1. \x{NNNN} broken in regex character classes (CRITICAL) - [\x{41}-\x{5A}] fails with "Invalid range" because \x{} isn't parsed inside [...] in RegexPreprocessorHelper.java
  2. /^$/m doesn't match empty strings (HIGH) - Java's Pattern.MULTILINE quirk: ^$ won't match empty input. Breaks XML::SAX INI file parsing.
  3. Indirect method call with unknown method + qualified class (MEDIUM) - throw Foo::Bar(args) is a syntax error when throw isn't predeclared. SubroutineParser.java rejects it incorrectly.

Fix Plan

See dev/modules/xml_simple.md for full analysis.

  • Phase 1: Fix regex \x{} in char classes (unblocks ~90% of tests)
  • Phase 2: Fix /^$/m empty string matching
  • Phase 3: Fix indirect method call parser
  • Phase 4: Add Storable lock stubs (minor)

Test plan

  • make passes (no regressions)
  • ./jcpan -j 8 -t XML::Simple passes
  • Unit tests for each fix

Generated with Devin

@fglock fglock force-pushed the feature/xml-simple-support branch from 93870c9 to 2e3de40 Compare April 3, 2026 15:04
fglock and others added 4 commits April 3, 2026 17:31
Investigation of ./jcpan -j 8 -t XML::Simple found 3 bugs:
- \x{NNNN} broken in regex character classes (CRITICAL)
- /^$/m does not match empty strings (Java MULTILINE quirk)
- Indirect method call fails with unknown method + qualified class

See dev/modules/xml_simple.md for full analysis and fix plan.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Six fixes that bring XML::Simple from 0% to 98.4% passing (479/487 subtests):

1. Regex: add \x{NNNN} handling inside character classes [...]
   - Was missing in handleRegexCharacterClassEscape (only \o{} was handled)
   - Also fix range validation look-ahead for \x{NNNN} and \o{NNNN}

2. Regex: work around Java MULTILINE quirk for empty strings
   - Java's Pattern.MULTILINE makes ^ fail on empty input
   - Strip MULTILINE for empty strings (no line breaks = flag irrelevant)

3. Parser: allow indirect method call with qualified class names
   - 'throw Foo::Bar(args)' was rejected when 'throw' unknown
   - Names with '::' are unambiguously packages, not function calls

4. Strict vars: fix 'use vars' with single uppercase letter variables
   - $S, $A etc. were incorrectly rejected even after 'use vars'
   - Removed override that forced existsGlobally=false for 1-char vars

5. Encode: add define_alias() delegating to Encode::Alias
   - Needed by XML::SAX::PurePerl for UTF-16 encoding aliases

6. Storable: add lock_store/lock_nstore/lock_retrieve stubs
   - Delegate to non-locking variants (JVM handles file safety)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two issues caused warnings::enabled() to always return false for custom
warning categories registered via warnings::register:

1. The no-args form used getCallerPackageAtLevel(0) which added a +1
   offset to caller(), skipping the direct caller and returning the
   wrong package name. Fixed to use caller(0) directly.

2. isEnabledInBits()/isFatalInBits() failed for custom categories
   because their bit offset (>= 128) was not set in the warning bits
   string (compiled before the category was registered). Fixed to fall
   back to checking if 'all' is enabled, since 'use warnings' implicitly
   enables all custom categories.

This completes XML::Simple support: 487/487 subtests now pass (100%).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…r globals

Single-letter globals ($A-$Z) auto-vivified under 'no strict' were
incorrectly bypassing 'use strict vars' because existsGlobalVariable()
returned true. The previous blunt fix (forcing existsGlobally=false for
all single-letter vars) blocked legitimately imported variables like $S
from XML::SAX::PurePerl::Productions via Exporter.

Added declaredGlobalVariables/Arrays/Hashes tracking sets in
GlobalVariable.java to distinguish explicitly declared globals (via
use vars, Exporter glob assignment) from auto-vivified ones. The strict
check for single-letter vars now consults isDeclaredGlobalVariable()
instead of unconditionally blocking.

- GlobalVariable.java: declaredGlobals sets + declare/isDeclared methods
- Vars.java: importVars() calls declareGlobal*() for each variable
- RuntimeGlob.java: set() calls declareGlobal*() on REFERENCE/ARRAY/HASH
- Variable.java, EmitVariable.java, BytecodeCompiler.java: updated check

Test results: uni/variables.t 66880/66880, XML::Simple 487/487, make OK

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the feature/xml-simple-support branch from 2e3de40 to f8ba441 Compare April 3, 2026 15:32
@fglock fglock merged commit 8258e1d into master Apr 3, 2026
2 checks passed
@fglock fglock deleted the feature/xml-simple-support branch April 3, 2026 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant