MakeImport/MakePEF: communicate exact member name to MakePEF even if file system does not support MacRoman-encoded filenames.

This commit is contained in:
Wolfgang Thaller 2017-04-25 01:16:09 +02:00
parent 3858c32613
commit d55bee477e
2 changed files with 49 additions and 1 deletions

View File

@ -1,6 +1,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <utility>
#include <vector>
#include <string>
@ -268,11 +269,28 @@ void MakeImportLibraryMulti(fs::path path, fs::path libname)
for(auto &member : members)
{
std::ostringstream memberNameStream;
// classic MacOS shared library names are in MacRoman and
// may contain wierd characters; the shared library name is used
// as the file name for the archive member, so there can be problems.
//
// We encode the file name to hex (and add a human readable name).
// MakePEF contains corresponding decoder logic.
memberNameStream << "imp__";
for(char c : member.name)
{
if(isalnum(c))
memberNameStream << c;
}
memberNameStream << "_";
for(char c : member.name)
{
int cc = (unsigned char) c;
memberNameStream << std::setw(2) << std::setfill('0') << std::hex
<< cc;
}
memberNameStream << "_" << memberIndex++;
string memberName = memberNameStream.str();

View File

@ -9,7 +9,7 @@
#include <assert.h>
#include <stdint.h>
#include <ctype.h>
#include "PEF.h"
@ -306,6 +306,36 @@ void mkpef(const std::string& inFn, const std::string& outFn)
}
}
if(name.length() > 5)
{
// the shared library name has been encoded as hex by MakeImport
// in order to avoid potential file name issues
// classic MacOS shared library names are in MacRoman and
// may contain wierd characters; the shared library name is used
// as the file name for the archive member, so there can be problems.
if(name.substr(0,5) == "imp__")
{
std::string realName;
int i;
int n = name.size();
for(i = 5; i < n && name[i] != '_'; i++)
;
++i;
for(; i + 1 < n && name[i] != '_'; i+=2)
{
char c1 = tolower(name[i]);
char c2 = tolower(name[i+1]);
assert(isdigit(c1) || (c1 >= 'a' && c1 <= 'f'));
assert(isdigit(c2) || (c2 >= 'a' && c2 <= 'f'));
int c = (c1 >= 'a' ? c1 - 'a' + 10 : c1 - '0') * 16
+ (c2 >= 'a' ? c2 - 'a' + 10 : c2 - '0');
realName += (char)c;
}
name = realName;
}
}
if(verboseFlag)
{
std::cerr << "PEF name \"" << name << '"';