diff --git a/Contrib/ExDLL/nsis_tchar.h b/Contrib/ExDLL/nsis_tchar.h index 9532d4e4..ee1a6b9f 100644 --- a/Contrib/ExDLL/nsis_tchar.h +++ b/Contrib/ExDLL/nsis_tchar.h @@ -34,7 +34,11 @@ typedef wchar_t _TUCHAR; // printfs #define _ftprintf fwprintf #define _sntprintf _snwprintf -#define _stprintf _swprintf +#if defined(_MSC_VER) && (_MSC_VER<=1200) +# define _stprintf swprintf +#else +# define _stprintf _swprintf +#endif #define _tprintf wprintf #define _vftprintf vfwprintf #define _vsntprintf _vsnwprintf diff --git a/Contrib/Library/LibraryLocal/LibraryLocal.cpp b/Contrib/Library/LibraryLocal/LibraryLocal.cpp index 19e275c9..cf43f8eb 100644 --- a/Contrib/Library/LibraryLocal/LibraryLocal.cpp +++ b/Contrib/Library/LibraryLocal/LibraryLocal.cpp @@ -103,13 +103,9 @@ int _tmain(int argc, TCHAR* argv[]) // Validate filename - tifstream fs(filename.c_str()); - - if (fs.is_open()) - { - filefound = 1; - fs.close(); - } + FILE*fIn = FOPEN(filename.c_str(), _T("rb")); + filefound = !!fIn; + fclose(fIn); // Work @@ -143,29 +139,25 @@ int _tmain(int argc, TCHAR* argv[]) // Write the version to an NSIS header file - tofstream header(argv[3], tofstream::out); - - if (header) + FILE*fHdr = FOPEN(argv[3], _T("wt")); + if (!fHdr) return 1; + + // File content is always ASCII so we don't use TCHAR + if (!filefound) { - - if (!filefound) - { - header << _T("!define LIBRARY_VERSION_FILENOTFOUND") << endl; - } - else if (!versionfound) - { - header << _T("!define LIBRARY_VERSION_NONE") << endl; - } - else - { - header << _T("!define LIBRARY_VERSION_HIGH ") << high << endl; - header << _T("!define LIBRARY_VERSION_LOW ") << low << endl; - } - - header.close(); - + fputs("!define LIBRARY_VERSION_FILENOTFOUND\n", fHdr); + } + else if (!versionfound) + { + fputs("!define LIBRARY_VERSION_NONE\n", fHdr); + } + else + { + fprintf(fHdr, "!define LIBRARY_VERSION_HIGH %u\n", high); + fprintf(fHdr, "!define LIBRARY_VERSION_LOW %u\n", low); } + fclose(fHdr); return 0; } diff --git a/Contrib/VPatch/Source/GenPat/GlobalTypes.h b/Contrib/VPatch/Source/GenPat/GlobalTypes.h index 034b45ff..cddabdef 100644 --- a/Contrib/VPatch/Source/GenPat/GlobalTypes.h +++ b/Contrib/VPatch/Source/GenPat/GlobalTypes.h @@ -49,8 +49,93 @@ #endif typedef uint32_t TFileOffset; - typedef ifstream bifstream; - typedef istream bistream; - typedef ofstream bofstream; - typedef ostream bostream; + + // This is a hacky partial replacement for [f]stream so we can open wchar_t* + #include "tchar.h" + #include + #include + +class simplebfstream { + FILE*m_File; + ios_base::iostate m_state; + streamsize m_LastReadCount; +public: + simplebfstream() : m_File(0), m_state(ios_base::badbit|ios_base::failbit) {} + ~simplebfstream() + { + if (m_File) fclose(m_File); + } + + bool open(const TCHAR*filename, ios_base::openmode mode) + { + TCHAR mAcc, mFmt = _T('b'); + if (ios::in&mode) mAcc = _T('r'); + if (ios::out&mode) mAcc = _T('w'); + assert(0==(mode&~(ios::in|ios::binary|ios::out))); + + TCHAR modestr[3] = {mAcc, mFmt, _T('\0')}; + m_File = FOPEN(filename, modestr); + m_state = m_File ? ios_base::goodbit : ios_base::badbit|ios_base::failbit; + + return good(); + } + + void close() + { + if (!m_File || fclose(m_File)) + { + m_state |= ios_base::failbit; + } + m_File = 0; + } + + bool is_open() const {return !!m_File;} + bool eof() const {return !!(ios_base::eofbit & m_state);} + bool bad() const {return !!(ios_base::badbit & m_state);} + bool fail() const {return !!((ios_base::failbit|ios_base::badbit) & m_state);} + bool good() const {return ios_base::goodbit==m_state;} + + streamsize gcount() const {return m_LastReadCount;} + streampos tellg() const {return ftell(m_File);} + + simplebfstream& read(char*s,streamsize n) + { + size_t cbio = fread(s, 1, n, m_File); + m_LastReadCount = cbio; + if (cbio != n) + { + m_state |= ferror(m_File) ? ios_base::badbit : (ios_base::eofbit|ios_base::failbit); + } + return *this; + } + + simplebfstream& seekg(streamoff off, ios_base::seekdir dir) + { + int origin = ios_base::beg==dir ? SEEK_SET : ios_base::cur==dir ? SEEK_CUR : SEEK_END; + if (fseek(m_File, off, origin)) + { + // BUGBUG: Does not follow standard + m_state |= ios_base::badbit|ios_base::failbit; + } + return *this; + } + + simplebfstream& seekp(streamoff off, ios_base::seekdir dir) {return seekg(off, dir);} + streampos tellp() const {return tellg();} + + simplebfstream& write(const char* s, streamsize n) + { + size_t cbio = fwrite(s, 1, n, m_File); + if (cbio != n) m_state |= ios_base::badbit; + return *this; + } + + bool operator ! () const {return fail();} +}; + + typedef simplebfstream bistream; + typedef bistream bifstream; + typedef simplebfstream bostream; + typedef bostream bofstream; + #endif // GlobalTypes_H diff --git a/Contrib/VPatch/Source/GenPat/POSIXUtil.cpp b/Contrib/VPatch/Source/GenPat/POSIXUtil.cpp index 5746aa75..4c2a0394 100644 --- a/Contrib/VPatch/Source/GenPat/POSIXUtil.cpp +++ b/Contrib/VPatch/Source/GenPat/POSIXUtil.cpp @@ -91,7 +91,7 @@ namespace POSIX { #endif uint32_t getFileSize(const TCHAR* sFileName) { - std::ifstream f; + bifstream f; f.open(sFileName, std::ios_base::binary | std::ios_base::in); if (!f.good() || f.eof() || !f.is_open()) { throw _T("File could not be read (getFileSize)"); diff --git a/Contrib/VPatch/Source/GenPat/main.cpp b/Contrib/VPatch/Source/GenPat/main.cpp index 64e3a505..5cd3b988 100644 --- a/Contrib/VPatch/Source/GenPat/main.cpp +++ b/Contrib/VPatch/Source/GenPat/main.cpp @@ -35,11 +35,17 @@ #include "tchar.h" -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(_WIN32) #define OPT_CHAR _T('/') #else #define OPT_CHAR _T('-') #endif +const TCHAR OPT_CHARSTR[] = {OPT_CHAR, _T('\0')} ; +// Win32 now supports "/" AND "-" switches (like makensis) but the filename warning only makes sense for "-" +#define OPT_FSCONFLICTCHARSTR _T("-") + +inline bool ISSINGLESWITCHCHAR(const TCHAR c) { return ( OPT_CHAR==(c) || (OPT_CHAR!=_T('-') && _T('-')==(c)) ); } +#undef OPT_CHAR #include "GlobalTypes.h" #include "POSIXUtil.h" @@ -71,7 +77,7 @@ int _tmain( int argc, TCHAR * argv[] ) { for(int i = 1; i < argc; i++) { tstring s(argv[i]); if(s.size() > 0) { - if(s[0] == OPT_CHAR) { + if(ISSINGLESWITCHCHAR(s[0])) { if(s.size() > 1) { if((s[1] == _T('v')) || (s[1] == _T('V'))) { beVerbose = true; @@ -127,13 +133,13 @@ int _tmain( int argc, TCHAR * argv[] ) { tout << _T(" GENPAT (sourcefile) (targetfile) (patchfile)\n\n"); tout << _T("Command line option (optional):\n"); - tout << OPT_CHAR << _T("R Replace a patch with same contents as source silently if it\n already exists.\n"); - tout << OPT_CHAR << _T("B=64 Set blocksize (default=64), multiple of 2 is required.\n"); - tout << OPT_CHAR << _T("V More verbose information during patch creation.\n"); - tout << OPT_CHAR << _T("O Deactivate match limit of the ") << OPT_CHAR << _T("A switch (sometimes smaller patches).\n"); - tout << OPT_CHAR << _T("A=500 Maximum number of block matches per block (improves performance).\n"); - tout << _T(" Default is 500, larger is slower. Use ") << OPT_CHAR << _T("V to see the cut-off aborts.\n\n"); - tout << _T("Note: filenames should never start with ") << OPT_CHAR << _T(" character!\n\n"); + tout << OPT_CHARSTR << _T("R Replace a patch with same contents as source silently if it\n already exists.\n"); + tout << OPT_CHARSTR << _T("B=64 Set blocksize (default=64), multiple of 2 is required.\n"); + tout << OPT_CHARSTR << _T("V More verbose information during patch creation.\n"); + tout << OPT_CHARSTR << _T("O Deactivate match limit of the ") << OPT_CHARSTR << _T("A switch (sometimes smaller patches).\n"); + tout << OPT_CHARSTR << _T("A=500 Maximum number of block matches per block (improves performance).\n"); + tout << _T(" Default is 500, larger is slower. Use ") << OPT_CHARSTR << _T("V to see the cut-off aborts.\n\n"); + tout << _T("Note: filenames should never start with ") << OPT_FSCONFLICTCHARSTR << _T(" character!\n\n"); tout << _T("Possible exit codes:\n"); tout << _T(" 0 Success\n"); tout << _T(" 1 Arguments missing\n"); @@ -189,7 +195,7 @@ int _tmain( int argc, TCHAR * argv[] ) { previousPatchSize = POSIX::getFileSize(patchFileName.c_str()); } catch(const TCHAR* s) { tout << _T("Patch file does not yet exist: ") << s << _T(", it will be created.\n"); - std::ofstream newfile; + bofstream newfile; newfile.open(patchFileName.c_str(), std::ios_base::binary | std::ios_base::out); newfile.close(); } @@ -280,7 +286,7 @@ int _tmain( int argc, TCHAR * argv[] ) { tempF.close(); // now empty the temporary file - std::ofstream clearF; + bofstream clearF; clearF.open(tempFileName.c_str(), std::ios_base::binary | std::ios_base::out); } catch(tstring s) { diff --git a/Contrib/VPatch/Source/GenPat/tchar.h b/Contrib/VPatch/Source/GenPat/tchar.h index 24e16bd2..bbdaad0a 100644 --- a/Contrib/VPatch/Source/GenPat/tchar.h +++ b/Contrib/VPatch/Source/GenPat/tchar.h @@ -10,6 +10,7 @@ # define _T(x) __T(x) # define _tmain wmain # define _tunlink _wunlink +# define FOPEN _wfopen typedef std::wstring tstring; typedef std::wistringstream tistringstream; @@ -21,6 +22,7 @@ # define _T(x) x # define _tmain main # define _tunlink _unlink +# define FOPEN fopen typedef std::string tstring; typedef std::istringstream tistringstream; diff --git a/Docs/src/compilerflags.but b/Docs/src/compilerflags.but index 2a40c48c..a27e5956 100644 --- a/Docs/src/compilerflags.but +++ b/Docs/src/compilerflags.but @@ -95,8 +95,8 @@ This command sets the minimal OS version of the target Windows system required i In particular, if you indicate a minimal OS of 5.0 or more, MakeNSIS will generate a \R{intro-unicode}{Unicode installer} (as Windows 2000 and more recent are Unicode fully-compatible OSes). -\c TargetMinimalOS 4.1 ; target Windows 9x or more recent -\c TargetMinimalOS 4.2 ; target Windows NT4 or more recent + +\c TargetMinimalOS 4.0 ; target Windows 9x/NT4 or more recent (Default) \c TargetMinimalOS 5.0 ; target Windows 2000 or more recent / make a Unicode installer \c TargetMinimalOS 5.1 ; target Windows XP or more recent / make a Unicode installer \c TargetMinimalOS 6.0 ; target Windows Vista or more recent / make a Unicode installer diff --git a/Source/Plugins.cpp b/Source/Plugins.cpp index a4d97146..9b1012ec 100644 --- a/Source/Plugins.cpp +++ b/Source/Plugins.cpp @@ -57,9 +57,15 @@ void Plugins::FindCommands(const tstring &path, bool displayInfo) } } -struct NSISException : public std::runtime_error +// VC6 cannot handle NSISException(const tstring& msg) : std::runtime_error(string(TtoCString(msg))) {} +struct NSISExceptionInner : public std::runtime_error { - NSISException(const tstring& msg) : std::runtime_error(string(TtoCString(msg))) {} + NSISExceptionInner(const char* msg) : std::runtime_error(string(msg)) {} // Unicode + NSISExceptionInner(const string&msg) : std::runtime_error(msg) {} // Ansi +}; +struct NSISException : public NSISExceptionInner +{ + NSISException(const tstring& msg) : NSISExceptionInner(TtoCString(msg)) {} }; namespace { diff --git a/Source/build.cpp b/Source/build.cpp index 6df36ae7..705d7fd2 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -150,6 +150,9 @@ CEXEBuild::CEXEBuild() : #ifdef _WIN32 definedlist.add(_T("NSIS_WIN32_MAKENSIS")); #endif +#ifdef _UNICODE + definedlist.add(_T("NSIS_UNICODE_MAKENSIS")); // This define might go away once makensis.exe is always unicode +#endif db_opt_save=db_comp_save=db_full_size=db_opt_save_u=db_comp_save_u=db_full_size_u=0; diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index c4d0fc11..11d59d32 100644 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -277,6 +277,9 @@ int _tmain(int argc, TCHAR **argv) int in_files=0; #ifdef _UNICODE +#if (defined(_MSC_VER) && (_MSC_VER<=1200)) + const int _O_U8TEXT=0x40000; // BUGBUG: This is bogus +#endif _setmode(_fileno(stdout), _O_U8TEXT); // set stdout to UTF-8 #ifdef _WIN32 g_initialCodepage = GetConsoleOutputCP(); diff --git a/Source/tstring.h b/Source/tstring.h index ec4982bc..4cd0ea64 100644 --- a/Source/tstring.h +++ b/Source/tstring.h @@ -101,7 +101,7 @@ public: ~TtoCString() { free(m_cStr); m_cStr = 0; } - operator const char*() { return m_cStr; } + operator const char*() const { return m_cStr; } private: char* m_cStr;