Encoding: Fix potential encoding issues with libarchive on Windows.

Because the 8bit string encoding in libarchive can be different than
the 8bit string encoding in CMake, change to call the wide version
of libarchive functions.  They are different if CMake is configured
to use UTF-8 as the internal encoding.

Create helper functions for some libarchive calls to use wstring
internally on platforms supporting it.
This commit is contained in:
Clinton Stimpson 2014-06-12 06:46:40 -06:00 committed by Brad King
parent 6b05e03de4
commit 71c981a213
2 changed files with 56 additions and 8 deletions

View File

@ -24,6 +24,28 @@ static std::string cm_archive_error_string(struct archive* a)
return e? e : "unknown error"; return e? e : "unknown error";
} }
//----------------------------------------------------------------------------
static void cm_archive_entry_copy_pathname(struct archive_entry* e,
const std::string& dest)
{
#if cmsys_STL_HAS_WSTRING
archive_entry_copy_pathname_w(e, cmsys::Encoding::ToWide(dest).c_str());
#else
archive_entry_copy_pathname(e, dest.c_str());
#endif
}
//----------------------------------------------------------------------------
static void cm_archive_entry_copy_sourcepath(struct archive_entry* e,
const std::string& file)
{
#if cmsys_STL_HAS_WSTRING
archive_entry_copy_sourcepath_w(e, cmsys::Encoding::ToWide(file).c_str());
#else
archive_entry_copy_sourcepath(e, file.c_str());
#endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
class cmArchiveWrite::Entry class cmArchiveWrite::Entry
{ {
@ -237,8 +259,8 @@ bool cmArchiveWrite::AddFile(const char* file,
std::cout << dest << "\n"; std::cout << dest << "\n";
} }
Entry e; Entry e;
archive_entry_copy_sourcepath(e, file); cm_archive_entry_copy_sourcepath(e, file);
archive_entry_set_pathname(e, dest.c_str()); cm_archive_entry_copy_pathname(e, dest);
if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK) if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK)
{ {
this->Error = "archive_read_disk_entry_from_file: "; this->Error = "archive_read_disk_entry_from_file: ";

View File

@ -91,6 +91,31 @@ extern char** environ;
# endif # endif
#endif #endif
#if defined(CMAKE_BUILD_WITH_CMAKE)
static std::string
cm_archive_entry_pathname(struct archive_entry *entry)
{
#if cmsys_STL_HAS_WSTRING
return cmsys::Encoding::ToNarrow(
archive_entry_pathname_w(entry)).c_str();
#else
return archive_entry_pathname(entry);
#endif
}
static int cm_archive_read_open_file(struct archive* a,
const char* file,
int block_size)
{
#if cmsys_STL_HAS_WSTRING
std::wstring wfile = cmsys::Encoding::ToWide(file);
return archive_read_open_filename_w(a, wfile.c_str(), block_size);
#else
return archive_read_open_filename(a, file, block_size);
#endif
}
#endif
#ifdef _WIN32 #ifdef _WIN32
class cmSystemToolsWindowsHandle class cmSystemToolsWindowsHandle
{ {
@ -1581,7 +1606,7 @@ namespace{
} }
strftime(tmp, sizeof(tmp), fmt, localtime(&tim)); strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
fprintf(out, " %s ", tmp); fprintf(out, " %s ", tmp);
fprintf(out, "%s", archive_entry_pathname(entry)); fprintf(out, "%s", cm_archive_entry_pathname(entry).c_str());
/* Extra information for links. */ /* Extra information for links. */
if (archive_entry_hardlink(entry)) /* Hard link */ if (archive_entry_hardlink(entry)) /* Hard link */
@ -1641,7 +1666,7 @@ bool extract_tar(const char* outFileName, bool verbose,
archive_read_support_compression_all(a); archive_read_support_compression_all(a);
archive_read_support_format_all(a); archive_read_support_format_all(a);
struct archive_entry *entry; struct archive_entry *entry;
int r = archive_read_open_file(a, outFileName, 10240); int r = cm_archive_read_open_file(a, outFileName, 10240);
if(r) if(r)
{ {
cmSystemTools::Error("Problem with archive_read_open_file(): ", cmSystemTools::Error("Problem with archive_read_open_file(): ",
@ -1666,7 +1691,7 @@ bool extract_tar(const char* outFileName, bool verbose,
if(extract) if(extract)
{ {
cmSystemTools::Stdout("x "); cmSystemTools::Stdout("x ");
cmSystemTools::Stdout(archive_entry_pathname(entry)); cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
} }
else else
{ {
@ -1676,7 +1701,7 @@ bool extract_tar(const char* outFileName, bool verbose,
} }
else if(!extract) else if(!extract)
{ {
cmSystemTools::Stdout(archive_entry_pathname(entry)); cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
cmSystemTools::Stdout("\n"); cmSystemTools::Stdout("\n");
} }
if(extract) if(extract)
@ -1706,7 +1731,8 @@ bool extract_tar(const char* outFileName, bool verbose,
else if(const char* linktext = archive_entry_symlink(entry)) else if(const char* linktext = archive_entry_symlink(entry))
{ {
std::cerr << "cmake -E tar: warning: skipping symbolic link \"" std::cerr << "cmake -E tar: warning: skipping symbolic link \""
<< archive_entry_pathname(entry) << "\" -> \"" << cm_archive_entry_pathname(entry)
<< "\" -> \""
<< linktext << "\"." << std::endl; << linktext << "\"." << std::endl;
} }
#endif #endif
@ -1715,7 +1741,7 @@ bool extract_tar(const char* outFileName, bool verbose,
cmSystemTools::Error("Problem with archive_write_header(): ", cmSystemTools::Error("Problem with archive_write_header(): ",
archive_error_string(ext)); archive_error_string(ext));
cmSystemTools::Error("Current file: ", cmSystemTools::Error("Current file: ",
archive_entry_pathname(entry)); cm_archive_entry_pathname(entry).c_str());
break; break;
} }
} }