示例#1
0
文件: if.cpp 项目: kainjow/Jeqyll
Liquid::IfTag::IfTag(bool unless, const Context& context, const StringRef& tagName, const StringRef& markup)
    : BlockTag(context, tagName, markup)
    , if_(!unless)
{
    blocks_.emplace_back(false);
    parseTag(markup);
}
示例#2
0
void KHTMLReader::parseNode(DOM::Node node)
{

    // check if this is a text node.
    DOM::Text t = node;
    if (!t.isNull()) {
        _writer->addText(state()->paragraph, t.data().string(), 1, state()->in_pre_mode);
        return; // no children anymore...
    }

    // is this really needed ? it can't do harm anyway.
    state()->format = _writer->currentFormat(state()->paragraph, true);
    state()->layout = _writer->currentLayout(state()->paragraph);
    pushNewState();

    DOM::Element e = node;

    bool go_recursive = true;

    if (!e.isNull()) {
        // get the CSS information
        parseStyle(e);
        // get the tag information
        go_recursive = parseTag(e);
    }
    if (go_recursive) {
        for (DOM::Node q = node.firstChild(); !q.isNull(); q = q.nextSibling()) {
            parseNode(q);
        }
    }
    popState();


}
示例#3
0
void Parser::parse(const char* src) {
	const char* ptr = src;
	mNodeStart = ptr;
	ERRNO(mbtowc(NULL, NULL, 0));	// reset shift state.
	while(*ptr) {
		// skip invalid utf-8 sequences.
		wchar_t w;
		int res = utf8towc(&w, ptr, 4);
		if(res <= 0) {
			if(res < 0) {
				printf("Invalid UTF-8 0x%x @ pos %" PRIuPTR "\n", (unsigned char)*ptr, ptr - src);
			}
			FLUSH;
			ptr++;
			mNodeStart = ptr;
			continue;
		} else if(res > 1) {	// valid utf-8 beyond ascii
			ptr += res;
			continue;
		}

		if(STREQ(ptr, "http://")) {	// unescaped link
			FLUSH;
			ptr = parseUnescapedUrl(ptr);
			mNodeStart = ptr;
			continue;
		}

		char c = *ptr;
		ptr++;
		if(c == '[') {	// start tag
			while(*ptr == '[') {
				ptr++;
			}
			const char* endPtr = strchr(ptr, ']');
			if(!endPtr) {
				break;
			}
			const char* newEndPtr = fixTag(ptr, endPtr);
			bool diff = newEndPtr != endPtr;
			endPtr = newEndPtr;
			flush(ptr-1);
			if(!diff) {
				mNodeStart = ptr;
				parseTag(ptr, endPtr - ptr);
			}
			ptr = endPtr;
			if(!diff) {
				ptr++;
			}
			mNodeStart = ptr;
		} else if(c == '\\' && *ptr == 'n') {
			flush(ptr-1);
			ptr++;
			mNodeStart = ptr;
			addLinebreakNode();
		}
	}
	FLUSH;
}
示例#4
0
static  bool
parse_card()
{
  e.logcount = 0; e.current_tran = 0; 
  int32_t iBlock;
  bool    bFailure = false;

  //printf("Reading out %d blocks\n", uiBlocks + 1);
  // Read the card from end to begin
  for (iBlock = uiBlocks; iBlock >= 0; iBlock--) {
    // Authenticate everytime we reach a trailer block
    if(is_debug) printf("  0x%02x : ", iBlock);
    if (iBlock / 4 == DO_NOT_ACCESS) { if(is_debug) printf("!\n"); continue; }
    if (is_trailer_block(iBlock)) {
      if (bFailure) {
        // When a failure occured we need to redo the anti-collision
        if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
          printf("!\nError: tag was removed\n");
          return false;
        }
        bFailure = false;
      }

      fflush(stdout);

      // Try to authenticate for the current sector
      if (!authenticate(iBlock, false)) {
        printf("!\nError: authentication failed for block 0x%02x\n", iBlock);
        return false;
      }
      // Try to read out the trailer
      if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
    	  if(is_debug) print_hex(mp.mpd.abtData, 16);
	  parserights(&e, uiBlocks / 4, mp.mpd.abtData); 
      } else {
        printf("!\nfailed to read trailer block 0x%02x\n", iBlock);
        bFailure = true;
      }
    } else {
      // Make sure a earlier readout did not fail
      if (!bFailure) {
        // Try to read out the data block
        if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
        	if(is_debug) print_hex(mp.mpd.abtData, 16);
		parseTag(&e, iBlock, mp.mpd.abtData); 
        } else {
          printf("!\nError: unable to read block 0x%02x\n", iBlock);
          bFailure = true;
        }
      }
    }
    if ( bFailure )
      return false;
  }
  fflush(stdout);

  return true;
}
示例#5
0
文件: tag.cpp 项目: jaju/hypar2
Tag::Tag (_char *pTagString, bool bParseAttributes) :
    m_pName (0),
    m_pTagAttrString (0),
    m_bEndTag (false),
    m_bSelfClosing (false)
{
    m_pStrEnd = pTagString + _strlen (pTagString);
    parseTag (pTagString, bParseAttributes);
}
示例#6
0
	bool Document::parseLine(std::string & _line, ElementPtr & _element)
	{
		// крутимся пока в строке есть теги
		while (true) {

			// сначала ищем по угловым скобкам
			size_t start = find(_line, '<');
			if (start == _line.npos) break;
			size_t end = _line.npos;

			// пытаемся вырезать многострочный коментарий
			if ((start + 3 < _line.size()) && (_line[start + 1] == '!') && (_line[start + 2] == '-') && (_line[start + 3] == '-')) {
				end = _line.find("-->", start + 4);
				if (end == _line.npos) break;
				end += 2;

			}
			else {
				end = find(_line, '>', start+1);
				if (end == _line.npos) break;

			}
			// проверяем на наличее тела
			size_t body = _line.find_first_not_of(" \t<");
			if (body < start) {

				std::string body_str = _line.substr(0, start);
				// текущий символ
				mCol = 0;

				if (_element != 0) 	{
					bool ok = true;

					if (_element->getContent().empty())
					{
						_element->setContent(internal_utility::convert_from_xml(body_str, ok));
					}
					else
					{
						_element->setContent2(internal_utility::convert_from_xml(body_str, ok));
					}

					if (!ok) {
						mLastError = ErrorType::IncorrectContent;
						return false;
					}
				}
			}
			// вырезаем наш тэг и парсим
			if (false == parseTag(_element, _line.substr(start+1, end-start-1))) {
				return false;
			}
			// и обрезаем текущую строку разбора
			_line = _line.substr(end+1);
		};
		return true;
	}
