Unicode fixes
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6216 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
615ce82030
commit
382b2fa282
11 changed files with 150 additions and 49 deletions
|
@ -34,7 +34,11 @@ typedef wchar_t _TUCHAR;
|
||||||
// printfs
|
// printfs
|
||||||
#define _ftprintf fwprintf
|
#define _ftprintf fwprintf
|
||||||
#define _sntprintf _snwprintf
|
#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 _tprintf wprintf
|
||||||
#define _vftprintf vfwprintf
|
#define _vftprintf vfwprintf
|
||||||
#define _vsntprintf _vsnwprintf
|
#define _vsntprintf _vsnwprintf
|
||||||
|
|
|
@ -103,13 +103,9 @@ int _tmain(int argc, TCHAR* argv[])
|
||||||
|
|
||||||
// Validate filename
|
// Validate filename
|
||||||
|
|
||||||
tifstream fs(filename.c_str());
|
FILE*fIn = FOPEN(filename.c_str(), _T("rb"));
|
||||||
|
filefound = !!fIn;
|
||||||
if (fs.is_open())
|
fclose(fIn);
|
||||||
{
|
|
||||||
filefound = 1;
|
|
||||||
fs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Work
|
// Work
|
||||||
|
|
||||||
|
@ -143,29 +139,25 @@ int _tmain(int argc, TCHAR* argv[])
|
||||||
|
|
||||||
// Write the version to an NSIS header file
|
// Write the version to an NSIS header file
|
||||||
|
|
||||||
tofstream header(argv[3], tofstream::out);
|
FILE*fHdr = FOPEN(argv[3], _T("wt"));
|
||||||
|
if (!fHdr) return 1;
|
||||||
if (header)
|
|
||||||
|
// File content is always ASCII so we don't use TCHAR
|
||||||
|
if (!filefound)
|
||||||
{
|
{
|
||||||
|
fputs("!define LIBRARY_VERSION_FILENOTFOUND\n", fHdr);
|
||||||
if (!filefound)
|
}
|
||||||
{
|
else if (!versionfound)
|
||||||
header << _T("!define LIBRARY_VERSION_FILENOTFOUND") << endl;
|
{
|
||||||
}
|
fputs("!define LIBRARY_VERSION_NONE\n", fHdr);
|
||||||
else if (!versionfound)
|
}
|
||||||
{
|
else
|
||||||
header << _T("!define LIBRARY_VERSION_NONE") << endl;
|
{
|
||||||
}
|
fprintf(fHdr, "!define LIBRARY_VERSION_HIGH %u\n", high);
|
||||||
else
|
fprintf(fHdr, "!define LIBRARY_VERSION_LOW %u\n", low);
|
||||||
{
|
|
||||||
header << _T("!define LIBRARY_VERSION_HIGH ") << high << endl;
|
|
||||||
header << _T("!define LIBRARY_VERSION_LOW ") << low << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(fHdr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,93 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef uint32_t TFileOffset;
|
typedef uint32_t TFileOffset;
|
||||||
typedef ifstream bifstream;
|
|
||||||
typedef istream bistream;
|
// This is a hacky partial replacement for <i|o>[f]stream so we can open wchar_t*
|
||||||
typedef ofstream bofstream;
|
#include "tchar.h"
|
||||||
typedef ostream bostream;
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
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
|
#endif // GlobalTypes_H
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace POSIX {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t getFileSize(const TCHAR* sFileName) {
|
uint32_t getFileSize(const TCHAR* sFileName) {
|
||||||
std::ifstream f;
|
bifstream f;
|
||||||
f.open(sFileName, std::ios_base::binary | std::ios_base::in);
|
f.open(sFileName, std::ios_base::binary | std::ios_base::in);
|
||||||
if (!f.good() || f.eof() || !f.is_open()) {
|
if (!f.good() || f.eof() || !f.is_open()) {
|
||||||
throw _T("File could not be read (getFileSize)");
|
throw _T("File could not be read (getFileSize)");
|
||||||
|
|
|
@ -35,11 +35,17 @@
|
||||||
|
|
||||||
#include "tchar.h"
|
#include "tchar.h"
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#if defined(__WIN32__) || defined(_WIN32)
|
||||||
#define OPT_CHAR _T('/')
|
#define OPT_CHAR _T('/')
|
||||||
#else
|
#else
|
||||||
#define OPT_CHAR _T('-')
|
#define OPT_CHAR _T('-')
|
||||||
#endif
|
#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 "GlobalTypes.h"
|
||||||
#include "POSIXUtil.h"
|
#include "POSIXUtil.h"
|
||||||
|
@ -71,7 +77,7 @@ int _tmain( int argc, TCHAR * argv[] ) {
|
||||||
for(int i = 1; i < argc; i++) {
|
for(int i = 1; i < argc; i++) {
|
||||||
tstring s(argv[i]);
|
tstring s(argv[i]);
|
||||||
if(s.size() > 0) {
|
if(s.size() > 0) {
|
||||||
if(s[0] == OPT_CHAR) {
|
if(ISSINGLESWITCHCHAR(s[0])) {
|
||||||
if(s.size() > 1) {
|
if(s.size() > 1) {
|
||||||
if((s[1] == _T('v')) || (s[1] == _T('V'))) {
|
if((s[1] == _T('v')) || (s[1] == _T('V'))) {
|
||||||
beVerbose = true;
|
beVerbose = true;
|
||||||
|
@ -127,13 +133,13 @@ int _tmain( int argc, TCHAR * argv[] ) {
|
||||||
tout << _T(" GENPAT (sourcefile) (targetfile) (patchfile)\n\n");
|
tout << _T(" GENPAT (sourcefile) (targetfile) (patchfile)\n\n");
|
||||||
|
|
||||||
tout << _T("Command line option (optional):\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_CHARSTR << _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_CHARSTR << _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_CHARSTR << _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_CHARSTR << _T("O Deactivate match limit of the ") << OPT_CHARSTR << _T("A switch (sometimes smaller patches).\n");
|
||||||
tout << OPT_CHAR << _T("A=500 Maximum number of block matches per block (improves performance).\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_CHAR << _T("V to see the cut-off aborts.\n\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_CHAR << _T(" character!\n\n");
|
tout << _T("Note: filenames should never start with ") << OPT_FSCONFLICTCHARSTR << _T(" character!\n\n");
|
||||||
tout << _T("Possible exit codes:\n");
|
tout << _T("Possible exit codes:\n");
|
||||||
tout << _T(" 0 Success\n");
|
tout << _T(" 0 Success\n");
|
||||||
tout << _T(" 1 Arguments missing\n");
|
tout << _T(" 1 Arguments missing\n");
|
||||||
|
@ -189,7 +195,7 @@ int _tmain( int argc, TCHAR * argv[] ) {
|
||||||
previousPatchSize = POSIX::getFileSize(patchFileName.c_str());
|
previousPatchSize = POSIX::getFileSize(patchFileName.c_str());
|
||||||
} catch(const TCHAR* s) {
|
} catch(const TCHAR* s) {
|
||||||
tout << _T("Patch file does not yet exist: ") << s << _T(", it will be created.\n");
|
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.open(patchFileName.c_str(), std::ios_base::binary | std::ios_base::out);
|
||||||
newfile.close();
|
newfile.close();
|
||||||
}
|
}
|
||||||
|
@ -280,7 +286,7 @@ int _tmain( int argc, TCHAR * argv[] ) {
|
||||||
tempF.close();
|
tempF.close();
|
||||||
|
|
||||||
// now empty the temporary file
|
// now empty the temporary file
|
||||||
std::ofstream clearF;
|
bofstream clearF;
|
||||||
clearF.open(tempFileName.c_str(), std::ios_base::binary | std::ios_base::out);
|
clearF.open(tempFileName.c_str(), std::ios_base::binary | std::ios_base::out);
|
||||||
}
|
}
|
||||||
catch(tstring s) {
|
catch(tstring s) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
# define _T(x) __T(x)
|
# define _T(x) __T(x)
|
||||||
# define _tmain wmain
|
# define _tmain wmain
|
||||||
# define _tunlink _wunlink
|
# define _tunlink _wunlink
|
||||||
|
# define FOPEN _wfopen
|
||||||
|
|
||||||
typedef std::wstring tstring;
|
typedef std::wstring tstring;
|
||||||
typedef std::wistringstream tistringstream;
|
typedef std::wistringstream tistringstream;
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
# define _T(x) x
|
# define _T(x) x
|
||||||
# define _tmain main
|
# define _tmain main
|
||||||
# define _tunlink _unlink
|
# define _tunlink _unlink
|
||||||
|
# define FOPEN fopen
|
||||||
|
|
||||||
typedef std::string tstring;
|
typedef std::string tstring;
|
||||||
typedef std::istringstream tistringstream;
|
typedef std::istringstream tistringstream;
|
||||||
|
|
|
@ -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).
|
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.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 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
|
\c TargetMinimalOS 6.0 ; target Windows Vista or more recent / make a Unicode installer
|
||||||
|
|
|
@ -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 {
|
namespace {
|
||||||
|
|
|
@ -150,6 +150,9 @@ CEXEBuild::CEXEBuild() :
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
definedlist.add(_T("NSIS_WIN32_MAKENSIS"));
|
definedlist.add(_T("NSIS_WIN32_MAKENSIS"));
|
||||||
#endif
|
#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;
|
db_opt_save=db_comp_save=db_full_size=db_opt_save_u=db_comp_save_u=db_full_size_u=0;
|
||||||
|
|
||||||
|
|
|
@ -277,6 +277,9 @@ int _tmain(int argc, TCHAR **argv)
|
||||||
int in_files=0;
|
int in_files=0;
|
||||||
|
|
||||||
#ifdef _UNICODE
|
#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
|
_setmode(_fileno(stdout), _O_U8TEXT); // set stdout to UTF-8
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
g_initialCodepage = GetConsoleOutputCP();
|
g_initialCodepage = GetConsoleOutputCP();
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
|
|
||||||
~TtoCString() { free(m_cStr); m_cStr = 0; }
|
~TtoCString() { free(m_cStr); m_cStr = 0; }
|
||||||
|
|
||||||
operator const char*() { return m_cStr; }
|
operator const char*() const { return m_cStr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* m_cStr;
|
char* m_cStr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue