INXString CMarkup::x_TextToDoc( char* szText, bool bAttrib ) const { // Convert text as seen outside XML document to XML friendly // replacing special characters with ampersand escape codes // E.g. convert "6>7" to "6>7" // // < less than // & ampersand // > greater than // // and for attributes: // // ' apostrophe or single quote // " double quote // static char* szaReplace[] = { "<", "&", ">", "'", """}; const char* pFind = bAttrib? "<&>\'\"":"<&>"; INXString csText; const char* pSource = szText; int nDestSize = strlen(pSource); nDestSize += nDestSize / 10 + 7; char* pDest = csText.GetBuffer(nDestSize); int nLen = 0; char cSource = *pSource; char* pFound; while ( cSource ) { if ( nLen > nDestSize - 6 ) { csText.ReleaseBuffer(nLen); nDestSize *= 2; pDest = csText.GetBuffer(nDestSize); } if ( (pFound=(char*)strchr(pFind,cSource)) != NULL ) { pFound = szaReplace[pFound-pFind]; strcpy(&pDest[nLen],pFound); nLen += strlen(pFound); } else { _tccpy( &pDest[nLen], pSource ); nLen += _tclen( pSource ); } pSource += _tclen( pSource ); cSource = *pSource; } csText.ReleaseBuffer(nLen); return csText; }
/////////////////////////////////////////////////////////////////////////////////////////////// // Pendant zu wsprintf() für string-Parameter; // im Unterschied zu Format() werden hier die übergebenen Parameter auf den Stack erwartet; // der Hauptteil dieser Routine beschäftigt sich damit, die Zeichenanzahl für den char*-Puffer // pTmp zu ermitteln, der dann nur noch an die Bibliotheksfunktion _vstprintf() übergeben wird void FormatV (string& rStr, LPCTSTR lpszFormat, va_list argList) { TX_ASSERT (TIsValidString(lpszFormat, false)); va_list argListSave = argList; // make a guess at the maximum length of the resulting string int nMaxLen = 0; for (LPCTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // handle '%' character, but watch out for '%%' if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%') { nMaxLen += _tclen(lpsz); continue; } int nItemLen = 0; // handle '%' character with format int nWidth = 0; for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // check for valid flags if (*lpsz == '#') nMaxLen += 2; // for '0x' else if (*lpsz == '*') nWidth = va_arg(argList, int); else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' || *lpsz == ' ') ; else // hit non-flag character break; } // get width and skip it if (nWidth == 0) { // width indicated by nWidth = _ttoi(lpsz); for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz)) ; } TX_ASSERT (nWidth >= 0); int nPrecision = 0; if (*lpsz == '.') { // skip past '.' separator (width.precision) lpsz = _tcsinc(lpsz); // get precision and skip it if (*lpsz == '*') { nPrecision = va_arg(argList, int); lpsz = _tcsinc(lpsz); }
bool CMarkupSTL::x_FindToken( CMarkupSTL::TokenPos& token ) { // Starting at token.nNext, bypass whitespace and find the next token // returns true on success, members of token point to token // returns false on end of document, members point to end of document const char * szDoc = token.szDoc; int nChar = token.nNext; token.bIsString = false; // By-pass leading whitespace while ( szDoc[nChar] && _tcschr(_T(" \t\n\r"),szDoc[nChar]) ) ++nChar; if ( ! szDoc[nChar] ) { // No token was found before end of document token.nL = nChar; token.nR = nChar; token.nNext = nChar; return false; } // Is it an opening quote? _TCHAR cFirstChar = szDoc[nChar]; if ( cFirstChar == _T('\"') || cFirstChar == _T('\'') ) { token.bIsString = true; // Move past opening quote ++nChar; token.nL = nChar; // Look for closing quote x_FindChar( token.szDoc, nChar, cFirstChar ); // Set right to before closing quote token.nR = nChar - 1; // Set nChar past closing quote unless at end of document if ( szDoc[nChar] ) ++nChar; } else { // Go until special char or whitespace token.nL = nChar; while ( szDoc[nChar] && ! _tcschr(_T(" \t\n\r<>=\\/?!"),szDoc[nChar]) ) nChar += _tclen(&szDoc[nChar]); // Adjust end position if it is one special char if ( nChar == token.nL ) ++nChar; // it is a special char token.nR = nChar - 1; } // nNext points to one past last char of token token.nNext = nChar; return true; }
INXString CMarkup::x_TextFromDoc( int nLeft, int nRight ) const { // Convert XML friendly text to text as seen outside XML document // ampersand escape codes replaced with special characters e.g. convert "6>7" to "6>7" // Conveniently the result is always the same or shorter in byte length // static char* szaCode[] = { "lt;","amp;", "gt;", "apos;", "quot;" }; static int anCodeLen[] = { 3,4,3,5,5 }; static char* szSymbol = "<&>\'\""; INXString csText; const char* pSource = (const char*)m_csDoc; int nDestSize = nRight - nLeft + 1; char* pDest = csText.GetBuffer(nDestSize); //LPTSTR pDest = csText.GetBuffer(nDestSize); int nLen = 0; int nCharLen = 0; int nChar = nLeft; while ( nChar <= nRight ) { if ( pSource[nChar] == '&') { // Look for matching &code; bool bCodeConverted = false; for ( int nMatch = 0; nMatch < 5; ++nMatch ) { if ( nChar <= nRight - anCodeLen[nMatch] && strncmp(szaCode[nMatch],&pSource[nChar+1],anCodeLen[nMatch]) == 0 ) { // Insert symbol and increment index past ampersand semi-colon pDest[nLen++] = szSymbol[nMatch]; nChar += anCodeLen[nMatch] + 1; bCodeConverted = true; break; } } // If the code is not converted, leave it as is if ( ! bCodeConverted ) { pDest[nLen++] = _T('&'); ++nChar; } } else // not & { nCharLen = _tclen(&pSource[nChar]); _tccpy( &pDest[nLen], &pSource[nChar] ); nLen += nCharLen; nChar += nCharLen; } } csText.ReleaseBuffer(nLen); return csText; }
CStdString CMarkupSTL::x_TextFromDoc( int nLeft, int nRight ) const { // Convert XML friendly text to text as seen outside XML document // replacing ampersand escape codes with special characters // E.g. convert "6>7" to "6>7" // // Conveniently the result is always the same or shorter in length // static _TCHAR* szaCode[] = { _T("lt;"),_T("amp;"),_T("gt;"),_T("apos;"),_T("quot;") }; static int anCodeLen[] = { 3,4,3,5,5 }; static _TCHAR* szSymbol = _T("<&>\'\""); CStdString csText; const _TCHAR* pSource = m_csDoc; int nDestSize = nRight - nLeft + 1; _TCHAR* pDest = csText.GetBuffer(nDestSize); int nLen = 0; int nCharLen; int nChar = nLeft; while ( nChar <= nRight ) { if ( pSource[nChar] == _T('&') ) { // Look for matching &code; for ( int nMatch = 0; nMatch < 5; ++nMatch ) { if ( nChar <= nRight - anCodeLen[nMatch] && _tcsncmp(szaCode[nMatch],&pSource[nChar+1],anCodeLen[nMatch]) == 0 ) { pDest[nLen++] = szSymbol[nMatch]; nChar += anCodeLen[nMatch] + 1; break; } } // If no match is found it means XML doc is invalid // no devastating harm done, ampersand code will just be left in result if ( nMatch == 5 ) { pDest[nLen++] = _T('&'); ++nChar; } } else { nCharLen = _tclen(&pSource[nChar]); _tccpy( &pDest[nLen], &pSource[nChar] ); nLen += nCharLen; nChar += nCharLen; } } csText.ReleaseBuffer(nLen); return csText; }
// formatting (using wsprintf style formatting) void __cdecl CStrClass::Format(LPCTSTR lpszFormat, ...) { va_list argList; va_start(argList, lpszFormat); // make a guess at the maximum length of the resulting string int nMaxLen = 0; for (LPCTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // handle '%' character, but watch out for '%%' if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%') { nMaxLen += _tclen(lpsz); continue; } int nItemLen = 0; // handle '%' character with format int nWidth = 0; for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // check for valid flags if (*lpsz == '#') nMaxLen += 2; // for '0x' else if (*lpsz == '*') nWidth = *va_arg(argList, int*); else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' || *lpsz == ' ') ; else // hit non-flag character break; } // get width and skip it if (nWidth == 0) { // width indicated by int nWidth = _ttoi(lpsz); for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz)) ; } int nPrecision = 0; if (*lpsz == '.') { // skip past '.' separator (width.precision) lpsz = _tcsinc(lpsz); // get precision and skip it if (*lpsz == '*') nPrecision = *va_arg(argList, int*); else {
inline int GetFormatLength(LPCTSTR apszFormat, va_list argList) { int nMaxLen = 0; for (LPCTSTR lpsz = apszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // handle '%' character, but watch out for '%%' if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%') { nMaxLen += _tclen(lpsz); continue; } int nItemLen = 0; // handle '%' character with format int nWidth = 0; for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // check for valid flags if (*lpsz == '#') nMaxLen += 2; // for '0x' else if (*lpsz == '*') nWidth = va_arg(argList, int); else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' || *lpsz == ' ') ; else // hit non-flag character break; } // get width and skip it if (nWidth == 0) { // width indicated by nWidth = _ttoi(lpsz); for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz)) ; } ASSERT(nWidth >= 0); int nPrecision = 0; if (*lpsz == '.') { // skip past '.' separator (width.precision) lpsz = _tcsinc(lpsz); // get precision and skip it if (*lpsz == '*') { nPrecision = va_arg(argList, int); lpsz = _tcsinc(lpsz); }
void CCuDlgLogFileAdd::OnOK() { // TODO: Add extra validation here CEdit* pEdit = (CEdit *) GetDlgItem(IDC_LOG_FILENAME); if (pEdit) { CString strFileName; pEdit->GetWindowText(strFileName); #ifdef UNIX if ( (strFileName.GetAt(0) != (FILENAME_SEPARATOR)) ) #else int ich0 = 0; int ich1 = (int)_tclen((const TCHAR*)strFileName + ich0); // ANSI -> 1 int ich2 = (int)_tclen((const TCHAR*)strFileName + ich1); // ANSI -> 1 if ( (strFileName.GetAt(ich1) != (_T(':'))) || (strFileName.GetAt(ich1+ich2) != (FILENAME_SEPARATOR)) ) #endif { MessageBeep(MB_ICONEXCLAMATION); AfxMessageBox(IDS_PATH_FOR_TRANSAC_LOG); return; } } CDialog::OnOK(); }
bool CMarkupSTL::x_FindChar( const char * szDoc, int& nChar, _TCHAR c ) { // static function const char * pChar = &szDoc[nChar]; while ( *pChar && *pChar != c ) pChar += _tclen( pChar ); nChar = pChar - szDoc; if ( ! *pChar ) return false; /* while ( szDoc[nChar] && szDoc[nChar] != c ) nChar += _tclen( &szDoc[nChar] ); if ( ! szDoc[nChar] ) return false; */ return true; }
bool CityList::parseLine(FILE* fp, Entry& entry, UINT& namePos) { TCHAR buf[512]; if (fgets(buf, sizeof(buf) / sizeof(buf[0]) - 1, fp) != NULL) { TCHAR* p; TCHAR* first = NULL; TCHAR* last = NULL; for (p = buf; p[0] != '\0' && p[0] != ';'; p += _tclen(p)) { if (p[0] == ' ' || p[0] == '\t' || p[0] == '\r' || p[0] == '\n') { // Found white space. if (last == NULL) last = p; } else { if (first == NULL) first = p; last = NULL; } } // Strip trailing spaces if any, and any comments. if (last != NULL) last[0] = '\0'; else p[0] = '\0'; if (first != NULL) { int latitude, longitude, name; if (_stscanf(first, "%d %d %n", &latitude, &longitude, &name) == 2 && first[name] != '\0') { entry.latitude = float(latitude) / 10000.0f; entry.longitude = float(longitude) / 10000.0f; entry.nameOff = namePos; UINT nameEnd = namePos + _tcslen(first + name) + 1; moreNames(nameEnd); _tcscpy(mpCityNames + namePos, first + name); namePos = nameEnd; return true; } } } return false; }
void press_textA(TCHAR *szText, COLORREF zcolor, RECT *r, HDC hdc) { RECT tr; tr.left = 0; tr.right = 1; SetTextColor(hdc, zcolor); DrawText(hdc, szText, -1, &tr, DT_LEFT | DT_SINGLELINE | DT_CALCRECT); r->right = r->left + tr.right; size_t index = mspf_size; mspf_size += (int) _tcslen(szText); if (calc_size == FALSE) { const TCHAR *dot_strings[] = {_T("."), _T(".."), _T("...")}; TCHAR szNew[1024]; if (index >= mspf_break || (index < mspf_break && index+_tcslen(szText) > mspf_break)) { int break_index = (int) (max(index, mspf_break)); int break_string_index = break_index - (int) index; int str_left = (int) _tclen(&szText[break_string_index]); if (str_left > 3) str_left = 3; if (index > mspf_break) str_left -= (int) (index - mspf_break); if (str_left < 1) str_left = 1; #ifdef WINVER StringCbCopy(szNew, sizeof(szNew), szText); StringCbCopy(&szNew[break_string_index], _tcslen(dot_strings[str_left-1]) + 1, dot_strings[str_left-1]); #else strcpy(szNew, szText); strcpy(&szNew[break_string_index], dot_strings[str_left-1]); #endif szText = szNew; } DrawText(hdc, szText, -1, r, DT_LEFT | DT_SINGLELINE | DT_VCENTER); } OffsetRect(r, tr.right, 0); }
void CSelection::Extend( Direction eDirection, Amount eAmount, BOOL bScrollIfNeccessary, BOOL bDamage, BOOL bAllowPastEndOfLine ) { CBuffer *pBuffer = m_pCtrl->GetBuffer(); int nLineCount = pBuffer->GetLineCount(); BOOL bEnforceSelBounds = BoundSelection(); int nSaveEndRow = m_nEndRow; int nSaveEndCol = m_nEndCol; BOOL bUsePreferredCol = FALSE; if ( nLineCount ) { int nOldEndRow = m_nEndRow; int nOldStartRow = m_nStartRow; LPCTSTR pszEndLineStart = pBuffer->GetLineText( m_nEndRow ); int nEndLineLen = pBuffer->GetLineLength( m_nEndRow ); BOOL bStartRowChanged = FALSE; switch ( eDirection ) { case eUp: { switch ( eAmount ) { case eChar: { m_nEndRow--; bUsePreferredCol = TRUE; break; } case ePage: { m_nEndRow -= ( m_pView->GetBottomIndex( FALSE ) - m_pView->GetTopIndex() ); break; } case eSmartAll: case eAll: { m_nEndRow = 0; break; } } break; } case eDown: { switch ( eAmount ) { case eChar: { m_nEndRow++; bUsePreferredCol = TRUE; break; } case ePage: { int nTemp = m_nEndRow + ( m_pView->GetBottomIndex( FALSE ) - m_pView->GetTopIndex() ); m_nEndRow = min( nLineCount, nTemp ); break; } case eAll: case eSmartAll: { m_nEndRow = nLineCount - 1; break; } } break; } case eLeft: { switch ( eAmount ) { case eChar: { if ( m_nEndCol == 0 || m_nEndCol > nEndLineLen ) m_nEndCol--; else m_nEndCol -= _tclen_prev( pszEndLineStart, pszEndLineStart + m_nEndCol ); if ( m_nEndCol < 0 ) { if ( bAllowPastEndOfLine && m_nEndRow > 0 ) { m_nEndRow--; m_nEndCol = pBuffer->GetLineLength( m_nEndRow ); bEnforceSelBounds = FALSE; // already enforced by previous statement! } else { m_nEndCol = 0; } } break; } case ePage: { m_nEndCol -= ( m_pView->GetRightIndex( FALSE ) - m_pView->GetLeftIndex() ); break; } case eAll: { m_nEndCol = 0; break; } case eSmartAll: { LPCTSTR pszLine = pBuffer->GetLineText( m_nEndRow ); int nFirstNonSpace = 0; while ( *pszLine && ( *pszLine == _T(' ') || *pszLine == _T('\t') ) ) { nFirstNonSpace++; pszLine = _tcsinc( pszLine ); } // jump between absolute left and 'textual' left m_nEndCol = ( m_nEndCol == nFirstNonSpace ? 0 : nFirstNonSpace ); break; } case eWord: { pBuffer->AdvanceToWordStart( m_nEndRow, m_nEndCol, FALSE, TRUE ); break; } case eWordEnd: { pBuffer->AdvanceToWordEnd( m_nEndRow, m_nEndCol, FALSE, TRUE ); break; } case eSentence: { pBuffer->AdvanceToSentenceStart( m_nEndRow, m_nEndCol, FALSE ); break; } } break; } case eRight: { switch ( eAmount ) { case eChar: { if ( m_nEndCol >= nEndLineLen ) m_nEndCol++; else m_nEndCol += _tclen( pszEndLineStart + m_nEndCol ); break; } case ePage: { m_nEndCol += ( m_pView->GetRightIndex( FALSE ) - m_pView->GetLeftIndex() ); break; } case eAll: { m_nEndCol = pBuffer->GetLineLength( m_nEndRow ); break; } case eSmartAll: { LPCTSTR pszStart = pBuffer->GetLineText( m_nEndRow ); int nLastChar = pBuffer->GetLineLength( m_nEndRow ); int nFirstNonSpace = nLastChar; LPCTSTR pszEnd = pszStart + nFirstNonSpace - 1; while ( ( pszEnd >= pszStart ) && ( *pszEnd == _T(' ') || *pszEnd == _T('\t') ) ) { nFirstNonSpace--; pszEnd = _tcsdec( pszStart, pszEnd ); } // jump between absolute right and 'textual' right m_nEndCol = ( m_nEndCol <= nFirstNonSpace ? nLastChar : nFirstNonSpace ); break; } case eWord: { pBuffer->AdvanceToWordStart( m_nEndRow, m_nEndCol, TRUE, TRUE ); break; } case eWordEnd: { pBuffer->AdvanceToWordEnd( m_nEndRow, m_nEndCol, TRUE, TRUE ); break; } case eSentence: { pBuffer->AdvanceToSentenceStart( m_nEndRow, m_nEndCol, TRUE ); break; } } break; } case eOutward: { switch ( eAmount ) { case eWord: { m_nStartCol = m_nEndCol; int nLineLen = pBuffer->GetLineLength( m_nEndRow ); if ( m_nStartCol <= nLineLen ) { if ( m_nStartCol ) { pBuffer->AdvanceToWordStart( m_nEndRow, m_nStartCol, FALSE, FALSE ); } m_nEndCol = m_nStartCol; if ( m_nStartCol < nLineLen ) { pBuffer->AdvanceToWordEnd( m_nEndRow, m_nEndCol, TRUE, FALSE ); } } break; } case eSentence: { m_nStartRow = m_nEndRow; m_nStartCol = 0; pBuffer->AdvanceToSentenceStart( m_nStartRow, m_nStartCol, FALSE ); m_nEndCol = m_nStartCol; m_nEndRow = m_nStartRow; pBuffer->AdvanceToSentenceStart( m_nEndRow, m_nEndCol, TRUE ); bStartRowChanged = ( m_nStartRow != nOldStartRow ); break; } } break; } } int nTemp = nLineCount - 1; m_nEndRow = min( m_nEndRow, nTemp ); m_nEndRow = max( 0, m_nEndRow ); m_nEndCol = ( nLineCount == 0 ) ? 0 : max( 0, m_nEndCol ); BOOL bEndViewColUpToDate = FALSE; // keep cursor within the line's bounds if requested to if ( bEnforceSelBounds ) { // special case: if moving left one char and beyond the end of the line, // do the fixup now or else the one-char move will be nullified by // EnforceSelBounds() if ( nLineCount && eDirection == eLeft && eAmount == eChar ) { int nEndRowLen = pBuffer->GetLineLength( m_nEndRow ); if ( m_nEndCol >= nEndRowLen ) { m_nEndCol = nEndRowLen - 1; m_nEndCol = max( 0, m_nEndCol ); } } if ( bUsePreferredCol && nSaveEndRow != m_nEndRow ) { m_nEndCol = pBuffer->ConvertViewColToBufferCol( m_nEndRow, m_nEndViewColPreferred ); } BOOL bFixup = EnforceSelBounds(); // if we didn't have to fix-up the selection, remember this new col position // as the preferred position. if ( !bFixup ) { if ( bUsePreferredCol && nSaveEndRow != m_nEndRow ) { // moved vertically -- need to translate view col from one row to another int nBuffCol = pBuffer->ConvertViewColToBufferCol( m_nEndRow, m_nEndViewColPreferred ); m_nEndViewCol = pBuffer->ConvertBufferColToViewCol( m_nEndRow, nBuffCol ); m_nEndCol = pBuffer->ConvertViewColToBufferCol( m_nEndRow, m_nEndViewCol ); } else if ( nSaveEndCol != m_nEndCol ) { m_nEndViewCol = pBuffer->ConvertBufferColToViewCol( m_nEndRow, m_nEndCol ); m_nEndViewColPreferred = m_nEndViewCol; } bEndViewColUpToDate = TRUE; } } // since m_nEndCol may have changed, we need to recalc the view position and re-snap m_nEndCol to the current row if ( !bEndViewColUpToDate ) { m_nEndViewCol = pBuffer->ConvertBufferColToViewCol( m_nEndRow, m_nEndCol ); m_nEndCol = pBuffer->ConvertViewColToBufferCol( m_nEndRow, m_nEndViewCol ); } if ( eDirection == eOutward ) { m_nStartViewCol = pBuffer->ConvertBufferColToViewCol( m_nStartRow, m_nStartCol ); } if ( bDamage ) { int nDamageStart = min( nOldEndRow, m_nEndRow ); int nDamageEnd = max( nOldEndRow, m_nEndRow ); if ( m_bColumnSel ) { nDamageStart = min( nDamageStart, nOldStartRow ); nDamageStart = min( nDamageStart, m_nStartRow ); nDamageEnd = max( nDamageEnd, nOldStartRow ); nDamageEnd = max( nDamageEnd, m_nStartRow ); } if ( bStartRowChanged ) { nDamageStart = min( nDamageStart, nOldStartRow ); nDamageStart = min( nDamageStart, m_nStartRow ); nDamageEnd = max( nDamageEnd, nOldEndRow ); nDamageEnd = max( nDamageEnd, m_nEndRow ); } m_pView->DamageView( nDamageStart, nDamageEnd ); } // if user changed lines, notify the control so it can normalize the text case in the // line that was just left. if ( eDirection == eUp || eDirection == eDown ) { m_pCtrl->OnChangeLineSelection(); } } else { m_nEndCol = m_nEndRow = m_nEndViewCol = m_nStartViewCol = m_nStartCol = m_nStartRow = 0; } if ( bScrollIfNeccessary ) { EnsureVisible( TRUE ); } }
EESTATUS GetExpr ( uint radix, PEEHSTR phStr, ulong *pEnd ) { EESTATUS retval = EENOMEMORY; char *pStr; char *pExprStr; HDEP hExprStr; int len; ulong strIndex; UINT nLen; Unreferenced( radix ); //M00KLUDGE - this routine will eventuall have to walk the bound tree // and format the expression because of ambiguous expressions // use the saved original string if there is one // (in case the expression has been modified) if (pExState->hExStrSav) { hExprStr = pExState->hExStrSav; len = pExState->ExLenSav; strIndex = pExState->strIndexSav; } else { hExprStr = pExState->hExStr; len = pExState->ExLen; strIndex = pExState->strIndex; } pExprStr = (char *) MemLock (hExprStr); nLen = len+1; if (((*phStr = MemAllocate (nLen)) != 0)) { // the expression has been bound and memory allocated char tempBuf[TYPESTRMAX]; UINT nb; UINT nIndex = 0; BOOL fHSYM; char *psz; ulong nAdj = 0; pStr = (char *) MemLock (*phStr); for (psz = pExprStr; (psz < pExprStr + len) && *psz; psz = _tcsinc (psz)) { fHSYM = FALSE; if (*psz == HSYM_MARKER) { HSYM hSym = GetHSYMFromHSYMCode(psz + 1); psz += HSYM_CODE_LEN; // skip embedded HSYM code fHSYM = TRUE; DASSERT (hSym); if (GetNameFromHSYM(tempBuf, hSym) == FALSE) { pExState->err_num = ERR_INTERNAL; MemUnLock(*phStr); MemUnLock(hExprStr); return EEGENERAL; } nb = _tcslen(tempBuf); // compute adjustment for strIndex: // if an HSYM is to the left of strIndex, // strIndex needs to be adjusted if (psz <= pExprStr + strIndex) nAdj += (nb - sizeof (char) - HSYM_CODE_LEN); } else { nb = 1; } // check if there is space in the buffer and // copy nb characters to the destination string if (nIndex + nb > nLen-1) { // there is not enough space, grow buffer MemUnLock(*phStr); nLen += NAMESTRMAX; if ((*phStr = MemReAlloc(*phStr, nLen)) == 0){ MemUnLock(hExprStr); return EENOMEMORY; } pStr = (char *) MemLock (*phStr); } if (fHSYM) { // copy name from tembBuf memcpy(pStr+nIndex, tempBuf, nb); nIndex += nb; } else { // copy a single character from pExprStr _tccpy (pStr + nIndex, psz); nIndex += _tclen (psz); } } pStr[nIndex++] = 0; MemUnLock (*phStr); // Reallocate the buffer in case it is too large DASSERT (nIndex <= nLen); if (nIndex < nLen && (*phStr = MemReAlloc(*phStr, nIndex)) == 0){ MemUnLock(hExprStr); return EENOMEMORY; } retval = EENOERROR; *pEnd = strIndex + nAdj; } MemUnLock (hExprStr); return retval; }