Skip to content

Fix/MultiFile pattern (Issue #696) - #697

Open
Pr0metheus2 wants to merge 7 commits into
LogExperts:Developmentfrom
Pr0metheus2:fix/MultiFile-support-for-mid-filename-index-tags-(app.1.log)
Open

Fix/MultiFile pattern (Issue #696)#697
Pr0metheus2 wants to merge 7 commits into
LogExperts:Developmentfrom
Pr0metheus2:fix/MultiFile-support-for-mid-filename-index-tags-(app.1.log)

Conversation

@Pr0metheus2

@Pr0metheus2 Pr0metheus2 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

This is a fix for #696

  • Fixed/MultiFile rollover patterns with an index before the extension:

    • RolloverFilenameBuilder: the parser was dropping literal text after the final placeholder, including .log.
    • *$J(.).log now correctly expands: app.log → app.1.log → app.2.log.
  • Updated MultiFile mask dialog legend:

    • Fixed incorrectly displayed <date> and <prefix> placeholders in English and German resources.
    • Added both usage examples:
      • *$J(.) → app.log, app.log.1, app.log.2
      • *$J(.).log → app.log, app.1.log, app.2.log
    • Added the examples in English, German, and Chinese.
    • Enlarged the dialog and syntax-help label so the date-format lines are no longer clipped.

Before
Legend_old

After
Legend_new

  • Fixed/Items in menu File/Multifile -> "Enable MultiFile" and "File name mask...", were always greyed out. Now they are displayed normally after the .log file is open.
    • removed the BackColor and ForeColor assignments for both:
      • multiFileEnabledStripMenuItem
      • multifileMaskToolStripMenuItem

Before
Multifile_old

After
Multifile_new

  • Added regression coverage:
    • Filename-builder tests for app.1.log and app.2.log.
    • Reader-level test that loads app.log, app.1.log, and app.2.log in correct order using *$J(.).log.
    • Kept the existing *$J(.) coverage for app.log.1 / app.log.2.

Verification:
- Full test suite: 1064 passed, 0 failed, 7 skipped.
- Resource project build: passed with 0 warnings, 0 errors.

- Fixed/MultiFile rollover patterns with an index before the extension:
    - RolloverFilenameBuilder: the parser was dropping literal text after the final placeholder, including .log.
    - *$J(.).log now correctly expands: app.log → app.1.log → app.2.log.

- Updated MultiFile mask dialog legend:
    - Fixed incorrectly displayed <date> and <prefix> placeholders in English and German resources.
    - Added both usage examples:
        *$J(.) → app.log, app.log.1, app.log.2
        *$J(.).log → app.log, app.1.log, app.2.log
    - Added the examples in English, German, and Chinese.
    - Enlarged the dialog and syntax-help label so the date-format lines are no longer clipped.

- Fixed/Items in menu File/Multifile -> "Enable MultiFile" and "Multi file mask...", were always greyed out. Now they are displayed normally after the .log file is open.
		- removed the BackColor and ForeColor assignments for both:
			- multiFileEnabledStripMenuItem
			- multifileMaskToolStripMenuItem

- Added regression coverage:
    - Filename-builder tests for app.1.log and app.2.log.
    - Reader-level test that loads app.log, app.1.log, and app.2.log in correct order using *$J(.).log.
    - Kept the existing *$J(.) coverage for app.log.1 / app.log.2.

  Verification:
	- Full test suite: 1064 passed, 0 failed, 7 skipped.
	- Resource project build: passed with 0 warnings, 0 errors.
}
}

_ = result.Append(Regex.Escape(segment.ToString()));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated Code — [RolloverFilenameBuilder.cs:241] is the exact shape of the state-0 flush at line 202. A tiny local FlushEscaped() would let both share it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added FlushEscaped() to share duplicated escaping code.

Comment thread src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs Outdated
Comment thread src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs Outdated
Comment thread src/LogExpert.Resources/Resources.de.resx Outdated
}
}

_ = result.Append(Regex.Escape(segment.ToString()));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Index parsing from a rotated file is still broken. Spec: "app.1.log → Rotated log (Index 1)". RolloverFilenameHandler calls SetFileName on whatever file the user opens; for $J(.).log the regex .(?'index'\d*).log has a greedy .* that swallows the digit in app.1.log, so Index parses as 0 and BuildFileName would produce app.1.1.log. Grouping only works when the active file (app.log) is opened. The same flaw pre-exists for *$J(.) with app.log.1, so it's parity rather than a regression — so the index mapping is only partially delivered.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • fixed parsing of $J(<prefix>) from rotated files, so both app.log.1 and app.1.log correctly identify index 1.
  • made wildcard matching non-greedy and anchored the generated regex to the complete filename.
  • updated rebuilding logic to remove an existing prefix plus index together before inserting the new index.
  • fixed $D(...) parsing to use positions in the escaped format string, preventing errors when a literal regex character such as . appears before $D

Added coverage for opening:

  • engine.log.1 with *$J(.) → builds engine.log.2
  • engine.1.log with *$J(.).log → builds engine.2.log

[TestCase("engine1.log", "engine2.log","engine$J.log")]
[TestCase("engine.log", "engine.log.1","*$J(.)")]
[TestCase("engine.log", "engine.1.log", "*$J(.).log")]
[TestCase("engine_2010-06-12.log", "engine_2010-06-12.log.1", "*$D(yyyy-MM-dd).log$J(.)")]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$I untested. For "$J, $I" support, the fix itself generalizes, but no test covers $I or $D followed by a trailing literal (e.g. *$D(yyyy-MM-dd)$J(.).log).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added cases which cover:

  • $I with a trailing literal .log, starting from a rotated file.
  • $D plus $J(.) followed by a trailing .log, also starting from a rotated file.

[TestCase("engine1.log", "engine2.log","engine$J.log")]
[TestCase("engine.log", "engine.log.1","*$J(.)")]
[TestCase("engine.log", "engine.1.log", "*$J(.).log")]
[TestCase("engine_2010-06-12.log", "engine_2010-06-12.log.1", "*$D(yyyy-MM-dd).log$J(.)")]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseFormatString computes datePos from the original string but edits the escaped one — a literal with regex metachars before $D (e.g. app.$D(yyyy-MM-dd)) corrupts the regex. Not introduced here, but the new trailing-literal support makes such patterns likelier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by locating and parsing $D(...) in the escaped format string. Offsets remain correct when literal regex metacharacters appear before the date placeholder.
Added a regression test for app.$D(yyyy-MM-dd).log that verifies date parsing and rebuilding.

Fixed by locating and parsing $D(...) in the escaped format string. Offsets remain correct when literal regex metacharacters appear before the date placeholder.
Added a regression test for app.$D(yyyy-MM-dd).log that verifies date parsing and rebuilding.

Added cases which cover:
- $I with a trailing literal .log, starting from a rotated file.
- $D plus $J(.) followed by a trailing .log, also starting from a rotated file.
  - Added FlushEscaped() to share duplicated escaping code.
  - Fixed parsing of $J(<prefix>) from rotated files, so both:
      - app.log.1
      - app.1.log
        correctly identify index 1.

  - Made wildcard matching non-greedy and anchored the generated regex to the complete filename.
  - Updated rebuilding logic to remove an existing prefix plus index together before inserting the new index.
  - Fixed $D(...) parsing to use positions in the escaped format string, preventing errors when a literal regex character such as . appears before $D.
@Pr0metheus2

Copy link
Copy Markdown
Contributor Author

Check please

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.

2 participants