summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorPierre Marie de Rodat <derodat@adacore.com>2025-10-14 00:11:37 +0200
committerEric Botcazou <ebotcazou@adacore.com>2025-10-14 00:24:19 +0200
commitbe496fd2aa528b4acc2002c04b7186a1f54b95e2 (patch)
tree9598a7ad2a26d700c4b0928d4d1aebe720b81739 /libcpp
parent304d7359a67b8f7b979bf5941c7a5cbabf1aebcf (diff)
libcpp: decode original directory strings for traditional CPP
In traditional CPP mode (-save-temps, -no-integrated-cpp, etc.), the compilation directory is conveyed to cc1 using a line such as: # <line> "/path/name//" This string literal can contain escape sequences, for instance, if the original source file was compiled in "/tmp/a\b", then this line will be: # <line> "/tmp/a\\b//" So reading the compilation directory must decode escape sequences. This last part is currently missing and this patch implements it. libcpp/ * init.cc (read_original_directory): Attempt to decode escape sequences with cpp_interpret_string_notranslate.
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/init.cc31
1 files changed, 27 insertions, 4 deletions
diff --git a/libcpp/init.cc b/libcpp/init.cc
index eb495e26eff..567d5e70381 100644
--- a/libcpp/init.cc
+++ b/libcpp/init.cc
@@ -893,11 +893,34 @@ read_original_directory (cpp_reader *pfile)
if (pfile->cb.dir_change)
{
- /* Smash the string directly, it's dead at this point */
- char *smashy = (char *)text;
- smashy[len - 3] = 0;
+ cpp_string s = { 0, 0 };
+ const char *dir_slashslash;
+ unsigned int dir_slashslash_len;
+
+ /* If we fail to decode escape sequences in the string literal, fall
+ back onto the literal itself, manually removing the opening and
+ closing quotes ("). */
+ if (cpp_interpret_string_notranslate (pfile, &string->val.str, 1, &s,
+ CPP_STRING))
+ {
+ /* At this point, the trailing NUL byte in S is included in its
+ length, so take it out. */
+ dir_slashslash = (const char *) s.text;
+ dir_slashslash_len = s.len - 1;
+ }
+ else
+ {
+ dir_slashslash = (const char *) string->val.str.text + 1;
+ dir_slashslash_len = string->val.str.len - 2;
+ }
+
+ /* Strip the trailing double slash. */
+ const unsigned dir_len = dir_slashslash_len - 2;
+ char *dir = (char *) alloca (dir_len + 1);
+ memcpy (dir, dir_slashslash, dir_len);
+ dir[dir_len] = '\0';
- pfile->cb.dir_change (pfile, smashy + 1);
+ pfile->cb.dir_change (pfile, dir);
}
/* We should be at EOL. */