251-stringize-str-escape.c (1103B)
1 /* Stringize of a string-literal argument must reproduce the source 2 * spelling, with `"` and `\` prefixed by `\` (C11 §6.10.3.2 ¶2). 3 * The lexer cooks string content, so `"a\nb"` becomes 3 bytes 4 * a,0x0A,b. Stringizing that requires re-escaping the embedded LF 5 * back to `\n`. The buggy `%pp-quote-bytes` only escaped `"` and 6 * `\` and emitted control bytes raw, producing a string with a 7 * literal newline byte (length 5) where C11 requires the 6-char 8 * spelling \"a\\nb\". 9 */ 10 11 #define S(x) #x 12 13 static int slen(const char *s) { int n = 0; while (s[n] != 0) n++; return n; } 14 15 int main(void) { 16 const char *s = S("a\nb"); 17 /* Expected: "a\nb" -> 6 source-spelling chars. The cooked bytes 18 * of that 6-char literal are: " a \ n b " (still 6 distinct 19 * bytes) because the produced source-spelling itself escapes 20 * the LF as \\ + n. */ 21 if (slen(s) != 6) return 1; 22 if (s[0] != '"') return 2; 23 if (s[1] != 'a') return 3; 24 if (s[2] != '\\') return 4; 25 if (s[3] != 'n') return 5; 26 if (s[4] != 'b') return 6; 27 if (s[5] != '"') return 7; 28 return 0; 29 }