This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 627f5071ea hrw4u: Fix section placement for hookless rules in u4wrh 
(#12956)
627f5071ea is described below

commit 627f5071ea83c1a2c06292e4abdb2daaa17e4119
Author: Leif Hedstrom <[email protected]>
AuthorDate: Tue Mar 17 09:12:52 2026 -0700

    hrw4u: Fix section placement for hookless rules in u4wrh (#12956)
    
    Old header_rewrite rules without an explicit hook condition
    default to REMAP. When u4wrh converted these, the section
    opened inside the if-block instead of wrapping it. Also emit
    comments inline inside if-blocks instead of deferring them
    to after the section closes, and remove the now-unused
    deferred comment machinery. In the forward direction, indent
    block-level comments at the statement level.
    
    Co-Authored-By: Keele Clendenin
---
 tools/hrw4u/src/hrw_visitor.py                     | 38 +++++++++++++---------
 tools/hrw4u/src/visitor.py                         |  2 +-
 tools/hrw4u/tests/data/conds/exceptions.txt        |  2 ++
 tools/hrw4u/tests/data/conds/no-hook.input.txt     |  6 ++++
 tools/hrw4u/tests/data/conds/no-hook.output.txt    |  3 ++
 .../tests/data/examples/all-nonsense.output.txt    |  8 ++---
 6 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/tools/hrw4u/src/hrw_visitor.py b/tools/hrw4u/src/hrw_visitor.py
index 3dbdfd6208..2878da0be2 100644
--- a/tools/hrw4u/src/hrw_visitor.py
+++ b/tools/hrw4u/src/hrw_visitor.py
@@ -57,7 +57,8 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
         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]:
@@ -84,12 +85,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
         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}"):
@@ -100,12 +95,10 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
                     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()
@@ -113,8 +106,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
             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
@@ -162,7 +153,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
             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:
@@ -178,9 +168,7 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
         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)
@@ -407,10 +395,27 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
     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
@@ -432,6 +437,9 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor):
 
     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
diff --git a/tools/hrw4u/src/visitor.py b/tools/hrw4u/src/visitor.py
index 90ea932e68..68182fb2b9 100644
--- a/tools/hrw4u/src/visitor.py
+++ b/tools/hrw4u/src/visitor.py
@@ -830,7 +830,7 @@ class HRW4UVisitor(hrw4uVisitor, BaseHRWVisitor):
         with self.debug_context("visitCommentLine"):
             comment_text = ctx.COMMENT().getText()
             self.debug(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):
diff --git a/tools/hrw4u/tests/data/conds/exceptions.txt 
b/tools/hrw4u/tests/data/conds/exceptions.txt
index 86e44106ba..fd12cfd4a0 100644
--- a/tools/hrw4u/tests/data/conds/exceptions.txt
+++ b/tools/hrw4u/tests/data/conds/exceptions.txt
@@ -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
diff --git a/tools/hrw4u/tests/data/conds/no-hook.input.txt 
b/tools/hrw4u/tests/data/conds/no-hook.input.txt
new file mode 100644
index 0000000000..603acdb71a
--- /dev/null
+++ b/tools/hrw4u/tests/data/conds/no-hook.input.txt
@@ -0,0 +1,6 @@
+REMAP {
+    if inbound.req.Debug {
+        # to return the debug header if http header debug: on
+        inbound.req.@DebugHeader = "TRUE";
+    }
+}
diff --git a/tools/hrw4u/tests/data/conds/no-hook.output.txt 
b/tools/hrw4u/tests/data/conds/no-hook.output.txt
new file mode 100644
index 0000000000..c57dcec7e5
--- /dev/null
+++ b/tools/hrw4u/tests/data/conds/no-hook.output.txt
@@ -0,0 +1,3 @@
+cond %{CLIENT-HEADER:Debug} ="" [NOT]
+# to return the debug header if http header debug: on
+set-header @DebugHeader "TRUE"
diff --git a/tools/hrw4u/tests/data/examples/all-nonsense.output.txt 
b/tools/hrw4u/tests/data/examples/all-nonsense.output.txt
index bb15eb068e..c8672c1f28 100644
--- a/tools/hrw4u/tests/data/examples/all-nonsense.output.txt
+++ b/tools/hrw4u/tests/data/examples/all-nonsense.output.txt
@@ -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
@@ -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 server URL information to adjust Host header
@@ -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]

Reply via email to