TRISTATE CTextParser::GetHexadecimal(unsigned long long int* pulli, int* piNumDigits)
{
	TRISTATE				tReturn;

	PushPosition();
	SkipWhiteSpace();

	tReturn = GetExactCharacter('0', FALSE);
	if (tReturn != TRITRUE)
	{
		PopPosition();
		return tReturn;
	}

	tReturn = GetExactCaseInsensitiveCharacter('X', FALSE);
	if (tReturn != TRITRUE)
	{
		PopPosition();
		return tReturn;
	}

	tReturn = GetHexadecimalPart(pulli, piNumDigits);
	if (tReturn != TRITRUE)
	{
		PopPosition();
	}
	else
	{
		PassPosition();
	}
	return tReturn;
}
TRISTATE CTextParser::GetInteger(unsigned long long int* pulli, int* piSign, int* piNumDigits, BOOL bSkipWhiteSpace)
{
	TRISTATE	tResult;

	PushPosition();

	if (bSkipWhiteSpace)
	{
		SkipWhiteSpace();
	}

	//Make sure we're not off the end of the file.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	tResult  = GetDigits(pulli, piSign, piNumDigits, bSkipWhiteSpace);
	if (tResult == TRITRUE)
	{
		//Make sure there are no decimals.
		if (mszParserPos[0] == '.')
		{
			PopPosition();
			return TRIFALSE;
		}

		PassPosition();
		return TRITRUE;
	}
	PopPosition();
	return tResult;
}
TRISTATE CTextParser::FindExactCharacterSequence(char* szSequence)
{
	char*			szPosition;
	TRISTATE		result;

	PushPosition();
	for (;;)
	{
		szPosition = mszParserPos;
		result = GetExactCharacterSequence(szSequence);
		if (result == TRIERROR)
		{
			//We've reached the end of the file without finding the identifier.
			PopPosition();
			return TRIFALSE;
		}
		else if (result == TRIFALSE)
		{
			//Try the next actual character along.
			StepRight();
			SkipWhiteSpace();
		}
		else if (result == TRITRUE)
		{
			mszParserPos = szPosition;
			PassPosition();
			return TRITRUE;
		}
	}
}
TRISTATE CTextParser::GetExactIdentifier(char* szIdentifier)
{
	char		cCurrent;
	int			iPos;
	TRISTATE	tResult;

	iPos = 0;
	PushPosition();
	SkipWhiteSpace();

	//Make sure we're not off the end of the file.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	for (;;)
	{
		if (szIdentifier[iPos] == 0)
		{
			//Got all the way to the NULL character.
			//If there are additional identifier characters then we do not have the right identifier.
			if (!mbOutsideText)
			{
				tResult = GetIdentifierCharacter(&cCurrent, iPos == 0);
				if (tResult == TRITRUE)
				{
					//Put the parser back where it was.
					PopPosition();
					return TRIFALSE;
				}
			}
			PassPosition();
			return TRITRUE;
		}
		if (!mbOutsideText)
		{
			cCurrent = mszParserPos[0];
			if (cCurrent == szIdentifier[iPos])
			{
				StepRight();
				iPos++;
			}
			else
			{
				//Put the parser back where it was.
				PopPosition();
				return TRIFALSE;
			}
		}
		else
		{
			//Put the parser back where it was.
			PopPosition();
			return TRIFALSE;
		}
	}
}
TRISTATE CTextParser::GetDebugCharacterSequence(char* szSequence)
{
	TRISTATE	tResult;

	PushPosition();
	tResult = GetExactCharacterSequence(szSequence);
	PopPosition();
	return tResult;
}
void CTextParser::Restart(void)
{
	mszParserPos = mszStartOfText;
	miLine = 0;
	miColumn = 0;
	masPositions.Kill();
	masPositions.Init(1);
	PushPosition();
	TestEnd();
}
TRISTATE CTextParser::FindStartOfLine(void)
{
	char cCurrent;
	BOOL bInQuotes;

	PushPosition();

	//If we're off the end of the file we can't return the beginning of the line.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	bInQuotes = FALSE;
	for (;;)
	{
		cCurrent = mszParserPos[0];
		if (cCurrent == '"')
		{
			bInQuotes = !bInQuotes;
		}
		if (!bInQuotes)
		{
			SkipLeftCStyleComment();
		}
		StepLeft();

		//If we have no more text then the start of the line is the start of the text.
		if (mbOutsideText)
		{
			mszParserPos = mszStartOfText;
			miColumn = 0;
			PassPosition();
			return TRITRUE;
		}

		if (!bInQuotes)
		{
			//Get the current character.
			cCurrent = mszParserPos[0];

			//If we get find an end of line character we've gone to far, go right again.
			if (cCurrent == '\n')
			{
				StepRight();
				PassPosition();
				return TRITRUE;
			}
		}
	}
}
TRISTATE CTextParser::GetExactCaseInsensitiveCharacterSequence(char* szSequence)
{
	int			iPos;
	char		c1, c2;

	PushPosition();
	SkipWhiteSpace();
	iPos = 0;

	//Make sure we're not off the end of the file.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	for (;;)
	{
		if (szSequence[iPos] == 0)
		{
			//Got all the way to the NULL character.
			PassPosition();
			return TRITRUE;
		}
		if (!mbOutsideText)
		{
			c1 = ToUpper(mszParserPos[0]);
			c2 = ToUpper(szSequence[iPos]);
			if (c1 == c2)
			{
				StepRight();
				iPos++;
			}
			else
			{
				//Put the parser back where it was.
				PopPosition();
				return TRIFALSE;
			}
		}
		else
		{
			//Put the parser back where it was.
			PopPosition();
			return TRIFALSE;
		}
	}
}
BOOL CTextParser::Init(char* szText, int iTextLen)
{
	//This assumes that szText has already been passified.
	if (szText == NULL)
	{
		miLine = 0;
		miColumn = 0;
		mszStartOfText = NULL;
		mszParserPos = NULL;
		mszEndOfText = NULL;
		miTextLen = 0;
		mbCaseSensitive = TRUE;
		mbAnnotated = FALSE;
		mbOutsideText = TRUE;
		masPositions.Init(32);
		return TRUE;
	}
	else if (CountCarriageReturns(szText, iTextLen) == 0)
	{
		miLine = 0;
		miColumn = 0;
		mszStartOfText = szText;
		mszParserPos = szText;
		mszEndOfText = &mszStartOfText[iTextLen - 1];
		miTextLen = iTextLen;
		mbCaseSensitive = TRUE;
		mbAnnotated = FALSE;
		TestEnd();
		masPositions.Init(32);
		PushPosition();
		return TRUE;
	}
	else
	{
		miLine = 0;
		miColumn = 0;
		mszStartOfText = NULL;
		mszParserPos = NULL;
		mszEndOfText = NULL;
		miTextLen = 0;
		masPositions.Init(32);

		gcLogger.Error("Parsed text contains carriage returns.");
		return FALSE;
	}
}
Example #10
0
File: midi.c Project: denemo/denemo
static void
do_one_note (gint mid_c_offset, gint enshift, gint notenum)
{//g_print("do one note Adding mask %x, Chord mask %x\n", (Denemo.keyboard_state & ADDING_MASK) , (Denemo.keyboard_state & CHORD_MASK));
  if ((Denemo.keyboard_state & ADDING_MASK) && (Denemo.keyboard_state & CHORD_MASK))
    {

      add_or_delete_note_to_chord (mid_c_offset, enshift, notenum);
    }
  else
    {
      DenemoObject *curobj = NULL;
      //check for non-printing notes - back up to the first non-printing note.
      gboolean non_printing_note = FALSE;
      PushPosition (NULL, NULL);
      while (cursor_to_prev_note ())
        {
          curobj = Denemo.project->movement->currentobject->data;
          if (!curobj->isinvisible)
            break;
          else
            non_printing_note = TRUE;
        }
      if (Denemo.project->movement->currentobject)
        {
          curobj = Denemo.project->movement->currentobject->data;
          if (non_printing_note)
            {
              if (!curobj->isinvisible)
                cursor_to_next_note ();
              (void)pop_position ();//Discard the pushed position
            }
          else
            PopPosition (NULL, NULL);// go to where we started, as there are no non-printing notes
        }
       else
            PopPosition (NULL, NULL);// go to where we started, as there are no non-printing notes
      action_note_into_score (mid_c_offset, enshift, notenum);

      if (Denemo.keyboard_state & ADDING_MASK)
        Denemo.keyboard_state |= CHORD_MASK;
      set_midi_in_status ();
    }
}
// ----------------------- Helper Functions ------------------------------
//////////////////////////////////////////////////////////////////////////
//
//
//////////////////////////////////////////////////////////////////////////
TRISTATE CTextParser::GetHFExactIdentifierAndInteger(char* szIdentifier, int* piInt)
{
	TRISTATE	tReturn;

	PushPosition();

	tReturn = GetExactIdentifier(szIdentifier);
	if ((tReturn == TRIERROR) || (tReturn == TRIFALSE))
	{
		PopPosition();
		return tReturn;
	}
	tReturn = GetInteger(piInt);
	if ((tReturn == TRIERROR) || (tReturn == TRIFALSE))
	{
		PopPosition();
		return tReturn;
	}

	PassPosition();
	return TRITRUE;
}
TRISTATE CTextParser::GetHFExactIdentifierAndString(char* szIdentifier, char* szString)
{
	TRISTATE	tReturn;

	PushPosition();

	tReturn = GetExactIdentifier(szIdentifier);
	if ((tReturn == TRIERROR) || (tReturn == TRIFALSE))
	{
		PopPosition();
		return tReturn;
	}
	tReturn = GetString(szString);
	if ((tReturn == TRIERROR) || (tReturn == TRIFALSE))
	{
		PopPosition();
		return tReturn;
	}

	PassPosition();
	return TRITRUE;
}
TRISTATE CTextParser::GetCharacterSequence(char* szSequence, int* piLength)
{
	char	c;
	BOOL	bFirst;
	int		iPos;

	bFirst = TRUE;
	iPos = 0;
	PushPosition();
	SkipWhiteSpace();

	//Make sure we're not off the end of the file.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	for (;;)
	{
		if (!mbOutsideText)
		{
			c = mszParserPos[0];
			StepRight();

			if (IsWhiteSpace(c))
			{
				if (bFirst)
				{
					if (szSequence)
						szSequence[iPos] = 0;

					PopPosition();
					return TRIFALSE;
				}
				else
				{
					if (szSequence)
						szSequence[iPos] = 0;

					if (szSequence)
						PassPosition();
					else
						PopPosition();

					SafeAssign(piLength, iPos);
					return TRITRUE;
				}
			}
			else
			{
				if (szSequence)
					szSequence[iPos] = c;
			}
		}
		else
		{
			if (bFirst)
			{
				PopPosition();
				SetErrorEndOfFile();
				return TRIERROR;
			}
			else
			{
				if (szSequence)
					szSequence[iPos] = 0;

				if (szSequence)
					PassPosition();
				else
					PopPosition();

				SafeAssign(piLength, iPos);
				return TRITRUE;
			}
		}
		bFirst = FALSE;
		iPos++;
	}
}
TRISTATE CTextParser::GetQuotedCharacterSequence(char cOpenQuote, char cCloseQuote, char* szString, int* piLength, BOOL bPassOnTest, BOOL bSkipWhiteSpace)
{
	int			iPos;
	char		cCurrent;
	TRISTATE	tReturn;
	char		cEscape;

	PushPosition();

	if (bSkipWhiteSpace)
	{
		SkipWhiteSpace();
	}

	if (!mbOutsideText)
	{
		if (GetExactCharacter(cOpenQuote, FALSE))
		{
			iPos = 0;
			for (;;)
			{
				if (!mbOutsideText)
				{
					cCurrent = mszParserPos[0];
					if (cCurrent == cCloseQuote)
					{
						if (szString)
							szString[iPos] = 0;

						StepRight();

						if (szString || bPassOnTest)
							PassPosition();
						else
							PopPosition();

						SafeAssign(piLength, iPos);
						return TRITRUE;
					}
					//We have an escape character...
					else if (cCurrent == '\\')
					{
						StepRight();
						tReturn = GetEscapeCode(&cEscape);
						if (szString)
							szString[iPos] = cEscape;

						iPos++;
						if (tReturn == TRIFALSE)
						{
							PopPosition();
							SetErrorSyntaxError();
							return TRIERROR;
						}
						else if (tReturn == TRIERROR)
						{
							PopPosition();
							//Don't set the error here, it's already been set by GetEscapeCode
							return TRIERROR;
						}
					}
					else if (cCurrent == '\n')
					{
						//Just ignore new lines.
						StepRight();
					}
					else
					{
						if (szString)
							szString[iPos] = cCurrent;

						iPos++;
						StepRight();
					}
				}
				else
				{
					//This has never been tested.
					PopPosition();
					SetErrorSyntaxError();
					return TRIERROR;
				}
			}
		}
		else
		{
			//No quote so not a string.
			PopPosition();
			return TRIFALSE;
		}
	}
	else
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}
}
BOOL CTextParser::SkipCPPStyleComment(void)
{
	char	cCurrent;
	int		iCount;

	if (mbOutsideText)
	{
		return TRUE;
	}

	PushPosition();
	cCurrent = mszParserPos[0];

	if (cCurrent == '/')
	{
		StepRight();
		if (!mbOutsideText)
		{
			cCurrent = mszParserPos[0];
			if (cCurrent == '/')
			{
				for (iCount = 0;; iCount++)
				{
					StepRight();
					if (!mbOutsideText)
					{
						cCurrent = mszParserPos[0];

						if (cCurrent == '\n')
						{
							//This is the end of the line and the end of the comment.
							StepRight();
							PassPosition();
							return TRUE;
						}

						if (mbAnnotated)
						{
							if (cCurrent == '@')
							{
								//Wasn't a comment, was an annotation.
								PopPosition();
								return FALSE;
							}
						}
					}
					else
					{
						PassPosition();
						return TRUE;
					}
				}
			}
			else
			{
				PopPosition();
				return TRUE;
			}
		}
		else
		{
			//Wasn't a comment.
			StepLeft();
			return TRUE;
		}
	}
	PopPosition();
	return TRUE;
}
void CTextParser::SkipLeftCStyleComment(void)
{
	char	cCurrent;
	int		iDepth;

	iDepth = 0;

	PushPosition();
	for (;;)
	{
		if (mbOutsideText)
		{
			PassPosition();
			return;
		}

		cCurrent = mszParserPos[0];
		if (cCurrent == '/')
		{
			StepLeft();
			if (!mbOutsideText)
			{
				cCurrent = mszParserPos[0];
				if (cCurrent == '*')
				{
					iDepth++;
				}
				else
				{
					//Wasn't a comment start... step back.
					StepRight();
				}
			}
			else
			{
				PassPosition();
				return;
			}
		}
		else if (cCurrent == '*')
		{
			StepLeft();
			if (!mbOutsideText)
			{
				cCurrent = mszParserPos[0];
				if (cCurrent == '/')
				{
					iDepth--;
				}
				else
				{
					//Wasn't the end of a comment... step back...
					StepRight();
				}
			}
			else
			{
				PassPosition();
				return;
			}
		}

		if (iDepth == 0)
		{
			//No more nested comments...  bail..
			return;
		}
		StepLeft();
	}
}
TRISTATE CTextParser::FindEndOfLine(void)
{
	char	cCurrent;
	BOOL	bInQuotes;
	char	cPrev;
	BOOL	bInCppComment;

	PushPosition();

	//If we're off the end of the file we can't go to the end of the line.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	bInCppComment = FALSE;
	bInQuotes = FALSE;
	cCurrent = 0;
	for (;;)
	{
		cPrev = cCurrent;
		cCurrent = mszParserPos[0];

		if ((cPrev == '/') && (cCurrent == '/'))
		{
			bInCppComment = TRUE;
		}

		if (!bInCppComment)
		{
			if (cCurrent == '"')
			{
				bInQuotes = !bInQuotes;
			}

			if (!bInQuotes)
			{
				SkipCStyleComment();
			}
		}


		//If we have no more text then ... blah, blah, blah
		if (mbOutsideText)
		{
			mszParserPos = mszEndOfText;
			miColumn--;  //This might work.
			PassPosition();
			return TRITRUE;
		}

		if ((!bInQuotes) || (bInCppComment))  //Note:  (NOT in quotes) OR (in Cpp comment).
		{
			//If we get find an end of line character we've gone to far, go right again.
			cCurrent = mszParserPos[0];
			if (cCurrent == '\n')
			{
				PassPosition();
				return TRITRUE;
			}
		}

		StepRight();
	}
}
TRISTATE CTextParser::GetIdentifier(char* szIdentifier, int* piLength, BOOL bPassOnTest)
{
	char	c;
	BOOL	bFirst;
	int		iPos;

	bFirst = TRUE;
	iPos = 0;
	PushPosition();
	SkipWhiteSpace();

	//Make sure we're not off the end of the file.
	if (mbOutsideText)
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}

	for (;;)
	{
		if (!mbOutsideText)
		{
			if (GetIdentifierCharacter(&c, bFirst) != TRITRUE)
			{
				if (bFirst)
				{
					if (szIdentifier)
						szIdentifier[iPos] = 0;

					PopPosition();
					return TRIFALSE;
				}
				else
				{
					if (szIdentifier)
						szIdentifier[iPos] = 0;

					if (szIdentifier || bPassOnTest)
						PassPosition();
					else
						PopPosition();

					SafeAssign(piLength, iPos);
					return TRITRUE;
				}
			}
			else
			{
				if (szIdentifier)
					szIdentifier[iPos] = c;
			}
		}
		else
		{
			if (bFirst)
			{
				PopPosition();
				SetErrorEndOfFile();
				return TRIERROR;
			}
			else
			{
				if (szIdentifier)
					szIdentifier[iPos] = 0;

				if (szIdentifier)
					PassPosition();
				else
					PopPosition();

				SafeAssign(piLength, iPos);
				return TRITRUE;
			}
		}
		bFirst = FALSE;
		iPos++;
	}
}
TRISTATE CTextParser::GetDigits(unsigned long long int* pulli, int* piSign, int* piNumDigits, BOOL bSkipWhiteSpace, BOOL bTestSign)
{
	unsigned long long int	iNum;
	int						iSign;
	int						iTemp;
	TRISTATE				tReturn;
	BOOL					bFirstDigit;
	int						i;

	//This still needs to be failed on the case where the number is larger than MAX_ULONG.
	PushPosition();
	if (bSkipWhiteSpace)
	{
		SkipWhiteSpace();
	}

	*pulli = 0;
	i = 0;
	if (!mbOutsideText)
	{
		iNum = 0;

		if (bTestSign)
			GetSign(&iSign);
		else
			iSign = 1;

		bFirstDigit = TRUE;
		for (;;)
		{
			if (!mbOutsideText)
			{
				tReturn = GetDigit(&iTemp);
				if (tReturn == TRITRUE)
				{
					i++;
					iNum *= 10;
					iNum += iTemp;
				}
				else if ((tReturn == TRIFALSE) || (tReturn == TRIERROR))
				{
					break;
				}
				bFirstDigit = FALSE;
			}
			else
			{
				break;
			}
		}

		if (bFirstDigit)
		{
			//might already have got a sign...  so reset the parser.
			PopPosition();
			return TRIFALSE;
		}
		else
		{
			*piSign = iSign;
			*pulli = iNum;
			if (piNumDigits)
			{
				*piNumDigits = i;
			}
			PassPosition();
			return TRITRUE;
		}
	}
	else
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}
}
TRISTATE CTextParser::GetOctal(unsigned long long int* pulli, int* piNumDigits)
{
	unsigned long long int	iNum;
	int						iTemp;
	TRISTATE				tReturn;
	int						i;

	PushPosition();
	SkipWhiteSpace();

	tReturn = GetExactCharacter('0', FALSE);
	if (tReturn != TRITRUE)
	{
		PopPosition();
		return tReturn;
	}

	*pulli = 0;
	i = 0;
	if (!mbOutsideText)
	{
		iNum = 0;

		for (;;)
		{
			if (!mbOutsideText)
			{
				tReturn = GetDigit(&iTemp, 8);
				if (tReturn == TRITRUE)
				{
					i++;
					iNum *= 8;
					iNum += iTemp;
				}
				else if ((tReturn == TRIFALSE) || (tReturn == TRIERROR))
				{
					*pulli = iNum;
					if (piNumDigits)
					{
						*piNumDigits = i;
					}
					PassPosition();
					return TRITRUE;
				}
			}
			else
			{
				if (i > 0)
				{
					*pulli = iNum;
					if (piNumDigits)
					{
						*piNumDigits = i;
					}
					PassPosition();
					return TRITRUE;
				}

				PopPosition();
				SetErrorSyntaxError();
				return TRIERROR;
			}
		}
	}
	else
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}
}
TRISTATE CTextParser::GetFloat(double* pf)
{
	unsigned long long int	ulliLeft;
	unsigned long long int	ulliRight;
	TRISTATE				tReturn;
	int						iNumDecimals;
	double					fLeft;
	double					fRight;
	double					fTemp;
	BOOL					bLeft;
	int						iSign;

	PushPosition();
	SkipWhiteSpace();

	*pf = 0.0f;
	if (!mbOutsideText)
	{
		//Try and get the mantissa.
		tReturn = GetDigits(&ulliLeft, &iSign, NULL);
		bLeft = TRUE;

		//Just return on errors an non-numbers.
		if (tReturn == TRIFALSE)
		{
			//There may still be a decimal point...
			ulliLeft = 0;
			bLeft = FALSE;
		}
		else if (tReturn == TRIERROR)
		{
			PopPosition();
			SetErrorSyntaxError();
			return TRIERROR;
		}

		fLeft = ((double)ulliLeft) * iSign;
		tReturn = GetExactCharacter('.', FALSE);
		if (tReturn == TRITRUE)
		{
			tReturn = GetDigits(&ulliRight, &iSign, &iNumDecimals);
			if (tReturn == TRITRUE)
			{
				if (iSign <= 0)
				{
					//Cant have: 34.-342 but -34.342 would be fine.
					PopPosition();
					SetErrorSyntaxError();
					return TRIERROR;
				}

				fRight = (double)ulliRight;
				fTemp = pow(10.0L, -iNumDecimals);
				fRight *= fTemp;

				if (fLeft >= 0)
				{
					*pf = fLeft + fRight;
				}
				else
				{
					*pf = fLeft - fRight;
				}
				PassPosition();
				return TRITRUE;
			}
			else
			{
				//A decimal point must be followed by a number.
				PopPosition();
				SetErrorSyntaxError();
				return TRIERROR;
			}
		}
		else
		{
			//No decimal point...
			if (!bLeft)
			{
				//No digits and no point...
				PopPosition();
				return TRIFALSE;
			}
			else
			{
				*pf = fLeft;
				PassPosition();
				return TRITRUE;
			}
		}
	}
	else
	{
		PopPosition();
		SetErrorEndOfFile();
		return TRIERROR;
	}
}