void THtmlParser::parse()
{
    while (pos < txt.length()) {
        QChar c = txt.at(pos++);
        if (c == QLatin1Char('<') && isTag(pos - 1)) {
            parseTag();
        } else {
            last().text += c;
        }
    }
}
示例#8
0
文件: if.cpp 项目: kainjow/Jeqyll
void Liquid::IfTag::handleUnknownTag(const StringRef& tagName, const StringRef& markup, Tokenizer& tokenizer)
{
    if (tagName == "elsif") {
        blocks_.emplace_back(false);
        parseTag(markup);
    } else if (tagName == "else") {
        blocks_.emplace_back(true);
    } else {
        BlockTag::handleUnknownTag(tagName, markup, tokenizer);
    }
}
示例#9
0
void SamiParser::_parse(Subtitle &sub) {
    const QString &text = this->all();
    sub.clear();
    int pos = 0;
    while (pos < text.size()) {
        const QChar c = text.at(pos);
        if (c.unicode() != '<') {
            ++pos;
            continue;
        }
        Tag tag = parseTag(text, pos);
        if (_Same(tag.name, "body"))
            break;
        if (_Same(tag.name, "sync")) {
            pos = tag.pos;
            break;
        }
    }
    RichTextBlockParser parser(text.midRef(pos));
    auto &comps = components(sub);
    while (!parser.atEnd()) {
        Tag tag;
        const QStringRef block_sync = parser.get("sync", "/?sync|/body|/sami", &tag);
        if (tag.name.isEmpty())
            break;
        const int sync = toInt(tag.value("start"));
        QMap<QString, QList<RichTextBlock> > blocks;
        RichTextBlockParser p(block_sync);
        while (!p.atEnd()) {
            const QList<RichTextBlock> paragraph = p.paragraph(&tag);
            blocks[tag.value("class").toString()] += paragraph;
        }
        for (auto it = blocks.begin(); it != blocks.end(); ++it) {
            SubComp *comp = nullptr;
            for (int i=0; i<sub.count(); ++i) {
                if (comps[i].language() == it.key()) {
                    comp = &comps[i];
                    break;
                }
            }
            if (!comp) {
                comp = &append(sub);
                comp->setLanguage(it.key());
            }
            (*comp)[sync] += it.value();
        }
    }

//	for (SubtitleComponent &comp : comps) {
//		if (comp.size() < 3)
//	}
}
示例#10
0
文件: tex.c 项目: shunlir/ctags
static void parseTexFile (tokenInfo *const token)
{
	do
	{
		readToken (token);

		if (isType (token, TOKEN_KEYWORD))
		{
			switch (token->keyword)
			{
				case KEYWORD_part:
					parseTag (token, TEXTAG_PART);
					break;
				case KEYWORD_chapter:
					parseTag (token, TEXTAG_CHAPTER);
					break;
				case KEYWORD_section:
					parseTag (token, TEXTAG_SECTION);
					break;
				case KEYWORD_subsection:
					parseTag (token, TEXTAG_SUBSECTION);
					break;
				case KEYWORD_subsubsection:
					parseTag (token, TEXTAG_SUBSUBSECTION);
					break;
				case KEYWORD_paragraph:
					parseTag (token, TEXTAG_PARAGRAPH);
					break;
				case KEYWORD_subparagraph:
					parseTag (token, TEXTAG_SUBPARAGRAPH);
					break;
				case KEYWORD_label:
					parseTag (token, TEXTAG_LABEL);
					break;
				case KEYWORD_include:
					parseTag (token, TEXTAG_INCLUDE);
					break;
				default:
					break;
			}
		}
	} while (TRUE);
}
示例#11
0
文件: Eval.cpp 项目: JensErat/task
////////////////////////////////////////////////////////////////////////////////
// Geometric   --> Tag {( "*" | "/" | "%" ) Tag}
bool Eval::parseGeometric (
  std::vector <std::pair <std::string, Lexer::Type> >& infix,
  int &i) const
{
  if (i < infix.size () &&
      parseTag (infix, i))
  {
    while (i < infix.size () &&
           (infix[i].first == "*" ||
            infix[i].first == "/" ||
            infix[i].first == "%") &&
           infix[i].second == Lexer::typeOperator)
    {
      ++i;
      if (! parseTag (infix, i))
        return false;
    }

    return true;
  }

  return false;
}
示例#12
0
void THtmlParser::parse()
{
    const QLatin1Char sgn('<');
    QChar c;

    while (pos < txt.length()) {
        c = txt.at(pos++);
        if (c == sgn && isTag(pos - 1)) {
            parseTag();
        } else {
            last().text += c;
        }
    }
}
示例#13
0
XmlNode * XmlReader::parseElement () {
    //XmlNode * e = NULL;
    char c = skipSpaces ();
    if (c == '\0') { // end of data
        return NULL;
    } else if (c == '<') { // we have a XML fragment
        c = getNextChar ();
        if (c == '?') {
            if (parseXmlHeader ()) {
                return parseElement ();
            }
            return NULL;
        } else if (c == '!') {
            if (startsWith (m_buffer, "![CDATA[", m_pos)) { // pure XML CDATA Definition
                m_pos+=8; // skip header ![CDATA[
                int end = indexOf (m_buffer, "]]>", m_pos);
                if (end == -1) {
                    MESSAGE ("Error: Non terminated CDATA section.\n");
                    m_failure = true;
                    return NULL; // CDATA not terminated
                }
                char * data = strdup (m_buffer, m_pos, m_pos+end);
                if (m_iconv) {
                    char * orig = data;
                    data = toUTF8 (orig, end);
                    free (orig);
                }
                m_pos += end+3;  // avoid trailing ]]>
                return new XmlNode (data, CDATA);
            }
            if (parseSpecial ('-', '-', "-->")) { // ignore comments <!-- -->
                return parseElement ();
            } else if (parseSpecial ('D', 'O', ">")) { // ignore external document type declaration <!DOCTYPE >
                // TODO: support parsing (and ignoring) internal doctype declaration
                return parseElement ();
            }
            MESSAGE ("Error: Unsupported tag syntax\n");
            m_failure = true;
            return NULL;
        }
        return parseTag (c);
    }
    return parseCData ();
}
示例#14
0
PgnStream::TokenType PgnStream::readNext()
{
	if (m_phase == OutOfGame)
		return NoToken;

	m_tokenType = NoToken;
	m_tokenString.clear();

	char c;
	while ((c = readChar()) != 0)
	{
		switch (c)
		{
		case ' ':
		case '\t':
		case '\n':
		case '\r':
		case '.':
			break;
		case '%':
			// Escape mechanism (skip this line)
			parseUntil("\n\r");
			m_tokenString.clear();
			break;
		case '[':
			if (m_phase != InTags)
			{
				rewindChar();
				m_phase = OutOfGame;
				return NoToken;
			}
			m_tokenType = PgnTag;
			parseTag();
			return m_tokenType;
		case '(':
		case '{':
			m_tokenType = PgnComment;
			parseComment(c);
			return m_tokenType;
		case ';':
			m_tokenType = PgnLineComment;
			parseUntil("\n\r");
			return m_tokenType;
		case '$':
			// NAG (Numeric Annotation Glyph)
			m_tokenType = PgnNag;
			parseUntil(" \t\n\r");
			return m_tokenType;
		case '*':
			// Unfinished game
			m_tokenType = PgnResult;
			m_tokenString = "*";
			m_phase = OutOfGame;
			return m_tokenType;
		case '1': case '2': case '3': case '4': case '5':
		case '6': case '7': case '8': case '9': case '0':
			// Move number or result
			m_tokenString.append(c);
			parseUntil(". \t\n\r");

			if (m_tokenString == "1-0"
			||  m_tokenString == "0-1"
			||  m_tokenString == "1/2-1/2")
			{
				m_tokenType = PgnResult;
				m_phase = OutOfGame;
			}
			else
			{
				if (m_tokenString.endsWith('.'))
					m_tokenString.chop(1);
				m_tokenType = PgnMoveNumber;
				m_phase = InGame;
			}
			return m_tokenType;
		default:
			m_tokenType = PgnMove;
			m_tokenString.append(c);
			parseUntil(" \t\n\r");
			m_phase = InGame;
			return m_tokenType;
		}
	}

	return NoToken;
}
示例#15
0
void Browser::parseHTML(string encodedText)
{
  unsigned int currentRow = 0, currentCol = 0, wordLength = 0;
  unsigned int writingPage = 0; // page currently being written to 
  unsigned int startPtr = 0, endPtr = 0, stringPtr = 0;
  string parsedString = "", currentWord = "", tag = "";
  bool extraSpace = false;
  
  currentPage = 0;
  numPages = 0;
  numLinks = 0;
  
  // traverse entire string, while
  // ignoring extra whitespace and
  // sending html tags to be parsed
  while(stringPtr < encodedText.length()){

	// found an opening tag
	if(encodedText[stringPtr] == '<')
	  {
		tag = "";
		//scan for closing tag or end of document
		while (encodedText[stringPtr] != '>' &&
			   stringPtr < encodedText.length())
		  {
			tag += encodedText[stringPtr];		     
			++stringPtr;
		  }

		//included closing > in tag
		tag += encodedText[stringPtr];
		
		// reached end of document with no closing tag
		if (encodedText[stringPtr] != '>' &&
			stringPtr >= encodedText.length())
		  {
			//opening '<' was not for a valid tag, copy as is
		  }
		
		// reached end of tag, send to parse
		else
		  {
			tag = parseTag(tag);
			++stringPtr; // move stringPtr past closing '>'
		  }

		parsedString += tag;
		extraSpace = false;
	  }

	else
	  {
		// scan for an opening tag
		while( encodedText[stringPtr] != '<' &&
			   stringPtr <= encodedText.length())
		  {
			if( (encodedText[stringPtr] == ' ' && extraSpace) ||
				encodedText[stringPtr] == '\n')
			  {
				//skip extra whitespace, treat newlines as single spaces
				if(encodedText[stringPtr] == '\n' && !extraSpace)
				  {
					parsedString += ' ';
					extraSpace = true;
				  }
			  }
			else if(encodedText[stringPtr] == ' ' && !extraSpace)
			  {
				//copy single space
				parsedString += encodedText[stringPtr];
				extraSpace = true;
			  }
			else
			  {
				//copy current non-space character
				parsedString += encodedText[stringPtr];
				extraSpace = false;
			  }
		
			++stringPtr;
		  }
	  }
  }

  // traverse entire parsed string, while
  // dividing parsed string into lines and
  // pages as required by browser dimensions
  while(startPtr < parsedString.length())
	{
	  startPtr = endPtr;
	  currentWord = "";
	  // find the end of the current word
	  while( parsedString[endPtr] != ' '  &&
			 parsedString[endPtr] != '\n' &&
			 endPtr < parsedString.length() )
		{
		  currentWord += parsedString[endPtr];
		  ++endPtr;
		}

	  // include trailing space in current word
	  currentWord += parsedString[endPtr];
	  
	  // size of word not including trailing space or \n
	  wordLength = endPtr - startPtr;

	  // word fits on current line
	  if(wordLength + currentCol < numColumns){
		//update position in current line
		currentCol += wordLength;
	  }

	  // word doesn't fit on current line, but a
	  // new line will fit on the current page
	  else if(currentRow < numRows){
		// add a new line and update positions
		pages[writingPage] += '\n';
		++currentRow;
		currentCol = wordLength;
	  }

	  // word doesn't fit on current line, and a new
	  // line will not fit on the current page
	  else{
		// initialize a new page and update positions
		pages[++writingPage] = "";	
		currentRow = 0;
		currentCol = wordLength;
	  }

	  if(parsedString[endPtr] == '\n')
		{
		  currentCol = 0;
		  ++currentRow;
		}

	  // copy current word to current page
	  pages[writingPage] += currentWord;
	  
	  // advance pointer past trailing space or \n
	  ++endPtr;
		
	}

  //total pages = the last page that was written to 
  numPages = writingPage;
}
示例#16
0
int main()
{
	//Transpose
	vec4 mat[4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

	__m128i xmm0 = _mm_unpacklo_epi32(_mm_castps_si128(mat[0]), _mm_castps_si128(mat[1]));
	__m128i xmm1 = _mm_unpackhi_epi32(_mm_castps_si128(mat[0]), _mm_castps_si128(mat[1]));
	__m128i xmm2 = _mm_unpacklo_epi32(_mm_castps_si128(mat[2]), _mm_castps_si128(mat[3]));
	__m128i xmm3 = _mm_unpackhi_epi32(_mm_castps_si128(mat[2]), _mm_castps_si128(mat[3]));

	vec4 trans[4];

	trans[0] = _mm_castsi128_ps(_mm_unpacklo_epi64(xmm0, xmm2));
	trans[1] = _mm_castsi128_ps(_mm_unpackhi_epi64(xmm0, xmm2));
	trans[2] = _mm_castsi128_ps(_mm_unpacklo_epi64(xmm1, xmm3));
	trans[3] = _mm_castsi128_ps(_mm_unpackhi_epi64(xmm1, xmm3));

	vec4 trans2[4];

	ml::transpose(trans2, mat);

	FILE* file = fopen("..\\..\\AppData\\VT.swf", "rb");
	fseek(file, 0, SEEK_END);
	size_t size = ftell(file);
	fseek(file, 0, SEEK_SET);
	unsigned char* fileData = (unsigned char*)malloc(size);
	fread(fileData, 1, size, file);
	fclose(file);

	MemReader data = {(const char*)fileData, (const char*)fileData+size, (const char*)fileData};
	
	//Read SWF header
	const u32 signatureAndVersion	= data.read<u32>();
	const u32 actualSize			= data.read<u32>();

	u32 signature = signatureAndVersion&0x00FFFFFF;
	u8	version = signatureAndVersion>>24;

	bool isCompressed   = signature=='\0SWC';
	bool isUncompressed = signature=='\0SWF';

	//if !isCompressed && !isUncompressed return error;

	MemReader data2 = {0, 0, 0};

	char* uncompressed = 0;
	if (isCompressed)
	{
		 uncompressed = (char*)malloc(actualSize-8);
		 data2.cur = data2.start = uncompressed;
		 data2.end = uncompressed+actualSize-8;
		 uLongf uncompressedSize = actualSize-8;
		 uncompress((Bytef*)uncompressed, &uncompressedSize, data.as<Bytef>(), size-8);
	}
	else if (isCompressed)
	{
		data2.cur = data2.start = data.as<char>();
		data2.end = data2.start+actualSize-8;
	}

	
	u8 bits = data2.read<u8>();
	u8 numBits = bits>>3;

	u32 rectSizeMinusOne = (numBits*4+5)>>3;
	data2.move(rectSizeMinusOne);
	
	const u16 frameRate	 = data2.read<u16>();
	const u16 frameCount = data2.read<u16>();

	std::set<u32>	tagsUsed;
	size_t tagCount = 0;

	while (data2.cur!=data2.end)
	{
		u16 tagHeader = data2.read<u16>();
		u32 tagLength = tagHeader&0x3F;
		u32 tagType = tagHeader>>6;
		tagsUsed.insert(tagType);

		if (tagLength==0x3F)
			tagLength = data2.read<u32>();
		data2.move(tagLength);

		parseTag(tagType);

		++tagCount;
	}

	if (uncompressed) free(uncompressed);

	printf("\nProcessed %d tags\n\n", tagCount);

	printf("        Tags used        \n");
	printf("-------------------------\n");

	std::set<u32>::iterator	it  = tagsUsed.begin(),
							end = tagsUsed.end();

	for (; it!=end; ++it)
	{
		parseTag(*it);
	}

	free(fileData);
}
示例#17
0
XmlNode *XmlNode::parse(string::iterator& curr, string::iterator end) {

    skipWS(curr,end);
    if (curr == end || *curr != '<') return NULL;

    string tag = parseTag(curr,end);
    if (tag.empty() || tag[0] == '/') return NULL;

    skipWS(curr,end);
    if (curr == end) return NULL;

    if (*curr == '<') {

        XmlNode *p = NULL;
        while (curr != end) {
            string::iterator mark = curr;
            string nexttag = parseTag(curr,end);
            if (nexttag.empty()) { if (p != NULL) delete p; return NULL; }
            if (nexttag[0] == '/') {
                // should be the closing </tag>
                if (nexttag.size() == tag.size()+1 && nexttag.find(tag,1) == 1) {
                    // is closing tag
                    if (p == NULL) p = new XmlLeaf(unquote(tag),"");
                    return p;
                } else {
                    if (p != NULL) delete p;
                    return NULL;
                }
            } else {
                if (p == NULL) p = new XmlBranch(unquote(tag));
                // an opening tag
                curr = mark;
                XmlNode *c = parse(curr,end);
                if (c != NULL) ((XmlBranch*)p)->pushnode(c);
            }
            skipWS(curr,end);
            if(curr == end || *curr != '<') {
                if (p != NULL) delete p;
                return NULL;
            }
        }

    } else {
        // XmlLeaf
        string value;
        while (curr != end && *curr != '<') {
            value += *curr;
            curr++;
        }
        if(curr == end) return NULL;
        string nexttag = parseTag(curr,end);
        if (nexttag.empty() || nexttag[0] != '/') return NULL;
        if (nexttag.size() == tag.size()+1 && nexttag.find(tag,1) == 1) {
            return new XmlLeaf(unquote(tag),unquote(value));
        } else {
            // error
            return NULL;
        }
    }

    // should never get here
    return NULL;
}
void QDeclarativeStyledTextPrivate::parse()
{
    QList<QTextLayout::FormatRange> ranges;
    QStack<QTextCharFormat> formatStack;

    QString drawText;
    drawText.reserve(text.count());

    int textStart = 0;
    int textLength = 0;
    int rangeStart = 0;
    const QChar *ch = text.constData();
    while (!ch->isNull()) {
        if (*ch == lessThan) {
            if (textLength)
                drawText.append(QStringRef(&text, textStart, textLength));
            if (rangeStart != drawText.length() && formatStack.count()) {
                QTextLayout::FormatRange formatRange;
                formatRange.format = formatStack.top();
                formatRange.start = rangeStart;
                formatRange.length = drawText.length() - rangeStart;
                ranges.append(formatRange);
            }
            rangeStart = drawText.length();
            ++ch;
            if (*ch == slash) {
                ++ch;
                if (parseCloseTag(ch, text)) {
                    if (formatStack.count())
                        formatStack.pop();
                }
            } else {
                QTextCharFormat format;
                if (formatStack.count())
                    format = formatStack.top();
                if (parseTag(ch, text, drawText, format))
                    formatStack.push(format);
            }
            textStart = ch - text.constData() + 1;
            textLength = 0;
        } else if (*ch == ampersand) {
            ++ch;
            drawText.append(QStringRef(&text, textStart, textLength));
            parseEntity(ch, text, drawText);
            textStart = ch - text.constData() + 1;
            textLength = 0;
        } else {
            ++textLength;
        }
        if (!ch->isNull())
            ++ch;
    }
    if (textLength)
        drawText.append(QStringRef(&text, textStart, textLength));
    if (rangeStart != drawText.length() && formatStack.count()) {
        QTextLayout::FormatRange formatRange;
        formatRange.format = formatStack.top();
        formatRange.start = rangeStart;
        formatRange.length = drawText.length() - rangeStart;
        ranges.append(formatRange);
    }

    layout.setText(drawText);
    layout.setAdditionalFormats(ranges);
}
示例#19
0
UINT CLiteHTMLReader::parseDocument(void)
{
	ASSERT(m_lpszBuffer != NULL);

	bool	bAbort = false;			// continue parsing or abort?
	bool	bIsClosingTag = false;	// tag parsed is a closing tag?
	bool	bIsOpeningTag = false;	// tag parsed is an opening tag?
	CString	strCharacters;			// character data 
	CString	strComment;				// comment data
	CString	strT;					// temporary storage
	DWORD	dwCharDataStart = 0L;	// starting position of character data
	DWORD	dwCharDataLen = 0L;		// length of character data
	LONG	lTemp = 0L;				// temporary storage
	TCHAR	ch = 0;					// character at current buffer position
	CLiteHTMLTag	oTag;			// tag information

	if ( (!m_lpszBuffer) || (!m_dwBufLen) )
		return (0U);

	// reset seek pointer to beginning
	ResetSeekPointer();

	// notify event handler about parsing startup
	if (getEventNotify(notifyStartStop))
	{
		bAbort = false;
		m_pEventHandler->BeginParse(m_dwAppData, bAbort);
		if (bAbort)	goto LEndParse;
	}

	// skip leading white-space characters
	while (isWhiteSpace(ReadChar()))
		;
	
	ch = UngetChar();
	while ((ch = ReadChar()) != NULL)
	{
		switch (ch)
		{

		// tag starting delimeter?
		case _T('<'):
			{
				UngetChar();
				
				strComment.Empty();
				if (!parseComment(strComment))
				{
					bIsOpeningTag = false;
					bIsClosingTag = false;
					if (!parseTag(oTag, bIsOpeningTag, bIsClosingTag))
					{
						++dwCharDataLen;

						// manually advance buffer position
						// because the last call to UngetChar()
						// moved it back one character
						ch = ReadChar();

						break;
					}
				}

				// clear pending notifications
				if ( (dwCharDataLen) || (strCharacters.GetLength()) )
				{
					strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen);
					NormalizeCharacters(strCharacters);
					
					if ( (strCharacters.GetLength()) && 
						 (getEventNotify(notifyCharacters)) )
					{
						bAbort = false;
						m_pEventHandler->Characters(strCharacters, m_dwAppData, bAbort);
						if (bAbort)	goto LEndParse;
					}

					strCharacters.Empty();
				}

				dwCharDataLen = 0L;
				dwCharDataStart = m_dwBufPos;

				if (strComment.GetLength())
				{
					if (getEventNotify(notifyComment))
					{
						bAbort = false;
						m_pEventHandler->Comment(strComment, m_dwAppData, bAbort);
						if (bAbort)	goto LEndParse;
					}
				}
				else
				{
					if ( (bIsOpeningTag) && (getEventNotify(notifyTagStart)) )
					{
						bAbort = false;
						m_pEventHandler->StartTag(&oTag, m_dwAppData, bAbort);
						if (bAbort)	goto LEndParse;
					}

					if ( (bIsClosingTag) && (getEventNotify(notifyTagEnd)) )
					{
						bAbort = false;
						m_pEventHandler->EndTag(&oTag, m_dwAppData, bAbort);
						if (bAbort)	goto LEndParse;
					}
				}

				break;
			}

		// entity reference beginning delimeter?
		case _T('&'):
			{
				UngetChar();

				lTemp = 0;
				if (m_bResolveEntities)
					lTemp = CLiteHTMLEntityResolver::resolveEntity(&m_lpszBuffer[m_dwBufPos], ch);
				
				if (lTemp)
				{
					strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen) + ch;
					m_dwBufPos += lTemp;
					dwCharDataStart = m_dwBufPos;
					dwCharDataLen = 0L;
				}
				else
				{
					ch = ReadChar();
					++dwCharDataLen;
				}
				
				break;
			}
		
		// any other character
		default:
			{
				++dwCharDataLen;
				break;
			}
		}
	}

	// clear pending notifications
	if ( (dwCharDataLen) || (strCharacters.GetLength()) )
	{
		strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen) + ch;
		NormalizeCharacters(strCharacters);
		strCharacters.TrimRight();	// explicit trailing white-space removal

		if ( (strCharacters.GetLength()) && 
			 (getEventNotify(notifyCharacters)) )
		{
			bAbort = false;
			m_pEventHandler->Characters(strCharacters, m_dwAppData, bAbort);
			if (bAbort)	goto LEndParse;
		}
	}

