コード例 #1
0
ファイル: CCString.cpp プロジェクト: Sdw195/Transcendence
CString CCString::Print (const CString &sString, DWORD dwFlags)

//	Print
//
//	Converts an arbitrary string into something that could be parsed as a string
//	by CodeChain (in particular, it escapes all weird characters).

	{
	bool bEscapeNeeded = ((dwFlags & PRFLAG_FORCE_QUOTES) ? true : false);

	//	Short-circuit null strings

	if (sString.IsBlank())
		{
		if (!(dwFlags & PRFLAG_NO_QUOTES)
				&& !(dwFlags & PRFLAG_ENCODE_FOR_DISPLAY))
			return CONSTLIT("\"\"");
		else
			return sString;
		}

	//	Parse

	char *pPos = sString.GetASCIIZPointer();
	char *pPosEnd = pPos + sString.GetLength();

	//	First see if we need to do anything at all.

	if (!bEscapeNeeded)
		{
		while (pPos < pPosEnd)
			{
			if ((BYTE)*pPos <= (BYTE)' ' || *pPos == '(' || *pPos == ')' || *pPos == ';' || *pPos == '\'' || *pPos == '\"'
					|| *pPos == '{' || *pPos == '}' || *pPos == ':'
					|| (*pPos >= '0' && *pPos <= '9'))
				{
				bEscapeNeeded = true;
				break;
				}

			pPos++;
			}
		}

	//	If we don't need escape or quotes, then we're done

	if (!bEscapeNeeded)
		return sString;

	//	Otherwise we need to parse

	pPos = sString.GetASCIIZPointer();
	
	char *pBuffer = new char [4 * sString.GetLength() + 32];
	char *pDest = pBuffer;

	if (!(dwFlags & PRFLAG_NO_QUOTES)
			&& !(dwFlags & PRFLAG_ENCODE_FOR_DISPLAY))
		*pDest++ = '\"';

	//	If we're encoding for display, we allow tabs and new-lines

	if (dwFlags & PRFLAG_ENCODE_FOR_DISPLAY)
		{
		while (pPos < pPosEnd)
			{
			//	Ignore zero

			if (*pPos == '\0')
				NULL;

			//	Allow tabs and new-lines

			else if (*pPos == '\t' || *pPos == '\r' || *pPos == '\n')
				*pDest++ = *pPos;

			//	Convert any low-ASCII characters to whitespace

			else if ((BYTE)*pPos < ' ' || (BYTE)(*pPos) == 255)
				*pDest++ = ' ';

			//	Otherwise, take the character unmodified

			else
				*pDest++ = *pPos;

			pPos++;
			}
		}

	//	Otherwise we escape every character in a reversable way
	else
		{
		while (pPos < pPosEnd)
			{
			if (*pPos == '\\')
				{
				*pDest++ = '\\';
				*pDest++ = '\\';
				}
			else if (*pPos == '\0')
				{
				*pDest++ = '\\';
				*pDest++ = '0';
				}
			else if (*pPos == '\"')
				{
				*pDest++ = '\\';
				*pDest++ = '\"';
				}
			else if (*pPos == '\n')
				{
				*pDest++ = '\\';
				*pDest++ = 'n';
				}
			else if ((BYTE)*pPos < ' ' || (BYTE)(*pPos) == 255)
				{
				*pDest++ = '\\';
				*pDest++ = 'x';
				*pDest++ = strGetHexDigit(((BYTE)(*pPos) / 16));
				*pDest++ = strGetHexDigit(((BYTE)(*pPos) % 16));
				}
			else
				*pDest++ = *pPos;

			pPos++;
			}
		}

	if (!(dwFlags & PRFLAG_NO_QUOTES)
			&& !(dwFlags & PRFLAG_ENCODE_FOR_DISPLAY))
		*pDest++ = '\"';

	*pDest++ = '\0';

	//	Done

	CString sResult(pBuffer);
	delete pBuffer;
	return sResult;
	}
コード例 #2
0
ファイル: Link.cpp プロジェクト: gmoromisato/Dev
ICCItem *CCodeChain::Link (const CString &sString, int iOffset, int *retiLinked, int *ioiCurLine)

