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.
This commit is contained in:
Pierre Marie de Rodat 2025-10-14 00:11:37 +02:00 committed by Eric Botcazou
parent 304d7359a6
commit be496fd2aa
1 changed files with 27 additions and 4 deletions

View File

@ -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;
pfile->cb.dir_change (pfile, smashy + 1);
/* 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, dir);
}
/* We should be at EOL. */