LEndParse:
	// notify event handler about parsing completion
	if (getEventNotify(notifyStartStop))
		m_pEventHandler->EndParse(m_dwAppData, bAbort);

	m_lpszBuffer = NULL;
	m_dwBufLen = 0L;
	return (m_dwBufPos);
}
示例#20
0
void LogManager::doLog(LogChannel* channel, const char* act, const char* srcname, uint line, const char* fnname, const char* tag, const char* msg, int msgLen, bool forceLineEnd)
{
	if (_shutdown) return;

	if (channel == NULL)
		channel = needThreadRootChannel();

	Mutex::ScopedLock lock(channel->_mutex);

	if (msgLen < 0)
		msgLen = strlen(msg);

	assert(channel);

	LogEntry e;
	e.time = float(SystemTimer::now());
	e.channel = channel;
	e.srcName = srcname;
	e.line = line;
	e.fnName = fnname;
	e.act = act;

	uint32 tagbuf = 0;

	if (tag == NULL)
		tag = parseTag(msg, msgLen, tagbuf);

	if (*tag == 0)
	{
		// no tag detected: use previous tag
		tagbuf = channel->_prevTag;
		tag = reinterpret_cast<const char*>(&tagbuf);
	}
	else
	{
		// TODO: MT-Safe
		strcpy(reinterpret_cast<char*>(&channel->_prevTag), tag);
	}

	e.tagStr = tag;
	e.tagID = tagId(tag);
	e.logLevel = getLogLevel(e.tagID);


	const char* lineStart = msg;
	const char* lineEnd = msg;
	const char* msgEnd = msg + msgLen;
	const char* ch = msg;

	while (true)
	{
		if (ch < msgEnd && *ch != '\n')
		{
			++ch;
			continue;
		}

		lineEnd = ch;

		e.lineEnd = *ch == '\n' || forceLineEnd;
		e.message = lineStart;
		e.messageLen = lineEnd - lineStart;

		doLog(&e);

		if (ch >= msgEnd) break;

		e.srcName = NULL;
		e.line = 0;
		e.fnName = NULL;

		lineStart = ++ch;
		if (ch >= msgEnd) break;
	}
}
void QQuickStyledTextPrivate::parse()
{
    QList<QTextLayout::FormatRange> ranges;
    QStack<QTextCharFormat> formatStack;

    QString drawText;
    drawText.reserve(text.count());

    updateImagePositions = !imgTags->isEmpty();

    int textStart = 0;
    int textLength = 0;
    int rangeStart = 0;
    bool formatChanged = false;

    const QChar *ch = text.constData();
    while (!ch->isNull()) {
        if (*ch == lessThan) {
            if (textLength) {
                appendText(text, textStart, textLength, drawText);
            } else if (prependSpace) {
                drawText.append(space);
                prependSpace = false;
                hasSpace = true;
            }

            if (rangeStart != drawText.length() && formatStack.count()) {
                if (formatChanged) {
                    QTextLayout::FormatRange formatRange;
                    formatRange.format = formatStack.top();
                    formatRange.start = rangeStart;
                    formatRange.length = drawText.length() - rangeStart;
                    ranges.append(formatRange);
                    formatChanged = false;
                } else if (ranges.count()) {
                    ranges.last().length += drawText.length() - rangeStart;
                }
            }
            rangeStart = drawText.length();
            ++ch;
            if (*ch == slash) {
                ++ch;
                if (parseCloseTag(ch, text, drawText)) {
                    if (formatStack.count()) {
                        formatChanged = true;
                        formatStack.pop();
                    }
                }
            } else {
                QTextCharFormat format;
                if (formatStack.count())
                    format = formatStack.top();
                if (parseTag(ch, text, drawText, format)) {
                    formatChanged = true;
                    formatStack.push(format);
                }
            }
            textStart = ch - text.constData() + 1;
            textLength = 0;
        } else if (*ch == ampersand) {
            ++ch;
            appendText(text, textStart, textLength, drawText);
            parseEntity(ch, text, drawText);
            textStart = ch - text.constData() + 1;
            textLength = 0;
        } else if (ch->isSpace()) {
            if (textLength)
                appendText(text, textStart, textLength, drawText);
            if (!preFormat) {
                prependSpace = !hasSpace;
                for (const QChar *n = ch + 1; !n->isNull() && n->isSpace(); ++n)
                    ch = n;
                hasNewLine = false;
            } else  if (*ch == lineFeed) {
                drawText.append(QChar(QChar::LineSeparator));
                hasNewLine = true;
            } else {
                drawText.append(QChar(QChar::Nbsp));
                hasNewLine = false;
            }
            textStart = ch - text.constData() + 1;
            textLength = 0;
        } else {
            ++textLength;
        }
        if (!ch->isNull())
            ++ch;
    }
    if (textLength)
        appendText(text, textStart, textLength, drawText);
    if (rangeStart != drawText.length() && formatStack.count()) {
        if (formatChanged) {
            QTextLayout::FormatRange formatRange;
            formatRange.format = formatStack.top();
            formatRange.start = rangeStart;
            formatRange.length = drawText.length() - rangeStart;
            ranges.append(formatRange);
        } else if (ranges.count()) {
            ranges.last().length += drawText.length() - rangeStart;
        }
    }

    layout.setText(drawText);
    layout.setAdditionalFormats(ranges);
}
示例#22
0
		bool xmlDocument::open(const std::string & _name)
		{
			clear();

			std::ifstream stream(_name.c_str());
			mLastErrorFile = _name;
			if (false == stream.is_open()) {
				mLastError = xml::errors::XML_ERROR_OPEN_FILE;
				return false;
			}
			// это текущая строка для разбора
			std::string line;
			// это строка из файла
			std::string read;
			// текущий узел для разбора
			xmlNodePtr currentNode = 0;

			while (false == stream.eof()) {
				// берем новую строку
				std::getline(stream, read);
				mLine ++;
				mCol = 0; // потом проверить на многострочных тэгах

				if (read.empty()) continue;

				// текущая строка для разбора и то что еще прочитали
				line += read;

				// крутимся пока в строке есть теги
				while (true) {

					// сначала ищем по угловым скобкам
					size_t start = find(line, '<');
					if (start == line.npos) break;

					size_t end = find(line, '>', start+1);
					if (end == line.npos) break;

					// проверяем на наличее тела
					size_t body = line.find_first_not_of(" \t<");
					if (body < start) {

						std::string body_str = line.substr(0, start);
						// текущий символ
						mCol = body_str.find_first_not_of(" \t");
						utility::trim(body_str);

						if (currentNode != 0) 	currentNode->addBody(body_str);

					}

					// вырезаем наш тэг и парсим
					if (false == parseTag(currentNode, line.substr(start+1, end-start-1))) {
						// ошибка установится внутри
						stream.close();
						return false;
					}

					// и обрезаем текущую строку разбора
					line = line.substr(end+1);

				}; // while (true)

			}; // while (!stream.eof())

			if (currentNode) {
				mLastError = xml::errors::XML_ERROR_NON_CLOSE_ALL_TAGS;
				stream.close();
				return false;
			}

			stream.close();
			return true;
		}
示例#23
0
文件: dcpdecrypt.cpp 项目: Hexkbr/vlc
/*
 * Parse the DER-encoded data at ps_data_der
 * saving the key in an S-expression
 */
int RSAKey::readDER( unsigned char const* ps_data_der, size_t length )
{
    struct tag_info tag_inf;
    gcry_mpi_t key_params[8];
    gcry_error_t err;
    int i;

    /* parse the ASN1 structure */
    if( parseTag( &ps_data_der, &length, &tag_inf )
            || tag_inf.tag != TAG_SEQUENCE || tag_inf.class_ || !tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( parseTag( &ps_data_der, &length, &tag_inf )
       || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( tag_inf.length != 1 || *ps_data_der )
        goto bad_asn1;  /* The value of the first integer is no 0. */
    ps_data_der += tag_inf.length;
    length -= tag_inf.length;

    for( i = 0; i < 8; i++ )
    {
        if( parseTag( &ps_data_der, &length, &tag_inf )
                || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
            goto bad_asn1;
        err = gcry_mpi_scan( key_params + i, GCRYMPI_FMT_USG, ps_data_der, tag_inf.length, NULL );
        if( err )
        {
            msg_Err( this->p_demux, "error scanning RSA parameter %d: %s", i, gpg_strerror( err ) );
            goto error;
        }
        ps_data_der += tag_inf.length;
        length -= tag_inf.length;
    }

    /* Convert from OpenSSL parameter ordering to the OpenPGP order.
     * First check that p < q; if not swap p and q and recompute u.
     */
    if( gcry_mpi_cmp( key_params[3], key_params[4] ) > 0 )
    {
        gcry_mpi_swap( key_params[3], key_params[4] );
        gcry_mpi_invm( key_params[7], key_params[3], key_params[4] );
    }

    /* Build the S-expression.  */
    err = gcry_sexp_build( & this->priv_key, NULL,
                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
                         key_params[0], key_params[1], key_params[2],
                         key_params[3], key_params[4], key_params[7] );
    if( err )
    {
        msg_Err( this->p_demux, "error building S-expression: %s", gpg_strerror( err ) );
        goto error;
    }

    /* clear data */
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_SUCCESS;

bad_asn1:
    msg_Err( this->p_demux, "could not parse ASN1 structure; key might be corrupted" );

error:
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_EGENERIC;
}
示例#24
0
NORI_NAMESPACE_BEGIN

NoriObject *loadFromXML(const std::string &filename) {
    /* Load the XML file using 'pugi' (a tiny self-contained XML parser implemented in C++) */
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(filename.c_str());

    /* Helper function: map a position offset in bytes to a more readable row/column value */
    auto offset = [&](ptrdiff_t pos) -> std::string {
        std::fstream is(filename);
        char buffer[1024];
        int line = 0, linestart = 0, offset = 0;
        while (is.good()) {
            is.read(buffer, sizeof(buffer));
            for (int i = 0; i < is.gcount(); ++i) {
                if (buffer[i] == '\n') {
                    if (offset + i >= pos)
                        return tfm::format("row %i, col %i", line + 1, pos - linestart);
                    ++line;
                    linestart = offset + i;
                }
            }
            offset += (int) is.gcount();
        }
        return "byte offset " + std::to_string(pos);
    };

    if (!result) /* There was a parser / file IO error */
        throw NoriException("Error while parsing \"%s\": %s (at %s)", filename, result.description(), offset(result.offset));

    /* Set of supported XML tags */
    enum ETag {
        /* Object classes */
        EScene                = NoriObject::EScene,
        EMesh                 = NoriObject::EMesh,
        EBSDF                 = NoriObject::EBSDF,
        ETEXTURE              = NoriObject::ETEXTURE,
        EPERLIN               = NoriObject::EPERLIN,
        EMIXTEXTURE           = NoriObject::EMIXTEXTURE,
        EMIXBUMPMAP           = NoriObject::EMIXBUMPMAP,
        EBUMPMAP              = NoriObject::EBUMPMAP,
        EPhaseFunction        = NoriObject::EPhaseFunction,
        EEmitter              = NoriObject::EEmitter,
        EMedium               = NoriObject::EMedium,
        EVolume               = NoriObject::EVolume,
        ECamera               = NoriObject::ECamera,
        EIntegrator           = NoriObject::EIntegrator,
        ESampler              = NoriObject::ESampler,
        ETest                 = NoriObject::ETest,
        EReconstructionFilter = NoriObject::EReconstructionFilter,

        /* Properties */
        EBoolean = NoriObject::EClassTypeCount,
        EInteger,
        EFloat,
        EString,
        EPoint,
        EVector,
        EColor,
        ETransform,
        ETranslate,
        EMatrix,
        ERotate,
        EScale,
        ELookAt,

        EInvalid
    };

    /* Create a mapping from tag names to tag IDs */
    std::map<std::string, ETag> tags;
    tags["scene"]      = EScene;
    tags["mesh"]       = EMesh;
    tags["bsdf"]       = EBSDF;
    tags["texture"]    = ETEXTURE;
    tags["bumpmap"]    = EBUMPMAP;
    tags["perlin"]     = EPERLIN;
    tags["mixTexture"] = EMIXTEXTURE;
    tags["mixBumpmap"] = EMIXBUMPMAP;
    tags["bumpmap"]    = EBUMPMAP;
    tags["emitter"]    = EEmitter;
    tags["camera"]     = ECamera;
    tags["medium"]     = EMedium;
    tags["volume"]     = EVolume;
    tags["phase"]      = EPhaseFunction;
    tags["integrator"] = EIntegrator;
    tags["sampler"]    = ESampler;
    tags["rfilter"]    = EReconstructionFilter;
    tags["test"]       = ETest;
    tags["boolean"]    = EBoolean;
    tags["integer"]    = EInteger;
    tags["float"]      = EFloat;
    tags["string"]     = EString;
    tags["point"]      = EPoint;
    tags["vector"]     = EVector;
    tags["color"]      = EColor;
    tags["transform"]  = ETransform;
    tags["translate"]  = ETranslate;
    tags["matrix"]     = EMatrix;
    tags["rotate"]     = ERotate;
    tags["scale"]      = EScale;
    tags["lookat"]     = ELookAt;

    /* Helper function to check if attributes are fully specified */
    auto check_attributes = [&](const pugi::xml_node &node, std::set<std::string> attrs) {
        for (auto attr : node.attributes()) {
            auto it = attrs.find(attr.name());
            if (it == attrs.end())
                throw NoriException("Error while parsing \"%s\": unexpected attribute \"%s\" in \"%s\" at %s",
                                    filename, attr.name(), node.name(), offset(node.offset_debug()));
            attrs.erase(it);
        }
        if (!attrs.empty())
            throw NoriException("Error while parsing \"%s\": missing attribute \"%s\" in \"%s\" at %s",
                                filename, *attrs.begin(), node.name(), offset(node.offset_debug()));
    };

    Eigen::Affine3f transform;

    /* Helper function to parse a Nori XML node (recursive) */
    std::function<NoriObject *(pugi::xml_node &, PropertyList &, int)> parseTag = [&](
    pugi::xml_node &node, PropertyList &list, int parentTag) -> NoriObject * {
        /* Skip over comments */
        if (node.type() == pugi::node_comment || node.type() == pugi::node_declaration)
            return nullptr;

        if (node.type() != pugi::node_element)
            throw NoriException(
                "Error while parsing \"%s\": unexpected content at %s",
                filename, offset(node.offset_debug()));

        /* Look up the name of the current element */
        auto it = tags.find(node.name());
        if (it == tags.end())
            throw NoriException("Error while parsing \"%s\": unexpected tag \"%s\" at %s",
            filename, node.name(), offset(node.offset_debug()));
        int tag = it->second;

        /* Perform some safety checks to make sure that the XML tree really makes sense */
        bool hasParent            = parentTag != EInvalid;
        bool parentIsObject       = hasParent && parentTag < NoriObject::EClassTypeCount;
        bool currentIsObject      = tag < NoriObject::EClassTypeCount;
        bool parentIsTransform    = parentTag == ETransform;
        bool currentIsTransformOp = tag == ETranslate || tag == ERotate || tag == EScale || tag == ELookAt || tag == EMatrix;

        if (!hasParent && !currentIsObject)
            throw NoriException("Error while parsing \"%s\": root element \"%s\" must be a Nori object (at %s)",
            filename, node.name(), offset(node.offset_debug()));

        if (parentIsTransform != currentIsTransformOp)
            throw NoriException("Error while parsing \"%s\": transform nodes "
            "can only contain transform operations (at %s)",
            filename,  offset(node.offset_debug()));

        if (hasParent && !parentIsObject && !(parentIsTransform && currentIsTransformOp))
            throw NoriException("Error while parsing \"%s\": node \"%s\" requires a Nori object as parent (at %s)",
            filename, node.name(), offset(node.offset_debug()));

        if (tag == EScene)
            node.append_attribute("type") = "scene";
        else if (tag == ETransform)
            transform.setIdentity();

        PropertyList propList;
        std::vector<NoriObject *> children;
        for (pugi::xml_node &ch: node.children()) {
            NoriObject *child = parseTag(ch, propList, tag);
            if (child)
                children.push_back(child);
        }

        NoriObject *result = nullptr;
        try {
            if (currentIsObject) {
                check_attributes(node, { "type" });

                /* This is an object, first instantiate it */
                result = NoriObjectFactory::createInstance(
                             node.attribute("type").value(),
                             propList
                         );

                if (result->getClassType() != (int) tag) {
                    throw NoriException(
                        "Unexpectedly constructed an object "
                        "of type <%s> (expected type <%s>): %s",
                        NoriObject::classTypeName(result->getClassType()),
                        NoriObject::classTypeName((NoriObject::EClassType) tag),
                        result->toString());
                }

                /* Add all children */
                for (auto ch: children) {
                    result->addChild(ch);
                    ch->setParent(result);
                }

                /* Activate / configure the object */
                result->activate();
            } else {
                /* This is a property */
                switch (tag) {
                case EString: {
                    check_attributes(node, { "name", "value" });
                    list.setString(node.attribute("name").value(), node.attribute("value").value());
                }
                break;
                case EFloat: {
                    check_attributes(node, { "name", "value" });
                    list.setFloat(node.attribute("name").value(), toFloat(node.attribute("value").value()));
                }
                break;
                case EInteger: {
                    check_attributes(node, { "name", "value" });
                    list.setInteger(node.attribute("name").value(), toInt(node.attribute("value").value()));
                }
                break;
                case EBoolean: {
                    check_attributes(node, { "name", "value" });
                    list.setBoolean(node.attribute("name").value(), toBool(node.attribute("value").value()));
                }
                break;
                case EPoint: {
                    check_attributes(node, { "name", "value" });
                    list.setPoint(node.attribute("name").value(), Point3f(toVector3f(node.attribute("value").value())));
                }
                break;
                case EVector: {
                    check_attributes(node, { "name", "value" });
                    list.setVector(node.attribute("name").value(), Vector3f(toVector3f(node.attribute("value").value())));
                }
                break;
                case EColor: {
                    check_attributes(node, { "name", "value" });
                    list.setColor(node.attribute("name").value(), Color3f(toVector3f(node.attribute("value").value()).array()));
                }
                break;
                case ETransform: {
                    check_attributes(node, { "name" });
                    list.setTransform(node.attribute("name").value(), transform.matrix());
                }
                break;
                case ETranslate: {
                    check_attributes(node, { "value" });
                    Eigen::Vector3f v = toVector3f(node.attribute("value").value());
                    transform = Eigen::Translation<float, 3>(v.x(), v.y(), v.z()) * transform;
                }
                break;
                case EMatrix: {
                    check_attributes(node, { "value" });
                    std::vector<std::string> tokens = tokenize(node.attribute("value").value());
                    if (tokens.size() != 16)
                        throw NoriException("Expected 16 values");
                    Eigen::Matrix4f matrix;
                    for (int i=0; i<4; ++i)
                        for (int j=0; j<4; ++j)
                            matrix(i, j) = toFloat(tokens[i*4+j]);
                    transform = Eigen::Affine3f(matrix) * transform;
                }
                break;
                case EScale: {
                    check_attributes(node, { "value" });
                    Eigen::Vector3f v = toVector3f(node.attribute("value").value());
                    transform = Eigen::DiagonalMatrix<float, 3>(v) * transform;
                }
                break;
                case ERotate: {
                    check_attributes(node, { "angle", "axis" });
                    float angle = degToRad(toFloat(node.attribute("angle").value()));
                    Eigen::Vector3f axis = toVector3f(node.attribute("axis").value());
                    transform = Eigen::AngleAxis<float>(angle, axis) * transform;
                }
                break;
                case ELookAt: {
                    check_attributes(node, { "origin", "target", "up" });
                    Eigen::Vector3f origin = toVector3f(node.attribute("origin").value());
                    Eigen::Vector3f target = toVector3f(node.attribute("target").value());
                    Eigen::Vector3f up = toVector3f(node.attribute("up").value());

                    Vector3f dir = (target - origin).normalized();
                    Vector3f left = up.normalized().cross(dir);
                    Vector3f newUp = dir.cross(left);

                    Eigen::Matrix4f trafo;
                    trafo << left, newUp, dir, origin,
                          0, 0, 0, 1;

                    transform = Eigen::Affine3f(trafo) * transform;
                }
                break;

                default:
                    throw NoriException("Unhandled element \"%s\"", node.name());
                };
            }
        } catch (const NoriException &e) {
            throw NoriException("Error while parsing \"%s\": %s (at %s)", filename,
                                e.what(), offset(node.offset_debug()));
        }

        return result;
    };

    PropertyList list;
    return parseTag(*doc.begin(), list, EInvalid);
}
gboolean
_gtk_source_language_file_parse_version1 (GtkSourceLanguage    *language,
					  GtkSourceContextData *ctx_data)
{
	xmlDocPtr doc;
	xmlNodePtr cur;
	GMappedFile *mf;
	gunichar esc_char = 0;
	xmlChar *lang_version = NULL;

	xmlKeepBlanksDefault (0);

	mf = g_mapped_file_new (language->priv->lang_file_name, FALSE, NULL);

	if (mf == NULL)
	{
		doc = NULL;
	}
	else
	{
		doc = xmlParseMemory (g_mapped_file_get_contents (mf),
				      g_mapped_file_get_length (mf));
#if GLIB_CHECK_VERSION(2,22,0)
		g_mapped_file_unref (mf);
#else
		g_mapped_file_free (mf);
#endif
	}

	if (doc == NULL)
	{
		g_warning ("Impossible to parse file '%s'",
			   language->priv->lang_file_name);
		return FALSE;
	}

	cur = xmlDocGetRootElement (doc);

	if (cur == NULL)
	{
		g_warning ("The lang file '%s' is empty",
			   language->priv->lang_file_name);
		goto error;
	}

	if (xmlStrcmp (cur->name, (const xmlChar *) "language") != 0)
	{
		g_warning ("File '%s' is of the wrong type",
			   language->priv->lang_file_name);
		goto error;
	}

	lang_version = xmlGetProp (cur, BAD_CAST "version");

	if (lang_version == NULL || strcmp ("1.0", (char*) lang_version) != 0)
	{
		if (lang_version != NULL)
			g_warning ("Wrong language version '%s' in file '%s', expected '%s'",
				   (char*) lang_version, language->priv->lang_file_name, "1.0");
		else
			g_warning ("Language version missing in file '%s'",
				   language->priv->lang_file_name);
		goto error;
	}

	if (!define_root_context (ctx_data, language))
	{
		g_warning ("Could not create root context for file '%s'",
			   language->priv->lang_file_name);
		goto error;
	}

	/* FIXME: check that the language name, version, etc. are the
	 * right ones - Paolo */

	cur = xmlDocGetRootElement (doc);
	cur = cur->xmlChildrenNode;
	g_return_val_if_fail (cur != NULL, FALSE);

	while (cur != NULL)
	{
		if (!xmlStrcmp (cur->name, (const xmlChar *)"escape-char"))
		{
			xmlChar *escape;

			escape = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
			esc_char = g_utf8_get_char_validated ((gchar*) escape, -1);

			if (esc_char == (gunichar) -1 || esc_char == (gunichar) -2)
			{
				g_warning ("Invalid (non UTF8) escape character in file '%s'",
					   language->priv->lang_file_name);
				esc_char = 0;
			}

			xmlFree (escape);
		}
		else
		{
			parseTag (language, cur, ctx_data);
		}

		cur = cur->next;
	}

	if (esc_char != 0)
		_gtk_source_context_data_set_escape_char (ctx_data, esc_char);

	_gtk_source_context_data_finish_parse (ctx_data, NULL, NULL);
	_gtk_source_language_define_language_styles (language);

	xmlFreeDoc (doc);
	xmlFree (lang_version);
	return TRUE;

error:
	if (doc)
		xmlFreeDoc (doc);
	xmlFree (lang_version);
	return FALSE;
}