//	Link
//
//	Parses the given string and converts it into a linked
//	chain of items

	{
	char *pStart;
	char *pPos;
	ICCItem *pResult = NULL;
	int iCurLine = (ioiCurLine ? *ioiCurLine : 1);

	pStart = sString.GetPointer() + iOffset;
	pPos = pStart;

	//	Skip any whitespace

	pPos = SkipWhiteSpace(pPos, &iCurLine);

	//	If we've reached the end, then we have
	//	nothing

	if (*pPos == '\0')
		pResult = CreateNil();

	//	If we've got a literal quote, then remember it

	else if (*pPos == SYMBOL_QUOTE)
		{
		int iLinked;

		pPos++;

		pResult = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine);
		if (pResult->IsError())
			return pResult;

		pPos += iLinked;

		//	Make it a literal

		pResult->SetQuoted();
		}

	//	If we've got an open paren then we start a list

	else if (*pPos == SYMBOL_OPENPAREN)
		{
		ICCItem *pNew = CreateLinkedList();
		if (pNew->IsError())
			return pNew;

		CCLinkedList *pList = dynamic_cast<CCLinkedList *>(pNew);

		//	Keep reading until we find the end

		pPos++;

		//	If the list is empty, then there's nothing to do

		pPos = SkipWhiteSpace(pPos, &iCurLine);
		if (*pPos == SYMBOL_CLOSEPAREN)
			{
			pList->Discard(this);
			pResult = CreateNil();
			pPos++;
			}

		//	Get all the items in the list

		else
			{
			while (*pPos != SYMBOL_CLOSEPAREN && *pPos != '\0')
				{
				ICCItem *pItem;
				int iLinked;

				pItem = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine);
				if (pItem->IsError())
					return pItem;

				//	Add the item to the list

				pList->Append(this, pItem, NULL);
				pItem->Discard(this);

				//	Move the position

				pPos += iLinked;

				//	Skip whitespace

				pPos = SkipWhiteSpace(pPos, &iCurLine);
				}

			//	If we have a close paren then we're done; Otherwise we've
			//	got an error of some kind

			if (*pPos == SYMBOL_CLOSEPAREN)
				{
				pPos++;
				pResult = pList;
				}
			else
				{
				pList->Discard(this);
				pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched open parenthesis"));
				}
			}
		}

	//	If this is an open brace then we've got a literal structure

	else if (*pPos == SYMBOL_OPENBRACE)
		{
		ICCItem *pNew = CreateSymbolTable();
		if (pNew->IsError())
			return pNew;

		CCSymbolTable *pTable = dynamic_cast<CCSymbolTable *>(pNew);

		//	Always literal

		pTable->SetQuoted();

		//	Keep reading until we find the end

		pPos++;

		//	If the list is empty, then there's nothing to do

		pPos = SkipWhiteSpace(pPos, &iCurLine);
		if (*pPos == SYMBOL_CLOSEBRACE)
			{
			pResult = pTable;
			pPos++;
			}

		//	Get all the items in the list

		else
			{
			while (*pPos != SYMBOL_CLOSEBRACE && *pPos != '\0')
				{
				//	Get the key

				ICCItem *pKey;
				int iLinked;

				pKey = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine);
				if (pKey->IsError())
					{
					pTable->Discard(this);
					return pKey;
					}

				//	Move the position and read a colon

				pPos += iLinked;
				pPos = SkipWhiteSpace(pPos, &iCurLine);
				if (*pPos != SYMBOL_COLON)
					{
					pKey->Discard(this);
					pTable->Discard(this);
					return CreateParseError(iCurLine, CONSTLIT("Struct value not found."));
					}

				pPos++;

				//	Get the value

				ICCItem *pValue;

				pValue = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine);
				if (pValue->IsError())
					{
					pKey->Discard(this);
					pTable->Discard(this);
					return pValue;
					}

				//	Move the position

				pPos += iLinked;

				//	Add the item to the table

				pResult = pTable->AddEntry(this, pKey, pValue);
				pKey->Discard(this);
				pValue->Discard(this);
				if (pResult->IsError())
					{
					pTable->Discard(this);
					return pResult;
					}

				//	Skip whitespace because otherwise we won't know whether we
				//	hit the end brace.

				pPos = SkipWhiteSpace(pPos, &iCurLine);
				}

			//	If we have a close paren then we're done; Otherwise we've
			//	got an error of some kind

			if (*pPos == SYMBOL_CLOSEBRACE)
				{
				pPos++;
				pResult = pTable;
				}
			else
				{
				pTable->Discard(this);
				pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched open brace"));
				}
			}
		}

	//	If this is an open quote, then read everything until
	//	the close quote

	else if (*pPos == SYMBOL_OPENQUOTE)
		{
		//	Parse the string, until the end quote, parsing escape codes

		char *pStartFragment = NULL;
		CString sResultString;

		bool bDone = false;
		while (!bDone)
			{
			pPos++;

			switch (*pPos)
				{
				case SYMBOL_CLOSEQUOTE:
				case '\0':
					{
					if (pStartFragment)
						{
						sResultString.Append(CString(pStartFragment, pPos - pStartFragment));
						pStartFragment = NULL;
						}

					bDone = true;
					break;
					}

				case SYMBOL_BACKSLASH:
					{
					if (pStartFragment)
						{
						sResultString.Append(CString(pStartFragment, pPos - pStartFragment));
						pStartFragment = NULL;
						}

					pPos++;
					if (*pPos == '\0')
						bDone = true;
					else if (*pPos == 'n')
						sResultString.Append(CString("\n", 1));
					else if (*pPos == 'r')
						sResultString.Append(CString("\r", 1));
					else if (*pPos == 't')
						sResultString.Append(CString("\t", 1));
					else if (*pPos == '0')
						sResultString.Append(CString("\0", 1));
					else if (*pPos == 'x' || *pPos == 'X')
						{
						pPos++;
						int iFirstDigit = strGetHexDigit(pPos);
						pPos++;
						int iSecondDigit = 0;
						if (*pPos == '\0')
							bDone = true;
						else
							iSecondDigit = strGetHexDigit(pPos);

						char chChar = (char)(16 * iFirstDigit + iSecondDigit);
						sResultString.Append(CString(&chChar, 1));
						}
					else
						sResultString.Append(CString(pPos, 1));

					break;
					}

				default:
					{
					if (pStartFragment == NULL)
						pStartFragment = pPos;

					break;
					}
				}
			}

		//	If we found the close, then create a string; otherwise,
		//	it is an error

		if (*pPos == SYMBOL_CLOSEQUOTE)
			{
			pResult = CreateString(sResultString);

			//	Always a literal

			pResult->SetQuoted();

			//	Skip past quote

			pPos++;
			}
		else
			pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched quote"));
		}

	//	If this is a close paren, then it is an error

	else if (*pPos == SYMBOL_CLOSEPAREN)
		pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched close parenthesis"));

	//	If this is a close brace, then it is an error

	else if (*pPos == SYMBOL_CLOSEBRACE)
		pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched close brace"));

	//	Colons cannot appear alone

	else if (*pPos == SYMBOL_COLON)
		pResult = CreateParseError(iCurLine, CONSTLIT("':' character must appear inside quotes or in a struct definition."));

	//	Otherwise this is an string of some sort

	else
		{
		char *pStartString;
		CString sIdentifier;
		int iInt;
		bool bNotInteger;

		pStartString = pPos;

		//	Look for whitespace

    	while (*pPos != '\0'
        		&& *pPos != ' ' && *pPos != '\n' && *pPos != '\r' && *pPos != '\t'
            	&& *pPos != SYMBOL_OPENPAREN
				&& *pPos != SYMBOL_CLOSEPAREN
				&& *pPos != SYMBOL_OPENQUOTE
				&& *pPos != SYMBOL_CLOSEQUOTE
				&& *pPos != SYMBOL_OPENBRACE
				&& *pPos != SYMBOL_CLOSEBRACE
				&& *pPos != SYMBOL_COLON
				&& *pPos != SYMBOL_QUOTE
				&& *pPos != ';')
        	pPos++;

		//	If we did not advance, then we clearly hit an error

		if (pStartString == pPos)
			pResult = CreateParseError(iCurLine, strPatternSubst(CONSTLIT("Unexpected character: %s"), CString(pPos, 1)));

		//	If we ended in a quote then that's a bug

		else if (*pPos == SYMBOL_QUOTE)
			pResult = CreateParseError(iCurLine, strPatternSubst(CONSTLIT("Identifiers must not use single quote characters: %s"), 
					strSubString(sString, iOffset + (pStartString - pStart), (pPos + 1 - pStartString))));

		//	Otherwise, get the identifier

		else
			{
			//	Create a string from the portion

			sIdentifier = strSubString(sString, iOffset + (pStartString - pStart), (pPos - pStartString));

			//	Check to see if this is a reserved identifier

			if (strCompareAbsolute(sIdentifier, CONSTLIT("Nil")) == 0)
				pResult = CreateNil();
			else if (strCompareAbsolute(sIdentifier, CONSTLIT("True")) == 0)
				pResult = CreateTrue();
			else
				{
				//	If this is an integer, create an integer; otherwise
				//	create a string

				iInt = strToInt(sIdentifier, 0, &bNotInteger);
				if (bNotInteger)
					pResult = CreateString(sIdentifier);
				else
					pResult = CreateInteger(iInt);
				}
			}
		}

	//	Return the result and the number of characters
	//	that we read

	if (retiLinked)
		*retiLinked = (pPos - pStart);

	if (ioiCurLine)
		*ioiCurLine = iCurLine;

	return pResult;
	}