NSIS/Source/utf.cpp
anders_k 7cc150c464 MakeNSIS can now generate Unicode or Ansi installers based on a script attribute. SCons generates both Ansi and Unicode stubs and plugins.
The official plugins are now stored in architecture specific subdirectories under NSIS\Plugins. !AddPluginDir also gained a new (optional) architecture flag because MakeNSIS now stores separate plugin information for each target architecture. Storing plugins in the root of the Plugins directory is no longer supported.

MinGW does not implement the unicode CRT startup functions so the entry point functions and linker parameters had to be changed. The unicode tools use the ansi entry point and a small helper function that calls into the real code: _tmain has full argc+argv emulation while wWinMain does not pass the command line parameters. The stubs do not use any CRT functions and have no CRT or unicode helper code, they call our entry point directly.



git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6269 212acab6-be3b-0410-9dea-997c60f758d6
2012-10-13 01:47:50 +00:00

93 lines
2.3 KiB
C++

/*
* utf.cpp
*
* This file is a part of NSIS.
*
* Copyright (C) 2011 Anders Kjersem
*
* Licensed under the zlib/libpng license (the "License");
* you may not use this file except in compliance with the License.
*
* Licence details can be found in the file COPYING.
*
* This software is provided 'as-is', without any express or implied
* warranty.
*
*/
#include "utf.h"
// BUGBUG: We might want to use MB_ERR_INVALID_CHARS but it is not supported
// on < WinXP or in our current POSIX implementation.
static const int UTF8MBTWCFLAGS = 0;
#define ExeHeadWStrFree free
static EXEHEADWCHAR_T* ExeHeadWStrAlloc(UINT cch)
{
EXEHEADWCHAR_T* s = (EXEHEADWCHAR_T*) malloc(cch*sizeof(EXEHEADWCHAR_T));
#if 0
// TODO: We should add POSIX versions of G/SetLastError
// if we want to tell _why_ UTF8ToExeHeadTStr failed...
if (!s) SetLastError(ERROR_OUTOFMEMORY);
#endif
return s;
}
#ifdef _UNICODE
void RawTStrToASCII(const TCHAR*in,char*out,UINT maxcch)
{
const bool empty = !maxcch;
for(; maxcch && *in; --maxcch) *out++ = (char) *in++;
if (!empty) *out = 0;
}
#else // !_UNICODE
EXEHEADTCHAR_T* UTF8ToExeHeadTStrDup(LPCSTR StrU8,UINT Codepage)
{
int cchW = MultiByteToWideChar(CP_UTF8,UTF8MBTWCFLAGS,StrU8,-1,NULL,0);
if (!cchW) return NULL;
WCHAR *bufWStr = (WCHAR*) ExeHeadWStrAlloc(cchW);
if (!bufWStr) return NULL;
EXEHEADTCHAR_T *outstr = NULL;
if (MultiByteToWideChar(CP_UTF8,UTF8MBTWCFLAGS,StrU8,-1,bufWStr,cchW))
{
int cbA = WideCharToMultiByte(Codepage,0,bufWStr,cchW,NULL,0,NULL,NULL);
if (cbA && (outstr = ExeHeadTStrAlloc(cbA)))
{
if (!WideCharToMultiByte(Codepage,0,bufWStr,cchW,outstr,cbA,NULL,NULL))
{
free(outstr);
outstr = NULL;
}
}
}
ExeHeadWStrFree(bufWStr);
return outstr;
}
#endif // ?_UNICODE
bool IsUTF8BOM(FILE*fstrm)
{
// ungetc is only guaranteed to support 1 pushback,
// lets hope no ASCII file starts with 0xEF and is not a BOM!
const int c = fgetc(fstrm);
if (EOF == c) return false;
if (0xef == c)
{
const int c2 = fgetc(fstrm);
if (0xbb == c2)
{
const int c3 = fgetc(fstrm);
if (0xbf == c3) return true;
ungetc(c3,fstrm);
}
ungetc(c2,fstrm);
}
ungetc(c,fstrm);
return false;
}