Improve filename handling when reading from archives

This updates GenericEntry's filename handling to be more careful
about Mac OS Roman vs. Unicode.  Most of the work is still done with
a CP-1252 conversion instead of MOR, but we now do a proper
conversion on the "display name", so we see the right thing in the
content list and file viewer.

Copy & paste, disk-to-file-archive, and file-archive-to-disk
conversions should work (correctly) as before.  Extracted files will
still have "_" or "%AA" instead of a Unicode TRADE MARK SIGN, but
that's fine for now -- we can extract and re-add the files losslessly.

The filenames are now stored in CStrings rather than WCHAR*.

Also, fixed a bad initializer in the file-archive-to-disk conversion
dialog.
This commit is contained in:
Andy McFadden 2015-01-08 17:41:53 -08:00
parent b79498da50
commit 00e6b3ab5e
18 changed files with 248 additions and 202 deletions

View File

@ -636,8 +636,7 @@ int AcuArchive::CreateEntry(const AcuFileEntry* pEntry)
* Create the new entry.
*/
pNewEntry = new AcuEntry(this);
CString fileName(pEntry->fileName);
pNewEntry->SetPathName(fileName);
pNewEntry->SetPathNameMOR(pEntry->fileName);
pNewEntry->SetFssep(kAcuFssep);
pNewEntry->SetFileType(pEntry->fileType);
pNewEntry->SetAuxType(pEntry->auxType);
@ -754,7 +753,7 @@ bool AcuArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
while (pSelEntry != NULL) {
pEntry = (AcuEntry*) pSelEntry->GetEntry();
LOGI(" Testing '%ls' (offset=%ld)", pEntry->GetDisplayName(),
LOGD(" Testing '%ls' (offset=%ld)", (LPCWSTR) pEntry->GetDisplayName(),
pEntry->GetOffset());
SET_PROGRESS_UPDATE2(0, pEntry->GetDisplayName(), NULL);
@ -764,11 +763,11 @@ bool AcuArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
if (nerr == kNuErrAborted) {
CString title;
CheckedLoadString(&title, IDS_MB_APP_NAME);
errMsg = "Cancelled.";
errMsg = L"Cancelled.";
pMsgWnd->MessageBox(errMsg, title, MB_OK);
} else {
errMsg.Format(L"Failed while testing '%ls': %hs.",
pEntry->GetPathName(), NuStrError(nerr));
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
}
goto bail;

View File

@ -471,9 +471,9 @@ void MainWindow::OnActionsCreateSubdir(void)
return;
}
LOGI("Creating subdir in '%ls'", pEntry->GetPathName());
LOGI("Creating subdir in '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
csDialog.fBasePath = pEntry->GetPathName();
csDialog.fBasePath = pEntry->GetPathNameUNI();
csDialog.fpArchive = fpOpenArchive;
csDialog.fpParentEntry = pEntry;
csDialog.fNewName = "New.Subdir";
@ -638,7 +638,7 @@ void MainWindow::DoBulkExtract(SelectionSet* pSelSet,
GenericEntry* pEntry = pSelEntry->GetEntry();
if (pEntry->GetDamaged()) {
LOGI("Skipping '%ls' due to damage", pEntry->GetPathName());
LOGI("Skipping '%ls' due to damage", (LPCWSTR) pEntry->GetPathNameUNI());
continue;
}
@ -686,7 +686,7 @@ void MainWindow::DoBulkExtract(SelectionSet* pSelSet,
pEntry->GetFileType(),
pEntry->GetAuxType(),
ReformatterSourceFormat(pEntry->GetSourceFS()),
pEntry->GetFileNameExtensionA());
pEntry->GetFileNameExtensionMOR());
pHolder->TestApplicability();
}
}
@ -787,7 +787,8 @@ bool MainWindow::ExtractEntry(GenericEntry* pEntry, int thread,
extractAs2MG = true;
} else {
LOGI("Not extracting funky image '%ls' as 2MG (len=%I64d)",
pEntry->GetPathName(), pEntry->GetUncompressedLen());
(LPCWSTR) pEntry->GetPathNameUNI(),
pEntry->GetUncompressedLen());
}
}
}
@ -826,7 +827,7 @@ bool MainWindow::ExtractEntry(GenericEntry* pEntry, int thread,
*/
ASSERT(pExtOpts->fExtractPath.Right(1) == "\\");
CString adjustedExtractPath(pExtOpts->fExtractPath);
if (!pExtOpts->fStripFolderNames && pEntry->GetSubVolName() != NULL) {
if (!pExtOpts->fStripFolderNames && !pEntry->GetSubVolName().IsEmpty()) {
adjustedExtractPath += pEntry->GetSubVolName();
adjustedExtractPath += "\\";
}

View File

@ -470,8 +470,7 @@ NuError BnyArchive::LoadContentsCallback(BnyFileEntry* pEntry)
* Create the new entry.
*/
pNewEntry = new BnyEntry(this);
CString fileNameW(fileName);
pNewEntry->SetPathName(fileNameW);
pNewEntry->SetPathNameMOR(fileName);
pNewEntry->SetFssep(kBNYFssep);
pNewEntry->SetFileType(pEntry->fileType);
pNewEntry->SetAuxType(pEntry->auxType);
@ -853,7 +852,7 @@ bool BnyArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
while (pSelEntry != NULL) {
pEntry = (BnyEntry*) pSelEntry->GetEntry();
LOGI(" Testing '%ls' (offset=%ld)", pEntry->GetDisplayName(),
LOGI(" Testing '%ls' (offset=%ld)", (LPCWSTR) pEntry->GetDisplayName(),
pEntry->GetOffset());
SET_PROGRESS_UPDATE2(0, pEntry->GetDisplayName(), NULL);
@ -867,7 +866,7 @@ bool BnyArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
pMsgWnd->MessageBox(errMsg, title, MB_OK);
} else {
errMsg.Format(L"Failed while testing '%ls': %hs.",
pEntry->GetPathName(), NuStrError(nerr));
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
}
goto bail;

View File

@ -202,7 +202,7 @@ CString MainWindow::CreateFileList(SelectionSet* pSelSet)
pEntry = pSelEntry->GetEntry();
ASSERT(pEntry != NULL);
fileName = DblDblQuote(pEntry->GetPathName());
fileName = DblDblQuote(pEntry->GetPathNameUNI());
subVol = pEntry->GetSubVolName();
ContentList::MakeFileTypeDisplayString(pEntry, fileTypeBuf);
fileType = DblDblQuote(fileTypeBuf); // Mac HFS types might have '"'?
@ -292,7 +292,7 @@ HGLOBAL MainWindow::CreateFileCollection(SelectionSet* pSelSet)
if (pEntry->GetRecordKind() != GenericEntry::kRecordKindVolumeDir) {
totalLength += sizeof(FileCollectionEntry);
totalLength += (wcslen(pEntry->GetPathName()) +1) * sizeof(WCHAR);
totalLength += (wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR);
numFiles++;
if (pEntry->GetRecordKind() != GenericEntry::kRecordKindDirectory) {
totalLength += (long) pEntry->GetDataForkLen();
@ -373,8 +373,7 @@ HGLOBAL MainWindow::CreateFileCollection(SelectionSet* pSelSet)
pEntry = pSelEntry->GetEntry();
ASSERT(pEntry != NULL);
CString displayName(pEntry->GetDisplayName());
fpActionProgress->SetArcName(displayName);
fpActionProgress->SetArcName(pEntry->GetDisplayName());
errStr = CopyToCollection(pEntry, &buf, &remainingLen);
if (!errStr.IsEmpty()) {
@ -460,7 +459,7 @@ CString MainWindow::CopyToCollection(GenericEntry* pEntry, void** pBuf,
memset(&collEnt, 0x99, sizeof(collEnt));
collEnt.signature = kEntrySignature;
collEnt.dataOffset = sizeof(collEnt);
collEnt.fileNameLen = (wcslen(pEntry->GetPathName()) +1) * sizeof(WCHAR);
collEnt.fileNameLen = (wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR);
if (pEntry->GetRecordKind() == GenericEntry::kRecordKindDirectory) {
collEnt.dataLen = collEnt.rsrcLen = collEnt.cmmtLen = 0;
} else {
@ -490,7 +489,7 @@ CString MainWindow::CopyToCollection(GenericEntry* pEntry, void** pBuf,
remLen -= sizeof(collEnt);
/* copy string with terminating null */
memcpy(buf, pEntry->GetPathName(), collEnt.fileNameLen);
memcpy(buf, pEntry->GetPathNameUNI(), collEnt.fileNameLen);
buf += collEnt.fileNameLen;
remLen -= collEnt.fileNameLen;

View File

@ -62,8 +62,8 @@ static inline int MaxVal(int a, int b)
int ContentList::OnCreate(LPCREATESTRUCT lpcs)
{
CString colHdrs[kNumVisibleColumns] = {
"Pathname", "Type", "Aux", "Mod Date",
"Format", "Size", "Ratio", "Packed", "Access"
L"Pathname", L"Type", L"Aux", L"Mod Date",
L"Format", L"Size", L"Ratio", L"Packed", L"Access"
}; // these should come from string table, not hard-coded
static int colFmt[kNumVisibleColumns] = {
LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT,
@ -90,7 +90,7 @@ int ContentList::OnCreate(LPCREATESTRUCT lpcs)
LoadHeaderImages();
CHeaderCtrl* pHeader = GetHeaderCtrl();
if (pHeader == NULL)
LOGI("GLITCH: couldn't get header ctrl");
LOGW("GLITCH: couldn't get header ctrl");
ASSERT(pHeader != NULL);
pHeader->SetImageList(&fHdrImageList);
@ -114,7 +114,7 @@ int ContentList::OnCreate(LPCREATESTRUCT lpcs)
void ContentList::OnDestroy(void)
{
LOGI("ContentList OnDestroy");
LOGD("ContentList OnDestroy");
ExportColumnWidths();
CListCtrl::OnDestroy();
@ -130,7 +130,7 @@ void ContentList::OnColumnClick(NMHDR* pnmh, LRESULT* pResult)
{
NM_LISTVIEW* pnmlv = (NM_LISTVIEW*) pnmh;
LOGI("OnColumnClick!!");
LOGD("ContentList OnColumnClick");
if (fpLayout->GetSortColumn() == pnmlv->iSubItem)
fpLayout->SetAscending(!fpLayout->GetAscending());
@ -156,7 +156,7 @@ void ContentList::NewColumnWidths(void)
int width = fpLayout->GetColumnWidth(i);
if (width == ColumnLayout::kWidthDefaulted) {
width = GetDefaultWidth(i);
LOGI("Defaulting width %d to %d", i, width);
LOGD("Defaulting width %d to %d", i, width);
fpLayout->SetColumnWidth(i, width);
}
SetColumnWidth(i, width);
@ -204,7 +204,7 @@ long* ContentList::GetSelectionSerials(long* pSelCount)
long maxCount;
maxCount = GetSelectedCount();
LOGI("GetSelectionSerials (maxCount=%d)", maxCount);
LOGD("GetSelectionSerials (maxCount=%d)", maxCount);
if (maxCount > 0) {
savedSel = new long[maxCount];
@ -420,6 +420,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
wcscpy(plvdi->item.pszText, pEntry->GetDisplayName());
}
#if 0 // no longer needed -- "display names" are converted to Unicode
/*
* Sanitize the string. This is really only necessary for
* HFS, which has 8-bit "Macintosh Roman" filenames. The Win32
@ -434,6 +435,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
str++;
}
}
#endif
break;
case 1: // type
MakeFileTypeDisplayString(pEntry, plvdi->item.pszText);
@ -494,7 +496,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
/*
* Helper functions for sort routine.
*/
static inline int CompareUnsignedLong(unsigned long u1, unsigned long u2)
static inline int CompareUnsignedLong(uint32_t u1, uint32_t u2)
{
if (u1 < u2)
return -1;

View File

@ -111,7 +111,7 @@ void ConvDiskOptionsDialog::ResetSizeControls(void)
CString spaceReq;
LOGI("Resetting size controls");
spaceReq.Format(IDS_CONVDISK_SPACEREQ, "(unknown)");
spaceReq.Format(IDS_CONVDISK_SPACEREQ, L"(unknown)");
pWnd = GetDlgItem(IDC_CONVDISK_SPACEREQ);
ASSERT(pWnd != NULL);
pWnd->SetWindowText(spaceReq);
@ -129,8 +129,8 @@ void ConvDiskOptionsDialog::ResetSizeControls(void)
void ConvDiskOptionsDialog::LimitSizeControls(long totalBlocks, long blocksUsed)
{
LOGI("LimitSizeControls %ld %ld", totalBlocks, blocksUsed);
LOGI("Full volume requires %ld bitmap blocks",
LOGD("LimitSizeControls %ld %ld", totalBlocks, blocksUsed);
LOGD("Full volume requires %ld bitmap blocks",
NewDiskSize::GetNumBitmapBlocks_ProDOS(totalBlocks));
CWnd* pWnd;

View File

@ -951,7 +951,7 @@ int DiskArchive::InternalReload(CWnd* pMsgWnd)
int DiskArchive::LoadDiskFSContents(DiskFS* pDiskFS, const WCHAR* volName)
{
static const WCHAR* kBlankFileName = L"<blank filename>";
static const char* kBlankFileNameMOR = "<blank filename>";
A2File* pFile;
DiskEntry* pNewEntry;
DiskFS::SubVolume* pSubVol;
@ -971,15 +971,15 @@ int DiskArchive::LoadDiskFSContents(DiskFS* pDiskFS, const WCHAR* volName)
if (pNewEntry == NULL)
return -1;
CString path(pFile->GetPathName());
CStringA path(pFile->GetPathName());
if (path.IsEmpty())
path = kBlankFileName;
path = kBlankFileNameMOR;
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) &&
wantCoerceDOSFilenames)
{
InjectLowercase(&path);
}
pNewEntry->SetPathName(path);
pNewEntry->SetPathNameMOR(path);
if (volName[0] != '\0')
pNewEntry->SetSubVolName(volName);
pNewEntry->SetFssep(pFile->GetFssep());
@ -2072,7 +2072,7 @@ bool DiskArchive::CreateSubdir(CWnd* pMsgWnd, GenericEntry* pParentEntry,
if (pFile->IsVolumeDirectory()) {
pathName = newName;
} else {
pathName = pParentEntry->GetPathName();
pathName = pParentEntry->GetPathNameMOR();
pathName += pParentEntry->GetFssep();
pathName += newName;
}
@ -2192,9 +2192,10 @@ bool DiskArchive::DeleteSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
goto bail;
}
LOGI(" Deleting '%ls' from '%hs'", (LPCWSTR) pEntry->GetPathName(),
LOGI(" Deleting '%ls' from '%hs'", (LPCWSTR) pEntry->GetPathNameUNI(),
(LPCSTR) pFile->GetDiskFS()->GetVolumeName());
SET_PROGRESS_UPDATE2(0, pEntry->GetPathName(), NULL);
// TODO: should be using display name for progress updater?
SET_PROGRESS_UPDATE2(0, pEntry->GetPathNameUNI(), NULL);
/*
* Ask the DiskFS to delete the file. As soon as this completes,
@ -2270,7 +2271,7 @@ bool DiskArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
RenameEntryDialog renameDlg(pMsgWnd);
DiskEntry* pEntry = (DiskEntry*) pSelEntry->GetEntry();
LOGI(" Renaming '%ls'", pEntry->GetPathName());
LOGI(" Renaming '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
if (!SetRenameFields(pMsgWnd, pEntry, &renameDlg))
break;
@ -2290,19 +2291,21 @@ bool DiskArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
dierr = pDiskFS->RenameFile(pFile, newNameA);
if (dierr != kDIErrNone) {
errMsg.Format(L"Unable to rename '%ls' to '%ls': %hs.",
pEntry->GetPathName(), (LPCWSTR) renameDlg.fNewName,
(LPCWSTR) pEntry->GetPathNameUNI(),
(LPCWSTR) renameDlg.fNewName,
DiskImgLib::DIStrError(dierr));
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
goto bail;
}
LOGD("Rename of '%ls' to '%ls' succeeded",
pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
(LPCWSTR) pEntry->GetDisplayName(),
(LPCWSTR) renameDlg.fNewName);
} else if (result == IDCANCEL) {
LOGI("Canceling out of remaining renames");
break;
} else {
/* 3rd possibility is IDIGNORE, i.e. skip this entry */
LOGI("Skipping rename of '%ls'", pEntry->GetDisplayName());
LOGI("Skipping rename of '%ls'", (LPCWSTR) pEntry->GetDisplayName());
}
pSelEntry = pSelSet->IterNext();
@ -2341,20 +2344,20 @@ bool DiskArchive::SetRenameFields(CWnd* pMsgWnd, DiskEntry* pEntry,
if (!pDiskFS->GetReadWriteSupported()) {
CString errMsg;
errMsg.Format(L"Unable to rename '%ls': operation not supported.",
pEntry->GetPathName());
(LPCWSTR) pEntry->GetPathNameUNI());
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
return false;
}
if (pDiskFS->GetFSDamaged()) {
CString errMsg;
errMsg.Format(L"Unable to rename '%ls': the disk it's on appears to be damaged.",
pEntry->GetPathName());
(LPCWSTR) pEntry->GetPathNameUNI());
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
return false;
}
pDialog->SetCanRenameFullPath(renameFullPath);
pDialog->fOldName = pEntry->GetPathName();
pDialog->fOldName = pEntry->GetPathNameUNI();
pDialog->fFssep = pEntry->GetFssep();
pDialog->fpArchive = this;
pDialog->fpEntry = pEntry;
@ -2576,7 +2579,7 @@ GenericArchive::XferStatus DiskArchive::XferSelection(CWnd* pMsgWnd,
if (pEntry->GetDamaged()) {
LOGI(" XFER skipping damaged entry '%ls'",
pEntry->GetDisplayName());
(LPCWSTR) pEntry->GetDisplayName());
continue;
}
@ -2584,15 +2587,14 @@ GenericArchive::XferStatus DiskArchive::XferSelection(CWnd* pMsgWnd,
* Do a quick de-colonizing pass for non-ProDOS volumes, then prepend
* the subvolume name (if any).
*/
fixedPathName = pEntry->GetPathName();
fixedPathName = pEntry->GetPathNameUNI();
if (fixedPathName.IsEmpty())
fixedPathName = L"(no filename)";
if (pEntry->GetFSFormat() != DiskImg::kFormatProDOS)
fixedPathName.Replace(PathProposal::kDefaultStoredFssep, '.');
if (pEntry->GetSubVolName() != NULL) {
CString tmpStr;
tmpStr = pEntry->GetSubVolName();
tmpStr += (char)PathProposal::kDefaultStoredFssep;
if (!pEntry->GetSubVolName().IsEmpty()) {
CString tmpStr = pEntry->GetSubVolName();
tmpStr += (char) PathProposal::kDefaultStoredFssep;
tmpStr += fixedPathName;
fixedPathName = tmpStr;
}

View File

@ -23,7 +23,7 @@ END_MESSAGE_MAP()
void EditPropsDialog::InitProps(GenericEntry* pEntry)
{
fPathName = pEntry->GetPathName();
fPathName = pEntry->GetPathNameUNI();
fProps.fileType = pEntry->GetFileType();
fProps.auxType = pEntry->GetAuxType();
fProps.access = pEntry->GetAccess();

View File

@ -43,7 +43,8 @@ public:
// init the "extract from archive" side from a GenericEntry struct
void Init(GenericEntry* pEntry) {
fStoredPathName = pEntry->GetPathName();
// TODO(Unicode): use Unicode/MOR conversion rather than CP-1252
fStoredPathName = pEntry->GetPathNameMOR();
fStoredFssep = pEntry->GetFssep();
//if (fStoredFssep == '\0') // e.g. embedded DOS 3.3 volume
// fStoredFssep = kDefaultStoredFssep;

View File

@ -13,6 +13,7 @@
#include "NufxArchive.h"
#include "FileNameConv.h"
#include "ContentList.h"
#include "../reformat/ReformatBase.h"
#include "Main.h"
#include <sys/stat.h>
#include <errno.h>
@ -47,12 +48,7 @@
*/
GenericEntry::GenericEntry(void)
: fPathName(NULL),
fFileName(NULL),
fFileNameExtension(NULL),
fFssep('\0'),
fSubVolName(NULL),
fDisplayName(NULL),
: fFssep('\0'),
fFileType(0),
fAuxType(0),
fAccess(0),
@ -77,24 +73,24 @@ GenericEntry::GenericEntry(void)
{
}
GenericEntry::~GenericEntry(void)
{
delete[] fPathName;
delete[] fSubVolName;
delete[] fDisplayName;
}
GenericEntry::~GenericEntry(void) {}
void GenericEntry::SetPathName(const WCHAR* path)
void GenericEntry::SetPathNameMOR(const char* path)
{
ASSERT(path != NULL && wcslen(path) > 0);
if (fPathName != NULL)
delete fPathName;
fPathName = wcsdup(path);
ASSERT(path != NULL && strlen(path) > 0);
fPathNameMOR = path;
// nuke the derived fields
fFileName = NULL;
fFileNameExtension = NULL;
delete[] fDisplayName;
fDisplayName = NULL;
fFileName = L"";
fFileNameExtension = L"";
fDisplayName = L"";
/*
* Generate the Unicode representation from the Mac OS Roman source.
* For now, we just treat the input as CP-1252.
*
* TODO(Unicode)
*/
fPathNameUNI = fPathNameMOR;
/*
* Warning: to be 100% pedantically correct here, we should NOT do this
@ -103,62 +99,73 @@ void GenericEntry::SetPathName(const WCHAR* path)
* the underscorage until the first GetPathName call.
*/
const Preferences* pPreferences = GET_PREFERENCES();
if (pPreferences->GetPrefBool(kPrSpacesToUnder))
SpacesToUnderscores(fPathName);
if (pPreferences->GetPrefBool(kPrSpacesToUnder)) {
SpacesToUnderscores(&fPathNameMOR);
}
}
const WCHAR* GenericEntry::GetFileName(void)
const CString& GenericEntry::GetFileName(void)
{
ASSERT(fPathName != NULL);
if (fFileName == NULL)
fFileName = PathName::FilenameOnly(fPathName, fFssep);
ASSERT(!fPathNameMOR.IsEmpty());
if (fFileName.IsEmpty()) {
fFileName = PathName::FilenameOnly(fPathNameUNI, fFssep);
}
return fFileName;
}
const WCHAR* GenericEntry::GetFileNameExtension(void)
const CString& GenericEntry::GetFileNameExtension(void)
{
ASSERT(fPathName != NULL);
if (fFileNameExtension == NULL)
fFileNameExtension = PathName::FindExtension(fPathName, fFssep);
ASSERT(!fPathNameMOR.IsEmpty());
if (fFileNameExtension.IsEmpty()) {
fFileNameExtension = PathName::FindExtension(fPathNameUNI, fFssep);
}
return fFileNameExtension;
}
CStringA GenericEntry::GetFileNameExtensionA(void)
const CStringA& GenericEntry::GetFileNameExtensionMOR(void)
{
return GetFileNameExtension();
ASSERT(!fPathNameMOR.IsEmpty());
if (fFileNameExtensionMOR.IsEmpty()) {
CString str = PathName::FindExtension(fPathNameUNI, fFssep);
// TODO(Unicode): either get the extension from the MOR filename,
// or convert this properly from Unicode to MOR (not CP-1252).
fFileNameExtensionMOR = str;
}
return fFileNameExtensionMOR;
}
void GenericEntry::SetSubVolName(const WCHAR* name)
{
delete[] fSubVolName;
fSubVolName = NULL;
if (name != NULL) {
fSubVolName = wcsdup(name);
}
fSubVolName = name;
}
const WCHAR* GenericEntry::GetDisplayName(void) const
// Simple Mac OS Roman to Unicode conversion.
static CString ConvertMORToUNI(const CStringA& strMOR)
{
ASSERT(fPathName != NULL);
if (fDisplayName != NULL)
return fDisplayName;
// TODO: hmm...
GenericEntry* pThis = const_cast<GenericEntry*>(this);
int len = wcslen(fPathName) +1;
if (fSubVolName != NULL)
len += wcslen(fSubVolName) +1;
pThis->fDisplayName = new WCHAR[len];
if (fSubVolName != NULL) {
WCHAR xtra[2] = { DiskFS::kDIFssep, '\0' };
wcscpy(pThis->fDisplayName, fSubVolName);
wcscat(pThis->fDisplayName, xtra);
} else {
pThis->fDisplayName[0] = '\0';
// We know that all MOR characters are represented in Unicode with a
// single BMP code point, so we know that strlen(MOR) == wcslen(UNI).
const int len = strMOR.GetLength();
CString strUNI;
WCHAR* uniBuf = strUNI.GetBuffer(len);
for (int i = 0; i < len; i++) {
uniBuf[i] = ReformatText::ConvertMacRomanToUTF16(strMOR[i]);
}
wcscat(pThis->fDisplayName, fPathName);
return pThis->fDisplayName;
strUNI.ReleaseBuffer(len);
return strUNI;
}
const CString& GenericEntry::GetDisplayName(void) const
{
ASSERT(!fPathNameMOR.IsEmpty());
if (!fDisplayName.IsEmpty()) {
return fDisplayName;
}
if (!fSubVolName.IsEmpty()) {
fDisplayName = fSubVolName + (WCHAR) DiskFS::kDIFssep;
}
fDisplayName += ConvertMORToUNI(fPathNameMOR);
return fDisplayName;
}
const WCHAR* GenericEntry::GetFileTypeString(void) const
@ -166,13 +173,9 @@ const WCHAR* GenericEntry::GetFileTypeString(void) const
return PathProposal::FileTypeString(fFileType);
}
/*static*/ void GenericEntry::SpacesToUnderscores(WCHAR* buf)
/*static*/ void GenericEntry::SpacesToUnderscores(CStringA* pStr)
{
while (*buf != '\0') {
if (*buf == ' ')
*buf = '_';
buf++;
}
pStr->Replace(' ', '_');
}
/*static*/ bool GenericEntry::CheckHighASCII(const uint8_t* buffer,
@ -1091,7 +1094,7 @@ void SelectionSet::AddToSet(GenericEntry* pEntry, int threadMask)
{
SelectionEntry* pSelEntry;
LOGV(" Sel '%ls'", pEntry->GetPathName());
LOGV(" Sel '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
if (!(threadMask & GenericEntry::kAllowVolumeDir) &&
pEntry->GetRecordKind() == GenericEntry::kRecordKindVolumeDir)
@ -1197,7 +1200,7 @@ void SelectionSet::Dump(void)
pEntry = fEntryHead;
while (pEntry != NULL) {
LOGI(" : name='%ls'", pEntry->GetEntry()->GetPathName());
LOGI(" : name='%ls'", (LPCWSTR) pEntry->GetEntry()->GetPathNameUNI());
pEntry = pEntry->GetNext();
}
}

View File

@ -191,14 +191,29 @@ public:
long GetIndex(void) const { return fIndex; }
void SetIndex(long idx) { fIndex = idx; }
const WCHAR* GetPathName(void) const { return fPathName; }
void SetPathName(const WCHAR* path);
const WCHAR* GetFileName(void);
const WCHAR* GetFileNameExtension(void); // returns e.g. ".SHK"
CStringA GetFileNameExtensionA(void);
/*
* Set the pathname. This comes from a file archive or disk image,
* so it's always in Mac OS Roman format.
*
* Calling this will invalidate any strings previously returned by
* GetPathName*(), GetFileName*(), and GetDisplayName().
*/
void SetPathNameMOR(const char* pathNameMOR);
const CStringA& GetPathNameMOR(void) const { return fPathNameMOR; }
const CString& GetPathNameUNI(void) const { return fPathNameUNI; }
const CString& GetFileName(void);
const CString& GetFileNameExtension(void); // returns e.g. ".SHK"
const CStringA& GetFileNameExtensionMOR(void);
/*
* Returns the "display" name. This is a combination of the sub-volume
* name and the path name. This string is intended for display only,
* and may include characters that aren't legal on the filesystem.
*/
const CString& GetDisplayName(void) const;
void SetSubVolName(const WCHAR* name);
const WCHAR* GetSubVolName(void) const { return fSubVolName; }
const WCHAR* GetDisplayName(void) const; // not really "const"
const CString& GetSubVolName(void) const { return fSubVolName; }
char GetFssep(void) const { return fFssep; }
void SetFssep(char fssep) { fFssep = fssep; }
@ -287,19 +302,32 @@ public:
size_t len, ConvertEOL* pConv, ConvertHighASCII* pConvHA,
bool* pLastCR);
protected:
private:
/*
* Convert spaces to underscores, modifying the string.
*/
static void SpacesToUnderscores(WCHAR* buf);
static void SpacesToUnderscores(CStringA* pStr);
private:
WCHAR* fPathName;
const WCHAR* fFileName; // points within fPathName
const WCHAR* fFileNameExtension; // points within fPathName
/*
* This represents a file from an archive or disk image, so the Mac OS
* Roman representation is the "true" version. The Unicode version
* is how we will use it on Windows (e.g. for file extraction), so
* it will be a CP-1252 conversion until the various libraries
* support UTF-16 filenames.
*
* The "display name" is only used for display, and should do a proper
* MOR to Unicode conversion so the file name looks right.
*/
CStringA fPathNameMOR; // original path name, Mac OS Roman chars
CString fPathNameUNI; // Unicode conversion
CString fFileName; // filename component of fPathNameUNI
CString fFileNameExtension; // filename extension from fPathNameUNI
CStringA fFileNameExtensionMOR;
char fFssep;
WCHAR* fSubVolName; // sub-volume prefix, or NULL if none
WCHAR* fDisplayName; // combination of sub-vol and path
CString fSubVolName; // sub-volume prefix, or NULL if none
mutable CString fDisplayName; // combination of sub-vol and path
uint32_t fFileType;
uint32_t fAuxType;
uint32_t fAccess;

View File

@ -1422,11 +1422,11 @@ void MainWindow::HandleDoubleClick(void)
if (pEntry == NULL)
return;
LOGI(" Double-click GOT '%ls'", pEntry->GetPathName());
LOGI(" Double-click got '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
const WCHAR* ext;
long fileType, auxType;
ext = PathName::FindExtension(pEntry->GetPathName(), pEntry->GetFssep());
ext = PathName::FindExtension(pEntry->GetPathNameUNI(), pEntry->GetFssep());
fileType = pEntry->GetFileType();
auxType = pEntry->GetAuxType();
@ -1587,7 +1587,7 @@ int MainWindow::TmpExtractForExternal(GenericEntry* pEntry)
{
const WCHAR* ext;
ext = PathName::FindExtension(pEntry->GetPathName(), pEntry->GetFssep());
ext = PathName::FindExtension(pEntry->GetPathNameUNI(), pEntry->GetFssep());
WCHAR nameBuf[MAX_PATH];
UINT unique;

View File

@ -796,8 +796,7 @@ NuResult NufxArchive::ContentFunc(NuArchive* pArchive, void* vpRecord)
pNewEntry = new NufxEntry(pArchive);
CStringW filenameW(pRecord->filenameMOR);
pNewEntry->SetPathName(filenameW);
pNewEntry->SetPathNameMOR(pRecord->filenameMOR);
pNewEntry->SetFssep(NuGetSepFromSysInfo(pRecord->recFileSysInfo));
pNewEntry->SetFileType(pRecord->recFileType);
pNewEntry->SetAuxType(pRecord->recExtraType);
@ -1389,7 +1388,7 @@ bool NufxArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
pEntry = (NufxEntry*) pSelEntry->GetEntry();
LOGI(" Testing %ld '%ls'", pEntry->GetRecordIdx(),
pEntry->GetPathName());
(LPCWSTR) pEntry->GetPathNameUNI());
nerr = NuTestRecord(fpArchive, pEntry->GetRecordIdx());
if (nerr != kNuErrNone) {
if (nerr == kNuErrAborted) {
@ -1399,7 +1398,7 @@ bool NufxArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
pMsgWnd->MessageBox(errMsg, title, MB_OK);
} else {
errMsg.Format(L"Failed while testing '%ls': %hs.",
pEntry->GetPathName(), NuStrError(nerr));
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
}
goto bail;
@ -1443,7 +1442,7 @@ bool NufxArchive::DeleteSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
pEntry = (NufxEntry*) pSelEntry->GetEntry();
LOGI(" Deleting %ld '%ls'", pEntry->GetRecordIdx(),
pEntry->GetPathName());
(LPCWSTR) pEntry->GetPathNameUNI());
nerr = NuDeleteRecord(fpArchive, pEntry->GetRecordIdx());
if (nerr != kNuErrNone) {
errMsg.Format(L"Unable to delete record %d: %hs.",
@ -1512,12 +1511,12 @@ bool NufxArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
SelectionEntry* pSelEntry = pSelSet->IterNext();
while (pSelEntry != NULL) {
NufxEntry* pEntry = (NufxEntry*) pSelEntry->GetEntry();
LOGI(" Renaming '%ls'", pEntry->GetPathName());
LOGD(" Renaming '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
RenameEntryDialog renameDlg(pMsgWnd);
renameDlg.SetCanRenameFullPath(renameFullPath);
renameDlg.SetCanChangeFssep(true);
renameDlg.fOldName = pEntry->GetPathName();
renameDlg.fOldName = pEntry->GetPathNameUNI();
renameDlg.fFssep = pEntry->GetFssep();
renameDlg.fpArchive = this;
renameDlg.fpEntry = pEntry;
@ -1530,19 +1529,19 @@ bool NufxArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
nerr = NuRename(fpArchive, pEntry->GetRecordIdx(),
newNameA, renameDlg.fFssep);
if (nerr != kNuErrNone) {
errMsg.Format(L"Unable to rename '%ls': %hs.", pEntry->GetPathName(),
NuStrError(nerr));
errMsg.Format(L"Unable to rename '%ls': %hs.",
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
break;
}
LOGI("Rename of '%ls' to '%ls' succeeded",
pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
LOGD("Rename of '%ls' to '%ls' succeeded",
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
} else if (result == IDCANCEL) {
LOGI("Canceling out of remaining renames");
break;
} else {
/* 3rd possibility is IDIGNORE, i.e. skip this entry */
LOGI("Skipping rename of '%ls'", pEntry->GetDisplayName());
LOGI("Skipping rename of '%ls'", (LPCWSTR) pEntry->GetDisplayName());
}
pSelEntry = pSelSet->IterNext();
@ -1606,7 +1605,7 @@ CString NufxArchive::TestPathName(const GenericEntry* pGenericEntry,
pEntry = GetEntries();
while (pEntry != NULL) {
if (pEntry != pGenericEntry &&
ComparePaths(pEntry->GetPathName(), pEntry->GetFssep(),
ComparePaths(pEntry->GetPathNameUNI(), pEntry->GetFssep(),
newName, newFssep) == 0)
{
errMsg = L"An entry with that name already exists.";
@ -1726,7 +1725,7 @@ bool NufxArchive::RecompressSelection(CWnd* pMsgWnd, SelectionSet* pSelSet,
ASSERT(pEntry != NULL);
CString dispStr;
dispStr.Format(L"Failed while recompressing '%ls': %ls.",
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
goto bail;
}
@ -1774,14 +1773,14 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
char* buf = NULL;
long len = 0;
LOGI(" Recompressing %ld '%ls'", pEntry->GetRecordIdx(),
pEntry->GetDisplayName());
LOGD(" Recompressing %ld '%ls'", pEntry->GetRecordIdx(),
(LPCWSTR) pEntry->GetDisplayName());
/* get a copy of the thread header */
pEntry->FindThreadInfo(threadKind, &thread, pErrMsg);
if (!pErrMsg->IsEmpty()) {
pErrMsg->Format(L"Unable to locate thread for %ls (type %d)",
pEntry->GetDisplayName(), threadKind);
(LPCWSTR) pEntry->GetDisplayName(), threadKind);
goto bail;
}
threadID = NuGetThreadID(&thread);
@ -1789,7 +1788,8 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
/* if it's already in the target format, skip it */
if (thread.thThreadFormat == pRecompOpts->fCompressionType) {
LOGI("Skipping (fmt=%d) '%ls'",
pRecompOpts->fCompressionType, pEntry->GetDisplayName());
pRecompOpts->fCompressionType,
(LPCWSTR) pEntry->GetDisplayName());
return true;
}
@ -1802,7 +1802,7 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
goto bail; /* abort anything that was pending */
} else if (result != IDOK) {
pErrMsg->Format(L"Failed while extracting '%ls': %ls",
pEntry->GetDisplayName(), (LPCWSTR) subErrMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) subErrMsg);
goto bail;
}
*pSizeInMemory += len;
@ -1884,13 +1884,24 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
/* in case we start handling CRC errors better */
if (pEntry->GetDamaged()) {
LOGI(" XFER skipping damaged entry '%ls'",
pEntry->GetDisplayName());
(LPCWSTR) pEntry->GetDisplayName());
continue;
}
LOGD(" XFER converting '%ls'", pEntry->GetDisplayName());
LOGD(" XFER converting '%ls'", (LPCWSTR) pEntry->GetDisplayName());
fileDetails.SetStrippedLocalPathName(pEntry->GetDisplayName());
// Generate a name that is the combination of the sub-volume name
// (if any) and the path name. This is likely the same as the
// "display name", but that is officially for display only, and
// shouldn't be used for this.
CString xferName;
const CString& subVolName = pEntry->GetSubVolName();
if (!subVolName.IsEmpty()) {
xferName = subVolName + (WCHAR) DiskFS::kDIFssep;
}
xferName += pEntry->GetPathNameUNI();
fileDetails.SetStrippedLocalPathName(xferName);
fileDetails.SetFssep(PathProposal::kDefaultStoredFssep);
fileDetails.SetFileSysFmt(DiskImg::kFormatUnknown);
fileDetails.SetFileType(pEntry->GetFileType());
@ -1935,7 +1946,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
goto bail; /* abort anything that was pending */
} else if (result != IDOK) {
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
goto bail;
}
@ -1956,7 +1967,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
goto bail; /* abort anything that was pending */
} else if (result != IDOK) {
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
goto bail;
}
@ -1979,7 +1990,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
goto bail; /* abort anything that was pending */
} else if (result != IDOK) {
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
goto bail;
}
@ -1991,7 +2002,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
if (dataLen < 0 && rsrcLen < 0) {
LOGI(" XFER: WARNING: nothing worth transferring in '%ls'",
pEntry->GetDisplayName());
(LPCWSTR) pEntry->GetDisplayName());
continue;
}
@ -2000,7 +2011,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
if (!errMsg.IsEmpty()) {
LOGI("XferFile failed!");
errMsg.Format(L"Failed while transferring '%ls': %ls.",
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
goto bail;
}

View File

@ -764,10 +764,10 @@ int ViewFilesDialog::ReformatPrep(GenericEntry* pEntry)
pEntry->GetFileType(),
pEntry->GetAuxType(),
MainWindow::ReformatterSourceFormat(pEntry->GetSourceFS()),
pEntry->GetFileNameExtensionA());
pEntry->GetFileNameExtensionMOR());
/* figure out which reformatters apply to this file */
LOGI("Testing reformatters");
LOGD("Testing reformatters");
fpHolder->TestApplicability();
return 0;

View File

@ -674,7 +674,9 @@ static const char gFileTypeNames[256][4] = {
* Sanitize a string. The Mac likes to stick control characters into
* things, e.g. ^C and ^M, and uses high ASCII for special characters.
*
* TODO: use Mac Roman unicode translation instead
* TODO(Unicode): we could do a Mac OS Roman to Unicode conversion, but
* we'd probably want to output UTF-8 (which Windows accessories like
* Notepad *are* able to read).
*/
static void MacSanitize(char* str)
{
@ -687,7 +689,7 @@ static void MacSanitize(char* str)
int MainWindow::LoadDiskFSContents(DiskFS* pDiskFS, const char* volName,
ScanOpts* pScanOpts)
{
static const char* kBlankFileName = "<blank filename>";
static const char* kBlankFileNameMOR = "<blank filename>";
DiskFS::SubVolume* pSubVol = NULL;
A2File* pFile;
@ -714,11 +716,10 @@ int MainWindow::LoadDiskFSContents(DiskFS* pDiskFS, const char* volName,
const char* ccp = pFile->GetPathName();
ASSERT(ccp != NULL);
if (strlen(ccp) == 0)
ccp = kBlankFileName;
ccp = kBlankFileNameMOR;
CString path(ccp);
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) && 0)
{
CStringA path(ccp);
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) && 0) {
InjectLowercase(&path);
}

View File

@ -284,6 +284,13 @@ public:
kRTFFlagColorTable = 1, // include color table
};
// Convert a Mac OS Roman character value (from a IIgs document) to
// its UTF-16 Unicode equivalent. This also includes a conversion
// for the control characters.
static uint16_t ConvertMacRomanToUTF16(uint8_t ch) {
return kUTF16Conv[ch];
}
protected:
void RTFBegin(int flags = 0);
void RTFEnd(void);
@ -373,20 +380,13 @@ protected:
// Convert a Mac OS Roman character value (from a IIgs document) to
// an 8-bit Windows CP1252 equivalent.
uint8_t ConvertMacRomanTo1252(uint8_t ch) {
static uint8_t ConvertMacRomanTo1252(uint8_t ch) {
if (ch < 128)
return ch;
else
return kCP1252Conv[ch-128];
}
// Convert a Mac OS Roman character value (from a IIgs document) to
// its UTF-16 Unicode equivalent. This also includes a conversion
// for the control characters.
uint16_t ConvertMacRomanToUTF16(uint8_t ch) {
return kUTF16Conv[ch];
}
void CheckGSCharConv(void);
private:

View File

@ -627,29 +627,29 @@ void VectorizeString(WCHAR* mangle, WCHAR** argv, int* pArgc)
* Convert a sub-string to lower case according to rules for English book
* titles. Assumes the initial string is in all caps.
*/
static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
static void DowncaseSubstring(CStringA* pStr, int startPos, int endPos,
bool prevWasSpace)
{
static const WCHAR* shortWords[] = {
L"of", L"the", L"a", L"an", L"and", L"to", L"in"
static const char* shortWords[] = {
"of", "the", "a", "an", "and", "to", "in"
};
static const WCHAR* leaveAlone[] = {
L"BBS", L"3D"
static const char* leaveAlone[] = {
"BBS", "3D"
};
static const WCHAR* justLikeThis[] = {
L"ProDOS", L"IIe", L"IIc", L"IIgs"
static const char* justLikeThis[] = {
"ProDOS", "IIe", "IIc", "IIgs"
};
CString token;
CStringA token;
bool firstCap = true;
int i;
token = pStr->Mid(startPos, endPos - startPos);
LOGV(" TOKEN: '%ls'", (LPCWSTR) token);
LOGV(" TOKEN: '%s'", (LPCSTR) token);
/* these words are left alone */
for (i = 0; i < NELEM(leaveAlone); i++) {
if (token.CompareNoCase(leaveAlone[i]) == 0) {
LOGV(" Leaving alone '%ls'", (LPCWSTR) token);
LOGV(" Leaving alone '%s'", (LPCSTR) token);
return;
}
}
@ -657,7 +657,7 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
/* words with specific capitalization */
for (i = 0; i < NELEM(justLikeThis); i++) {
if (token.CompareNoCase(justLikeThis[i]) == 0) {
LOGI(" Setting '%ls' to '%ls'", (LPCWSTR) token, justLikeThis[i]);
LOGI(" Setting '%s' to '%s'", (LPCSTR) token, justLikeThis[i]);
for (int j = startPos; j < endPos; j++)
pStr->SetAt(j, justLikeThis[i][j - startPos]);
return;
@ -668,7 +668,7 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
if (prevWasSpace) {
for (i = 0; i < NELEM(shortWords); i++) {
if (token.CompareNoCase(shortWords[i]) == 0) {
LOGV(" No leading cap for '%ls'", (LPCWSTR) token);
LOGV(" No leading cap for '%s'", (LPCSTR) token);
firstCap = false;
break;
}
@ -676,9 +676,9 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
}
/* check for roman numerals; we leave those capitalized */
CString romanTest = token.SpanIncluding(L"IVX");
CString romanTest = token.SpanIncluding("IVX");
if (romanTest.GetLength() == token.GetLength()) {
LOGV(" Looks like roman numerals '%ls'", (LPCWSTR) token);
LOGV(" Looks like roman numerals '%s'", (LPCSTR) token);
return;
}
@ -690,10 +690,10 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
}
}
void InjectLowercase(CString* pStr)
void InjectLowercase(CStringA* pStr)
{
int len = pStr->GetLength();
static const WCHAR* kGapChars = L" .:&-+/\\()<>@*";
static const char kGapChars[] = " .:&-+/\\()<>@*";
int startPos, endPos;
//*pStr = "AND PRODOS FOR THE IIGS";
@ -701,7 +701,7 @@ void InjectLowercase(CString* pStr)
//LOGI("InjectLowercase: '%ls'", (LPCWSTR) *pStr);
for (int i = 0; i < len; i++) {
WCHAR ch = pStr->GetAt(i);
char ch = pStr->GetAt(i);
if (ch >= 'a' && ch <= 'z') {
LOGI("Found lowercase 0x%04x, skipping InjectLower", ch);
return;
@ -711,10 +711,10 @@ void InjectLowercase(CString* pStr)
startPos = 0;
while (startPos < len) {
/* find start of token */
WCHAR ch;
char ch;
do {
ch = pStr->GetAt(startPos);
if (wcschr(kGapChars, ch) == NULL)
if (strchr(kGapChars, ch) == NULL)
break;
startPos++;
} while (startPos < len);
@ -725,7 +725,7 @@ void InjectLowercase(CString* pStr)
endPos = startPos + 1;
while (endPos < len) {
ch = pStr->GetAt(endPos);
if (wcschr(kGapChars, ch) != NULL)
if (strchr(kGapChars, ch) != NULL)
break;
endPos++;
}

View File

@ -253,11 +253,11 @@ const WCHAR* Stristr(const WCHAR* string1, const WCHAR* string2);
void VectorizeString(WCHAR* mangle, WCHAR** argv, int* pArgc);
/*
* Convert parts of the filename to lower case.
* Convert parts of the Mac OS Roman filename to lower case.
*
* If the name already has lowercase characters, do nothing.
*/
void InjectLowercase(CString* pStr);
void InjectLowercase(CStringA* pStr);
/*
* Test to see if a sub-string matches a value in a set of strings. The set