diff --git a/Contrib/Library/LibraryLocal/LibraryLocal.cpp b/Contrib/Library/LibraryLocal/LibraryLocal.cpp index cf43f8eb..ae0f2b3b 100644 --- a/Contrib/Library/LibraryLocal/LibraryLocal.cpp +++ b/Contrib/Library/LibraryLocal/LibraryLocal.cpp @@ -103,7 +103,7 @@ int _tmain(int argc, TCHAR* argv[]) // Validate filename - FILE*fIn = FOPEN(filename.c_str(), _T("rb")); + FILE*fIn = FOPEN(filename.c_str(), ("rb")); filefound = !!fIn; fclose(fIn); @@ -139,7 +139,7 @@ int _tmain(int argc, TCHAR* argv[]) // Write the version to an NSIS header file - FILE*fHdr = FOPEN(argv[3], _T("wt")); + FILE*fHdr = FOPEN(argv[3], ("wt")); if (!fHdr) return 1; // File content is always ASCII so we don't use TCHAR diff --git a/Source/Plugins.cpp b/Source/Plugins.cpp index 9b1012ec..db4bbfeb 100644 --- a/Source/Plugins.cpp +++ b/Source/Plugins.cpp @@ -72,7 +72,7 @@ namespace { // This function slurps the whole file into the vector. // Modified so the huge vector isn't returned by value. void read_file(const tstring& filename, vector& data) { - FILE*file = FOPEN(filename.c_str(), _T("rb")); + FILE*file = FOPEN(filename.c_str(), ("rb")); if (!file) throw NSISException(_T("Can't open file '") + filename + _T("'")); diff --git a/Source/build.cpp b/Source/build.cpp index 705d7fd2..cecd9c9e 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -2482,7 +2482,7 @@ int CEXEBuild::pack_exe_header() // write out exe header, pack, read back in, and // update the header info - FILE *tmpfile=FOPEN(build_packname,_T("wb")); + FILE *tmpfile=FOPEN(build_packname,("wb")); if (!tmpfile) { ERROR_MSG(_T("Error: writing temporary file \"%s\" for pack\n"),build_packname); @@ -2593,7 +2593,7 @@ int CEXEBuild::write_output(void) INFO_MSG(_T("\nOutput: \"%s\"\n"), full_path.c_str()); } - FILE *fp = FOPEN(build_output_filename,_T("w+b")); + FILE *fp = FOPEN(build_output_filename,("w+b")); if (!fp) { ERROR_MSG(_T("Can't open output file\n")); @@ -3684,7 +3684,7 @@ int CEXEBuild::load_stub() } int CEXEBuild::update_exehead(const tstring& file, size_t *size/*=NULL*/) { - FILE *tmpfile = _tfopen(file.c_str(), _T("rb")); + FILE *tmpfile = FOPEN(file.c_str(), ("rb")); if (!tmpfile) { ERROR_MSG(_T("Error: opening stub \"%s\"\n"), file.c_str()); diff --git a/Source/icon.cpp b/Source/icon.cpp index 67983b96..81f62eb8 100644 --- a/Source/icon.cpp +++ b/Source/icon.cpp @@ -19,7 +19,7 @@ extern FILE *g_output; static FILE * open_icon(const TCHAR* filename, IconGroupHeader& igh) { - FILE* f = FOPEN(filename, _T("rb")); + FILE* f = FOPEN(filename, ("rb")); if (!f) throw runtime_error("can't open file"); diff --git a/Source/script.cpp b/Source/script.cpp index 89c779f4..b61136d3 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -2565,7 +2565,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int k=line.gettoken_enum(1, _T("all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0IDD_LICENSE_FSRB\0IDD_LICENSE_FSCB\0")); if (k<0) PRINTHELP(); - FILE *fui = FOPEN(line.gettoken_str(2), _T("rb")); + FILE *fui = FOPEN(line.gettoken_str(2), ("rb")); if (!fui) { ERROR_MSG(_T("Error: Can't open \"%s\"!\n"), line.gettoken_str(2)); return PS_ERROR; @@ -3188,6 +3188,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_P_EXECUTE: { TCHAR *exec=line.gettoken_str(1); + SCRIPT_MSG(_T("!execute: \"%s\"\n"),exec); #ifdef _WIN32 PROCESS_INFORMATION pi; STARTUPINFO si={sizeof(STARTUPINFO),}; @@ -3202,7 +3203,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) system(execfixed); my_convert_free(execfixed); #endif - SCRIPT_MSG(_T("!execute: \"%s\"\n"),exec); } case TOK_P_ADDINCLUDEDIR: { diff --git a/Source/util.cpp b/Source/util.cpp index bb35d412..995868f4 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -79,7 +79,7 @@ double my_wtof(const wchar_t *str) // Returns -3 if the size doesn't match // Returns -4 if the bpp doesn't match int update_bitmap(CResourceEditor* re, WORD id, const TCHAR* filename, int width/*=0*/, int height/*=0*/, int maxbpp/*=0*/) { - FILE *f = FOPEN(filename, _T("rb")); + FILE *f = FOPEN(filename, ("rb")); if (!f) return -1; if (fgetc(f) != 'B' || fgetc(f) != 'M') { @@ -157,17 +157,22 @@ TCHAR *CharPrev(const TCHAR *s, const TCHAR *p) { return (TCHAR *) s; } -TCHAR *CharNext(const TCHAR *s) { +char *CharNextA(const char *s) { int l = 0; if (s && *s) l = max(1, mblen(s, MB_CUR_MAX)); - return (TCHAR *) s + l; + return (char *) s + l; +} + +WCHAR *CharNextW(const WCHAR *s) { + // BUGBUG: Is this the best we can do? + return s + 1; } char *CharNextExA(WORD codepage, const char *s, int flags) { char buf[1024]; snprintf(buf, 1024, "CP%d", codepage); - setlocale(LC_CTYPE, buf); + const char* orglocct = setlocale(LC_CTYPE, buf); const char* np; int len = mblen(s, strlen(s)); @@ -176,7 +181,7 @@ char *CharNextExA(WORD codepage, const char *s, int flags) { else np = s + 1; - setlocale(LC_CTYPE, ""); + setlocale(LC_CTYPE, orglocct); return (char *) np; } @@ -300,42 +305,58 @@ BOOL IsValidCodePage(UINT CodePage) return TRUE; } +#ifdef _UNICODE +void PathConvertWinToPosix(char*p) +{ + if ('\"' == *p) ++p; // Skip opening quote if any (For !system) + size_t len = strlen(p); + + /* Replace drive letter X: by /X */ + if (len >= 2 && ':' == p[1]) + { + p[1] = (char) tolower((int) p[0]); + p[0] = '/'; + } + + do + { + if ('\\' == *p) *p = '/'; + p = CharNextA(p); + } + while (*p); +} +#endif +void PathConvertWinToPosix(TCHAR*p) +{ + if (_T('\"') == *p) ++p; // Skip opening quote if any (For !system) + size_t len = _tcsclen(p); + + /* Replace drive letter X: by /X */ + if (len >= 2 && _T(':') == p[1]) + { + p[1] = (TCHAR) tolower((int) p[0]); + p[0] = _T('/'); + } + + do + { + if (_T('\\') == *p) *p = _T('/'); + p = CharNext(p); + } + while (*p); +} + #define MY_ERROR_MSG(x) {if (g_display_errors) {PrintColorFmtMsg_ERR(_T("%s"), x);}} TCHAR *my_convert(const TCHAR *path) { - // TODO: (orip) ref. this func. to use std::string? TCHAR *converted_path = _tcsdup(path); - size_t len = _tcsclen(path); - if(!converted_path) { MY_ERROR_MSG(_T("Error: could not allocate memory in my_convert()\n")); - return (TCHAR*) path; /* dirty */ + return 0; } - - /* Replace drive letter X: by /X */ - if(len >= 2) - { - if (path[1] == _T(':')) - { - converted_path[0] = _T('/'); - converted_path[1] = (TCHAR) tolower((int) path[0]); - } - } - - TCHAR *p = converted_path; - - do - { - if (*p == _T('\\')) - { - *p = _T('/'); - } - p = CharNext(p); - } - while (*p); - + PathConvertWinToPosix(converted_path); return converted_path; } @@ -352,17 +373,43 @@ int my_open(const TCHAR *pathname, int flags) my_convert_free(converted_pathname); return result; } - -FILE *my_fopen(const TCHAR *path, const TCHAR *mode) -{ - TCHAR *converted_path = my_convert(path); - - FILE *result = _tfopen(converted_path, mode); - my_convert_free(converted_path); - return result; -} #endif//!_WIN32 +FILE* my_fopen(const TCHAR *path, const char *mode) +{ + FILE*f = 0; +#ifndef _UNICODE + f = fopen(path, mode); +#else +#ifdef _WIN32 + TCHAR tmode[20]; + for (int i=0; ; ++i) if (0 == (tmode[i] = mode[i])) break; + f = _wfopen(path, tmode); +#else + const char* orglocct = setlocale(LC_CTYPE, ""); + const wchar_t* srcW = path; + size_t cb = wcsrtombs(0,&srcW,0,0); + if (-1 != cb) + { + char* nativepath = (char*) malloc(++cb); + if (nativepath) + { + cb = wcsrtombs(nativepath,&path,cb,0); + if (-1 != cb) + { + PathConvertWinToPosix(nativepath); + f = fopen(nativepath, mode); + } + free(nativepath); + } + } + setlocale(LC_CTYPE, orglocct); +#endif +#endif + return f; +} + + void *operator new(size_t size) throw(bad_alloc) { void *p = malloc(size); if (!p) @@ -579,7 +626,7 @@ static bool GetDLLVersionUsingRE(const tstring& filepath, DWORD& high, DWORD & l { bool found = false; - FILE *fdll = FOPEN(filepath.c_str(), _T("rb")); + FILE *fdll = FOPEN(filepath.c_str(), ("rb")); if (!fdll) return 0; diff --git a/Source/util.h b/Source/util.h index f2f3be73..77e06575 100644 --- a/Source/util.h +++ b/Source/util.h @@ -82,9 +82,12 @@ inline void PrintColorFmtMsg_ERR(const TCHAR *fmtstr, ...) va_end(val); } + + #ifndef _WIN32 TCHAR *CharPrev(const TCHAR *s, const TCHAR *p); -TCHAR *CharNext(const TCHAR *s); +char *CharNextA(const char *s); +WCHAR *CharNextW(const WCHAR *s); char *CharNextExA(WORD codepage, const char *s, int flags); int wsprintf(TCHAR *s, const TCHAR *format, ...); int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, @@ -93,13 +96,16 @@ int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); BOOL IsValidCodePage(UINT CodePage); +#ifdef _UNICODE +#define CharNext CharNextW +#else +#define CharNext CharNextA +#endif TCHAR *my_convert(const TCHAR *path); void my_convert_free(TCHAR *converted_path); int my_open(const TCHAR *pathname, int flags); -FILE *my_fopen(const TCHAR *path, const TCHAR *mode); -#define FOPEN(a, b) my_fopen(a, b) #define OPEN(a, b) my_open(a, b) #else @@ -107,11 +113,13 @@ FILE *my_fopen(const TCHAR *path, const TCHAR *mode); #define my_convert(x) (x) #define my_convert_free(x) -#define FOPEN(a, b) _tfopen(a, b) #define OPEN(a, b) _topen(a, b) #endif +FILE* my_fopen(const TCHAR *path, const char *mode); +#define FOPEN(a, b) my_fopen((a), (b)) + // round a value up to be a multiple of 512 // assumption: T is an int type template