예제 #1
0
// 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);
}
예제 #2
0
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;
}
예제 #3
0
파일: vmdreg.cpp 프로젝트: hkaiser/TRiAS
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++;
		}
	}
}
예제 #4
0
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;
}
예제 #5
0
파일: hook.cpp 프로젝트: byplayer/yamy
/// 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;
    }
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
			}
		}
	}
}
예제 #10
0
파일: response.c 프로젝트: OpenFlex/ldc
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;
}
예제 #11
0
// 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();
}
예제 #12
0
// 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;
}