/*************************************************************************** stylesheetparser.cpp - description ------------------- begin : gio ago 19 2004 copyright : (C) 2004 by gulmini luciano email : gulmini.luciano@student.unife.it ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stylesheetparser.h" #include #include static const TQString msg1(i18n("has not been closed")), msg2(i18n("needs an opening parenthesis ")); stylesheetParser::stylesheetParser(const TQString& s){ m_styleSheet = s; m_styleSheet=m_styleSheet.right(m_styleSheet.length()-whiteSpaces(0)); m_stopProcessing = false; m_orderNumber = 0; } int stylesheetParser::whiteSpaces(int d){ int ws=0; for( unsigned int i=d;i tmp(m_styleSheet.left(k+ws),++m_orderNumber); m_stylesheetStructure["/*"+TQString::number(m_orderNumber,10)]=tmp; m_styleSheet=m_styleSheet.right(m_styleSheet.length()-k-ws); parse(); } else { m_stopProcessing = true; emit errorOccurred(i18n("The comment") + " :\n" +m_styleSheet.mid(0,20) + "...\n "+ msg1); return; } } unsigned int stylesheetParser::numberOfParenthesisInAParenthesisBlock(parenthesisKind p, const TQString& b){ TQChar searchFor = '{'; if (p == closed) searchFor = '}'; int num = 0; int len = b.length(); bool ignore = false; for (int i = 0; i < len; i++) { if (b[i] == '/' && (i + 1 < len) && b[i + 1] == '*') ignore = true; if (b[i] == '*' && (i + 1 < len) && b[i + 1] == '/') ignore = false; if (!ignore && b[i] == searchFor) num++; } return num; } int findParanthesis(const TQString& string, const TQChar &ch, int startPos = 0) { int pos = -1; int len = string.length(); bool ignore = false; for (int i = startPos; i < len; i++) { if (string[i] == '/' && (i + 1 < len) && string[i + 1] == '*') ignore = true; if (string[i] == '*' && (i + 1 < len) && string[i + 1] == '/') ignore = false; if (!ignore && string[i] == ch) { pos = i; break; } } return pos; } void stylesheetParser::parseSelector(){ int closingParenthesisPos = findParanthesis(m_styleSheet, '}'); if(closingParenthesisPos==-1) { m_stopProcessing = true; emit errorOccurred(i18n("The selector") + " :\n" +m_styleSheet.mid(0,20) + "...\n "+ msg1); return; } TQString temp(m_styleSheet.left(closingParenthesisPos+1)); if(numberOfParenthesisInAParenthesisBlock(closed,temp) < numberOfParenthesisInAParenthesisBlock(opened,temp)){ m_stopProcessing = true; emit errorOccurred(i18n("The selector") + " :\n" +m_styleSheet.mid(0,20) + "...\n "+ msg1); return; } if(numberOfParenthesisInAParenthesisBlock(closed,temp) > numberOfParenthesisInAParenthesisBlock(opened,temp)){ m_stopProcessing = true; emit errorOccurred(i18n("The selector") + " :\n" +m_styleSheet.mid(0,20) + "...\n "+ msg2); return; } int closingParentheses = 1, openingParentheses = 0; while(true){ openingParentheses = numberOfParenthesisInAParenthesisBlock(closed,m_styleSheet.left(closingParenthesisPos+1)); //m_styleSheet.left(closingParenthesisPos+1).contains("{"); if(openingParentheses==closingParentheses){ TQString selectorName=m_styleSheet.left(findParanthesis(m_styleSheet, '{')/*m_styleSheet.find("{")*/).stripWhiteSpace(), selectorValue=m_styleSheet.mid(findParanthesis(m_styleSheet, '{')/*m_styleSheet.find("{")*/+1, closingParenthesisPos - m_styleSheet.find("{") -1); selectorName.remove("\n").remove("\t"); selectorValue.remove("\n").remove("\t"); TQPair tmp(selectorValue,++m_orderNumber); if (m_stylesheetStructure.contains(selectorName)) { uint i = 2; TQString s = selectorName + TQString("-v%1").arg(i); while (m_stylesheetStructure.contains(s)) { i++; s = selectorName + TQString("-v%1").arg(i); } selectorName = s; } m_stylesheetStructure[selectorName]=tmp; break; } else { closingParenthesisPos = findParanthesis(m_styleSheet, '{',closingParenthesisPos+1)/*m_styleSheet.find("}",closingParenthesisPos+1)*/; closingParentheses++; } } int ws=whiteSpaces(closingParenthesisPos+1); m_styleSheet=m_styleSheet.right(m_styleSheet.length()-closingParenthesisPos-1-ws); parse(); } void stylesheetParser::parseAtRules1(){ //TODO this needs to be fixed : in case the at rule is not properly closed the parser hangs if(m_styleSheet.find("{") == -1) { m_stopProcessing = true; emit errorOccurred(m_styleSheet.mid(0,20) + "...\n " + msg2); return; } int closingParenthesisPos = m_styleSheet.find("}"), closingParentheses = 0; if(closingParenthesisPos==-1) return; else closingParentheses = 1; int openingParentheses=0; while(true){ openingParentheses = m_styleSheet.left(closingParenthesisPos+1).contains("{"); if(openingParentheses==closingParentheses) break; else { closingParenthesisPos = m_styleSheet.find("}",closingParenthesisPos+1); if( closingParenthesisPos!= -1 ) closingParentheses++; else { m_stopProcessing = true; emit errorOccurred(m_styleSheet.mid(0,20) + "...\n " + msg1); return; } } } int ws=whiteSpaces(closingParenthesisPos+1); TQPair tmp(m_styleSheet.left(closingParenthesisPos+1+ws),++m_orderNumber); m_stylesheetStructure["@rule"+TQString::number(m_orderNumber,10)]=tmp; m_styleSheet=m_styleSheet.right(m_styleSheet.length()-closingParenthesisPos-1-ws); parse(); } void stylesheetParser::parseAtRules2(){ //TODO this needs to be fixed : in case the at rule is not properly closed the parser hangs int semicolonPos = m_styleSheet.find(";"); if(semicolonPos==-1) { m_stopProcessing = true; emit errorOccurred(m_styleSheet.mid(0,20) + "...\n " + msg1); return; } int ws=whiteSpaces(semicolonPos+1); TQPair tmp(m_styleSheet.left(semicolonPos+1+ws),++m_orderNumber); m_stylesheetStructure["@rule"+TQString::number(m_orderNumber,10)]=tmp; m_styleSheet=m_styleSheet.right(m_styleSheet.length()-semicolonPos-1-ws); parse(); } #include "stylesheetparser.moc"