Home | History | Annotate | Line # | Download | only in unit-tests
char-005c-reverse-solidus.mk revision 1.1
      1 # $NetBSD: char-005c-reverse-solidus.mk,v 1.1 2025/06/29 09:40:13 rillig Exp $
      2 #
      3 # Tests for the character U+005C "REVERSE SOLIDUS".
      4 #
      5 # See also:
      6 #	TODO
      7 #	TODO
      8 #	TODO
      9 
     10 # TODO: Where is this character used normally?
     11 # TODO: What are the edge cases?
     12 
     13 # TODO: escape '#' in lines
     14 # TODO: escape '#' in comments
     15 # TODO: escape ':' in modifiers
     16 # TODO: escape any character in condition strings
     17 
     18 # begin https://gnats.netbsd.org/46139
     19 
     20 # Too see the details of parsing, uncomment the following line.
     21 #.MAKEFLAGS: -dcpv
     22 
     23 # This backslash is treated as a line continuation.
     24 # It does not end up in the variable value.
     25 LINE_CONTINUATION=foo\
     26 # This line is still part of the variable assignment
     27 .if ${LINE_CONTINUATION:C,[^a-z],<>,gW} != "foo"
     28 .  error
     29 .endif
     30 
     31 # The variable value contains two backslashes.
     32 TWO_BACKSLASHES_AT_EOL=foo\\
     33 .if ${TWO_BACKSLASHES_AT_EOL:C,[^a-z],<>,gW} != "foo<><>"
     34 .  error
     35 .endif
     36 
     37 TRAILING_WHITESPACE=foo\ # trailing space
     38 .if ${TRAILING_WHITESPACE:C,[^a-z],<>,gW} != "foo<><>"
     39 .  error
     40 .endif
     41 
     42 # The simplest was to produce a single backslash is the :U modifier.
     43 BACKSLASH=	${:U\\}
     44 .if ${BACKSLASH} != "\\"
     45 .  error
     46 .endif
     47 BACKSLASH_C=	${:U1:C,.,\\,}
     48 .if ${BACKSLASH_C} != "\\"
     49 .  error
     50 .endif
     51 
     52 # expect+5: Unclosed expression, expecting "}" for modifier "Mx\}"
     53 # At the point where the unclosed expression is detected, the ":M" modifier
     54 # has been applied to the expression.  Its pattern is "x}", which doesn't
     55 # match the single backslash.
     56 # expect: while evaluating variable "BACKSLASH" with value ""
     57 .if ${BACKSLASH:Mx\}
     58 .  error
     59 .else
     60 # FIXME: After an error in the condition, both branches must be skipped.
     61 # expect+1: Missing argument for ".error"
     62 .  error
     63 .endif
     64 
     65 # expect+1: Unclosed expression, expecting "}" for modifier "Mx\\}"
     66 .if ${BACKSLASH:Mx\\}
     67 .  error
     68 .else
     69 # FIXME: After an error in the condition, both branches must be skipped.
     70 # expect+1: Missing argument for ".error"
     71 .  error
     72 .endif
     73 
     74 # expect+1: Unclosed expression, expecting "}" for modifier "Mx\\\\\\\\}"
     75 .if ${BACKSLASH:Mx\\\\\\\\}
     76 .  error
     77 .else
     78 # FIXME: After an error in the condition, both branches must be skipped.
     79 # expect+1: Missing argument for ".error"
     80 .  error
     81 .endif
     82 
     83 # Adding more text after the backslash adds to the pattern, as the backslash
     84 # serves to escape the ":" that is otherwise used to separate the modifiers.
     85 # The result is a single ":M" modifier with the pattern "x:Nzzz".
     86 .if ${BACKSLASH:Mx\:Nzzz} != ""
     87 .  error
     88 .endif
     89 
     90 # The pattern ends up as "x\:Nzzz".  Only the sequence "\:" is unescaped, all
     91 # others, including "\\", are left as-is.
     92 .if ${BACKSLASH:Mx\\:Nzzz} != ""
     93 .  error
     94 .endif
     95 
     96 # The pattern for the ":M" modifier ends up as "x\\\\\\\:Nzzz".  Only the
     97 # sequence "\:" is unescaped, all others, including "\\", are left as-is.
     98 .if ${BACKSLASH:Mx\\\\\\\\:Nzzz} != ""
     99 .  error
    100 .endif
    101 
    102 # The ":M" modifier is parsed differently than the other modifiers.  To
    103 # circumvent the peculiarities of that parser, the pattern can be passed via
    104 # an expression.  There, the usual escaping rules for modifiers apply.
    105 # expect+1: Unfinished backslash at the end in pattern "\" of modifier ":M"
    106 .if ${BACKSLASH:M${BACKSLASH}} != "\\"
    107 # FIXME: After an error in the condition, both branches must be skipped.
    108 # expect+1: Missing argument for ".error"
    109 .  error
    110 .else
    111 .  error
    112 .endif
    113 
    114 # Trying to bypass the parser by using a direct expression doesn't work, as
    115 # the parser for the ":M" modifier does not parse the subexpression like in
    116 # all other places, but instead counts the braces and tries to decode the
    117 # escaping, which fails in this case.
    118 # expect+1: Unclosed expression, expecting "}" for modifier "M${:U\\\\}} != "\\""
    119 .if ${BACKSLASH:M${:U\\\\}} != "\\"
    120 .  error
    121 .else
    122 # expect+1: Missing argument for ".error"
    123 .  error
    124 .endif
    125 
    126 # Matching a backslash with the pattern matching characters works.
    127 .if ${BACKSLASH:M?} != "\\"
    128 .  error
    129 .endif
    130 .if ${BACKSLASH:M*} != "\\"
    131 .  error
    132 .endif
    133 .if ${BACKSLASH:M[Z-a]} != "\\"
    134 .  error
    135 .endif
    136 .if ${BACKSLASH:M[\\]} != "\\"
    137 .  error
    138 .endif
    139 
    140 # end https://gnats.netbsd.org/46139
    141