/** * @brief Get canonical application name (all non-alphanumeric characters are stripped). * @param pszAppName - buffer for resulting application name. * @param nBufferSize - size of file name buffer. * @param bAllowSpaces - true if spaces are allowed. * @return length of the name. */ size_t GetCanonicalAppName(PTSTR pszAppName, size_t nBufferSize, BOOL bAllowSpaces) { if (nBufferSize == 0) return 0; if (*g_szAppName != _T('\0')) { --nBufferSize; size_t nStrLength = _tcslen(g_szAppName); if (nStrLength > nBufferSize) nStrLength = nBufferSize; size_t nSrcPos = 0, nDstPos = 0; WORD wCharMask = C1_ALPHA | C1_DIGIT; if (bAllowSpaces) wCharMask |= C1_SPACE; while (nSrcPos < nStrLength) { WORD arrCharType[2]; #ifdef _UNICODE size_t nCharSize = GetUnicodeCharSize((const BYTE*)(g_szAppName + nSrcPos)) / sizeof(WCHAR); GetStringTypeW(CT_CTYPE1, g_szAppName + nSrcPos, (int)nCharSize, arrCharType); #else size_t nCharSize = IsDBCSLeadByte(g_szAppName[nSrcPos]) ? 2 : 1; GetStringTypeA(LOCALE_USER_DEFAULT, CT_CTYPE1, g_szAppName + nSrcPos, (int)nCharSize, arrCharType); #endif if (*arrCharType & wCharMask) { pszAppName[nDstPos++] = g_szAppName[nSrcPos++]; if (nCharSize > 1) pszAppName[nDstPos++] = g_szAppName[nSrcPos++]; } else { /*if (*arrCharType & C1_SPACE) pszAppName[nDstPos++] = _T('_');*/ nSrcPos += (DWORD)nCharSize; } } pszAppName[nDstPos] = _T('\0'); return nDstPos; } else { TCHAR szAppFileName[MAX_PATH]; if (! GetModuleFileName(NULL, szAppFileName, countof(szAppFileName))) return FALSE; PTSTR pszFileName = PathFindFileName(szAppFileName); PathRemoveExtension(pszFileName); _tcscpy_s(pszAppName, nBufferSize, pszFileName); return _tcslen(pszAppName); } }
/* INTERNAL: Set ctype behaviour for a codepage */ static void msvcrt_set_ctype(unsigned int codepage, LCID lcid) { CPINFO cp; memset(&cp, 0, sizeof(CPINFO)); if (GetCPInfo(codepage, &cp)) { int i; char str[3]; unsigned char *traverse = (unsigned char *)cp.LeadByte; memset(MSVCRT_current_ctype, 0, sizeof(MSVCRT__ctype)); MSVCRT___lc_codepage = codepage; MSVCRT___lc_collate_cp = codepage; /* Switch ctype macros to MBCS if needed */ MSVCRT___mb_cur_max = cp.MaxCharSize; /* Set remaining ctype flags: FIXME: faster way to do this? */ str[1] = str[2] = 0; for (i = 0; i < 256; i++) { if (!(MSVCRT__pctype[i] & MSVCRT_LEADBYTE)) { str[0] = i; GetStringTypeA(lcid, CT_CTYPE1, str, 1, MSVCRT__pctype + i); } } /* Set leadbyte flags */ while (traverse[0] || traverse[1]) { for( i = traverse[0]; i <= traverse[1]; i++ ) MSVCRT_current_ctype[i+1] |= MSVCRT_LEADBYTE; traverse += 2; }; } }
BOOL __cdecl __crtGetStringTypeW( DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType, int code_page, int lcid ) { static int f_use = 0; /* * Look for unstubbed 'preferred' flavor. Otherwise use available flavor. * Must actually call the function to ensure it's not a stub. */ if (0 == f_use) { unsigned short dummy; if (0 != GetStringTypeW(CT_CTYPE1, L"\0", 1, &dummy)) f_use = USE_W; else if (0 != GetStringTypeA(0, CT_CTYPE1, "\0", 1, &dummy)) f_use = USE_A; else return FALSE; } /* Use "W" version */ if (USE_W == f_use) { return GetStringTypeW(dwInfoType, lpSrcStr, cchSrc, lpCharType); } /* Use "A" version */ if (USE_A == f_use) { int buff_size; BOOL retbool; unsigned char *buffer; WORD * pwCharInfo; /* * Convert string and return the requested information. Note that * we are converting to a multibyte string so there is not a * one-to-one correspondence between number of wide chars in the * input string and the number of *bytes* in the buffer. However, * there had *better be* a one-to-one correspondence between the * number of wide characters and the number of WORDs in the * return buffer. */ /* * Use __lc_codepage for conversion if code_page not specified */ if (0 == code_page) code_page = __lc_codepage; /* find out how big a buffer we need */ if ( 0 == (buff_size = WideCharToMultiByte( code_page, WC_COMPOSITECHECK | WC_SEPCHARS, lpSrcStr, cchSrc, NULL, 0, NULL, NULL )) ) return FALSE; /* allocate enough space for chars */ __try { buffer = (unsigned char *)_alloca( sizeof(char) * buff_size ); (void)memset( buffer, 0, sizeof(char) * buff_size ); } __except( EXCEPTION_EXECUTE_HANDLER ) { buffer = NULL; } if ( buffer == NULL ) return FALSE; /* do the conversion */ if ( 0 == WideCharToMultiByte( code_page, WC_COMPOSITECHECK | WC_SEPCHARS, lpSrcStr, cchSrc, buffer, buff_size, NULL, NULL ) ) return FALSE; /* allocate enough space for result (+1 for sanity check) */ __try { pwCharInfo = (WORD *)_alloca( sizeof(WORD) * (buff_size + 1) ); } __except( EXCEPTION_EXECUTE_HANDLER ) { pwCharInfo = NULL; } if ( pwCharInfo == NULL ) return FALSE; /* do we use default lcid */ if (0 == lcid) lcid = __lc_handle[LC_CTYPE]; /* set to known value */ pwCharInfo[cchSrc - 1] = pwCharInfo[cchSrc] = 0xFFFF; /* obtain result */ retbool = GetStringTypeA( lcid, dwInfoType, buffer, buff_size, pwCharInfo ); /* * GetStringTypeA does not reveal how many WORDs have been * modifed - to be safe we use another buffer and then * verify that EXACTLY cchSrc WORDs were modified. Note that * not all multibyte LCID/codepage combos are guaranteed to work. */ if (pwCharInfo[cchSrc - 1] == 0xFFFF || pwCharInfo[cchSrc] != 0xFFFF) return FALSE; memmove(lpCharType, pwCharInfo, cchSrc * sizeof(WORD)); return retbool; }
void CCrystalParser::WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ) { // The parser must be attached to a view! ASSERT( m_pTextView ); int nLineLength = m_pTextView->GetLineLength( nLineIndex ); int nTabWidth = m_pTextView->GetTabSize(); int nLineCharCount = 0; int nCharCount = 0; LPCTSTR szLine = m_pTextView->GetLineChars( nLineIndex ); int nLastBreakPos = 0; int nLastCharBreakPos = 0; bool bBreakable = false; TCHAR ch; int nCharWidth = m_pTextView->GetCharWidth(); WORD wCharType; for( int i = 0; i < nLineLength; i++ ) { ch = szLine[i]; // remember position of whitespace for wrap if( bBreakable ) { nLastBreakPos = i; nLastCharBreakPos = nCharCount; bBreakable = false; } // increment char counter (evtl. expand tab) if( ch == _T('\t') ) { nLineCharCount+= (nTabWidth - nCharCount % nTabWidth); nCharCount+= (nTabWidth - nCharCount % nTabWidth); // remember whitespace bBreakable = true; } else { #ifndef _UNICODE if( IsDBCSLeadByte((BYTE)ch) ) { nLineCharCount += 2; nCharCount += 2; GetStringTypeA(LOCALE_USER_DEFAULT,CT_CTYPE3, &szLine[i], 2, &wCharType); // remember whitespace if( (wCharType & (C3_IDEOGRAPH | C3_HIRAGANA | C3_KATAKANA))) bBreakable = true; } else { nLineCharCount ++; nCharCount ++; // remember whitespace if( ch == _T(' ') ) bBreakable = true; } #else if (ch & 0xff80) { int n = m_pTextView->GetCharWidthFromChar(ch) / nCharWidth; nLineCharCount += n; nCharCount += n; GetStringTypeW(CT_CTYPE3, &ch, 1, &wCharType); // remember whitespace if( wCharType & (C3_IDEOGRAPH | C3_HIRAGANA | C3_KATAKANA) ) bBreakable = true; } else { nLineCharCount ++; nCharCount ++; // remember whitespace if( ch == _T(' ') ) bBreakable = true; } #endif } // wrap line if( nLineCharCount >= nMaxLineWidth ) { // if no wrap position found, but line is to wide, // wrap at current position if( nLastBreakPos == 0 ) { nLastBreakPos = i; nLastCharBreakPos = nCharCount; } if( anBreaks ) anBreaks[nBreaks++] = nLastBreakPos; else nBreaks++; nLineCharCount = nCharCount - nLastCharBreakPos; nLastBreakPos = 0; } #ifndef _UNICODE if (IsDBCSLeadByte((BYTE)ch)) i++; #endif } }
void* _Locale_ctype_create(const char * name) { char cname[_Locale_MAX_SIMPLE_NAME]; char cp_name[MAX_CP_LEN+1]; int NativeCP; unsigned char Buffer[256]; unsigned char *ptr; unsigned short ctable[256]; CPINFO CPInfo; int i; wchar_t *wbuffer; int BufferSize; _Locale_ctype_t *ltype=(_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t)); if(!ltype) return ltype; memset(ltype, 0, sizeof(_Locale_ctype_t)); __Extract_locale_name(name, LC_CTYPE, cname); if(__GetLCIDFromName(cname, <ype->lcid, cp_name)==-1) { free(ltype); return NULL; } ltype->cp = atoi(cp_name); NativeCP=__intGetACP(ltype->lcid); if(NativeCP == 0) NativeCP=__intGetOCP(ltype->lcid); /* Make table with all characters. */ for(i = 0; i < 256; ++i) Buffer[i] = i; if(!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; } if(CPInfo.MaxCharSize > 1) { for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2) for(i=*ptr; i <= *(ptr+1); ++i) Buffer[i] = 0; } if(NativeCP != ltype->cp) { OSVERSIONINFO ver_info; ver_info.dwOSVersionInfoSize = sizeof(ver_info); GetVersionEx(&ver_info); if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { // Convert character sequence to Unicode. BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0); wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t)); if(!MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize)) { free(wbuffer); free(ltype); return NULL; } GetStringTypeW(CT_CTYPE1, wbuffer, 256, ctable); for(i = 0; i < 256; ++i) ltype->ctable[i]=(unsigned int)ctable[i]; if(CPInfo.MaxCharSize > 1) { for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2) for(i=*ptr; i <= *(ptr+1); i++) ltype->ctable[i] = _LEADBYTE; } free(wbuffer); } else { unsigned char TargetBuffer[256]; GetStringTypeA(ltype->lcid, CT_CTYPE1, (const char*)Buffer, 256, ctable); // Convert character sequence to target code page. BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0); wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t)); if(!MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize)) { free(wbuffer); free(ltype); return NULL; } if(!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE)) { free(wbuffer); free(ltype); return NULL; } free(wbuffer); // Translate ctype table. for(i = 0; i < 256; ++i) { if(!TargetBuffer[i]) continue; ltype->ctable[TargetBuffer[i]] = ctable[i]; } // Mark lead byte. if(!GetCPInfo(ltype->cp, &CPInfo)) { free(ltype); return NULL; } if(CPInfo.MaxCharSize > 1) { for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2) for(i=*ptr; i <= *(ptr+1); ++i) ltype->ctable[i] = _LEADBYTE; } } } else { GetStringTypeA(ltype->lcid, CT_CTYPE1, (const char*)Buffer, 256, ctable); for(i = 0; i < 256; ++i) ltype->ctable[i]=(unsigned int)ctable[i]; if(CPInfo.MaxCharSize > 1) { for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2) for(i=*ptr; i <= *(ptr+1); ++i) ltype->ctable[i] = _LEADBYTE; } } return ltype; }
BOOL __cdecl __crtGetStringTypeA( DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType, int code_page, int lcid ) { static int f_use = 0; /* * Look for unstubbed 'preferred' flavor. Otherwise use available flavor. * Must actually call the function to ensure it's not a stub. */ if (0 == f_use) { unsigned short dummy; if (0 != GetStringTypeA(0, CT_CTYPE1, "\0", 1, &dummy)) f_use = USE_A; else if (0 != GetStringTypeW(CT_CTYPE1, L"\0", 1, &dummy)) f_use = USE_W; else return FALSE; } /* Use "A" version */ if (USE_A == f_use) { if (0 == lcid) lcid = __lc_handle[LC_CTYPE]; return GetStringTypeA(lcid, dwInfoType, lpSrcStr, cchSrc, lpCharType); } /* Use "W" version */ if (USE_W == f_use) { int retval; int buff_size; BOOL retbool = FALSE; wchar_t *wbuffer = NULL; /* * Convert string and return the requested information. Note that * we are converting to a wide character string so there is not a * one-to-one correspondence between number of multibyte chars in the * input string and the number of wide chars in the buffer. However, * there had *better be* a one-to-one correspondence between the * number of multibyte characters and the number of WORDs in the * return buffer. */ /* * Use __lc_codepage for conversion if code_page not specified */ if (0 == code_page) code_page = __lc_codepage; /* find out how big a buffer we need */ if (0 == (buff_size = MultiByteToWideChar(code_page, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, lpSrcStr, cchSrc, NULL, 0))) goto done; /* allocate enough space for wide chars */ if (NULL == (wbuffer = (wchar_t *)_calloc_crt(sizeof(wchar_t), buff_size))) goto done; /* do the conversion */ if (0 == (retval = MultiByteToWideChar(code_page, MB_PRECOMPOSED, lpSrcStr, cchSrc, wbuffer, buff_size))) goto done; /* obtain result */ retbool = GetStringTypeW(dwInfoType, wbuffer, retval, lpCharType); done: _free_crt(wbuffer); return retbool; } }
static BOOL __cdecl __crtGetStringTypeA_stat( _locale_t plocinfo, DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType, int code_page, int lcid, BOOL bError ) { static int f_use = 0; /* * Look for unstubbed 'preferred' flavor. Otherwise use available * flavor. Must actually call the function to ensure it's not a stub. * (Always try wide version first so WinNT can process codepage correctly.) */ if (0 == f_use) { unsigned short dummy; if (0 != GetStringTypeW(CT_CTYPE1, L"\0", 1, &dummy)) f_use = USE_W; else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) f_use = USE_A; } /* Use "A" version */ if (USE_A == f_use || f_use == 0) { char *cbuffer = NULL; int ret; int AnsiCP; if (0 == lcid) lcid = plocinfo->locinfo->lc_handle[LC_CTYPE]; if (0 == code_page) code_page = plocinfo->locinfo->lc_codepage; if ( -1 == (AnsiCP = __ansicp(lcid))) return FALSE; /* If current code-page is not ansi code page, convert it to ansi code page * as GetStringTypeA uses ansi code page to find the strig type. */ if ( AnsiCP != code_page) { cbuffer = __convertcp(code_page, AnsiCP, lpSrcStr, &cchSrc, NULL, 0); if (cbuffer == NULL) return FALSE; lpSrcStr = cbuffer; } ret = GetStringTypeA(lcid, dwInfoType, lpSrcStr, cchSrc, lpCharType); if ( cbuffer != NULL) _free_crt(cbuffer); return ret; } /* Use "W" version */ if (USE_W == f_use) { int retval1; int buff_size; wchar_t *wbuffer; BOOL retval2 = FALSE; /* * Convert string and return the requested information. Note that * we are converting to a wide character string so there is not a * one-to-one correspondence between number of multibyte chars in the * input string and the number of wide chars in the buffer. However, * there had *better be* a one-to-one correspondence between the * number of multibyte characters and the number of WORDs in the * return buffer. */ /* * Use __lc_codepage for conversion if code_page not specified */ if (0 == code_page) code_page = plocinfo->locinfo->lc_codepage; /* find out how big a buffer we need */ if ( 0 == (buff_size = MultiByteToWideChar( code_page, bError ? MB_PRECOMPOSED | MB_ERR_INVALID_CHARS : MB_PRECOMPOSED, lpSrcStr, cchSrc, NULL, 0 )) ) return FALSE; /* allocate enough space for wide chars */ wbuffer = (wchar_t *)_calloca( sizeof(wchar_t), buff_size ); if ( wbuffer == NULL ) { return FALSE; } (void)memset( wbuffer, 0, sizeof(wchar_t) * buff_size ); /* do the conversion */ if ( 0 != (retval1 = MultiByteToWideChar( code_page, MB_PRECOMPOSED, lpSrcStr, cchSrc, wbuffer, buff_size )) ) /* obtain result */ retval2 = GetStringTypeW( dwInfoType, wbuffer, retval1, lpCharType ); _freea(wbuffer); return retval2; } else /* f_use is neither USE_A nor USE_W */ return FALSE; }