diff --git a/app/ACUArchive.cpp b/app/ACUArchive.cpp index 37ec012..727836f 100644 --- a/app/ACUArchive.cpp +++ b/app/ACUArchive.cpp @@ -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; diff --git a/app/Actions.cpp b/app/Actions.cpp index c1835cb..4a32ff8 100644 --- a/app/Actions.cpp +++ b/app/Actions.cpp @@ -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 += "\\"; } diff --git a/app/BNYArchive.cpp b/app/BNYArchive.cpp index cc19f29..0c762cd 100644 --- a/app/BNYArchive.cpp +++ b/app/BNYArchive.cpp @@ -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; diff --git a/app/Clipboard.cpp b/app/Clipboard.cpp index 3d49358..70845cb 100644 --- a/app/Clipboard.cpp +++ b/app/Clipboard.cpp @@ -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; diff --git a/app/ContentList.cpp b/app/ContentList.cpp index 904218b..bf901ae 100644 --- a/app/ContentList.cpp +++ b/app/ContentList.cpp @@ -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; diff --git a/app/ConvDiskOptionsDialog.cpp b/app/ConvDiskOptionsDialog.cpp index dad44df..5e05f58 100644 --- a/app/ConvDiskOptionsDialog.cpp +++ b/app/ConvDiskOptionsDialog.cpp @@ -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; diff --git a/app/DiskArchive.cpp b/app/DiskArchive.cpp index e940153..44352f1 100644 --- a/app/DiskArchive.cpp +++ b/app/DiskArchive.cpp @@ -951,7 +951,7 @@ int DiskArchive::InternalReload(CWnd* pMsgWnd) int DiskArchive::LoadDiskFSContents(DiskFS* pDiskFS, const WCHAR* volName) { - static const WCHAR* kBlankFileName = L""; + static const char* kBlankFileNameMOR = ""; 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; } diff --git a/app/EditPropsDialog.cpp b/app/EditPropsDialog.cpp index e0a23e1..252ea1c 100644 --- a/app/EditPropsDialog.cpp +++ b/app/EditPropsDialog.cpp @@ -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(); diff --git a/app/FileNameConv.h b/app/FileNameConv.h index ec81f00..29e1ff5 100644 --- a/app/FileNameConv.h +++ b/app/FileNameConv.h @@ -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; diff --git a/app/GenericArchive.cpp b/app/GenericArchive.cpp index a834d80..a4f8cf8 100644 --- a/app/GenericArchive.cpp +++ b/app/GenericArchive.cpp @@ -13,6 +13,7 @@ #include "NufxArchive.h" #include "FileNameConv.h" #include "ContentList.h" +#include "../reformat/ReformatBase.h" #include "Main.h" #include #include @@ -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(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(); } } diff --git a/app/GenericArchive.h b/app/GenericArchive.h index 9ba4ad3..b44f0dd 100644 --- a/app/GenericArchive.h +++ b/app/GenericArchive.h @@ -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; diff --git a/app/Main.cpp b/app/Main.cpp index 7886cad..4ace631 100644 --- a/app/Main.cpp +++ b/app/Main.cpp @@ -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; diff --git a/app/NufxArchive.cpp b/app/NufxArchive.cpp index 31a0294..1bcaa6f 100644 --- a/app/NufxArchive.cpp +++ b/app/NufxArchive.cpp @@ -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; } diff --git a/app/ViewFilesDialog.cpp b/app/ViewFilesDialog.cpp index 4b146b8..59a4017 100644 --- a/app/ViewFilesDialog.cpp +++ b/app/ViewFilesDialog.cpp @@ -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; diff --git a/mdc/Main.cpp b/mdc/Main.cpp index 797457a..5fd9f87 100644 --- a/mdc/Main.cpp +++ b/mdc/Main.cpp @@ -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 = ""; + static const char* kBlankFileNameMOR = ""; 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); } diff --git a/reformat/ReformatBase.h b/reformat/ReformatBase.h index 484d4c0..d3b7232 100644 --- a/reformat/ReformatBase.h +++ b/reformat/ReformatBase.h @@ -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: diff --git a/util/Util.cpp b/util/Util.cpp index 5f96087..baf7360 100644 --- a/util/Util.cpp +++ b/util/Util.cpp @@ -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++; } diff --git a/util/Util.h b/util/Util.h index 0c5c060..2f62b7a 100644 --- a/util/Util.h +++ b/util/Util.h @@ -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