// symbol test static bool isSymbolChar(_TCHAR i_c) { if (i_c == _T('\0')) return false; if (_istlead(i_c) || _istalpha(i_c) || _istdigit(i_c) || _istlead(i_c)) return true; #ifdef UNICODE if (0x80 <= i_c && _istgraph(i_c)) return true; #endif // UNICODE if (_istpunct(i_c)) return !!_tcschr(_T("-+/?_\\"), i_c); #ifdef UNICODE // check arrows if (_tcschr(_T("\x2190\x2191\x2192\x2193"), i_c)) { return true; } #endif // UNICODE return _istgraph(i_c); }
SCODE _AfxParseDisplayName(LPMONIKER lpmk, LPBC lpbc, LPTSTR lpszRemainder, ULONG* cchEaten, LPMONIKER* plpmkOut) { USES_CONVERSION; ASSERT(lpmk != NULL); ASSERT(AfxIsValidString(lpszRemainder)); ASSERT(cchEaten != NULL); ASSERT(plpmkOut != NULL); SCODE sc; if (lpbc != NULL) { // ask moniker to parse the display name itself sc = lpmk->ParseDisplayName(lpbc, NULL, T2OLE(lpszRemainder), cchEaten, plpmkOut); } else { // skip leading delimiters int cEaten = 0; LPTSTR lpszSrc = lpszRemainder; while (*lpszSrc != '\0' && (*lpszSrc == '\\' || *lpszSrc == '/' || *lpszSrc == ':' || *lpszSrc == '!' || *lpszSrc == '[')) { if (_istlead(*lpszSrc)) ++lpszSrc, ++cEaten; ++lpszSrc; ++cEaten; } // parse next token in lpszRemainder TCHAR szItemName[_MAX_PATH]; LPTSTR lpszDest = szItemName; while (*lpszSrc != '\0' && *lpszSrc != '\\' && *lpszSrc != '/' && *lpszSrc != ':' && *lpszSrc != '!' && *lpszSrc != '[' && cEaten < _MAX_PATH-1) { if (_istlead(*lpszSrc)) *lpszDest++ = *lpszSrc++, ++cEaten; *lpszDest++ = *lpszSrc++; ++cEaten; } *cchEaten = cEaten; sc = CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName), plpmkOut); } return sc; }
void WINAPI ExtFormatStrings (CString& rString, LPCTSTR lpszFormat, LPCTSTR *rglpsz, int nString) { // determine length of destination string int nTotalLen = 0; LPCTSTR pchSrc = lpszFormat; while (*pchSrc != '\0') { if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '9')) { int i = pchSrc[1] - '1'; pchSrc += 2; if (i >= nString) ++nTotalLen; else if (rglpsz[i] != NULL) nTotalLen += lstrlen(rglpsz[i]); } else { #if defined(WIN32) if (_istlead (*pchSrc)) ++nTotalLen, ++pchSrc; #endif // WIN32 ++pchSrc; ++nTotalLen; } } pchSrc = lpszFormat; rString.Empty(); while (*pchSrc != '\0') { if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '9')) { int i = pchSrc[1] - '1'; pchSrc += 2; if (i >= nString) { TRACE1("Error: illegal string index requested %d.\n", i); rString += '?'; } else if (rglpsz[i] != NULL) rString += rglpsz[i]; } else { #if defined(WIN32) if (_istlead(*pchSrc)) rString += *pchSrc++; // copy first of 2 bytes #endif rString += *pchSrc++; } } }
CString CSPTimeSpan::Format(LPCTSTR pFormat) const // formatting timespans is a little trickier than formatting CSPTimes // * we are only interested in relative time formats, ie. it is illegal // to format anything dealing with absolute time (i.e. years, months, // day of week, day of year, timezones, ...) // * the only valid formats: // %D - # of days -- NEW !!! // %H - hour in 24 hour format // %M - minute (0-59) // %S - seconds (0-59) // %% - percent sign { TCHAR szBuffer[maxTimeBufferSize]; TCHAR ch; LPTSTR pch = szBuffer; while ((ch = *pFormat++) != '\0') { ASSERT(pch < &szBuffer[maxTimeBufferSize]); if (ch == '%') { switch (ch = *pFormat++) { default: ASSERT(FALSE); // probably a bad format character case '%': *pch++ = ch; break; case 'D': pch += wsprintf(pch, _T("%ld"), GetDays()); break; case 'H': pch += wsprintf(pch, _T("%02d"), GetHours()); break; case 'M': pch += wsprintf(pch, _T("%02d"), GetMinutes()); break; case 'S': pch += wsprintf(pch, _T("%02d"), GetSeconds()); break; } } else { *pch++ = ch; if (_istlead(ch)) { ASSERT(pch < &szBuffer[maxTimeBufferSize]); *pch++ = *pFormat++; } } } *pch = '\0'; return szBuffer; }
/// get class name and title name static void getClassNameTitleName(HWND i_hwnd, bool i_isInMenu, tstringi *o_className, tstring *o_titleName) { tstringi &className = *o_className; tstring &titleName = *o_titleName; bool isTheFirstTime = true; if (i_isInMenu) { className = titleName = _T("MENU"); isTheFirstTime = false; } while (true) { _TCHAR buf[MAX(GANA_MAX_PATH, GANA_MAX_ATOM_LENGTH)]; // get class name if (i_hwnd) GetClassName(i_hwnd, buf, NUMBER_OF(buf)); else GetModuleFileName(GetModuleHandle(NULL), buf, NUMBER_OF(buf)); buf[NUMBER_OF(buf) - 1] = _T('\0'); if (isTheFirstTime) className = buf; else className = tstringi(buf) + _T(":") + className; // get title name if (i_hwnd) { GetWindowText(i_hwnd, buf, NUMBER_OF(buf)); buf[NUMBER_OF(buf) - 1] = _T('\0'); for (_TCHAR *b = buf; *b; ++ b) if (_istlead(*b) && b[1]) b ++; else if (_istcntrl(*b)) *b = _T('?'); } if (isTheFirstTime) titleName = buf; else titleName = tstring(buf) + _T(":") + titleName; // next loop or exit if (!i_hwnd) break; i_hwnd = GetParent(i_hwnd); isTheFirstTime = false; } }
UINT CEditView::PrintInsideRect(CDC* pDC, RECT& rectLayout, UINT nIndexStart, UINT nIndexStop) // worker function for laying out text in a rectangle. { ASSERT_VALID(this); ASSERT_VALID(pDC); BOOL bWordWrap = (GetStyle() & ES_AUTOHSCROLL) == 0; // get buffer and real starting and ending postions UINT nLen = GetBufferLength(); if (nIndexStart >= nLen) return nLen; LPCTSTR lpszText = LockBuffer(); if (nIndexStop > nLen) nIndexStop = nLen; ASSERT(nIndexStart < nLen); // calculate text & tab metrics TEXTMETRIC tm; pDC->GetTextMetrics(&tm); int cyChar = tm.tmHeight + tm.tmExternalLeading; #ifndef _MAC int nTabStop = m_nTabStops * pDC->GetTabbedTextExtent(_T("\t"), 1, 0, NULL).cx / 8 / 4; #else int nTabStop = pDC->GetTextExtent(_T("\t"), 1).cx; #endif int aCharWidths[256]; pDC->GetCharWidth(0, 255, aCharWidths); int y = rectLayout.top; UINT cx = rectLayout.right - rectLayout.left; UINT nIndex = nIndexStart; VERIFY(pDC->SaveDC() != 0); BOOL bLayoutOnly = pDC->IntersectClipRect(&rectLayout) == NULLREGION; do { UINT nIndexEnd = EndOfLine(lpszText, nIndexStop, nIndex); if (nIndex == nIndexEnd) { y += cyChar; } else if (bWordWrap) { // word-wrap printing do { UINT nIndexWrap = ClipLine(pDC, aCharWidths, cx, nTabStop, lpszText, nIndex, nIndexEnd); UINT nIndexWord = nIndexWrap; if (nIndexWord != nIndexEnd) { while (nIndexWord > nIndex && !isspace(lpszText[nIndexWord])) { nIndexWord--; } if (nIndexWord == nIndex) nIndexWord = nIndexWrap; } CRect rect(rectLayout.left, y, rectLayout.right, y+cyChar); if (!bLayoutOnly && pDC->RectVisible(rect)) { #ifndef _MAC pDC->TabbedTextOut(rect.left, y, (LPCTSTR)(lpszText+nIndex), nIndexWord-nIndex, 1, &nTabStop, rect.left); #else pDC->TextOut(rect.left, y, (LPCTSTR)(lpszText+nIndex), nIndexWord-nIndex); #endif } y += cyChar; nIndex = nIndexWord; while (nIndex < nIndexEnd && isspace(lpszText[nIndex])) nIndex++; } while (nIndex < nIndexEnd && y+cyChar <= rectLayout.bottom); nIndexEnd = nIndex; } else { // non-word wrap printing (much easier and faster) CRect rect(rectLayout.left, y, rectLayout.right, y+cyChar); if (!bLayoutOnly && pDC->RectVisible(rect)) { UINT nIndexClip = ClipLine(pDC, aCharWidths, cx, nTabStop, lpszText, nIndex, nIndexEnd); if (nIndexClip < nIndexEnd) { if (_istlead(*(lpszText+nIndexClip))) nIndexClip++; nIndexClip++; } #ifndef _MAC pDC->TabbedTextOut(rect.left, y, (LPCTSTR)(lpszText+nIndex), nIndexClip-nIndex, 1, &nTabStop, rect.left); #else pDC->TextOut(rect.left, y, (LPCTSTR)(lpszText+nIndex), nIndexClip-nIndex); #endif } y += cyChar; } nIndex = NextLine(lpszText, nIndexStop, nIndexEnd); } while (nIndex < nIndexStop && y+cyChar <= rectLayout.bottom); pDC->RestoreDC(-1); UnlockBuffer(); ASSERT_VALID(this); rectLayout.bottom = y; return nIndex; }
static UINT AFXAPI ClipLine(CDC* pDC, int aCharWidths[256], int cxLine, int nTabStop, LPCTSTR lpszText, UINT nIndex, UINT nIndexEnd) { ASSERT_VALID(pDC); ASSERT(nIndex < nIndexEnd); ASSERT(AfxIsValidAddress(lpszText, nIndexEnd, FALSE)); UNUSED_ALWAYS(nTabStop); // unused in Mac build TEXTMETRIC tm; ::GetTextMetrics(pDC->m_hDC, &tm); // make an initial guess on the number of characters that will fit int cx = 0; LPCTSTR lpszStart = lpszText + nIndex; LPCTSTR lpszStop = lpszText + nIndexEnd; LPCTSTR lpsz = lpszStart; while (lpsz < lpszStop) { #ifndef _MAC if (*lpsz == '\t') cx += nTabStop - (cx % nTabStop); else #endif { #ifdef _UNICODE if (*lpsz <= 0xFF) cx += aCharWidths[(BYTE)*lpsz]; else cx += tm.tmAveCharWidth; #else //_UNICODE if (_afxDBCS && _istlead(*lpsz)) { ++lpsz; cx += tm.tmAveCharWidth; } else cx += aCharWidths[(BYTE)*lpsz]; #endif //!_UNICODE } ++lpsz; if (cx > cxLine) break; } // adjust for errors in the guess #ifndef _MAC cx = pDC->GetTabbedTextExtent(lpszStart, lpsz-lpszStart, 1, &nTabStop).cx; #else cx = pDC->GetTextExtent(lpszStart, lpsz-lpszStart).cx; #endif if (cx > cxLine) { // remove characters until it fits do { ASSERT(lpsz != lpszStart); if (_afxDBCS) lpsz = _tcsdec(lpszStart, lpsz); else --lpsz; #ifndef _MAC cx = pDC->GetTabbedTextExtent(lpszStart, lpsz-lpszStart, 1, &nTabStop).cx; #else cx = pDC->GetTextExtent(lpszStart, lpsz-lpszStart).cx; #endif } while (cx > cxLine); } else if (cx < cxLine) { // add characters until it doesn't fit while (lpsz < lpszStop) { lpsz = _tcsinc(lpsz); ASSERT(lpsz <= lpszStop); #ifndef _MAC cx = pDC->GetTabbedTextExtent(lpszStart, lpsz-lpszStart, 1, &nTabStop).cx; #else cx = pDC->GetTextExtent(lpszStart, lpsz-lpszStart).cx; #endif if (cx > cxLine) { if (_afxDBCS) lpsz = _tcsdec(lpszStart, lpsz); else --lpsz; break; } } } // return index of character just past the last that would fit return lpsz - lpszText; }
BOOL CEditView::FindText(LPCTSTR lpszFind, BOOL bNext, BOOL bCase) { ASSERT_VALID(this); ASSERT(lpszFind != NULL); ASSERT(*lpszFind != '\0'); UINT nLen = GetBufferLength(); int nStartChar, nEndChar; GetEditCtrl().GetSel(nStartChar, nEndChar); UINT nStart = nStartChar; int iDir = bNext ? +1 : -1; // can't find a match before the first character if (nStart == 0 && iDir < 0) return FALSE; CWaitCursor wait; LPCTSTR lpszText = LockBuffer(); if (iDir < 0) { // always go back one for search backwards nStart -= (lpszText+nStart) - _tcsdec(lpszText, lpszText+nStart); } else if (nStartChar != nEndChar && SameAsSelected(lpszFind, bCase)) { // easy to go backward/forward with SBCS if (_istlead(lpszText[nStart])) nStart++; nStart += iDir; } // handle search with nStart past end of buffer size_t nLenFind = lstrlen(lpszFind); if (nStart+nLenFind-1 >= nLen) { if (iDir < 0 && nLen >= nLenFind) { if (_afxDBCS) { // walk back to previous character n times nStart = nLen; int n = nLenFind; while (n--) { nStart -= (lpszText+nStart) - _tcsdec(lpszText, lpszText+nStart); } } else { // single-byte character set is easy and fast nStart = nLen - nLenFind; } ASSERT(nStart+nLenFind-1 <= nLen); } else { UnlockBuffer(); return FALSE; } } // start the search at nStart LPCTSTR lpsz = lpszText + nStart; AFX_COMPARE_PROC pfnCompare = bCase ? lstrcmp : lstrcmpi; if (_afxDBCS) { // double-byte string search LPCTSTR lpszStop; if (iDir > 0) { // start at current and find _first_ occurrance lpszStop = lpszText + nLen - nLenFind + 1; } else { // start at top and find _last_ occurrance lpszStop = lpsz; lpsz = lpszText; } LPCTSTR lpszFound = NULL; while (lpsz <= lpszStop) { if (!bCase || (*lpsz == *lpszFind && (!_istlead(*lpsz) || lpsz[1] == lpszFind[1]))) { LPTSTR lpch = (LPTSTR)(lpsz + nLenFind); TCHAR chSave = *lpch; *lpch = '\0'; int nResult = (*pfnCompare)(lpsz, lpszFind); *lpch = chSave; if (nResult == 0) { lpszFound = lpsz; if (iDir > 0) break; } } lpsz = _tcsinc(lpsz); } UnlockBuffer(); if (lpszFound != NULL) { int n = (int)(lpszFound - lpszText); GetEditCtrl().SetSel(n, n+nLenFind); return TRUE; } } else { // single-byte string search UINT nCompare; if (iDir < 0) nCompare = (UINT)(lpsz - lpszText) + 1; else nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1; while (nCompare > 0) { ASSERT(lpsz >= lpszText); ASSERT(lpsz+nLenFind-1 <= lpszText+nLen-1); LPSTR lpch = (LPSTR)(lpsz + nLenFind); char chSave = *lpch; *lpch = '\0'; int nResult = (*pfnCompare)(lpsz, lpszFind); *lpch = chSave; if (nResult == 0) { UnlockBuffer(); int n = (int)(lpsz - lpszText); GetEditCtrl().SetSel(n, n+nLenFind); ASSERT_VALID(this); return TRUE; } // restore character at end of search *lpch = chSave; // move on to next substring nCompare--; lpsz += iDir; } UnlockBuffer(); } ASSERT_VALID(this); return FALSE; }
void CRecent::UpdateMenu( HMENU hMenu ) { // メニューなし? if( !hMenu ) return; // ファイル(&F)メニューの取得 HMENU hSubMenu = ::GetSubMenu( hMenu, 0 ); // 最近使ったフォルダ(&P)ポップアップメニューの取得 HMENU hPathMenu = ::GetSubMenu( hSubMenu, 12 ); // 最近使ったファイル(&F)ポップアップメニューの取得 HMENU hFileMenu = ::GetSubMenu( hSubMenu, 13 ); // 項目が無い場合 if( ::strlen(m_RecentPath[0]) <= 0 ) { // ディセーブルにする ::EnableMenuItem( hPathMenu, ID_MRU_PATH0, MF_BYCOMMAND|MF_GRAYED ); } else { INT i; // メニューアイテムの削除 for( i = 0; i < RECENT_MAX; i++ ) { ::DeleteMenu( hPathMenu, ID_MRU_PATH0+i, MF_BYCOMMAND ); } CHAR szRecent[_MAX_PATH]; CHAR szTemp[_MAX_PATH]; for( i = 0; i < RECENT_MAX; i++ ) { if( ::strlen(m_RecentPath[i]) > 0 ) { // パスをメニュー用に短くしたりする ::strcpy( szRecent, m_RecentPath[i] ); // '&'付きのファイルの'&'を'&&'に変換する LPCSTR pSrc = szRecent; LPSTR pDst = szTemp; while( *pSrc != 0 ) { if( *pSrc == '&' ) *pDst++ = '&'; if( _istlead(*pSrc) ) *pDst++ = *pSrc++; *pDst++ = *pSrc++; } *pDst = 0; ::wsprintf( szRecent, "&%d ", (i+1)%10 ); ::strcat( szRecent, szTemp ); // メニューに追加 ::InsertMenu( hPathMenu, i, MF_BYPOSITION, ID_MRU_PATH0+i, szRecent ); } else { break; } } } // 項目が無い場合 if( ::strlen(m_RecentName[0]) <= 0 ) { // ディセーブルにする ::EnableMenuItem( hFileMenu, ID_MRU_FILE0, MF_BYCOMMAND|MF_GRAYED ); } else { INT i; // メニューアイテムの削除 for( i = 0; i < RECENT_MAX; i++ ) { ::DeleteMenu( hFileMenu, ID_MRU_FILE0+i, MF_BYCOMMAND ); } CHAR szRecent[_MAX_PATH]; CHAR szTemp[_MAX_PATH]; for( i = 0; i < RECENT_MAX; i++ ) { if( ::strlen(m_RecentName[i]) > 0 ) { // パスをメニュー用に短くしたりする ::strcpy( szRecent, m_RecentName[i] ); MakeManuPath( szRecent ); // '&'付きのファイルの'&'を'&&'に変換する LPCSTR pSrc = szRecent; LPSTR pDst = szTemp; while( *pSrc != 0 ) { if( *pSrc == '&' ) *pDst++ = '&'; if( _istlead(*pSrc) ) *pDst++ = *pSrc++; *pDst++ = *pSrc++; } *pDst = 0; ::wsprintf( szRecent, "&%d ", (i+1)%10 ); ::strcat( szRecent, szTemp ); // メニューに追加 ::InsertMenu( hFileMenu, i, MF_BYPOSITION, ID_MRU_FILE0+i, szRecent ); } else { break; } } } }
int response_expand(size_t *pargc, char ***pargv) { struct Narg n; char *cp; int recurse = 0; n.argc = 0; n.argvmax = 0; /* dimension of n.argv[] */ n.argv = NULL; for (size_t i = 0; i < *pargc; ++i) { cp = (*pargv)[i]; if (*cp == '@') { char *buffer; char *bufend; char *p; int comment = 0; cp++; p = getenv(cp); if (p) { buffer = strdup(p); if (!buffer) goto noexpand; bufend = buffer + strlen(buffer); } else { long length; int fd; int nread; size_t len; #if __DMC__ length = filesize(cp); #else struct stat statbuf; if (stat(cp, &statbuf)) goto noexpand; length = statbuf.st_size; #endif if (length & 0xF0000000) /* error or file too big */ goto noexpand; len = length; buffer = (char *)malloc(len + 1); if (!buffer) goto noexpand; bufend = &buffer[len]; /* Read file into buffer */ #if _WIN32 fd = _open(cp,O_RDONLY|O_BINARY); #else fd = open(cp,O_RDONLY); #endif if (fd == -1) goto noexpand; nread = read(fd,buffer,len); close(fd); if (nread != len) goto noexpand; } // The logic of this should match that in setargv() for (p = buffer; p < bufend; p++) { char *d; char c,lastc; unsigned char instring; int num_slashes,non_slashes; switch (*p) { case 26: /* ^Z marks end of file */ goto L2; case 0xD: case '\n': if (comment) { comment = 0; } case 0: case ' ': case '\t': continue; // scan to start of argument case '#': comment = 1; continue; case '@': if (comment) { continue; } recurse = 1; default: /* start of new argument */ if (comment) { continue; } if (addargp(&n,p)) goto noexpand; instring = 0; c = 0; num_slashes = 0; for (d = p; 1; p++) { lastc = c; if (p >= bufend) goto Lend; c = *p; switch (c) { case '"': /* Yes this looks strange,but this is so that we are MS Compatible, tests have shown that: \\\\"foo bar" gets passed as \\foo bar \\\\foo gets passed as \\\\foo \\\"foo gets passed as \"foo and \"foo gets passed as "foo in VC! */ non_slashes = num_slashes % 2; num_slashes = num_slashes / 2; for (; num_slashes > 0; num_slashes--) { d--; *d = '\0'; } if (non_slashes) { *(d-1) = c; } else { instring ^= 1; } break; case 26: Lend: *d = 0; // terminate argument goto L2; case 0xD: // CR c = lastc; continue; // ignore case '@': recurse = 1; goto Ladd; case ' ': case '\t': if (!instring) { case '\n': case 0: *d = 0; // terminate argument goto Lnextarg; } default: Ladd: if (c == '\\') num_slashes++; else num_slashes = 0; *d++ = c; break; } #ifdef _MBCS if (_istlead (c)) { *d++ = *++p; if (*(d - 1) == '\0') { d--; goto Lnextarg; } } #endif } break; } Lnextarg: ; } L2: ; } else if (addargp(&n,(*pargv)[i])) goto noexpand; } if (n.argvmax == 0) { n.argvmax = 1; n.argv = (char **) calloc(n.argvmax, sizeof(char *)); if (!n.argv) return 1; } else n.argv[n.argc] = NULL; if (recurse) { /* Recursively expand @filename */ if (response_expand(&n.argc,&n.argv)) goto noexpand; } *pargc = n.argc; *pargv = n.argv; return 0; /* success */ noexpand: /* error */ free(n.argv); /* BUG: any file buffers are not free'd */ return 1; }
// get a parsed line. // if no more lines exist, returns false bool Parser::getLine(std::vector<Token> *o_tokens) { o_tokens->clear(); m_lineNumber = m_internalLineNumber; tstringi line; bool isTokenExist = false; continue_getLineLoop: while (getLine(&line)) { const _TCHAR *t = line.c_str(); continue_getTokenLoop: while (true) { // skip white space while (*t != _T('\0') && _istspace(*t)) t ++; if (*t == _T('\0') || *t == _T('#')) goto break_getTokenLoop; // no more tokens exist if (*t == _T('\\') && *(t + 1) == _T('\0')) goto continue_getLineLoop; // continue to next line const _TCHAR *tokenStart = t; // comma or empty token if (*t == _T(',')) { if (!isTokenExist) o_tokens->push_back(Token(_T(""), false)); isTokenExist = false; o_tokens->push_back(Token(Token::Type_comma)); t ++; goto continue_getTokenLoop; } // paren if (*t == _T('(')) { o_tokens->push_back(Token(Token::Type_openParen)); isTokenExist = false; t ++; goto continue_getTokenLoop; } if (*t == _T(')')) { if (!isTokenExist) o_tokens->push_back(Token(_T(""), false)); isTokenExist = true; o_tokens->push_back(Token(Token::Type_closeParen)); t ++; goto continue_getTokenLoop; } isTokenExist = true; // prefix if (m_prefixes) for (size_t i = 0; i < m_prefixes->size(); i ++) if (_tcsnicmp(tokenStart, m_prefixes->at(i).c_str(), m_prefixes->at(i).size()) == 0) { o_tokens->push_back(Token(m_prefixes->at(i), false)); t += m_prefixes->at(i).size(); goto continue_getTokenLoop; } // quoted or regexp if (*t == _T('"') || *t == _T('\'') || *t == _T('/') || (*t == _T('\\') && *(t + 1) == _T('m') && *(t + 2) != _T('\0'))) { bool isRegexp = !(*t == _T('"') || *t == _T('\'')); _TCHAR q[2] = { *t++, _T('\0') }; // quote character if (q[0] == _T('\\')) { t++; q[0] = *t++; } tokenStart = t; while (*t != _T('\0') && *t != q[0]) { if (*t == _T('\\') && *(t + 1)) t ++; if (_istlead(*t) && *(t + 1)) t ++; t ++; } tstring str = interpretMetaCharacters(tokenStart, t - tokenStart, q, isRegexp); #ifdef _MBCS if (isRegexp) str = guardRegexpFromMbcs(str.c_str()); #endif // concatinate continuous string if (!isRegexp && 0 < o_tokens->size() && o_tokens->back().isString() && o_tokens->back().isQuoted()) o_tokens->back().add(str); else o_tokens->push_back(Token(str, true, isRegexp)); if (*t != _T('\0')) t ++; goto continue_getTokenLoop; } // not quoted { while (isSymbolChar(*t)) { if (*t == _T('\\')) if (*(t + 1)) t ++; else break; if (_istlead(*t) && *(t + 1)) t ++; t ++; } if (t == tokenStart) { ErrorMessage e; e << _T("invalid character "); #ifdef UNICODE e << _T("U+"); e << std::hex; // << std::setw(4) << std::setfill(_T('0')); e << (int)(wchar_t)*t; #else e << _T("\\x"); e << std::hex; // << std::setw(2) << std::setfill(_T('0')); e << (int)(u_char)*t; #endif e << std::dec; if (_istprint(*t)) e << _T("(") << *t << _T(")"); throw e; } _TCHAR *numEnd = NULL; long value = _tcstol(tokenStart, &numEnd, 0); if (tokenStart == numEnd) { tstring str = interpretMetaCharacters(tokenStart, t - tokenStart); o_tokens->push_back(Token(str, false)); } else { o_tokens->push_back( Token(value, tstringi(tokenStart, numEnd - tokenStart))); t = numEnd; } goto continue_getTokenLoop; } } break_getTokenLoop: if (0 < o_tokens->size()) break; m_lineNumber = m_internalLineNumber; isTokenExist = false; } return 0 < o_tokens->size(); }
// Compute a character delta table for correctly positioning the screen // font characters where the printer characters will appear on the page CSize CPreviewDC::ComputeDeltas(int& x, LPCTSTR lpszString, UINT &nCount, BOOL bTabbed, UINT nTabStops, LPINT lpnTabStops, int nTabOrigin, LPTSTR lpszOutputString, int* pnDxWidths, int& nRightFixup) { ASSERT_VALID(this); TEXTMETRIC tmAttrib; TEXTMETRIC tmScreen; ::GetTextMetrics(m_hAttribDC, &tmAttrib); ::GetTextMetrics(m_hDC, &tmScreen); CSize sizeExtent; ::GetTextExtentPointA(m_hAttribDC, "A", 1, &sizeExtent); CPoint ptCurrent; UINT nAlignment = ::GetTextAlign(m_hAttribDC); BOOL bUpdateCP = (nAlignment & TA_UPDATECP) != 0; if (bUpdateCP) { ::GetCurrentPositionEx(m_hDC, &ptCurrent); x = ptCurrent.x; } LPCTSTR lpszCurChar = lpszString; LPCTSTR lpszStartRun = lpszString; int* pnCurDelta = pnDxWidths; int nStartRunPos = x; int nCurrentPos = x; int nStartOffset = 0; int nTabWidth = 0; if (bTabbed) { if (nTabStops == 1) { nTabWidth = lpnTabStops[0]; } else { // Get default size of a tab nTabWidth = LOWORD(::GetTabbedTextExtentA(m_hAttribDC, "\t", 1, 0, NULL)); } } for (UINT i = 0; i < nCount; i++) { BOOL bSpace = ((_TUCHAR)*lpszCurChar == (_TUCHAR)tmAttrib.tmBreakChar); if (bSpace || (bTabbed && *lpszCurChar == '\t')) { // bSpace will be either TRUE (==1) or FALSE (==0). For spaces // we want the space included in the GetTextExtent, for tabs we // do not want the tab included int nRunLength = (int)(lpszCurChar - lpszStartRun) + bSpace; CSize sizeExtent; ::GetTextExtentPoint(m_hAttribDC, lpszStartRun, nRunLength, &sizeExtent); int nNewPos = nStartRunPos + sizeExtent.cx - tmAttrib.tmOverhang; // now, if this is a Tab (!bSpace), compute the next tab stop if (!bSpace) { nNewPos = ComputeNextTab(nNewPos, nTabStops, lpnTabStops, nTabOrigin, nTabWidth); } // Add this width to previous width if (pnCurDelta == pnDxWidths) nStartOffset += nNewPos - nCurrentPos; else *(pnCurDelta-1) += nNewPos - nCurrentPos; nCurrentPos = nNewPos; nStartRunPos = nCurrentPos; // set start of run // *lpszCurChar must be SBC: tmBreakChar or '\t' lpszStartRun = lpszCurChar + 1; } else { // For the non-tabbed or non-tab-character case int cxScreen; if (_istlead(*lpszCurChar)) { cxScreen = tmScreen.tmAveCharWidth; *pnCurDelta = tmAttrib.tmAveCharWidth; } else { #ifndef _MAC ::GetCharWidth(m_hDC, (_TUCHAR)*lpszCurChar, (_TUCHAR)*lpszCurChar, &cxScreen); if (!::GetCharWidth(m_hAttribDC, (_TUCHAR)*lpszCurChar, (_TUCHAR)*lpszCurChar, pnCurDelta)) { // If printer driver fails the above call, use the average width *pnCurDelta = tmAttrib.tmAveCharWidth; } #else cxScreen = m_aCharWidthsDraw[(_TUCHAR)*lpszCurChar]; *pnCurDelta = m_aCharWidthsAttrib[(_TUCHAR)*lpszCurChar]; #endif } *pnCurDelta -= tmAttrib.tmOverhang; cxScreen -= tmScreen.tmOverhang; nCurrentPos += *pnCurDelta; // update current position // Center character in allotted space if (pnCurDelta != pnDxWidths) { int diff = (*pnCurDelta - cxScreen) / 2; *pnCurDelta -= diff; *(pnCurDelta - 1) += diff; } *lpszOutputString++ = *lpszCurChar; if (_istlead(*lpszCurChar)) { *lpszOutputString++ = *(lpszCurChar+1); // copy trailing byte *(pnCurDelta + 1) = *pnCurDelta; // double wide nCurrentPos += *pnCurDelta; pnCurDelta++; i++; } pnCurDelta++; } lpszCurChar = _tcsinc(lpszCurChar); } nAlignment &= TA_CENTER|TA_RIGHT; sizeExtent.cx = nCurrentPos - x; nRightFixup = 0; if (nAlignment == TA_LEFT) x += nStartOffset; // Full left side adjustment else if (nAlignment == TA_CENTER) x += nStartOffset/2; // Adjust Center by 1/2 left side adjustment else if (nAlignment == TA_RIGHT) nRightFixup = nStartOffset; // Right adjust needed later if TA_UPDATECP if (bUpdateCP) ::MoveToEx(m_hDC, x, ptCurrent.y, NULL); nCount = (UINT)(pnCurDelta - pnDxWidths); // number of characters output return sizeExtent; }