Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions tools/hrw4u/src/hrw_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def __init__(
self._if_depth = 0 # Track nesting depth of if blocks
self._in_elif_mode = False
self._just_closed_nested = False
self._deferred_comments: list[str] = []

self._pre_section_if_start: int | None = None

@lru_cache(maxsize=128)
def _cached_percent_parsing(self, pct_text: str) -> tuple[str, str | None]:
Expand All @@ -84,12 +85,6 @@ def _reset_condition_state(self) -> None:
self._in_group = False
self._group_terms.clear()

def _flush_deferred_comments(self) -> None:
"""Emit comments that were deferred while inside a rule's if-block."""
for comment in self._deferred_comments:
self.output.append(comment)
self._deferred_comments.clear()

def _start_new_section(self, section_type: SectionType) -> None:
"""Start a new section, handling continuation of existing sections."""
with self.debug_context(f"start_section {section_type.value}"):
Expand All @@ -100,21 +95,17 @@ def _start_new_section(self, section_type: SectionType) -> None:
self.emit("}")
self._if_depth -= 1
self._reset_condition_state()
self._flush_deferred_comments()
if self.output and self.output[-1] != "":
self.output.append("")
return

prev = bool(self.output)
had_section = self._section_opened
self._close_if_and_section()
self._reset_condition_state()

if had_section and self.output and self.output[-1] != "":
self.output.append("")

self._flush_deferred_comments()

self._section_label = section_type
self.emit(f"{section_type.value} {{")
self._section_opened = True
Expand Down Expand Up @@ -162,7 +153,6 @@ def visitProgram(self, ctx: u4wrhParser.ProgramContext) -> list[str]:
for line in ctx.line():
self.visit(line)
self._close_if_and_section()
self._flush_deferred_comments()

var_declarations = self.symbol_resolver.get_var_declarations()
if var_declarations:
Expand All @@ -178,9 +168,7 @@ def visitCommentLine(self, ctx: u4wrhParser.CommentLineContext) -> None:
with self.debug_context("visitCommentLine"):
comment_text = ctx.COMMENT().getText()
self._flush_pending_condition()
if self._if_depth > 0:
self._deferred_comments.append(comment_text)
elif self._section_opened:
if self._if_depth > 0 or self._section_opened:
self.emit(comment_text)
else:
self.output.append(comment_text)
Expand Down Expand Up @@ -407,10 +395,27 @@ def _close_if_and_section(self) -> None:
def _ensure_section_open(self, section_label: SectionType) -> None:
"""Ensure a section is open for statements."""
if not self._section_opened:
relocated_lines = None
relocated_if_depth = 0
if self._if_depth > 0 and self._pre_section_if_start is not None:
relocated_lines = self.output[self._pre_section_if_start:]
relocated_if_depth = self._if_depth
self.output = self.output[:self._pre_section_if_start]
self.stmt_indent -= self._if_depth
self._if_depth = 0
self._pre_section_if_start = None

self.emit(f"{section_label.value} {{")
self._section_opened = True
self.increase_indent()

if relocated_lines:
indent_prefix = " " * SystemDefaults.INDENT_SPACES
for line in relocated_lines:
self.output.append(indent_prefix + line if line.strip() else line)
self._if_depth = relocated_if_depth
self.stmt_indent += relocated_if_depth

def _start_elif_mode(self) -> None:
"""Handle elif line transitions."""
# After endif, we need to close the parent if-statement
Expand All @@ -432,6 +437,9 @@ def _handle_else_transition(self) -> None:

def _start_if_block(self, condition_expr: str) -> None:
"""Start a new if block."""
if not self._section_opened and self._pre_section_if_start is None:
self._pre_section_if_start = len(self.output)

if self._in_elif_mode:
self.emit(f"}} elif {condition_expr} {{")
self._in_elif_mode = False
Expand Down
2 changes: 1 addition & 1 deletion tools/hrw4u/src/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def visitCommentLine(self, ctx) -> None:
with self.debug_context("visitCommentLine"):
comment_text = ctx.COMMENT().getText()
self.debug_log(f"preserving comment: {comment_text}")
self.output.append(comment_text)
self.emit_line(comment_text, self.stmt_indent)

def visitStatement(self, ctx) -> None:
with self.debug_context("visitStatement"), self.trap(ctx):
Expand Down
2 changes: 2 additions & 0 deletions tools/hrw4u/tests/data/conds/exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
implicit-cmp.input: u4wrh
# Double negation !(x != y) emits GROUP/GROUP:END [NOT] pairs; reverse can't reconstruct the original form
double-negation.input: hrw4u
# Old format without explicit hook defaults to REMAP; hrw4u always emits explicit sections
no-hook.input: u4wrh
6 changes: 6 additions & 0 deletions tools/hrw4u/tests/data/conds/no-hook.input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
REMAP {
if inbound.req.Debug {
# to return the debug header if http header debug: on
inbound.req.@DebugHeader = "TRUE";
}
}
3 changes: 3 additions & 0 deletions tools/hrw4u/tests/data/conds/no-hook.output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cond %{CLIENT-HEADER:Debug} ="" [NOT]
# to return the debug header if http header debug: on
set-header @DebugHeader "TRUE"
8 changes: 4 additions & 4 deletions tools/hrw4u/tests/data/examples/all-nonsense.output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ cond %{GROUP}
cond %{GROUP:END}
skip-remap TRUE
no-op [L]
# like [L]
# like [L]

cond %{READ_REQUEST_HDR_HOOK} [AND]
# Header presence / equality and capture groups
Expand Down Expand Up @@ -132,9 +132,9 @@ cond %{GROUP}
cond %{GROUP:END}
counter "write_methods_seen"
set-state-int8 0 42
# assign int8
# assign int8
set-state-int16 0 6553
# assign int16
# assign int16

cond %{SEND_REQUEST_HDR_HOOK} [AND]
# Use NEXT-HOP information to adjust Host header
Expand Down Expand Up @@ -174,7 +174,7 @@ elif
cond %{CACHE} ("miss","skipped")
cond %{GROUP:END}
set-header X-Cache "%{CACHE}"
# echo the value
# echo the value
# Status transforms + reason

cond %{READ_RESPONSE_HDR_HOOK} [AND]
Expand Down
Loading