CFX_ByteStringC CPDF_SimpleParser::GetWord() {
  const uint8_t* pStart;
  FX_DWORD dwSize;
  int type;
  ParseWord(pStart, dwSize, type);
  if (dwSize == 1 && pStart[0] == '<') {
    while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') {
      m_dwCurPos++;
    }
    if (m_dwCurPos < m_dwSize) {
      m_dwCurPos++;
    }
    return CFX_ByteStringC(pStart,
                           (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData)));
  }
  if (dwSize == 1 && pStart[0] == '(') {
    int level = 1;
    while (m_dwCurPos < m_dwSize) {
      if (m_pData[m_dwCurPos] == ')') {
        level--;
        if (level == 0) {
          break;
        }
      }
      if (m_pData[m_dwCurPos] == '\\') {
        if (m_dwSize <= m_dwCurPos) {
          break;
        }
        m_dwCurPos++;
      } else if (m_pData[m_dwCurPos] == '(') {
        level++;
      }
      if (m_dwSize <= m_dwCurPos) {
        break;
      }
      m_dwCurPos++;
    }
    if (m_dwCurPos < m_dwSize) {
      m_dwCurPos++;
    }
    return CFX_ByteStringC(pStart,
                           (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData)));
  }
  return CFX_ByteStringC(pStart, dwSize);
}
Beispiel #2
0
UWORD ParseCPPLines
(
	struct SyntaxHandle *handle, 
	LineDef** lines,
	BSTR textData,
	UWORD startoffset,
	UWORD maxlength,
	CArray <SyntaxChunk, SyntaxChunk>& SyntaxArr
)
{
	SyntaxArr.SetSize(maxlength);	// hm.. TODO, add instead
	SyntaxChunk* syntax = SyntaxArr.GetData();
	int ChunkUsed = 0;

	UWORD	parsedlength = 0;
	BOOL	donext;

	int nline = 0;

	if (maxlength == 0) return 0;

	int offset = 0;

	do
	{
	//	register UWORD	len = linenode->LineLen;
		UBYTE	el = 0;
		BOOL	cont = FALSE;

		if (offset == 0)	/* If first line in the doc */
			el = 0;
		else
		{
//			while (!prevline->IsParsed
			el = 0;//syntax[-1].Element;
		}
	//	linenode->BegEl = el;		/* Attr at beginning of line taken from the previous line's EndAttr */

	//	if (linenode->Syntax) free(linenode->Syntax);
	//	linenode->Syntax = (SyntaxChunk*)malloc(sizeof(struct SyntaxChunk)*(linenode->LineLen+1));

		lines[nline]->m_ckOffset = ChunkUsed;

		syntax->Length = 0;
		syntax->Element = el;
		syntax->Flags = ElementFlags[el];

		ChunkUsed += 1;

		int linelen = lines[nline]->m_lineLength;

		WCHAR* lineData = &textData[offset];

		UWORD	col = 0;

		while (col < linelen)
		{
			WCHAR *c = &lineData[col];
			UWORD	ellen = 1;	/* Assume */
			UBYTE	sel = 255;
			BOOL	off = FALSE;

			if (!(ctype[*c] & C))
			{
				if (el == 0) ellen = ParseWord(lineData, col, linelen, &sel);
			}
			else
			{
				if (c[0] == '/')  /* This could be the start of a comment */
	         {
	            if ((el == 0) || (el == EL_PREPROCESSOR))   /* Can have comments on same line as preprocessor */
	            {
	               if (c[1] == '/')	/* CPP comment, set rest of line to that */
	               {
	                  el = EL_CPPCOMMENT;
							ellen = linelen-col;
	               }
	               else if (c[1] == '*')	/* ANSI comment */
	               {
	                  el = EL_COMMENT;
							ellen = 2;
	               }
	               else
	               {
	                  if (el != EL_PREPROCESSOR)	/* If it wasn't a comment and we're not */
	                     sel = EL_SYMBOL;			/* in preprocessor make it a symbol */
	               }
	            }
	         }
	         else if (c[0] == '*')   /* This could be the end of a comment */
	         {
	            if ((el == EL_COMMENT) && (c[1] == '/'))
	            {
	               off = TRUE;
						el = 0;
						ellen = 2;
	            }
	            else
	            {
	               if (el == 0) /* It was just a normal symbol */
	               {
							sel = EL_SYMBOL;
	               }
	            }
	         }
	         else if (c[0] == '\"')  /* Either beginning or ending a string quote */
	         {
	            if (el == 0) /* Beginning */
	            {
	               el = EL_STRING;
	            }
	            else if (el == EL_STRING)   // Maybe it's ending */
	            {
					/* Here we check if it's a \", then we check if it's a \\" */
						if (((col > 0) && (c[-1] != '\\')) ||	/* it's not a '\"' */
							 ((col > 1) && (c[-2] == '\\')))		/* it's a '\\"' */
						{
							off = TRUE;
							el = 0;
						}
	            }
	         }
	         else if (c[0] == '\'')  /* Either beginning or ending a char quote */
	         {
	            if (el == 0) /* Beginning */
	            {
	               el = EL_CHARACTER;
	            }
	            else if (el == EL_CHARACTER)   /* Maybe it's ending */
	            {
					/* Here we check if it's a \', then we check if it's a \\' */
						if (((col > 0) && (c[-1] != '\\')) ||	/* it's not a \' */
							 ((col > 1) && (c[-2] == '\\')))		/* it's a \\' */
						{
							off = TRUE;
							el = 0;
						}
	            }
	         }
	         else if (c[0] == '#')   /* If first non-blank char on line, this is preprocessor statement */
	         {
	            if (el == 0)
	            {
	               /* TODO: Check if first non-blank */
	               el = EL_PREPROCESSOR;
	            }
	         }
	         else if (c[0] == '\\')  /* If last on line, this is a continuation on the next line */
	         {
	            if ((col == linelen-1) &&   /* last on line */
	                (el != EL_CPPCOMMENT))
	            {
	               if (el) cont = TRUE;  /* Only need to continue if there was some previous el */
	            }
	         }
			}

			if (sel == 255) sel = el;

			if (off) syntax->Length += ellen;

		/* If the element has changed goto next syntax chunk */
			if (sel != syntax->Element)
			{
			// Only create new if the previous syntax chunk contains something
			// if not, just overwrite that one
				if (syntax->Length > 0)
				{
					ChunkUsed++;
					syntax++;
				}

				syntax->Length = 0;
				syntax->Element = sel;
				syntax->Flags = ElementFlags[sel];
			}

			if (!off) syntax->Length += ellen;

		//	CString msg;
		//	msg.Format("%d", syntax->Length);
		//	AfxMessageBox(msg/*(LPCTSTR)(&lineData[col])*/);

			col += ellen;
      }

//		msg.Format("%d, %d, %d", linelen, offset, maxlength);
//		AfxMessageBox(msg);

		offset += linelen+1;

		syntax++;	// Always new on each line

		nline++;
#if 0
		linenode->Syntax = realloc(linenode->Syntax, linenode->ChunkUsed*sizeof(struct SyntaxChunk));

   /* numlines is used later to know the number of lines to visually update
		folded lines shouldn't be included in this count */
      if (!linenode->Folded) parsedlines++;

	/* Set this line's EndEl */
      if ((el == EL_COMMENT) || cont) /* This continues over several lines */
         linenode->EndEl= el;
      else
         linenode->EndEl = 0;

      donext = FALSE;   /* Assume that we're not gonna parse the next line */

		if (--maxlines)
		{
	   /* Check if Next line is candidate for scanning
	 	  	First check if there IS a next line */
	      if ((nextline = linenode->Succ)->Succ)
	      {
	         /* If the next line's BegEl is different than the line we just
	         	parsed's EndAttr then parse the next one too */
	         if (nextline->BegEl != linenode->EndEl)
	         {
	            linenode = nextline;
	            donext = TRUE;
	         }
	      }
		}
#endif
   }
	while (offset < maxlength/*-1*/);
//   while (donext);

	SyntaxArr.SetSize(ChunkUsed);

   return parsedlength;     /* Number of lines that were parsed */
}
void FileStringReader::HandlePragma(char *str)
{
	if (!memcmp(str, "id ", 3)) {
		this->data.next_string_id = strtoul(str + 3, NULL, 0);
	} else if (!memcmp(str, "name ", 5)) {
		strecpy(_lang.name, str + 5, lastof(_lang.name));
	} else if (!memcmp(str, "ownname ", 8)) {
		strecpy(_lang.own_name, str + 8, lastof(_lang.own_name));
	} else if (!memcmp(str, "isocode ", 8)) {
		strecpy(_lang.isocode, str + 8, lastof(_lang.isocode));
	} else if (!memcmp(str, "textdir ", 8)) {
		if (!memcmp(str + 8, "ltr", 3)) {
			_lang.text_dir = TD_LTR;
		} else if (!memcmp(str + 8, "rtl", 3)) {
			_lang.text_dir = TD_RTL;
		} else {
			error("Invalid textdir %s", str + 8);
		}
	} else if (!memcmp(str, "digitsep ", 9)) {
		str += 9;
		strecpy(_lang.digit_group_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_group_separator));
	} else if (!memcmp(str, "digitsepcur ", 12)) {
		str += 12;
		strecpy(_lang.digit_group_separator_currency, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_group_separator_currency));
	} else if (!memcmp(str, "decimalsep ", 11)) {
		str += 11;
		strecpy(_lang.digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_decimal_separator));
	} else if (!memcmp(str, "winlangid ", 10)) {
		const char *buf = str + 10;
		long langid = strtol(buf, NULL, 16);
		if (langid > (long)UINT16_MAX || langid < 0) {
			error("Invalid winlangid %s", buf);
		}
		_lang.winlangid = (uint16)langid;
	} else if (!memcmp(str, "grflangid ", 10)) {
		const char *buf = str + 10;
		long langid = strtol(buf, NULL, 16);
		if (langid >= 0x7F || langid < 0) {
			error("Invalid grflangid %s", buf);
		}
		_lang.newgrflangid = (uint8)langid;
	} else if (!memcmp(str, "gender ", 7)) {
		if (this->master) error("Genders are not allowed in the base translation.");
		char *buf = str + 7;

		for (;;) {
			const char *s = ParseWord(&buf);

			if (s == NULL) break;
			if (_lang.num_genders >= MAX_NUM_GENDERS) error("Too many genders, max %d", MAX_NUM_GENDERS);
			strecpy(_lang.genders[_lang.num_genders], s, lastof(_lang.genders[_lang.num_genders]));
			_lang.num_genders++;
		}
	} else if (!memcmp(str, "case ", 5)) {
		if (this->master) error("Cases are not allowed in the base translation.");
		char *buf = str + 5;

		for (;;) {
			const char *s = ParseWord(&buf);

			if (s == NULL) break;
			if (_lang.num_cases >= MAX_NUM_CASES) error("Too many cases, max %d", MAX_NUM_CASES);
			strecpy(_lang.cases[_lang.num_cases], s, lastof(_lang.cases[_lang.num_cases]));
			_lang.num_cases++;
		}
	} else {
		StringReader::HandlePragma(str);
	}
}