diff options
| author | Pierre Marie de Rodat <derodat@adacore.com> | 2025-10-14 00:11:37 +0200 |
|---|---|---|
| committer | Eric Botcazou <ebotcazou@adacore.com> | 2025-10-14 00:24:19 +0200 |
| commit | be496fd2aa528b4acc2002c04b7186a1f54b95e2 (patch) | |
| tree | 9598a7ad2a26d700c4b0928d4d1aebe720b81739 /libcpp | |
| parent | 304d7359a67b8f7b979bf5941c7a5cbabf1aebcf (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.cc | 31 |
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. */ |
