wxchar.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,611 行 · 第 1/4 页
CPP
1,611 行
/////////////////////////////////////////////////////////////////////////////
// Name: wxchar.cpp
// Purpose: wxChar implementation
// Author: Ove K鍁en
// Modified by: Ron Lee
// Created: 09/04/99
// RCS-ID: $Id: wxchar.cpp,v 1.105.2.1 2006/01/06 17:06:41 VZ Exp $
// Copyright: (c) wxWidgets copyright
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "wxchar.h"
#endif
// ===========================================================================
// headers, declarations, constants
// ===========================================================================
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define _ISOC9X_SOURCE 1 // to get vsscanf()
#define _BSD_SOURCE 1 // to still get strdup()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __WXWINCE__
#include <time.h>
#include <locale.h>
#else
#include "wx/msw/wince/time.h"
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/wxchar.h"
#include "wx/string.h"
#include "wx/hash.h"
#endif
#if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H)
#include <windef.h>
#include <winbase.h>
#include <winnls.h>
#include <winnt.h>
#endif
#if defined(__MWERKS__) && __MSL__ >= 0x6000
namespace std {}
using namespace std ;
#endif
#ifdef __WXMAC__
#include "wx/mac/private.h"
#endif
#if wxUSE_WCHAR_T
size_t WXDLLEXPORT wxMB2WC(wchar_t *buf, const char *psz, size_t n)
{
// assume that we have mbsrtowcs() too if we have wcsrtombs()
#ifdef HAVE_WCSRTOMBS
mbstate_t mbstate;
memset(&mbstate, 0, sizeof(mbstate_t));
#endif
if (buf) {
if (!n || !*psz) {
if (n) *buf = wxT('\0');
return 0;
}
#ifdef HAVE_WCSRTOMBS
return mbsrtowcs(buf, &psz, n, &mbstate);
#else
return wxMbstowcs(buf, psz, n);
#endif
}
#ifdef HAVE_WCSRTOMBS
return mbsrtowcs((wchar_t *) NULL, &psz, 0, &mbstate);
#else
return wxMbstowcs((wchar_t *) NULL, psz, 0);
#endif
}
size_t WXDLLEXPORT wxWC2MB(char *buf, const wchar_t *pwz, size_t n)
{
#ifdef HAVE_WCSRTOMBS
mbstate_t mbstate;
memset(&mbstate, 0, sizeof(mbstate_t));
#endif
if (buf) {
if (!n || !*pwz) {
// glibc2.1 chokes on null input
if (n) *buf = '\0';
return 0;
}
#ifdef HAVE_WCSRTOMBS
return wcsrtombs(buf, &pwz, n, &mbstate);
#else
return wxWcstombs(buf, pwz, n);
#endif
}
#ifdef HAVE_WCSRTOMBS
return wcsrtombs((char *) NULL, &pwz, 0, &mbstate);
#else
return wxWcstombs((char *) NULL, pwz, 0);
#endif
}
#endif // wxUSE_WCHAR_T
bool WXDLLEXPORT wxOKlibc()
{
#if wxUSE_WCHAR_T && defined(__UNIX__) && defined(__GLIBC__) && !defined(__WINE__)
// glibc 2.0 uses UTF-8 even when it shouldn't
wchar_t res = 0;
if ((MB_CUR_MAX == 2) &&
(wxMB2WC(&res, "\xdd\xa5", 1) == 1) &&
(res==0x765)) {
// this is UTF-8 allright, check whether that's what we want
char *cur_locale = setlocale(LC_CTYPE, NULL);
if ((strlen(cur_locale) < 4) ||
(strcasecmp(cur_locale + strlen(cur_locale) - 4, "utf8")) ||
(strcasecmp(cur_locale + strlen(cur_locale) - 5, "utf-8"))) {
// nope, don't use libc conversion
return false;
}
}
#endif
return true;
}
// ============================================================================
// printf() functions business
// ============================================================================
// special test mode: define all functions below even if we don't really need
// them to be able to test them
#ifdef wxTEST_PRINTF
#undef wxFprintf
#undef wxPrintf
#undef wxSprintf
#undef wxVfprintf
#undef wxVsprintf
#undef wxVprintf
#undef wxVsnprintf_
#undef wxSnprintf_
#define wxNEED_WPRINTF
int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr );
#endif
// ----------------------------------------------------------------------------
// implement [v]snprintf() if the system doesn't provide a safe one
// ----------------------------------------------------------------------------
#if !defined(wxVsnprintf_)
int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
const wxChar *format, va_list argptr)
{
// buffer to avoid dynamic memory allocation each time for small strings
char szScratch[1024];
// number of characters in the buffer so far, must be less than lenMax
size_t lenCur = 0;
for ( size_t n = 0; ; n++ )
{
const wxChar chCur = format[n];
if ( chCur == wxT('%') )
{
static char s_szFlags[256] = "%";
size_t flagofs = 1;
bool adj_left = false,
in_prec = false,
prec_dot = false,
done = false;
int ilen = 0;
size_t min_width = 0,
max_width = wxSTRING_MAXLEN;
do
{
#define CHECK_PREC \
if (in_prec && !prec_dot) \
{ \
s_szFlags[flagofs++] = '.'; \
prec_dot = true; \
}
#define APPEND_CH(ch) \
{ \
if ( lenCur == lenMax ) \
return -1; \
\
buf[lenCur++] = ch; \
}
#define APPEND_STR(s) \
{ \
for ( const wxChar *p = s; *p; p++ ) \
{ \
APPEND_CH(*p); \
} \
}
// what follows '%'?
const wxChar ch = format[++n];
switch ( ch )
{
case wxT('\0'):
APPEND_CH(_T('\0'));
done = true;
break;
case wxT('%'):
APPEND_CH(_T('%'));
done = true;
break;
case wxT('#'):
case wxT('0'):
case wxT(' '):
case wxT('+'):
case wxT('\''):
CHECK_PREC
s_szFlags[flagofs++] = ch;
break;
case wxT('-'):
CHECK_PREC
adj_left = true;
s_szFlags[flagofs++] = ch;
break;
case wxT('.'):
CHECK_PREC
in_prec = true;
prec_dot = false;
max_width = 0;
// dot will be auto-added to s_szFlags if non-negative
// number follows
break;
case wxT('h'):
ilen = -1;
CHECK_PREC
s_szFlags[flagofs++] = ch;
break;
case wxT('l'):
ilen = 1;
CHECK_PREC
s_szFlags[flagofs++] = ch;
break;
case wxT('q'):
case wxT('L'):
ilen = 2;
CHECK_PREC
s_szFlags[flagofs++] = ch;
break;
case wxT('Z'):
ilen = 3;
CHECK_PREC
s_szFlags[flagofs++] = ch;
break;
case wxT('*'):
{
int len = va_arg(argptr, int);
if (in_prec)
{
if (len<0) break;
CHECK_PREC
max_width = len;
}
else
{
if (len<0)
{
adj_left = !adj_left;
s_szFlags[flagofs++] = '-';
len = -len;
}
min_width = len;
}
flagofs += ::sprintf(s_szFlags+flagofs,"%d",len);
}
break;
case wxT('1'): case wxT('2'): case wxT('3'):
case wxT('4'): case wxT('5'): case wxT('6'):
case wxT('7'): case wxT('8'): case wxT('9'):
{
int len = 0;
CHECK_PREC
while ( (format[n] >= wxT('0')) &&
(format[n] <= wxT('9')) )
{
s_szFlags[flagofs++] = format[n];
len = len*10 + (format[n] - wxT('0'));
n++;
}
if (in_prec)
max_width = len;
else
min_width = len;
n--; // the main loop pre-increments n again
}
break;
case wxT('d'):
case wxT('i'):
case wxT('o'):
case wxT('u'):
case wxT('x'):
case wxT('X'):
CHECK_PREC
s_szFlags[flagofs++] = ch;
s_szFlags[flagofs] = '\0';
if (ilen == 0 )
{
int val = va_arg(argptr, int);
::sprintf(szScratch, s_szFlags, val);
}
else if (ilen == -1)
{
// NB: 'short int' value passed through '...'
// is promoted to 'int', so we have to get
// an int from stack even if we need a short
short int val = (short int) va_arg(argptr, int);
::sprintf(szScratch, s_szFlags, val);
}
else if (ilen == 1)
{
long int val = va_arg(argptr, long int);
::sprintf(szScratch, s_szFlags, val);
}
else if (ilen == 2)
{
#if SIZEOF_LONG_LONG
long long int val = va_arg(argptr, long long int);
::sprintf(szScratch, s_szFlags, val);
#else // !long long
long int val = va_arg(argptr, long int);
::sprintf(szScratch, s_szFlags, val);
#endif // long long/!long long
}
else if (ilen == 3)
{
size_t val = va_arg(argptr, size_t);
::sprintf(szScratch, s_szFlags, val);
}
{
const wxMB2WXbuf tmp =
wxConvLibc.cMB2WX(szScratch);
APPEND_STR(tmp);
}
done = true;
break;
case wxT('e'):
case wxT('E'):
case wxT('f'):
case wxT('g'):
case wxT('G'):
CHECK_PREC
s_szFlags[flagofs++] = ch;
s_szFlags[flagofs] = '\0';
if (ilen == 2)
{
long double val = va_arg(argptr, long double);
::sprintf(szScratch, s_szFlags, val);
}
else
{
double val = va_arg(argptr, double);
::sprintf(szScratch, s_szFlags, val);
}
{
const wxMB2WXbuf tmp =
wxConvLibc.cMB2WX(szScratch);
APPEND_STR(tmp);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?