Support special ${U+1}...${U+FFFFFFFF} Unicode character defines

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6324 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2013-03-29 02:04:21 +00:00
parent 12cb8bf7e3
commit 9fa3398dd9
5 changed files with 56 additions and 0 deletions

View file

@ -213,6 +213,13 @@ NSIS version as a 32 bit number.
\c !error "NSIS 2.47 or higher is required to build this installer!"
\c !endif
\S1{preunicodecodepoint} $\{U+1\}...$\{U+FFFFFFFF\}
A Unicode (UCS-4) character.
\c !define U+ABC "SIS" # Define will override
\c DetailPrint "${U+2115}${U+ABC}" # DOUBLE-STRUCK CAPITAL N + "SIS"
\S1{scopepredefines} Scope Predefines
Standard predefines that contain information of the current code scope.

View file

@ -24,6 +24,8 @@ Released on ?, 2013
\b The index of the changed section is stored in $0 during .onSelChange callbacks (\W{http://sourceforge.net/support/tracker.php?aid=1634936}{RFE #1634936})
\b $\{U+1\}...$\{U+FFFFFFFF\} are treated as a Unicode codepoint unless there is already a define with that name
\S2{} Minor Changes
\b %temp%\\Low will be used if the installer cannot write to %temp% nor %windir%\\Temp (\W{http://sourceforge.net/support/tracker.php?aid=2909242}{bug #2909242}, \W{http://sourceforge.net/support/tracker.php?aid=2912824}{patch #2912824})

View file

@ -684,6 +684,23 @@ void CEXEBuild::ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hi
ps_addtoline(s,defname,hist);
defname.add(_T(""),sizeof(_T("")));
t=definedlist.find((TCHAR*)defname.get());
TCHAR unichar[4+1];
if (!t && _T('U')==s[0] && _T('+')==s[1])
{
TCHAR *n=s+2;
unsigned long utf32=_tcstoul(n,&t,16);
// We only want to accept "${U+HEXDIGITS}" and not "${U+ -HEXDIGITS }"
if (*t || _T('-')==*n || _T('+')==*n) t=0;
if (_T(' ')==*n || _T('\t')==*n) t=0; // TODO: _istspace()?
if (!utf32) t=0; // Don't allow "${U+0}"
if (t)
{
UINT32 codpts[]={utf32,UNICODE_REPLACEMENT_CHARACTER,'?'};
for(UINT i=0; i < COUNTOF(codpts); ++i)
if (WCFromCodePoint(unichar,COUNTOF(unichar),codpts[i])) break;
t=unichar;
}
}
if (t && hist.find((TCHAR*)defname.get(),0)<0)
{
in+=_tcslen(s)+2;

View file

@ -56,6 +56,33 @@ inline UINT UTF8ToWC_Prepare(LPCSTR StrU8,UINT cbU8)
return UTF8ToWC_Convert(StrU8,cbU8,0,0);
}
UINT WCFromCodePoint(wchar_t*Dest,UINT cchDest,UINT32 CodPt)
{
// Don't allow half surrogate pairs
if (CodPt >= 0xd800 && CodPt <= 0xdfff) CodPt = UNICODE_REPLACEMENT_CHARACTER;
#ifdef _WIN32
if (CodPt <= 0xffff && cchDest)
{
*Dest = (wchar_t) CodPt;
return 1;
}
else if (cchDest >= 2)
{
const UINT32 lead_offset = 0xd800 - (0x10000 >> 10);
UINT16 lead = lead_offset + (CodPt >> 10), trail = 0xdc00 + (CodPt & 0x3ff);
Dest[0] = lead, Dest[1] = trail;
return 2;
}
return 0;
#else
iconvdescriptor iconvd;
if (!iconvd.Open("wchar_t",iconvd::GetHostEndianUCS4Code())) return 0;
size_t inleft = 4;
UINT cchW = iconvd.Convert(&codpt,&inleft,Dest,cchDest*sizeof(wchar_t)) / sizeof(wchar_t);
return !inleft ? cchW : 0;
#endif
}
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,WORD SrcCP)
{
/*\

View file

@ -23,6 +23,8 @@
#include <stdio.h>
#include "util.h" // For my_fopen
const UINT16 UNICODE_REPLACEMENT_CHARACTER = 0xfffd;
#define TSTR_INPUTCHARSET _T("ACP|OEM|CP#|UTF8|UTF16LE")
@ -54,6 +56,7 @@ inline UINT32 CodePointFromUTF16SurrogatePair(unsigned short lea,unsigned short
UINT StrLenUTF16LE(const void*str);
bool StrSetUTF16LE(tstring&dest, const void*src);
UINT WCFromCodePoint(wchar_t*Dest,UINT cchDest,UINT32 CodPt);
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,WORD SrcCP);
UINT DetectUTFBOM(FILE*strm);
WORD GetEncodingFromString(const TCHAR*s);