static Chunk *parseInternal(Chunk *ctail, const QString& txt, uint& start, uint cnt, bool interpretNewLine) {
  Chunk *chead = ctail;

  if (ctail->group) {
    ctail = new Chunk(ctail, Chunk::None, false, true);
  }
  for (uint& i = start; i < cnt; ++i) {
    QChar c = txt[i];
    Chunk::VOffset dir = Chunk::Down;
    switch (c.unicode()) {
      case '\n':
        if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
          while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
            ctail = ctail->prev;
          }
          ctail = new Chunk(ctail, Chunk::None, false, true);
        }
        if (!ctail->text.isEmpty() || ctail->locked()) {
          if (ctail->vOffset != Chunk::None) {
            ctail = new Chunk(ctail->prev, Chunk::None, false, true);
          } else {
            ctail = new Chunk(ctail, Chunk::None, false, true);
          }
        }
        ctail->linebreak = true;
        ctail = new Chunk(ctail, Chunk::None, false, true);
        break;
      case '\t':
        if (!ctail->text.isEmpty() || ctail->locked()) {
          if (ctail->vOffset != Chunk::None) {
            ctail = new Chunk(ctail->prev, Chunk::None, false, true);
          } else {
            ctail = new Chunk(ctail, Chunk::None, false, true);
          }
        }
        ctail->tab = true;
        ctail = new Chunk(ctail, Chunk::None, false, true);
        break;
      case 0x5c:   // \ /**/

        if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
          while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
            ctail = ctail->prev;
          }
          ctail = new Chunk(ctail, Chunk::None, false, true);
        }


        if (ctail->vOffset != Chunk::None && !ctail->text.isEmpty()) {
          ctail = new Chunk(ctail->prev, Chunk::None, false, true);
        }
        ++i;
        if (i == cnt) {
          setNormalChar('\\', &ctail);
        } else {
          int skip = 0;
          if (!parseOutChar(txt, i, &skip, &ctail, interpretNewLine)) {
            setNormalChar(txt[i], &ctail);
          } else {
            i += skip - 1;
          }
        }
        break;
      case 0x5e:   // ^
        dir = Chunk::Up;
      case 0x5f:   // _ (dir is set to Down at beginning of loop)
        if (ctail->text.isEmpty() && !ctail->group) {
          setNormalChar(c, &ctail);
        } else {
          if (ctail->vOffset != Chunk::None) {
            if (ctail->vOffset != dir) {
              ctail = new Chunk(ctail->prev, dir, false, true);
            } else if (ctail->group) {
              ctail = new Chunk(ctail, dir, false, true);
            } else {
              ctail = new Chunk(ctail, dir, false, true);
            }
          } else {
            ctail = new Chunk(ctail, dir, false, true);
          }
        }
        break;
      case 0x7b:   // {
        if (ctail->text.isEmpty() && !ctail->group) {
          bool rc = false;
          new Chunk(ctail, Chunk::None, true, true);
          dumpattr(ctail->group, "start group with non-group and empty text");
          rc = 0L != parseInternal(ctail->group, txt, ++i, cnt, interpretNewLine);
          assert(rc);
          dumpattr(ctail->group, "after start group with non-group and empty text");
          if (!rc) {
            return 0L;
          }
        } else {
          bool rc = false;
          if (ctail->vOffset == Chunk::None) {
            rc = 0L != parseInternal(new Chunk(ctail, Chunk::None, true, true), txt, ++i, cnt, interpretNewLine);
          } else {
            rc = 0L != parseInternal(new Chunk(ctail->prev, Chunk::None, true, true), txt, ++i, cnt,  interpretNewLine);
          }
          if (!rc) {
            return 0L;
          }
        }
        break;
      case 0x7d:   // }
        if (chead->prev && chead->prev->group == chead) {
          return chead;
        } else {
          setNormalChar(c, &ctail);
        }
        break;
      case '[':
        {
          bool vector = false;
          int vectorIndexStart = -1;
          int vectorIndexEnd = -1;
          int bracketStack = 1;
          int pos = -1;
          bool equation = txt[i + 1] == '=';
          for (uint searchPt = i + 1; bracketStack != 0 && searchPt < cnt; ++searchPt) {
            if (txt[searchPt] == ']') {
              if (--bracketStack == 0) {
                pos = searchPt;
                break;
              } else if (bracketStack == 1 && vector && vectorIndexEnd == -1) {
                vectorIndexEnd = searchPt - 1;
              }
            } else if (txt[searchPt] == '[') {
              ++bracketStack;
              if (!vector && !equation) {
                vector = true;
                vectorIndexStart = searchPt + 1;
              }
            }
          }

          if (pos < 0 || pos == int(i) + 1 /* empty [] */) {
            return 0L;
          }

          if (ctail->locked() || !ctail->text.isEmpty()) {
            if (ctail->vOffset != Chunk::None) {
              ctail = new Chunk(ctail->prev, Chunk::None, false, true);
            } else {
              ctail = new Chunk(ctail, Chunk::None, false, true);
            }
          }

          if (vector) {
            ctail->text = txt.mid(i + 1, vectorIndexStart - i - 2).trimmed();
            ctail->expression = txt.mid(vectorIndexStart, vectorIndexEnd - vectorIndexStart + 1);
            ctail->vector = true;
          } else {
            ctail->text = txt.mid(i + 1, pos - i - 1).trimmed();
            ctail->scalar = true;
          }
          i = uint(pos);
        }
        break;
      default:
#if 0
        if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
          ctail = new Chunk(ctail->prev, Chunk::None, false, true);
        }
#endif
        if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
          while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) {
            ctail = ctail->prev;
          }
          ctail = new Chunk(ctail, Chunk::None, false, true);
        }
        setNormalChar(c, &ctail);
        break;
    }
  }

  return chead;
}
Exemplo n.º 2
0
QValidator::State NexusAddressValidator::validate(QString &input, int &pos) const
{
    // Correction
    for(int idx=0; idx<input.size();)
    {
        bool removeChar = false;
        QChar ch = input.at(idx);
        // Transform characters that are visually close
        switch(ch.unicode())
        {
        case 'l':
        case 'I':
            input[idx] = QChar('1');
            break;
        case '0':
        case 'O':
            input[idx] = QChar('o');
            break;
        // Qt categorizes these as "Other_Format" not "Separator_Space"
        case 0x200B: // ZERO WIDTH SPACE
        case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
            removeChar = true;
            break;
        default:
            break;
        }
        // Remove whitespace
        if(ch.isSpace())
            removeChar = true;
        // To next character
        if(removeChar)
            input.remove(idx, 1);
        else
            ++idx;
    }

    // Validation
    QValidator::State state = QValidator::Acceptable;
    for(int idx=0; idx<input.size(); ++idx)
    {
        int ch = input.at(idx).unicode();

        if(((ch >= '0' && ch<='9') ||
           (ch >= 'a' && ch<='z') ||
           (ch >= 'A' && ch<='Z')) &&
           ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
        {
            // Alphanumeric and not a 'forbidden' character
        }
        else
        {
            state = QValidator::Invalid;
        }
    }

    // Empty address is "intermediate" input
    if(input.isEmpty())
    {
        state = QValidator::Intermediate;
    }

    return state;
}
Exemplo n.º 3
0
void RTFGenParser::text(const QString &text)
{
    if (m_res_size)
        return;
    unsigned size = res.length();
    if (size > m_max_size){
        textPos = start_pos;
        m_res_size = size;
        return;
    }
    for (int i = 0; i < (int)(text.length()); i++){
        QChar c = text[i];
        if (c.isSpace()){
            unsigned size = res.length();
            if (size > m_max_size){
                textPos = start_pos + i;
                m_res_size = size;
                return;
            }
        }
        // In Qt, unless you force the paragraph direction with (Left/Right)
        // Ctrl-Shift (also known as Key_Direction_L and Key_Direction_R),
        // the P tag won't have a DIR attribute at all. In such cases, unlike
        // HTML, Qt will render the paragraph LTR or RTL according to the
        // first strong character (as Unicode TR#9 defines). Thus, if the
        // direction isn't known yet, we check each character till we find
        // a strong one.
        if ((m_lastParagraphPos != 0) && (m_paragraphDir == DirUnknown))
        {
            switch(c.direction())
            {
            case QChar::DirL:
                res.insert(m_lastParagraphPos, "\\ltrpar");
                m_paragraphDir = DirLTR;
                break;
            case QChar::DirR:
                res.insert(m_lastParagraphPos, "\\rtlpar");
                m_paragraphDir = DirRTL;
                break;
            default: // to avoid warnings
                break;
            }
        }

        unsigned short u = c.unicode();
        if (c == '\r' || c == '\n')
            continue;
        if ((c == '{') || (c == '}') || (c == '\\')){
            char b[5];
            snprintf(b, sizeof(b), "\\\'%02x", u & 0xFF);
            res += b;
            m_bSpace = false;
            continue;
        }
        if (u < 0x80){
            if (m_bSpace)
                res += ' ';
            res += (char)u;
            m_bSpace = false;
            continue;
        }
        QString s;
        s += c;
        if (m_codec){
            string plain;
            plain = static_cast<string>(m_codec->fromUnicode(s));
            if ((plain.length() == 1) && (m_codec->toUnicode(plain.c_str()) == s)){
                char b[5];
                snprintf(b, sizeof(b), "\\\'%02x", plain[0] & 0xFF);
                res += b;
                m_bSpace = false;
                continue;
            }
        }
        res += "\\u";
        res += number(s[0].unicode());
        res += "?";
        m_bSpace = false;
    }
}
Exemplo n.º 4
0
bool QQuickSvgParser::parsePathDataFast(const QString &dataStr, QPainterPath &path)
{
    qreal x0 = 0, y0 = 0;              // starting point
    qreal x = 0, y = 0;                // current point
    char lastMode = 0;
    QPointF ctrlPt;
    const QChar *str = dataStr.constData();
    const QChar *end = str + dataStr.size();

    while (str != end) {
        while (str->isSpace())
            ++str;
        QChar pathElem = *str;
        ++str;
        QChar endc = *end;
        *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee
        QVarLengthArray<qreal, 8> arg;
        parseNumbersArray(str, arg);
        *const_cast<QChar *>(end) = endc;
        if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
            arg.append(0);//dummy
        const qreal *num = arg.constData();
        int count = arg.count();
        while (count > 0) {
            qreal offsetX = x;        // correction offsets
            qreal offsetY = y;        // for relative commands
            switch (pathElem.unicode()) {
            case 'm': {
                if (count < 2) {
                    num++;
                    count--;
                    break;
                }
                x = x0 = num[0] + offsetX;
                y = y0 = num[1] + offsetY;
                num += 2;
                count -= 2;
                path.moveTo(x0, y0);

                 // As per 1.2  spec 8.3.2 The "moveto" commands
                 // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
                 // the subsequent pairs shall be treated as implicit 'lineto' commands.
                 pathElem = QLatin1Char('l');
            }
                break;
            case 'M': {
                if (count < 2) {
                    num++;
                    count--;
                    break;
                }
                x = x0 = num[0];
                y = y0 = num[1];
                num += 2;
                count -= 2;
                path.moveTo(x0, y0);

                // As per 1.2  spec 8.3.2 The "moveto" commands
                // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
                // the subsequent pairs shall be treated as implicit 'lineto' commands.
                pathElem = QLatin1Char('L');
            }
                break;
            case 'z':
            case 'Z': {
                x = x0;
                y = y0;
                count--; // skip dummy
                num++;
                path.closeSubpath();
            }
                break;
            case 'l': {
                if (count < 2) {
                    num++;
                    count--;
                    break;
                }
                x = num[0] + offsetX;
                y = num[1] + offsetY;
                num += 2;
                count -= 2;
                path.lineTo(x, y);

            }
                break;
            case 'L': {
                if (count < 2) {
                    num++;
                    count--;
                    break;
                }
                x = num[0];
                y = num[1];
                num += 2;
                count -= 2;
                path.lineTo(x, y);
            }
                break;
            case 'h': {
                x = num[0] + offsetX;
                num++;
                count--;
                path.lineTo(x, y);
            }
                break;
            case 'H': {
                x = num[0];
                num++;
                count--;
                path.lineTo(x, y);
            }
                break;
            case 'v': {
                y = num[0] + offsetY;
                num++;
                count--;
                path.lineTo(x, y);
            }
                break;
            case 'V': {
                y = num[0];
                num++;
                count--;
                path.lineTo(x, y);
            }
                break;
            case 'c': {
                if (count < 6) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c1(num[0] + offsetX, num[1] + offsetY);
                QPointF c2(num[2] + offsetX, num[3] + offsetY);
                QPointF e(num[4] + offsetX, num[5] + offsetY);
                num += 6;
                count -= 6;
                path.cubicTo(c1, c2, e);
                ctrlPt = c2;
                x = e.x();
                y = e.y();
                break;
            }
            case 'C': {
                if (count < 6) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c1(num[0], num[1]);
                QPointF c2(num[2], num[3]);
                QPointF e(num[4], num[5]);
                num += 6;
                count -= 6;
                path.cubicTo(c1, c2, e);
                ctrlPt = c2;
                x = e.x();
                y = e.y();
                break;
            }
            case 's': {
                if (count < 4) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c1;
                if (lastMode == 'c' || lastMode == 'C' ||
                    lastMode == 's' || lastMode == 'S')
                    c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
                else
                    c1 = QPointF(x, y);
                QPointF c2(num[0] + offsetX, num[1] + offsetY);
                QPointF e(num[2] + offsetX, num[3] + offsetY);
                num += 4;
                count -= 4;
                path.cubicTo(c1, c2, e);
                ctrlPt = c2;
                x = e.x();
                y = e.y();
                break;
            }
            case 'S': {
                if (count < 4) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c1;
                if (lastMode == 'c' || lastMode == 'C' ||
                    lastMode == 's' || lastMode == 'S')
                    c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
                else
                    c1 = QPointF(x, y);
                QPointF c2(num[0], num[1]);
                QPointF e(num[2], num[3]);
                num += 4;
                count -= 4;
                path.cubicTo(c1, c2, e);
                ctrlPt = c2;
                x = e.x();
                y = e.y();
                break;
            }
            case 'q': {
                if (count < 4) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c(num[0] + offsetX, num[1] + offsetY);
                QPointF e(num[2] + offsetX, num[3] + offsetY);
                num += 4;
                count -= 4;
                path.quadTo(c, e);
                ctrlPt = c;
                x = e.x();
                y = e.y();
                break;
            }
            case 'Q': {
                if (count < 4) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF c(num[0], num[1]);
                QPointF e(num[2], num[3]);
                num += 4;
                count -= 4;
                path.quadTo(c, e);
                ctrlPt = c;
                x = e.x();
                y = e.y();
                break;
            }
            case 't': {
                if (count < 2) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF e(num[0] + offsetX, num[1] + offsetY);
                num += 2;
                count -= 2;
                QPointF c;
                if (lastMode == 'q' || lastMode == 'Q' ||
                    lastMode == 't' || lastMode == 'T')
                    c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
                else
                    c = QPointF(x, y);
                path.quadTo(c, e);
                ctrlPt = c;
                x = e.x();
                y = e.y();
                break;
            }
            case 'T': {
                if (count < 2) {
                    num += count;
                    count = 0;
                    break;
                }
                QPointF e(num[0], num[1]);
                num += 2;
                count -= 2;
                QPointF c;
                if (lastMode == 'q' || lastMode == 'Q' ||
                    lastMode == 't' || lastMode == 'T')
                    c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
                else
                    c = QPointF(x, y);
                path.quadTo(c, e);
                ctrlPt = c;
                x = e.x();
                y = e.y();
                break;
            }
            case 'a': {
                if (count < 7) {
                    num += count;
                    count = 0;
                    break;
                }
                qreal rx = (*num++);
                qreal ry = (*num++);
                qreal xAxisRotation = (*num++);
                qreal largeArcFlag  = (*num++);
                qreal sweepFlag = (*num++);
                qreal ex = (*num++) + offsetX;
                qreal ey = (*num++) + offsetY;
                count -= 7;
                qreal curx = x;
                qreal cury = y;
                pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
                        int(sweepFlag), ex, ey, curx, cury);

                x = ex;
                y = ey;
            }
                break;
            case 'A': {
                if (count < 7) {
                    num += count;
                    count = 0;
                    break;
                }
                qreal rx = (*num++);
                qreal ry = (*num++);
                qreal xAxisRotation = (*num++);
                qreal largeArcFlag  = (*num++);
                qreal sweepFlag = (*num++);
                qreal ex = (*num++);
                qreal ey = (*num++);
                count -= 7;
                qreal curx = x;
                qreal cury = y;
                pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
                        int(sweepFlag), ex, ey, curx, cury);

                x = ex;
                y = ey;
            }
                break;
            default:
                return false;
            }
            lastMode = pathElem.toLatin1();
        }
    }
    return true;
}
Exemplo n.º 5
0
void gtAction::write(const QString& text, gtStyle *style)
{
	if (isFirstWrite)
	{
		if (!doAppend)
		{
			if (it->nextInChain() != 0)
			{
				PageItem *nextItem = it->nextInChain();
				while (nextItem != 0)
				{
					nextItem->itemText.clear();
					nextItem = nextItem->nextInChain();
				}
			}
			it->itemText.clear();
		}
	}
	int paragraphStyle = -1;
	if (style->target() == "paragraph")
	{
		gtParagraphStyle* pstyle = dynamic_cast<gtParagraphStyle*>(style);
		assert(pstyle != NULL);
		paragraphStyle = applyParagraphStyle(pstyle);
		if (isFirstWrite)
			inPara = true;
	}
	else if (style->target() == "frame")
	{
		gtFrameStyle* fstyle = dynamic_cast<gtFrameStyle*>(style);
		assert(fstyle != NULL);
		applyFrameStyle(fstyle);
	}

	if ((inPara) && (!lastCharWasLineChange) && (text.left(1) != "\n") && (lastParagraphStyle != -1))
		paragraphStyle = lastParagraphStyle;

	if (paragraphStyle == -1)
		paragraphStyle = 0; //::findParagraphStyle(textFrame->doc(), textFrame->doc()->currentStyle);

	const ParagraphStyle& paraStyle = textFrame->doc()->paragraphStyles()[paragraphStyle];

	gtFont* font = style->getFont();
	QString fontName = validateFont(font).scName();
	CharStyle lastStyle, newStyle;
	int lastStyleStart = 0;
	
	if ((inPara) && (!overridePStyleFont))
	{
		if (paraStyle.charStyle().font().isNone())
		{
			gtFont font2(*font);
			font2.setName(paraStyle.charStyle().font().scName());
			QString fontName2 = validateFont(&font2).scName();
			newStyle.setFont((*textFrame->doc()->AllFonts)[fontName2]);
		}
	}
	else
	{
		setCharStyleAttributes(font, newStyle);
	}
	/*newStyle.eraseCharStyle(paraStyle.charStyle());*/

	lastStyle = newStyle;
	lastStyleStart = it->itemText.length();

	QChar ch0(0), ch5(5), ch10(10), ch13(13);
	for (int a = 0; a < text.length(); ++a)
	{
		if ((text.at(a) == ch0) || (text.at(a) == ch13))
			continue;
		QChar ch = text.at(a);
		if ((ch == ch10) || (ch == ch5))
			ch = ch13;
		else if (ch.unicode() == 0x2028)
			ch = SpecialChars::LINEBREAK;
		else if (ch.unicode() == 0x2029)
			ch = SpecialChars::PARSEP;
		
		int pos = it->itemText.length();
		it->itemText.insertChars(pos, QString(ch));
		if (ch == SpecialChars::PARSEP) 
		{
			if (paraStyle.hasName())
			{
				ParagraphStyle pstyle;
				pstyle.setParent(paraStyle.name());
				it->itemText.applyStyle(pos, pstyle);
			}
			else
				it->itemText.applyStyle(pos, paraStyle);
		}
	}
	it->itemText.applyCharStyle(lastStyleStart, it->itemText.length()-lastStyleStart, lastStyle);
	if (paraStyle.hasName())
	{
		ParagraphStyle pStyle;
		pStyle.setParent(paraStyle.name());
		it->itemText.applyStyle(qMax(0,it->itemText.length()-1), pStyle);
	}
	else
		it->itemText.applyStyle(qMax(0,it->itemText.length()-1), paraStyle);
	
	lastCharWasLineChange = text.right(1) == "\n";
	inPara = style->target() == "paragraph";
	lastParagraphStyle = paragraphStyle;
	if (isFirstWrite)
		isFirstWrite = false;
}
Exemplo n.º 6
0
int Lexer::scanToken()
{
    if (_stackToken != -1) {
        int tk = _stackToken;
        _stackToken = -1;
        return tk;
    }

    _terminator = false;

again:
    _validTokenText = false;
    _tokenLinePtr = _lastLinePtr;

    while (_char.isSpace()) {
        if (unsigned sequenceLength = isLineTerminatorSequence()) {
            _tokenLinePtr = _codePtr + sequenceLength - 1;

            if (_restrictedKeyword) {
                // automatic semicolon insertion
                _tokenLine = _currentLineNumber;
                _tokenStartPtr = _codePtr - 1;
                return T_SEMICOLON;
            } else {
                _terminator = true;
                syncProhibitAutomaticSemicolon();
            }
        }

        scanChar();
    }

    _tokenStartPtr = _codePtr - 1;
    _tokenLine = _currentLineNumber;

    if (_codePtr > _endPtr)
        return EOF_SYMBOL;

    const QChar ch = _char;
    scanChar();

    switch (ch.unicode()) {
    case '~': return T_TILDE;
    case '}': return T_RBRACE;

    case '|':
        if (_char == QLatin1Char('|')) {
            scanChar();
            return T_OR_OR;
        } else if (_char == QLatin1Char('=')) {
            scanChar();
            return T_OR_EQ;
        }
        return T_OR;

    case '{': return T_LBRACE;

    case '^':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_XOR_EQ;
        }
        return T_XOR;

    case ']': return T_RBRACKET;
    case '[': return T_LBRACKET;
    case '?': return T_QUESTION;

    case '>':
        if (_char == QLatin1Char('>')) {
            scanChar();
            if (_char == QLatin1Char('>')) {
                scanChar();
                if (_char == QLatin1Char('=')) {
                    scanChar();
                    return T_GT_GT_GT_EQ;
                }
                return T_GT_GT_GT;
            } else if (_char == QLatin1Char('=')) {
                scanChar();
                return T_GT_GT_EQ;
            }
            return T_GT_GT;
        } else if (_char == QLatin1Char('=')) {
            scanChar();
            return T_GE;
        }
        return T_GT;

    case '=':
        if (_char == QLatin1Char('=')) {
            scanChar();
            if (_char == QLatin1Char('=')) {
                scanChar();
                return T_EQ_EQ_EQ;
            }
            return T_EQ_EQ;
        }
        return T_EQ;

    case '<':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_LE;
        } else if (_char == QLatin1Char('<')) {
            scanChar();
            if (_char == QLatin1Char('=')) {
                scanChar();
                return T_LT_LT_EQ;
            }
            return T_LT_LT;
        }
        return T_LT;

    case ';': return T_SEMICOLON;
    case ':': return T_COLON;

    case '/':
        if (_char == QLatin1Char('*')) {
            scanChar();
            while (_codePtr <= _endPtr) {
                if (_char == QLatin1Char('*')) {
                    scanChar();
                    if (_char == QLatin1Char('/')) {
                        scanChar();

                        if (_engine) {
                            _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
                                                tokenStartLine(), tokenStartColumn() + 2);
                        }

                        goto again;
                    }
                } else {
                    scanChar();
                }
            }
        } else if (_char == QLatin1Char('/')) {
            while (_codePtr <= _endPtr && !isLineTerminator()) {
                scanChar();
            }
            if (_engine) {
                _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
                                    tokenStartLine(), tokenStartColumn() + 2);
            }
            goto again;
        } if (_char == QLatin1Char('=')) {
            scanChar();
            return T_DIVIDE_EQ;
        }
        return T_DIVIDE_;

    case '.':
        if (_char.isDigit()) {
            QVarLengthArray<char,32> chars;

            chars.append(ch.unicode()); // append the `.'

            while (_char.isDigit()) {
                chars.append(_char.unicode());
                scanChar();
            }

            if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
                if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
                                              _codePtr[1].isDigit())) {

                    chars.append(_char.unicode());
                    scanChar(); // consume `e'

                    if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
                        chars.append(_char.unicode());
                        scanChar(); // consume the sign
                    }

                    while (_char.isDigit()) {
                        chars.append(_char.unicode());
                        scanChar();
                    }
                }
            }

            chars.append('\0');

            const char *begin = chars.constData();
            const char *end = 0;
            bool ok = false;

            _tokenValue = qstrtod(begin, &end, &ok);

            if (end - begin != chars.size() - 1) {
                _errorCode = IllegalExponentIndicator;
                _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number.");
                return T_ERROR;
            }

            return T_NUMERIC_LITERAL;
        }
        return T_DOT;

    case '-':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_MINUS_EQ;
        } else if (_char == QLatin1Char('-')) {
            scanChar();

            if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
                _stackToken = T_MINUS_MINUS;
                return T_SEMICOLON;
            }

            return T_MINUS_MINUS;
        }
        return T_MINUS;

    case ',': return T_COMMA;

    case '+':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_PLUS_EQ;
        } else if (_char == QLatin1Char('+')) {
            scanChar();

            if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
                _stackToken = T_PLUS_PLUS;
                return T_SEMICOLON;
            }

            return T_PLUS_PLUS;
        }
        return T_PLUS;

    case '*':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_STAR_EQ;
        }
        return T_STAR;

    case ')': return T_RPAREN;
    case '(': return T_LPAREN;

    case '&':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_AND_EQ;
        } else if (_char == QLatin1Char('&')) {
            scanChar();
            return T_AND_AND;
        }
        return T_AND;

    case '%':
        if (_char == QLatin1Char('=')) {
            scanChar();
            return T_REMAINDER_EQ;
        }
        return T_REMAINDER;

    case '!':
        if (_char == QLatin1Char('=')) {
            scanChar();
            if (_char == QLatin1Char('=')) {
                scanChar();
                return T_NOT_EQ_EQ;
            }
            return T_NOT_EQ;
        }
        return T_NOT;

    case '\'':
    case '"': {
        const QChar quote = ch;
        bool multilineStringLiteral = false;

        const QChar *startCode = _codePtr;

        if (_engine) {
            while (_codePtr <= _endPtr) {
                if (isLineTerminator()) {
                    if (qmlMode())
                        break;
                    _errorCode = IllegalCharacter;
                    _errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal.");
                    return T_ERROR;
                } else if (_char == QLatin1Char('\\')) {
                    break;
                } else if (_char == quote) {
                    _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
                    scanChar();

                    return T_STRING_LITERAL;
                }
                scanChar();
            }
        }

        _validTokenText = true;
        _tokenText.resize(0);
        startCode--;
        while (startCode != _codePtr - 1)
            _tokenText += *startCode++;

        while (_codePtr <= _endPtr) {
            if (unsigned sequenceLength = isLineTerminatorSequence()) {
                multilineStringLiteral = true;
                _tokenText += _char;
                if (sequenceLength == 2)
                    _tokenText += *_codePtr;
                scanChar();
            } else if (_char == quote) {
                scanChar();

                if (_engine)
                    _tokenSpell = _engine->newStringRef(_tokenText);

                return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
            } else if (_char == QLatin1Char('\\')) {
                scanChar();

                QChar u;

                switch (_char.unicode()) {
                // unicode escape sequence
                case 'u': {
                    bool ok = false;
                    u = decodeUnicodeEscapeCharacter(&ok);
                    if (! ok) {
                        _errorCode = IllegalUnicodeEscapeSequence;
                        _errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence.");
                        return T_ERROR;
                    }
                } break;

                // hex escape sequence
                case 'x': {
                    bool ok = false;
                    u = decodeHexEscapeCharacter(&ok);
                    if (!ok) {
                        _errorCode = IllegalHexadecimalEscapeSequence;
                        _errorMessage = QCoreApplication::translate("QmlParser", "Illegal hexadecimal escape sequence.");
                        return T_ERROR;
                    }
                } break;

                // single character escape sequence
                case '\\': u = QLatin1Char('\\'); scanChar(); break;
                case '\'': u = QLatin1Char('\''); scanChar(); break;
                case '\"': u = QLatin1Char('\"'); scanChar(); break;
                case 'b':  u = QLatin1Char('\b'); scanChar(); break;
                case 'f':  u = QLatin1Char('\f'); scanChar(); break;
                case 'n':  u = QLatin1Char('\n'); scanChar(); break;
                case 'r':  u = QLatin1Char('\r'); scanChar(); break;
                case 't':  u = QLatin1Char('\t'); scanChar(); break;
                case 'v':  u = QLatin1Char('\v'); scanChar(); break;

                case '0':
                    if (! _codePtr->isDigit()) {
                        scanChar();
                        u = QLatin1Char('\0');
                        break;
                    }
                    // fall through
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    _errorCode = IllegalEscapeSequence;
                    _errorMessage = QCoreApplication::translate("QmlParser", "Octal escape sequences are not allowed.");
                    return T_ERROR;

                case '\r':
                case '\n':
                case 0x2028u:
                case 0x2029u:
                    scanChar();
                    continue;

                default:
                    // non escape character
                    u = _char;
                    scanChar();
                }

                _tokenText += u;
            } else {
                _tokenText += _char;
                scanChar();
            }
        }

        _errorCode = UnclosedStringLiteral;
        _errorMessage = QCoreApplication::translate("QmlParser", "Unclosed string at end of line.");
        return T_ERROR;
    }
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        return scanNumber(ch);

    default: {
        QChar c = ch;
        bool identifierWithEscapeChars = false;
        if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) {
            identifierWithEscapeChars = true;
            bool ok = false;
            c = decodeUnicodeEscapeCharacter(&ok);
            if (! ok) {
                _errorCode = IllegalUnicodeEscapeSequence;
                _errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence.");
                return T_ERROR;
            }
        }
        if (isIdentifierStart(c)) {
            if (identifierWithEscapeChars) {
                _tokenText.resize(0);
                _tokenText += c;
                _validTokenText = true;
            }
            while (true) {
                c = _char;
                if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
                    if (! identifierWithEscapeChars) {
                        identifierWithEscapeChars = true;
                        _tokenText.resize(0);
                        _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
                        _validTokenText = true;
                    }

                    scanChar(); // skip '\\'
                    bool ok = false;
                    c = decodeUnicodeEscapeCharacter(&ok);
                    if (! ok) {
                        _errorCode = IllegalUnicodeEscapeSequence;
                        _errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence.");
                        return T_ERROR;
                    }
                    if (isIdentifierPart(c))
                        _tokenText += c;
                    continue;
                } else if (isIdentifierPart(c)) {
                    if (identifierWithEscapeChars)
                        _tokenText += c;

                    scanChar();
                    continue;
                }

                _tokenLength = _codePtr - _tokenStartPtr - 1;

                int kind = T_IDENTIFIER;

                if (! identifierWithEscapeChars)
                    kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);

                if (_engine) {
                    if (kind == T_IDENTIFIER && identifierWithEscapeChars)
                        _tokenSpell = _engine->newStringRef(_tokenText);
                    else
                        _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
                }

                return kind;
            }
        }
        }

        break;
    }

    return T_ERROR;
}
Exemplo n.º 7
0
static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
{
    return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
                 (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
}
Exemplo n.º 8
0
/*
    Returns \c true if the current line (and upwards) forms a braceless
    control statement; otherwise returns \c false.

    The first line of the following example is a "braceless control
    statement":

        if ( x )
            y;
*/
static bool matchBracelessControlStatement()
{
    int delimDepth = 0;

    if ( yyLine->endsWith("else") )
        return true;

    if ( !yyLine->endsWith(QLatin1Char(')')) )
        return false;

    for ( int i = 0; i < SmallRoof; i++ ) {
        int j = yyLine->length();
        while ( j > 0 ) {
            j--;
            QChar ch = (*yyLine)[j];

            switch ( ch.unicode() ) {
            case ')':
                delimDepth++;
                break;
            case '(':
                delimDepth--;
                if ( delimDepth == 0 ) {
                    if ( yyLine->indexOf(*iflikeKeyword) != -1 ) {
                        /*
                            We have

                                if ( x )
                                    y

                            "if ( x )" is not part of the statement
                            "y".
                        */
                        return true;
                    }
                }
                if ( delimDepth == -1 ) {
                    /*
                      We have

                          if ( (1 +
                                2)

                      and not

                          if ( 1 +
                               2 )
                    */
                    return false;
                }
                break;
            case '{':
            case '}':
            case ';':
                /*
                    We met a statement separator, but not where we
                    expected it. What follows is probably a weird
                    continuation line. Be careful with ';' in for,
                    though.
                */
                if ( ch != QChar(';') || delimDepth == 0 )
                    return false;
            }
        }

        if ( !readLine() )
            break;
    }
    return false;
}
Exemplo n.º 9
0
void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &block)
{
    if (block.textList()) { // its a list-item
        const int listLevel = block.textList()->format().indent();
        if (m_listStack.isEmpty() || m_listStack.top() != block.textList()) {
            // not the same list we were in.
            while (m_listStack.count() >= listLevel && !m_listStack.isEmpty() && m_listStack.top() != block.textList() ) { // we need to close tags
                m_listStack.pop();
                writer.writeEndElement(); // list
                if (m_listStack.count())
                    writer.writeEndElement(); // list-item
            }
            while (m_listStack.count() < listLevel) {
                if (m_listStack.count())
                    writer.writeStartElement(textNS, QString::fromLatin1("list-item"));
                writer.writeStartElement(textNS, QString::fromLatin1("list"));
                if (m_listStack.count() == listLevel - 1) {
                    m_listStack.push(block.textList());
                    writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("L%1")
                            .arg(block.textList()->formatIndex()));
                }
                else {
                    m_listStack.push(0);
                }
            }
        }
        writer.writeStartElement(textNS, QString::fromLatin1("list-item"));
    }
    else {
        while (! m_listStack.isEmpty()) {
            m_listStack.pop();
            writer.writeEndElement(); // list
            if (m_listStack.count())
                writer.writeEndElement(); // list-item
        }
    }

    if (block.length() == 1) { // only a linefeed
        writer.writeEmptyElement(textNS, QString::fromLatin1("p"));
        writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("p%1")
            .arg(block.blockFormatIndex()));
        if (block.textList())
            writer.writeEndElement(); // numbered-paragraph
        return;
    }
    writer.writeStartElement(textNS, QString::fromLatin1("p"));
    writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("p%1")
        .arg(block.blockFormatIndex()));
    for (QTextBlock::Iterator frag= block.begin(); !frag.atEnd(); frag++) {
        writer.writeCharacters(QString()); // Trick to make sure that the span gets no linefeed in front of it.
        writer.writeStartElement(textNS, QString::fromLatin1("span"));

        QString fragmentText = frag.fragment().text();
        if (fragmentText.length() == 1 && fragmentText[0] == 0xFFFC) { // its an inline character.
            writeInlineCharacter(writer, frag.fragment());
            writer.writeEndElement(); // span
            continue;
        }

        writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("c%1")
            .arg(frag.fragment().charFormatIndex()));
        bool escapeNextSpace = true;
        int precedingSpaces = 0, precedingTabs = 0;
        int exportedIndex = 0;
        for (int i=0; i <= fragmentText.count(); ++i) {
            bool isTab = false, isSpace = false;
            if (i < fragmentText.count()) {
                QChar character = fragmentText[i];
                isTab = character.unicode() == '\t';
                isSpace = character.unicode() == ' ';
                if (character.unicode() == 0x2028) { // soft-return
                    writer.writeCharacters(fragmentText.mid(exportedIndex, i));
                    writer.writeEmptyElement(textNS, QString::fromLatin1("line-break"));
                    exportedIndex = i+1;
                    continue;
                }
                if (isSpace) {
                    ++precedingSpaces;
                    escapeNextSpace = true;
                }
                else if (isTab) {
                    precedingTabs++;
                }
            }
            // find more than one space. -> <text:s text:c="2" />
            if (!isSpace && escapeNextSpace && precedingSpaces > 1) {
                const bool startParag = exportedIndex == 0 && i == precedingSpaces;
                if (!startParag)
                    writer.writeCharacters(fragmentText.mid(exportedIndex, i - precedingSpaces + 1 - exportedIndex));
                writer.writeEmptyElement(textNS, QString::fromLatin1("s"));
                const int count = precedingSpaces - (startParag?0:1);
                if (count > 1)
                    writer.writeAttribute(textNS, QString::fromLatin1("c"), QString::number(count));
                precedingSpaces = 0;
                exportedIndex = i;
            }
            // find tabs.   ->  <text:tab text:tab-ref="3" />  or <text:tab/>
            if (!isTab && precedingTabs) {
                writer.writeCharacters(fragmentText.mid(exportedIndex, i - precedingTabs - exportedIndex));
                writer.writeEmptyElement(textNS, QString::fromLatin1("tab"));
                if (precedingTabs > 1)
                    writer.writeAttribute(textNS, QString::fromLatin1("tab-ref"), QString::number(precedingTabs));
                precedingTabs = 0;
                exportedIndex = i;
            }
            if (!isSpace && !isTab)
                precedingSpaces = 0;
        }

        writer.writeCharacters(fragmentText.mid(exportedIndex));
        writer.writeEndElement(); // span
    }
    writer.writeCharacters(QString()); // Trick to make sure that the span gets no linefeed behind it.
    writer.writeEndElement(); // p
    if (block.textList())
        writer.writeEndElement(); // list-item
}
Exemplo n.º 10
0
QString PageGenerator::fileBase(const Node *node) const
{
    if (node->relates())
	node = node->relates();
    else if (!node->isInnerNode())
	node = node->parent();
#ifdef QDOC_QML
    if (node->subType() == Node::QmlPropertyGroup) {
        node = node->parent();
    }
#endif        

    QString base = node->doc().baseName();
    if (!base.isEmpty())
        return base;

    const Node *p = node;

    forever {
        const Node *pp = p->parent();
        base.prepend(p->name());
#ifdef QDOC_QML
        /*
          To avoid file name conflicts in the html directory,
          we prepend a prefix (by default, "qml-") to the file name of QML
          element doc files.
         */
        if ((p->subType() == Node::QmlClass) ||
            (p->subType() == Node::QmlBasicType)) {
            if (!base.startsWith(QLatin1String("QML:")))
                base.prepend(outputPrefix(QLatin1String("QML")));
        }
#endif
        if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake)
            break;
        base.prepend(QLatin1Char('-'));
        p = pp;
    }
    
    if (node->type() == Node::Fake) {
#ifdef QDOC2_COMPAT
        if (base.endsWith(".html"))
            base.truncate(base.length() - 5);
#endif
    }

    // the code below is effectively equivalent to:
    //   base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
    //   base = base.trimmed();
    //   base.replace(" ", "-");
    //   base = base.toLower();
    // as this function accounted for ~8% of total running time
    // we optimize a bit...

    QString res;
    // +5 prevents realloc in fileName() below
    res.reserve(base.size() + 5);
    bool begun = false;
    for (int i = 0; i != base.size(); ++i) {
        QChar c = base.at(i);
        uint u = c.unicode();
        if (u >= 'A' && u <= 'Z')
            u -= 'A' - 'a';
        if ((u >= 'a' &&  u <= 'z') || (u >= '0' && u <= '9')) {
            res += QLatin1Char(u);
            begun = true;
        }
        else if (begun) {
            res += QLatin1Char('-');
            begun = false;
        }
    }
    while (res.endsWith(QLatin1Char('-')))
        res.chop(1);
    return res;
}
Exemplo n.º 11
0
void KoXmlWriter::addTextSpan(const QString& text, const QMap<int, int>& tabCache) {
    int len = text.length();
    int nrSpaces = 0; // number of consecutive spaces
    bool leadingSpace = false;
    QString str;
    str.reserve(len);

    // Accumulate chars either in str or in nrSpaces (for spaces).
    // Flush str when writing a subelement (for spaces or for another reason)
    // Flush nrSpaces when encountering two or more consecutive spaces
    for (int i = 0; i < len; ++i) {
        QChar ch = text[i];
        ushort unicode = ch.unicode();
        if (unicode == ' ') {
            if (i == 0)
                leadingSpace = true;
            ++nrSpaces;
        } else {
            if (nrSpaces > 0) {
                // For the first space we use ' '.
                // "it is good practice to use (text:s) for the second and all following SPACE
                // characters in a sequence." (per the ODF spec)
                // however, per the HTML spec, "authors should not rely on user agents to render
                // white space immediately after a start tag or immediately before an end tag"
                // (and both we and OO.o ignore leading spaces in <text:p> or <text:h> elements...)
                if (!leadingSpace) {
                    str += ' ';
                    --nrSpaces;
                }
                if (nrSpaces > 0) { // there are more spaces
                    if (!str.isEmpty())
                        addTextNode(str);
                    str.clear();
                    startElement("text:s");
                    if (nrSpaces > 1) // it's 1 by default
                        addAttribute("text:c", nrSpaces);
                    endElement();
                }
            }
            nrSpaces = 0;
            leadingSpace = false;

            switch (unicode) {
                case '\t':
                    if (!str.isEmpty())
                        addTextNode(str);
                    str.clear();
                    startElement("text:tab");
                    if (tabCache.contains(i))
                        addAttribute("text:tab-ref", tabCache[i] + 1);
                    endElement();
                    break;
                    // gracefully handle \f form feed in text input.
                    // otherwise the xml will not be valid.
                    // \f can be added e.g. in ascii import filter.
                case '\f':
                case '\n':
                case QChar::LineSeparator:
                    if (!str.isEmpty())
                        addTextNode(str);
                    str.clear();
                    startElement("text:line-break");
                    endElement();
                    break;
                default:
                    // don't add stuff that is not allowed in xml. The stuff we need we have already handled above
                    if (ch.unicode() >= 0x20) {
                        str += text[i];
                    }
                    break;
            }
        }
    }
    // either we still have text in str or we have spaces in nrSpaces
    if (!str.isEmpty()) {
        addTextNode(str);
    }
    if (nrSpaces > 0) { // there are more spaces
        startElement("text:s");
        if (nrSpaces > 1) // it's 1 by default
            addAttribute("text:c", nrSpaces);
        endElement();
    }
}
Exemplo n.º 12
0
bool QUimInputContext::filterEvent( const QEvent *event )
{
#ifdef ENABLE_DEBUG
    // qDebug("filterEvent");
#endif

    int type = event->type();

    if ( type != QEvent::KeyPress &&
            type != QEvent::KeyRelease )
        return FALSE;

    QKeyEvent *keyevent = ( QKeyEvent * ) event;
    int qkey = keyevent->key();

    int modifier = 0;
    if ( keyevent->state() & Qt::ShiftButton )
        modifier |= UMod_Shift;
    if ( keyevent->state() & Qt::ControlButton )
        modifier |= UMod_Control;
    if ( keyevent->state() & Qt::AltButton )
        modifier |= UMod_Alt;
#if defined(Q_WS_X11)
    if ( keyevent->state() & Qt::MetaButton )
        modifier |= UMod_Meta;
#endif

    int key = 0;
    if ( isascii( qkey ) && isprint( qkey ) )
    {
        int ascii = keyevent->ascii();
        if ( isalpha( ascii ) )
        {
            key = ascii;  // uim needs lower/upper encoded key
        }
        else
        {
            if ( keyevent->state() & Qt::ControlButton &&
                 ( ascii >= 0x01 && ascii <= 0x1a ) )
                if ( keyevent->state() & Qt::ShiftButton )
                    key = ascii + 0x40;
                else
                    key = ascii + 0x60;
            else
                key = qkey;
        }
    }
    else if ( qkey == Qt::Key_unknown )
    {
        QString text = keyevent->text();
        if ( !text.isNull() )
        {
            QChar s = text.at(0);
            key = unicodeToUKey ( s.unicode() );
        }
        else
        {
            key = UKey_Other;
        }
    }
    else
    {
        if ( qkey >= Qt::Key_F1 && qkey <= Qt::Key_F35 )
        {
            key = qkey - Qt::Key_F1 + UKey_F1;
        }
        else if ( qkey >= Qt::Key_Dead_Grave && qkey <= Qt::Key_Dead_Horn )
        {
            key = qkey - Qt::Key_Dead_Grave + UKey_Dead_Grave;
        }
        else if ( qkey >= Qt::Key_Kanji && qkey <= Qt::Key_Eisu_toggle )
        {
            key = qkey - Qt::Key_Kanji + UKey_Kanji;
        }
        else if ( qkey >= Qt::Key_Hangul && qkey <= Qt::Key_Hangul_Special )
        {
            key = qkey - Qt::Key_Hangul + UKey_Hangul;
        }
        else
        {
            switch ( qkey )
            {
            case Qt::Key_Tab: key = UKey_Tab; break;
            case Qt::Key_BackSpace: key = UKey_Backspace; break;
            case Qt::Key_Escape: key = UKey_Escape; break;
            case Qt::Key_Delete: key = UKey_Delete; break;
            case Qt::Key_Return: key = UKey_Return; break;
            case Qt::Key_Left: key = UKey_Left; break;
            case Qt::Key_Up: key = UKey_Up; break;
            case Qt::Key_Right: key = UKey_Right; break;
            case Qt::Key_Down: key = UKey_Down; break;
            case Qt::Key_Prior: key = UKey_Prior; break;
            case Qt::Key_Next: key = UKey_Next; break;
            case Qt::Key_Home: key = UKey_Home; break;
            case Qt::Key_End: key = UKey_End; break;
            case Qt::Key_Multi_key: key = UKey_Multi_key; break;
            case Qt::Key_Mode_switch: key = UKey_Mode_switch; break;
            case Qt::Key_Codeinput: key = UKey_Codeinput; break;
            case Qt::Key_SingleCandidate: key = UKey_SingleCandidate; break;
            case Qt::Key_MultipleCandidate: key = UKey_MultipleCandidate; break;
            case Qt::Key_PreviousCandidate: key = UKey_PreviousCandidate; break;
            case Qt::Key_Shift: key = UKey_Shift_key; break;
            case Qt::Key_Control: key = UKey_Control_key; break;
            case Qt::Key_Alt: key = UKey_Alt_key; break;
            case Qt::Key_Meta: key = UKey_Meta_key; break;
            case Qt::Key_CapsLock: key = UKey_Caps_Lock; break;
            case Qt::Key_NumLock: key = UKey_Num_Lock; break;
            case Qt::Key_ScrollLock: key = UKey_Scroll_Lock; break;
            default: key = UKey_Other;
            }
        }
    }

    int notFiltered;
    if ( type == QEvent::KeyPress )
    {
        notFiltered = uim_press_key( m_uc, key, modifier );
#ifdef Q_WS_X11
        if ( notFiltered )
            return mCompose->handle_qkey( keyevent );
#else
        if ( notFiltered )
            return FALSE;
#endif
    }
    else if ( type == QEvent::KeyRelease )
    {
        notFiltered = uim_release_key( m_uc, key, modifier );
#ifdef Q_WS_X11
        if ( notFiltered )
            return mCompose->handle_qkey( keyevent );
#else
        if ( notFiltered )
            return FALSE;
#endif
    }

    return TRUE;
}
Exemplo n.º 13
0
int Lexer::nextTokenKind()
{
    int token = Parser::Token_INVALID;
    if (m_curpos >= m_contentSize) {
        m_tokenBegin = -1;
        m_tokenEnd = -1;
        createNewline(m_curpos);
        return 0;
    }
    QChar* it = m_content.data();
    it += m_curpos;
    m_tokenBegin = m_curpos;

    if (it->isSpace())
    {
        token = Parser::Token_WHITESPACE;
        while (m_curpos < m_contentSize && it->isSpace())
        {
            if (it->unicode() == '\n')
            {
                createNewline(m_curpos);
            }
            it++;
            m_curpos++;
        }
        m_curpos--;
    }
    else if (it->isDigit())
    {
	QRegExp regex("\\d+\\.\\d+|\\d+\\.\\d+|\\d+\\.\\d+e-?\\d+|\\d+\\.\\d+e-?\\d+|[\\dABCDEF]+#\\d{1,2}|\\d+");
	
	if ( regex.indexIn(m_content, m_curpos) != -1)
	{
	  kDebug() << "Matched: " << regex.cap();
	  
	  m_curpos += regex.matchedLength() - 1;
	  token = Parser::Token_INTEGER_LITERAL;
	}
    }
    else if (it->unicode() == '-')
    {
	  if ((it + 1)->unicode() == '>')
	  {
	      m_curpos++;
	      token = Parser::Token_LEADS_TO;
	  }
	  else  if ((it + 1)->unicode() == '-')
	  {
	      m_curpos++;
	      token = Parser::Token_LIST_DIFFERENCE;
	  }
	  else
	  {
	      token = Parser::Token_MINUS;
	  }
    }    
    else if (it->unicode() == '+')
    {
	if ((it + 1)->unicode() == '+')
        {
            m_curpos++;
            token = Parser::Token_LIST_ADDITION;
        }
        else
        {
            token = Parser::Token_PLUS;
        }
    }
    else if (it->unicode() == '$' && processCharLiteral(it + 1))
    {
        token = Parser::Token_CHAR_LITERAL;
    }
    else if (it->unicode() == '}')
    {
        token = Parser::Token_RBRACE;
        if (state() == Tuple)
        {
            popState();
        }
    }
    else if (it->unicode() == '_')
    {
        token = Parser::Token_UNDERLINE;
    }
    else if (it->unicode() == '{')
    {
        token = Parser::Token_LBRACE;
        pushState(Tuple);
    }
    else if (it->unicode() == ')')
    {
        token = Parser::Token_RPAREN;
    }
    else if (it->unicode() == '(')
    {
        token = Parser::Token_LPAREN;
    }
    else if (it->unicode() == ']')
    {
        token = Parser::Token_RBRACKET;
    }
    else if (it->unicode() == '[')
    {
        token = Parser::Token_LBRACKET;
    }
    else if (it->unicode() == ',')
    {
        token = Parser::Token_COMMA;
    }
    else if (it->unicode() == '#')
    {
        token = Parser::Token_POUND_SIGN;
    }
    else if (it->unicode() == '!')
    {
        token = Parser::Token_EXCLAMATION;
    }
    else if (it->unicode() == '<')
    {
        if ( (it + 1)->unicode() == '-')
        {
            m_curpos += 1;
            token = Parser::Token_LIST_COMPREHENSION_LEADS_TO;
        }
        else if ( (it + 1)->unicode() == '<' )
        {
            m_curpos += 1;
            token = Parser::Token_BINARY_OPEN;
        }
        else
        {
            token = Parser::Token_IS_SMALLER;
        }
    }
    else if (it->unicode() == '>')
    {
        if ((it + 1)->unicode() == '=')
        {
            m_curpos++;
            token = Parser::Token_IS_GREATER_OR_EQUAL;
        }
        else if ( (it + 1)->unicode() == '>' )
        {
            m_curpos += 1;
            token = Parser::Token_BINARY_CLOSE;
        }
        else
        {
            token = Parser::Token_IS_GREATER;
        }
    }
    else if (it->unicode() == '?')
    {
        token = Parser::Token_QUESTION;
    }
    else if (it->unicode() == '%')
    {
        token = Parser::Token_COMMENT;
        while (it->unicode() != '\n')
        {
            m_curpos++;
            it++;
        }
        createNewline(m_curpos);
    }
    else if (it->unicode() == '/')
    {
        if ((it + 1)->unicode() == '=')
        {
            token = Parser::Token_IS_NOT_EQUAL;
        }
        else
        {
            token = Parser::Token_FORWARD_SLASH;
        }
    }
    else if (it->unicode() == '*')
    {
        token = Parser::Token_MUL;
    }
    else if (it->unicode() == '|')
    {
        if ((it + 1)->unicode() == '|')
        {
            m_curpos++;
            token = Parser::Token_DOUBLE_PIPE;
        }
        else
        {
            token = Parser::Token_PIPE;
        }
    }
    else if (it->unicode() == ':')
    {
        if ( (it + 1)->unicode() == ':')
        {
            m_curpos += 1;
            token = Parser::Token_DOUBLE_COLON;
        }
        else
        {
            token = Parser::Token_COLON;
        }
    }
    else if (it->unicode() == '.')
    {
        token = Parser::Token_DOT;
    }
    else if (it->unicode() == ';')
    {
        token = Parser::Token_SEMICOLON;
    }
    else if (it->unicode() == '\'')
    {
        token = Parser::Token_ATOM_LITERAL;
        it++;
        m_curpos++;
        int startPos = m_curpos;
        while (m_curpos < m_contentSize
                && (it->unicode() != '\'')) {
            if (it->unicode() == '\n') createNewline(m_curpos);
            it++;
            m_curpos++;
        }
        // if the string is never terminated, make sure we don't overflow the boundaries
        if ( m_curpos == m_contentSize ) {
            --m_curpos;
        }
    }
    else if (it->unicode() == '"')
    {
        token = Parser::Token_STRING_LITERAL;
        it++;
        m_curpos++;
        while (m_curpos < m_contentSize
                && (it->unicode() != '\"')) {
            if (it->unicode() == '\n') createNewline(m_curpos);
            it++;
            m_curpos++;
        }
        // if the string is never terminated, make sure we don't overflow the boundaries
        if ( m_curpos == m_contentSize ) {
            --m_curpos;
        }
    }
    else if (it->unicode() == '=')
    {
        if ((it + 1)->unicode() == '=')
        {
            m_curpos++;
            token = Parser::Token_IS_EQUAL;
        }
        else if ((it + 1)->unicode() == '<') {
            m_curpos++;
            token = Parser::Token_IS_SMALLER_OR_EQUAL;
        }
        else if ((it + 1)->unicode() == ':' && (it + 2)->unicode() == '=')
        {
            m_curpos += 2;
            token = Parser::Token_EXACT_EQUATIONAL;
        }
        else if ((it + 1)->unicode() == '/' && (it + 2)->unicode() == '=')
        {
            m_curpos += 2;
            token = Parser::Token_EXACT_NOT_EQUATIONAL;
        }
        else
        {
            token = Parser::Token_ASSIGN;
        }
    }
    else if (it->isLetter() && it->isUpper())
    {
        QString name;
        while (m_curpos < m_contentSize && (isValidVariableIdentifier(it))) {
            name.append(*it);
            it++;
            m_curpos++;
        }
        m_curpos--;
        token = Parser::Token_VARIABLE;
    }
    else if (it->isLetter() && it->isLower())
    {
        QString name;
        while (m_curpos < m_contentSize && (isValidVariableIdentifier(it))) {
            name.append(*it);
            it++;
            m_curpos++;
        }

        m_curpos--;

        if (name == "after") {
            token = Parser::Token_AFTER;
        } else if (name == "begin") {
            token = Parser::Token_BEGIN;
        } else if (name == "case") {
            token = Parser::Token_CASE;
        } else if (name == "if") {
            token = Parser::Token_IF;
        } else if (name == "catch") {
            token = Parser::Token_CATCH;
        } else if (name == "cond") {
            token = Parser::Token_COND;
        } else if (name == "end") {
            token = Parser::Token_END;
        } else if (name == "fun") {
            token = Parser::Token_FUN;
        } else if (name == "let") {
            token = Parser::Token_LET;
        } else if (name == "of") {
            token = Parser::Token_OF;
        } else if (name == "catch") {
            token = Parser::Token_CATCH;
        } else if (name == "receive") {
            token = Parser::Token_RECEIVE;
        } else if (name == "when") {
            token = Parser::Token_WHEN;
        } else if (name == "div") {
            token = Parser::Token_INT_DIV;
        } else if (name == "rem") {
            token = Parser::Token_INT_REM;
        } else if (name == "or") {
            token = Parser::Token_OR;
        } else if (name == "xor") {
            token = Parser::Token_XOR;
        } else if (name == "bor") {
            token = Parser::Token_BIT_OR;
        } else if (name == "bxor") {
            token = Parser::Token_BIT_XOR;
        } else if (name == "query") {
            token = Parser::Token_QUERY;
        } else if (name == "bsl") {
            token = Parser::Token_SL;
        } else if (name == "bsr") {
            token = Parser::Token_SR;
        } else if (name == "and") {
            token = Parser::Token_AND;
        } else if (name == "band") {
            token = Parser::Token_BIT_AND;
        } else if (name == "not") {
            token = Parser::Token_NOT;
        } else if (name == "bnot") {
            token = Parser::Token_BIT_NOT;
        } else if (name == "orelse") {
            token = Parser::Token_ORELSE;
        } else if (name == "andalso") {
            token = Parser::Token_ANDALSO;
        } else if (name == "module") {
            token = Parser::Token_MODULE_DIRECTIVE;
        } else if (name == "include") {
            token = Parser::Token_INCLUDE_DIRECTIVE;
        } else if (name == "export") {
            token = Parser::Token_EXPORT_DIRECTIVE;
        } else if (name == "file") {
            token = Parser::Token_FILE_DIRECTIVE;
        } else if (name == "record") {
            token = Parser::Token_RECORD_DIRECTIVE;
        } else if (name == "include") {
            token = Parser::Token_INCLUDE_DIRECTIVE;
        } else if (name == "behaviour"){
	  token = Parser::Token_BEHAVIOUR_DIRECTIVE;
	} else if (name == "define"){
	  token = Parser::Token_DEFINE_DIRECTIVE;
	}	
        else
        {
            token = Parser::Token_ATOM_LITERAL;
        }
    }

    m_tokenEnd = m_curpos;
    m_curpos++;

    return token;
}
void DTMFServiceDepricated::playDTMFTone(const QChar& keyToPlay)
{
    PHONE_DEBUG2("DTMFServiceDepricated::playDTMFTone keyToPlay:", keyToPlay);
    m_parameters.SetKeyCode(keyToPlay.unicode());
    TRAP_IGNORE( m_call.HandlePlayDTMFL() );
}
Exemplo n.º 15
0
Arquivo: mhi.cpp Projeto: Olti/mythtv
// Draw a line of text in the given position within the image.
// It would be nice to be able to use TTFFont for this but it doesn't provide
// what we want.
void MHIText::AddText(int x, int y, const QString &str, MHRgba colour)
{
    if (!m_parent->IsFaceLoaded()) return;
    FT_Face face = m_parent->GetFontFace();
    FT_Error error = FT_Set_Char_Size(face, 0, Point2FT(m_fontsize),
                                      FONT_WIDTHRES, FONT_HEIGHTRES);

    // X positions are computed to 64ths and rounded.
    // Y positions are in pixels
    int posX = Point2FT(x);
    int pixelY = y;
    FT_Bool useKerning = FT_HAS_KERNING(face);
    FT_UInt previous = 0;

    int len = str.length();
    for (int n = 0; n < len; n++)
    {
        // Load the glyph.
        QChar ch = str[n];
        FT_UInt glyphIndex = FT_Get_Char_Index(face, ch.unicode());
        if (glyphIndex == 0)
        {
            previous = 0;
            continue;
        }

        if (useKerning && previous != 0)
        {
            FT_Vector delta;
            FT_Get_Kerning(face, previous, glyphIndex,
                           FT_KERNING_DEFAULT, &delta);
            posX += delta.x;
        }
        error = FT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER);

        if (error)
            continue; // ignore errors

        FT_GlyphSlot slot = face->glyph;
        if (slot->format != FT_GLYPH_FORMAT_BITMAP)
            continue; // Problem

        if ((enum FT_Pixel_Mode_)slot->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
            continue;

        unsigned char *source = slot->bitmap.buffer;
        // Get the origin for the bitmap
        int baseX = FT2Point(posX) + slot->bitmap_left;
        int baseY = pixelY - slot->bitmap_top;
        // Copy the bitmap into the image.
        for (int i = 0; i < slot->bitmap.rows; i++)
        {
            for (int j = 0; j < slot->bitmap.width; j++)
            {
                int greyLevel = source[j];
                // Set the pixel to the specified colour but scale its
                // brightness according to the grey scale of the pixel.
                int red = colour.red();
                int green = colour.green();
                int blue = colour.blue();
                int alpha = colour.alpha() *
                    greyLevel / slot->bitmap.num_grays;
                int xBit =  j + baseX;
                int yBit =  i + baseY;

                // The bits ought to be inside the bitmap but
                // I guess there's the possibility
                // that rounding might put it outside.
                if (xBit >= 0 && xBit < m_width &&
                    yBit >= 0 && yBit < m_height)
                {
                    m_image.setPixel(xBit, yBit,
                                     qRgba(red, green, blue, alpha));
                }
            }
            source += slot->bitmap.pitch;
        }
        posX += slot->advance.x;
        previous = glyphIndex;
    }
}
Exemplo n.º 16
0
bool
Text::isLdc(const QChar& c) const
{
    return (c.unicode()>=begin && c.unicode()<=end);
}
Exemplo n.º 17
0
Arquivo: mhi.cpp Projeto: Olti/mythtv
// Return the bounding rectangle for a piece of text drawn in the
// current font. If maxSize is non-negative it sets strLen to the
// number of characters that will fit in the space and returns the
// bounds for those characters.
// N.B.  The box is relative to the origin so the y co-ordinate will
// be negative. It's also possible that the x co-ordinate could be
// negative for slanted fonts but that doesn't currently happen.
QRect MHIText::GetBounds(const QString &str, int &strLen, int maxSize)
{
    if (!m_parent->IsFaceLoaded())
        return QRect(0,0,0,0);

    FT_Face face = m_parent->GetFontFace();
    FT_Error error = FT_Set_Char_Size(face, 0, Point2FT(m_fontsize),
                                      FONT_WIDTHRES, FONT_HEIGHTRES);
    if (error)
        return QRect(0,0,0,0);

    int maxAscent = 0, maxDescent = 0, width = 0;
    FT_Bool useKerning = FT_HAS_KERNING(face);
    FT_UInt previous = 0;

    for (int n = 0; n < strLen; n++)
    {
        QChar ch = str.at(n);
        FT_UInt glyphIndex = FT_Get_Char_Index(face, ch.unicode());

        if (glyphIndex == 0)
        {
            LOG(VB_MHEG, LOG_INFO, QString("[mhi] Unknown glyph 0x%1")
                .arg(ch.unicode(),0,16));
            previous = 0;
            continue;
        }

        int kerning = 0;

        if (useKerning && previous != 0)
        {
            FT_Vector delta;
            FT_Get_Kerning(face, previous, glyphIndex,
                           FT_KERNING_DEFAULT, &delta);
            kerning = delta.x;
        }

        error = FT_Load_Glyph(face, glyphIndex, 0); // Don't need to render.

        if (error)
            continue; // ignore errors.

        FT_GlyphSlot slot = face->glyph; /* a small shortcut */
        FT_Pos advance = slot->metrics.horiAdvance + kerning;

        if (maxSize >= 0)
        {
            if (FT2Point(width + advance) > maxSize)
            {
                // There isn't enough space for this character.
                strLen = n;
                break;
            }
        }
        // Calculate the ascent and descent of this glyph.
        int descent = slot->metrics.height - slot->metrics.horiBearingY;

        if (slot->metrics.horiBearingY > maxAscent)
            maxAscent = slot->metrics.horiBearingY;

        if (descent > maxDescent)
            maxDescent = descent;

        width += advance;
        previous = glyphIndex;
    }

    return QRect(0, -FT2Point(maxAscent), FT2Point(width), FT2Point(maxAscent + maxDescent));
}
Exemplo n.º 18
0
/*!
    Returns a Qt version of the given \a sys_fmt Symbian locale format string.
*/
static QString s60ToQtFormat(const QString &sys_fmt)
{
    TLocale *locale = _s60Locale.GetLocale();

    QString result;
    QString other;
    QString qtformatchars = QString::fromLatin1("adhmsyzAHM");

    QChar c;
    int i = 0;
    bool open_escape = false;
    bool abbrev_next = false;
    bool locale_indep_ordering = false;
    bool minus_mode = false;
    bool plus_mode = false;
    bool n_mode = false;
    TTimeFormat tf = locale->TimeFormat();

    while (i < sys_fmt.size()) {

        c = sys_fmt.at(i);

        // let formatting thru
        if (c.unicode() == '%') {
            // if we have gathered string, concat it
            if (!other.isEmpty()) {
                result += other;
                other.clear();
            }
            // if we have open escape, end it
            if (open_escape) {
                result += QLatin1Char('\'');
                open_escape = false;
            }

            ++i;
            if (i >= sys_fmt.size())
                break;

            c = sys_fmt.at(i);

            // process specials
            abbrev_next = c.unicode() == '*';
            plus_mode = c.unicode() == '+';
            minus_mode = c.unicode() == '-';

            if (abbrev_next || plus_mode || minus_mode) {
                ++i;
                if (i >= sys_fmt.size())
                    break;

                c = sys_fmt.at(i);

                if (plus_mode || minus_mode) {
                    // break on undefined plus/minus mode
                    if (c.unicode() != 'A' && c.unicode() != 'B')
                        break;
                }
            }

            switch (c.unicode()) {
                case 'F':
                {
                    // locale indep mode on
                    locale_indep_ordering = true;
                    break;
                }

                case '/':
                {
                    // date sep 0-3
                    ++i;
                    if (i >= sys_fmt.size())
                        break;

                    c = sys_fmt.at(i);
                    if (c.isDigit() && c.digitValue() <= 3) {
                        TChar s = locale->DateSeparator(c.digitValue());
                        TUint val = s;
                        // some indexes return zero for empty
                        if (val > 0)
                            result += QChar(val);
                    }
                    break;
                }

                case 'D':
                {
                    if (!locale_indep_ordering)
                        break;

                    if (!abbrev_next)
                        result += QLatin1String("dd");
                    else
                        result += QLatin1Char('d');

                    break;
                }

                case 'M':
                {
                    if (!locale_indep_ordering)
                        break;

                    if (!n_mode) {
                        if (!abbrev_next)
                            result += QLatin1String("MM");
                        else
                            result += QLatin1String("M");
                    } else {
                        if (!abbrev_next)
                            result += QLatin1String("MMMM");
                        else
                            result += QLatin1String("MMM");
                    }

                    break;
                }

                case 'N':
                {
                    n_mode = true;

                    if (!locale_indep_ordering)
                        break;

                    if (!abbrev_next)
                        result += QLatin1String("MMMM");
                    else
                        result += QLatin1String("MMM");

                    break;
                }

                case 'Y':
                {
                    if (!locale_indep_ordering)
                        break;

                    if (!abbrev_next)
                        result += QLatin1String("yyyy");
                    else
                        result += QLatin1String("yy");

                    break;
                }

                case 'E':
                {
                    if (!abbrev_next)
                        result += QLatin1String("dddd");
                    else
                        result += QLatin1String("ddd");

                    break;
                }

                case ':':
                {
                    // timesep 0-3
                    ++i;
                    if (i >= sys_fmt.size())
                        break;

                    c = sys_fmt.at(i);
                    if (c.isDigit() && c.digitValue() <= 3) {
                        TChar s = locale->TimeSeparator(c.digitValue());
                        TUint val = s;
                        // some indexes return zero for empty
                        if (val > 0)
                            result += QChar(val);
                    }

                    break;
                }

                case 'J':
                {
                    if (tf == ETime24 && !abbrev_next)
                        result += QLatin1String("hh");
                    else
                        result += QLatin1Char('h');

                    break;
                }

                case 'H':
                {
                    if (!abbrev_next)
                        result += QLatin1String("hh");
                    else
                        result += QLatin1Char('h');

                    break;
                }

                case 'I':
                {
                    result += QLatin1Char('h');
                    break;
                }

                case 'T':
                {
                    if (!abbrev_next)
                        result += QLatin1String("mm");
                    else
                        result += QLatin1Char('m');

                    break;
                }

                case 'S':
                {
                    if (!abbrev_next)
                        result += QLatin1String("ss");
                    else
                        result += QLatin1Char('s');

                    break;
                }

                case 'B':
                {
                    // only done for 12h clock
                    if (tf == ETime24)
                        break;
                }

                    // fallthru to A
                case 'A': {
                    // quickie to get capitalization, can't use s60 string as is because Qt 'hh' format's am/pm logic
                    TAmPmName ampm = TAmPmName();
                    TChar first(ampm[0]);
                    QString qtampm = QString::fromLatin1(first.IsUpper() ? "AP" : "ap");

                    int pos = locale->AmPmSymbolPosition();

                    if ((minus_mode && pos != ELocaleBefore) ||
                        (plus_mode && pos != ELocaleAfter))
                        break;

                    if (!abbrev_next && locale->AmPmSpaceBetween()) {
                        if (pos == ELocaleBefore)
                            qtampm.append(QLatin1Char(' '));
                        else
                            qtampm.prepend(QLatin1Char(' '));
                    }

                    result += qtampm;
                    }
                    break;

                case '.': {
                        // decimal sep
                        TChar s = locale->DecimalSeparator();
                        TUint val = s;
                        if (val > 0)
                            result += QChar(val);
                    }
                    break;

                case 'C':
                {
                    // six digits in s60, three digits in qt
                    if (!abbrev_next) {
                        result += QLatin1String("zzz");
                    } else {
                        // next char is number from 0-6, how many digits to display
                        ++i;
                        if (i >= sys_fmt.size())
                            break;

                        c = sys_fmt.at(i);

                        if (c.isDigit()) {
                            // try to match wanted digits
                            QChar val(c.digitValue());

                            if (val >= 3) {
                                result += QLatin1String("zzz");
                            } else if (val > 0) {
                                result += QLatin1Char('z');
                            }
                        }
                    }
                    break;
                }

                // these cases fallthru
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                {

                    // shouldn't parse these with %F
                    if (locale_indep_ordering)
                        break;

                    TDateFormat df = locale->DateFormat();

                    const char **locale_dep;
                    switch (df) {
                        default: // fallthru to american
                        case EDateAmerican:
                            locale_dep = us_locale_dep;
                            break;
                        case EDateEuropean:
                            locale_dep = eu_locale_dep;
                            break;
                        case EDateJapanese:
                            locale_dep = jp_locale_dep;
                            break;
                    }
                    int offset = 0;
                    if (abbrev_next)
                        offset += 5;
                    if (n_mode)
                        offset += 10;

                    result += QLatin1String(locale_dep[offset + (c.digitValue()-1)]);
                    break;
                }

                case '%': // fallthru percent
                {
                // any junk gets copied as is
                }
                default:
                {
                    result += c;
                    break;
                }

                case 'Z': // Qt doesn't support these :(
                case 'X':
                case 'W':
                {
                    break;
                }
            }
        } else {
            // double any single quotes, don't begin escape
            if (c.unicode() == '\'') {
                // end open escape
                if (open_escape) {
                    result += other;
                    other.clear();
                    result += QLatin1Char('\'');
                    open_escape = false;
                }

                other += c;
            }

            // gather chars and escape them in one go if any format chars are found
            if (!open_escape && qtformatchars.indexOf(c) != -1) {
                result += QLatin1Char('\'');
                open_escape = true;
            }
            other += c;
        }

        ++i;
    }

    if (!other.isEmpty())
        result += other;
    if (open_escape)
        result += QLatin1Char('\'');

    return result;
}
Exemplo n.º 19
0
static inline QChar convertHex(QChar c1, QChar c2)
{
    return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
}
Exemplo n.º 20
0
/*!
    Returns \c true if the font has a glyph that corresponds to the given \a character.

    \sa supportedWritingSystems()
*/
bool QRawFont::supportsCharacter(QChar character) const
{
    return supportsCharacter(character.unicode());
}
Exemplo n.º 21
0
int Lexer::scanNumber(QChar ch)
{
    if (ch != QLatin1Char('0')) {
        QVarLengthArray<char, 64> buf;
        buf += ch.toLatin1();

        QChar n = _char;
        const QChar *code = _codePtr;
        while (n.isDigit()) {
            buf += n.toLatin1();
            n = *code++;
        }

        if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) {
            if (code != _codePtr) {
                _codePtr = code - 1;
                scanChar();
            }
            buf.append('\0');
            _tokenValue = strtod(buf.constData(), 0);
            return T_NUMERIC_LITERAL;
        }
    } else if (_char.isDigit() && !qmlMode()) {
        _errorCode = IllegalCharacter;
        _errorMessage = QCoreApplication::translate("QmlParser", "Decimal numbers cannot start with \"0\".");
        return T_ERROR;
    }

    QVarLengthArray<char,32> chars;
    chars.append(ch.unicode());

    if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
        ch = _char; // remember the x or X to use it in the error message below.

        // parse hex integer literal
        chars.append(_char.unicode());
        scanChar(); // consume `x'

        while (isHexDigit(_char)) {
            chars.append(_char.unicode());
            scanChar();
        }

        if (chars.size() < 3) {
            _errorCode = IllegalHexNumber;
            _errorMessage = QCoreApplication::translate("QmlParser", "At least one hexadecimal digit is required after \"0%1\".").arg(ch);
            return T_ERROR;
        }

        _tokenValue = integerFromString(chars.constData(), chars.size(), 16);
        return T_NUMERIC_LITERAL;
    }

    // decimal integer literal
    while (_char.isDigit()) {
        chars.append(_char.unicode());
        scanChar(); // consume the digit
    }

    if (_char == QLatin1Char('.')) {
        chars.append(_char.unicode());
        scanChar(); // consume `.'

        while (_char.isDigit()) {
            chars.append(_char.unicode());
            scanChar();
        }

        if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
            if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
                                          _codePtr[1].isDigit())) {

                chars.append(_char.unicode());
                scanChar(); // consume `e'

                if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
                    chars.append(_char.unicode());
                    scanChar(); // consume the sign
                }

                while (_char.isDigit()) {
                    chars.append(_char.unicode());
                    scanChar();
                }
            }
        }
    } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
        if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
                                      _codePtr[1].isDigit())) {

            chars.append(_char.unicode());
            scanChar(); // consume `e'

            if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
                chars.append(_char.unicode());
                scanChar(); // consume the sign
            }

            while (_char.isDigit()) {
                chars.append(_char.unicode());
                scanChar();
            }
        }
    }

    if (chars.size() == 1) {
        // if we ended up with a single digit, then it was a '0'
        _tokenValue = 0;
        return T_NUMERIC_LITERAL;
    }

    chars.append('\0');

    const char *begin = chars.constData();
    const char *end = 0;
    bool ok = false;

    _tokenValue = qstrtod(begin, &end, &ok);

    if (end - begin != chars.size() - 1) {
        _errorCode = IllegalExponentIndicator;
        _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number.");
        return T_ERROR;
    }

    return T_NUMERIC_LITERAL;
}
Exemplo n.º 22
0
static bool qIsAlnum(QChar ch)
{
    uint u = uint(ch.unicode());
    // matches [a-zA-Z0-9_]
    return u - 'a' < 26 || u - 'A' < 26 || u - '0' < 10 || u == '_';
}
Exemplo n.º 23
0
// force encoding of '>'.  this function is needed for XMPP-Core, which
//  requires the '>' character to be encoded as "&gt;" even though this is
//  not required by the XML spec.
// Also remove chars that are ouside the allowed range for XML (see validChar)
//  and invalid surrogate pairs
static QString sanitizeForStream(const QString &in)
{
	QString out;
	bool intag = false;
	bool inquote = false;
	QChar quotechar;
	int inlength = in.length();
	for(int n = 0; n < inlength; ++n)
	{
		QChar c = in[n];
		bool escape = false;
		if(c == '<')
		{
			intag = true;
		}
		else if(c == '>')
		{
			if(inquote) {
				escape = true;
			} else if(!intag) {
				escape = true;
			} else {
				intag = false;
			}
		}
		else if(c == '\'' || c == '\"')
		{
			if(intag)
			{
				if(!inquote)
				{
					inquote = true;
					quotechar = c;
				}
				else
				{
					if(quotechar == c) {
						inquote = false;
					}
				}
			}
		}

		if(escape) {
			out += "&gt;";
		 } else {
			// don't silently drop invalid chars in element or attribute names,
			// because that's something that should not happen.
			if (intag && (!inquote)) {
				out += c;
			} else if (validChar(c.unicode()))  {
				out += c;
			} else if (highSurrogate(c.unicode()) && (n+1 < inlength) && lowSurrogate(in[n+1].unicode())) {
				//uint unicode = (c.unicode() & 0x3FF) << 10 | in[n+1].unicode() & 0x3FF + 0x10000;
				// we don't need to recheck this, because 0x10000 <= unicode <= 0x100000 is always true
				out += c;
				out += in[n+1];
				++n;
			} else {
				qDebug("Dropping invalid XML char U+%04x",c.unicode());
			}
		}
	}
	return out;
}
Exemplo n.º 24
0
int Lexer::nextTokenKind()
{
    int token = Parser::Token_INVALID;
    if ( m_curpos >= m_contentSize )
    {
        return 0;
    }
    QChar* it = m_content.data();
    it += m_curpos;
    switch ( state() )
    {
        case VariableValueState:
            it = ignoreWhitespaceAndComment( it );
            m_tokenBegin = m_curpos;
            if( m_curpos < m_contentSize )
            {
                if( it->unicode() == '\n' )
                {
                    popState();
                    createNewline( m_curpos );
                    token = Parser::Token_NEWLINE;
                }else if( it->unicode() == '\\' && isCont(it) )

                {
                    pushState(ContState);
                    token = Parser::Token_CONT;
                }else if( it->unicode() == '"')
                {
                    it++;
                    m_curpos++;
                    QChar* lastit = it;
                    while( ( it->unicode() != '"' || lastit->unicode() == '\\' && it->unicode() == '"' ) && it->unicode() != '\n' && it->unicode() != '#' && !isCont( it ) && m_curpos < m_contentSize )
                    {
                        lastit = it;
                        it++;
                        m_curpos++;
                    }
                    if( it->unicode() != '"' && it->unicode() != '#' )
                    {
                        m_curpos--;
                    }
                    token = Parser::Token_VALUE;
                    if( it->unicode() == '#' )
                    {
                        m_tokenEnd = m_curpos - 1;
                        do
                        {
                            it++;
                            m_curpos++;
                        }while( it->unicode() != '\n' && m_curpos < m_contentSize );
                        if( it->unicode() == '\n')
                        {
                            m_curpos--;
                        }
                        return token;
                    }
                }else if( it->unicode() == '(' )
                {
                    unsigned int bracecount = 0;
                    while( ( it->unicode() != ';' || bracecount > 0 ) && it->unicode() != '\n' && !isCont( it )  && m_curpos < m_contentSize )
                    {
                        if( it->unicode() == '(' )
                        {
                            bracecount++;
                        }else if( it->unicode() == ')' && bracecount > 0 )
                        {
                            bracecount--;
                        }
                        ++it;
                        ++m_curpos;
                    }
                    if( it->unicode() != ';' )
                    {
                        m_curpos--;
                    }
                    token = Parser::Token_VALUE;
                }else
                {
                    while( !it->isSpace() && !isCont(it) && it->unicode() != '#' && m_curpos < m_contentSize )
                    {
                        it++;
                        m_curpos++;
                    }
                    m_curpos--;
                    token = Parser::Token_VALUE;
                }
            }
            break;
        case FunctionArgState:
            m_tokenBegin = m_curpos;
            if( it->unicode() == '\n' )
            {
                createNewline( m_curpos );
                token = Parser::Token_NEWLINE;
            }else if( it->unicode() == '\\' && isCont(it) )
            {
                pushState( ContState );
                token = Parser::Token_CONT;
            }else if( it->unicode() == ',' )
            {
                token = Parser::Token_COMMA;
            }else if( it->unicode() == ')' )
            {
                popState();
                token = Parser::Token_RPAREN;
            }else
            {
                unsigned int parentCount = 0;
                while( parentCount > 0 || ( it->unicode() != ')' && it->unicode() != ',' ) && m_curpos < m_contentSize )
                {
                    if( it->unicode() == ')' )
                    {
                        parentCount--;
                    }else if( it->unicode() == '(' )
                    {
                        parentCount++;
                    }
                    ++it;
                    ++m_curpos;
                }
                m_curpos--;
                token = Parser::Token_VALUE;
            }
            break;
        case ContState:
            it = ignoreWhitespaceAndComment( it );
            m_tokenBegin = m_curpos;
            if( m_curpos < m_contentSize )
            {
                if ( it->unicode() == '\n' )
                {
                    createNewline( m_curpos );
                    token = Parser::Token_NEWLINE;
                    m_tokenEnd = m_curpos;
                    popState();
                    QChar* temp = it;
                    int newpos = m_curpos;
                    do
                    {
                        temp++;
                        newpos++;
                        if(temp->unicode() == '#' )
                        {
                            while( temp->unicode() != '\n' && newpos < m_contentSize )
                            {
                                temp++;
                                newpos++;
                            }
                            createNewline( m_curpos );
                            temp++;
                            m_curpos = newpos;
                            newpos++;
                        }
                    }while( temp->isSpace() && temp->unicode() != '\n' && m_curpos < m_contentSize );
                    m_curpos++;
                    return token;
                }
            }
            break;
        case DefaultState:
            it = ignoreWhitespaceAndComment( it );
            m_tokenBegin = m_curpos;
            if( m_curpos < m_contentSize )
            {
                if ( isBeginIdentifierCharacter( it ) )
                {
                    token = Parser::Token_IDENTIFIER;
                    while ( !it->isSpace() && isIdentifierCharacter( it )  && m_curpos < m_contentSize )
                    {
                        it++;
                        m_curpos++;
                    }
                    if( !isEndIdentifierCharacter( ( it-1 ) ) )
                    {
                        token = Parser::Token_INVALID;
                    }
                    m_curpos--;
                }
                else
                {
                    //Now the stuff that will generate a proper token
                    QChar* c2 = m_curpos < m_contentSize ? it + 1 : 0 ;
                    switch ( it->unicode() )
                    {
                        case '|':
                            token = Parser::Token_OR;
                            break;
                        case '!':
                            token = Parser::Token_EXCLAM;
                            break;
                        case '(':
                            pushState( FunctionArgState );
                            token = Parser::Token_LPAREN;
                            break;
                        case '{':
                            token = Parser::Token_LBRACE;
                            break;
                        case '}':
                            token = Parser::Token_RBRACE;
                            break;
                        case ':':
                            token = Parser::Token_COLON;
                            break;
                        case '~':
                            if ( c2 && c2->unicode() == '=' )
                            {
                                pushState( VariableValueState );
                                m_curpos++;
                                token = Parser::Token_TILDEEQ;
                            }
                            break;
                        case '*':
                            if ( c2 && c2->unicode() == '=' )
                            {
                                pushState( VariableValueState );
                                m_curpos++;
                                token = Parser::Token_STAREQ;
                            }
                            break;
                        case '-':
                            if ( c2 && c2->unicode() == '=' )
                            {
                                pushState( VariableValueState );
                                m_curpos++;
                                token = Parser::Token_MINUSEQ;
                            }
                            break;
                        case '+':
                            if ( c2 && c2->unicode() == '=' )
                            {
                                pushState( VariableValueState );
                                m_curpos++;
                                token = Parser::Token_PLUSEQ;
                            }
                            break;
                        case '=':
                            pushState( VariableValueState );
                            token = Parser::Token_EQUAL;
                            break;
                        case '\n':
                            createNewline( m_curpos );
                            token = Parser::Token_NEWLINE;
                            break;
                        default:
                            break;
                    }
                }
            }
            break;
        default:
            token = Parser::Token_INVALID;
            break;
    }
    if ( m_curpos >= m_contentSize )
    {
        return 0;
    }
    m_tokenEnd = m_curpos;
    m_curpos++;
    return token;
}
Exemplo n.º 25
0
/*
    Returns the recommended indent for the bottom line of yyProgram,
    assuming it's a continuation line.

    We're trying to align the continuation line against some parenthesis
    or other bracked left opened on a previous line, or some interesting
    operator such as '='.
*/
int QmlJSIndenter::indentForContinuationLine()
{
    int braceDepth = 0;
    int delimDepth = 0;

    bool leftBraceFollowed = *yyLeftBraceFollows;

    for (int i = 0; i < SmallRoof; i++) {
        int hook = -1;

        int j = yyLine->length();
        while (j > 0 && hook < 0) {
            j--;
            QChar ch = yyLine->at(j);

            switch (ch.unicode()) {
            case ')':
                delimDepth++;
                break;
            case ']':
                braceDepth++;
                break;
            case '}':
                braceDepth++;
                break;
            case '(':
                delimDepth--;
                /*
                    An unclosed delimiter is a good place to align at,
                    at least for some styles (including Qt's).
                */
                if (delimDepth == -1)
                    hook = j;
                break;

            case '[':
                braceDepth--;
                /*
                    An unclosed delimiter is a good place to align at,
                    at least for some styles (including Qt's).
                */
                if (braceDepth == -1)
                    hook = j;
                break;
            case '{':
                braceDepth--;
                /*
                    A left brace followed by other stuff on the same
                    line is typically for an enum or an initializer.
                    Such a brace must be treated just like the other
                    delimiters.
                */
                if (braceDepth == -1) {
                    if (j < yyLine->length() - 1)
                        hook = j;
                    else
                        return 0; // shouldn't happen
                }
                break;
            case '=':
                /*
                    An equal sign is a very natural alignment hook
                    because it's usually the operator with the lowest
                    precedence in statements it appears in. Case in
                    point:

                        int x = 1 +
                                2;

                    However, we have to beware of constructs such as
                    default arguments and explicit enum constant
                    values:

                        void foo(int x = 0,
                                  int y = 0);

                    And not

                        void foo(int x = 0,
                                        int y = 0);

                    These constructs are caracterized by a ',' at the
                    end of the unfinished lines or by unbalanced
                    parentheses.
                */
                Q_ASSERT(j - 1 >= 0);

                if (QString::fromLatin1("!=<>").indexOf(yyLine->at(j - 1)) == -1 &&
                     j + 1 < yyLine->length() && yyLine->at(j + 1) != QLatin1Char('=')) {
                    if (braceDepth == 0 && delimDepth == 0 &&
                         j < yyLine->length() - 1 &&
                         !yyLine->endsWith(QLatin1Char(',')) &&
                         (yyLine->contains(QLatin1Char('(')) == yyLine->contains(QLatin1Char(')'))))
                        hook = j;
                }
            }
        }

        if (hook >= 0) {
            /*
                Yes, we have a delimiter or an operator to align
                against! We don't really align against it, but rather
                against the following token, if any. In this example,
                the following token is "11":

                    int x = (11 +
                              2);

                If there is no such token, we use a continuation indent:

                    static QRegExp foo(QString(
                            "foo foo foo foo foo foo foo foo foo"));
            */
            hook++;
            while (hook < yyLine->length()) {
                if (!yyLine->at(hook).isSpace())
                    return columnForIndex(*yyLine, hook);
                hook++;
            }
            return indentOfLine(*yyLine) + ppContinuationIndentSize;
        }

        if (braceDepth != 0)
            break;

        /*
            The line's delimiters are balanced. It looks like a
            continuation line or something.
        */
        if (delimDepth == 0) {
            if (leftBraceFollowed) {
                /*
                    We have

                        int main()
                        {

                    or

                        Bar::Bar()
                            : Foo(x)
                        {

                    The "{" should be flush left.
                */
                if (!isContinuationLine())
                    return indentOfLine(*yyLine);
            } else if (isContinuationLine() || yyLine->endsWith(QLatin1Char(','))) {
                /*
                    We have

                        x = a +
                            b +
                            c;

                    or

                        int t[] = {
                            1, 2, 3,
                            4, 5, 6

                    The "c;" should fall right under the "b +", and the
                    "4, 5, 6" right under the "1, 2, 3,".
                */
                return indentOfLine(*yyLine);
            } else {
                /*
                    We have

                        stream << 1 +
                                2;

                    We could, but we don't, try to analyze which
                    operator has precedence over which and so on, to
                    obtain the excellent result

                        stream << 1 +
                                  2;

                    We do have a special trick above for the assignment
                    operator above, though.
                */
                return indentOfLine(*yyLine) + ppContinuationIndentSize;
            }
        }

        if (!readLine())
            break;
    }
    return 0;
}
Exemplo n.º 26
0
static inline bool isValidNumber(const QChar &c)
{
    register ushort u = c.unicode();
    return (u >= '0' && u <= '9');
}
Exemplo n.º 27
0
// Apply a simple variant type to a DOM property
static bool applySimpleProperty(const QVariant &v, bool translateString, DomProperty *dom_prop)
{
    switch (v.type()) {
    case QVariant::String: {
        DomString *str = new DomString();
        str->setText(v.toString());
        if (!translateString)
            str->setAttributeNotr(QStringLiteral("true"));
        dom_prop->setElementString(str);
    }
        return true;

    case QVariant::ByteArray:
        dom_prop->setElementCstring(QString::fromUtf8(v.toByteArray()));
        return true;

    case QVariant::Int:
        dom_prop->setElementNumber(v.toInt());
        return true;

    case QVariant::UInt:
        dom_prop->setElementUInt(v.toUInt());
        return true;

    case QVariant::LongLong:
        dom_prop->setElementLongLong(v.toLongLong());
        return true;

    case QVariant::ULongLong:
        dom_prop->setElementULongLong(v.toULongLong());
        return true;

    case QVariant::Double:
        dom_prop->setElementDouble(v.toDouble());
        return true;

    case QVariant::Bool:
        dom_prop->setElementBool(v.toBool() ? QFormBuilderStrings::instance().trueValue : QFormBuilderStrings::instance().falseValue);
        return true;

    case QVariant::Char: {
        DomChar *ch = new DomChar();
        const QChar character = v.toChar();
        ch->setElementUnicode(character.unicode());
        dom_prop->setElementChar(ch);
    }
        return true;

    case QVariant::Point: {
        DomPoint *pt = new DomPoint();
        const QPoint point = v.toPoint();
        pt->setElementX(point.x());
        pt->setElementY(point.y());
        dom_prop->setElementPoint(pt);
    }
        return true;

    case QVariant::PointF: {
        DomPointF *ptf = new DomPointF();
        const QPointF pointf = v.toPointF();
        ptf->setElementX(pointf.x());
        ptf->setElementY(pointf.y());
        dom_prop->setElementPointF(ptf);
    }
        return true;

    case QVariant::Color: {
        DomColor *clr = new DomColor();
        const QColor color = qvariant_cast<QColor>(v);
        clr->setElementRed(color.red());
        clr->setElementGreen(color.green());
        clr->setElementBlue(color.blue());
        const int alphaChannel = color.alpha();
        if (alphaChannel != 255)
            clr->setAttributeAlpha(alphaChannel);
        dom_prop->setElementColor(clr);
    }
        return true;

    case QVariant::Size: {
        DomSize *sz = new DomSize();
        const QSize size = v.toSize();
        sz->setElementWidth(size.width());
        sz->setElementHeight(size.height());
        dom_prop->setElementSize(sz);
    }
        return true;

    case QVariant::SizeF: {
        DomSizeF *szf = new DomSizeF();
        const QSizeF sizef = v.toSizeF();
        szf->setElementWidth(sizef.width());
        szf->setElementHeight(sizef.height());
        dom_prop->setElementSizeF(szf);
    }
        return true;

    case QVariant::Rect: {
        DomRect *rc = new DomRect();
        const QRect rect = v.toRect();
        rc->setElementX(rect.x());
        rc->setElementY(rect.y());
        rc->setElementWidth(rect.width());
        rc->setElementHeight(rect.height());
        dom_prop->setElementRect(rc);
    }
        return true;

    case QVariant::RectF: {
        DomRectF *rcf = new DomRectF();
        const QRectF rectf = v.toRectF();
        rcf->setElementX(rectf.x());
        rcf->setElementY(rectf.y());
        rcf->setElementWidth(rectf.width());
        rcf->setElementHeight(rectf.height());
        dom_prop->setElementRectF(rcf);
    }
        return true;

    case QVariant::Font: {
        DomFont *fnt = new DomFont();
        const QFont font = qvariant_cast<QFont>(v);
        const uint mask = font.resolve();
        if (mask & QFont::WeightResolved) {
            fnt->setElementBold(font.bold());
            fnt->setElementWeight(font.weight());
        }
        if (mask & QFont::FamilyResolved)
            fnt->setElementFamily(font.family());
        if (mask & QFont::StyleResolved)
            fnt->setElementItalic(font.italic());
        if (mask & QFont::SizeResolved)
            fnt->setElementPointSize(font.pointSize());
        if (mask & QFont::StrikeOutResolved)
            fnt->setElementStrikeOut(font.strikeOut());
        if (mask & QFont::UnderlineResolved)
            fnt->setElementUnderline(font.underline());
        if (mask & QFont::KerningResolved)
            fnt->setElementKerning(font.kerning());
        if (mask & QFont::StyleStrategyResolved) {
            const QMetaEnum styleStrategy_enum = metaEnum<QAbstractFormBuilderGadget>("styleStrategy");
            fnt->setElementStyleStrategy(QLatin1String(styleStrategy_enum.valueToKey(font.styleStrategy())));
        }
        dom_prop->setElementFont(fnt);
    }
        return true;

#ifndef QT_NO_CURSOR
    case QVariant::Cursor: {
        const QMetaEnum cursorShape_enum = metaEnum<QAbstractFormBuilderGadget>("cursorShape");
        dom_prop->setElementCursorShape(QLatin1String(cursorShape_enum.valueToKey(qvariant_cast<QCursor>(v).shape())));
        }
        return true;
#endif

    case QVariant::KeySequence: {
        DomString *s = new DomString();
        s->setText(qvariant_cast<QKeySequence>(v).toString(QKeySequence::PortableText));
        dom_prop->setElementString(s);
        }
        return true;

    case QVariant::Locale: {
        DomLocale *dom = new DomLocale();
        const QLocale locale = qvariant_cast<QLocale>(v);

        const QMetaEnum language_enum = metaEnum<QAbstractFormBuilderGadget>("language");
        const QMetaEnum country_enum = metaEnum<QAbstractFormBuilderGadget>("country");

        dom->setAttributeLanguage(QLatin1String(language_enum.valueToKey(locale.language())));
        dom->setAttributeCountry(QLatin1String(country_enum.valueToKey(locale.country())));

        dom_prop->setElementLocale(dom);
        }
        return true;

    case QVariant::SizePolicy: {
        DomSizePolicy *dom = new DomSizePolicy();
        const QSizePolicy sizePolicy = qvariant_cast<QSizePolicy>(v);

        dom->setElementHorStretch(sizePolicy.horizontalStretch());
        dom->setElementVerStretch(sizePolicy.verticalStretch());

        const QMetaEnum sizeType_enum = metaEnum<QAbstractFormBuilderGadget>("sizeType");

        dom->setAttributeHSizeType(QLatin1String(sizeType_enum.valueToKey(sizePolicy.horizontalPolicy())));
        dom->setAttributeVSizeType(QLatin1String(sizeType_enum.valueToKey(sizePolicy.verticalPolicy())));

        dom_prop->setElementSizePolicy(dom);
    }
        return true;

    case QVariant::Date: {
        DomDate *dom = new DomDate();
        const QDate date = qvariant_cast<QDate>(v);

        dom->setElementYear(date.year());
        dom->setElementMonth(date.month());
        dom->setElementDay(date.day());

        dom_prop->setElementDate(dom);
        }
        return true;

    case QVariant::Time: {
        DomTime *dom = new DomTime();
        const QTime time = qvariant_cast<QTime>(v);

        dom->setElementHour(time.hour());
        dom->setElementMinute(time.minute());
        dom->setElementSecond(time.second());

        dom_prop->setElementTime(dom);
        }
        return true;

    case QVariant::DateTime: {
        DomDateTime *dom = new DomDateTime();
        const QDateTime dateTime = qvariant_cast<QDateTime>(v);

        dom->setElementHour(dateTime.time().hour());
        dom->setElementMinute(dateTime.time().minute());
        dom->setElementSecond(dateTime.time().second());
        dom->setElementYear(dateTime.date().year());
        dom->setElementMonth(dateTime.date().month());
        dom->setElementDay(dateTime.date().day());

        dom_prop->setElementDateTime(dom);
    }
        return true;

    case QVariant::Url: {
        DomUrl *dom = new DomUrl();
        const QUrl url = v.toUrl();

        DomString *str = new DomString();
        str->setText(url.toString());
        dom->setElementString(str);

        dom_prop->setElementUrl(dom);
    }
        return true;

    case QVariant::StringList: {
        DomStringList *sl = new DomStringList;
        sl->setElementString(qvariant_cast<QStringList>(v));
        dom_prop->setElementStringList(sl);
    }
        return true;

    default:
        break;
    }

    return false;
}
Exemplo n.º 28
0
/*!
  Load, parse, and process a qdoc configuration file. This
  function is only called by the other load() function, but
  this one is recursive, i.e., it calls itself when it sees
  an \c{include} statement in the qdog configuration file.
 */
void Config::load(Location location, const QString& fileName)
{
    QRegExp keySyntax("\\w+(?:\\.\\w+)*");

#define SKIP_CHAR() \
    do { \
        location.advance(c); \
        ++i; \
        c = text.at(i); \
        cc = c.unicode(); \
    } while (0)

#define SKIP_SPACES() \
    while (c.isSpace() && cc != '\n') \
        SKIP_CHAR()

#define PUT_CHAR() \
    word += c; \
    SKIP_CHAR();

    if (location.depth() > 16)
        location.fatal(tr("Too many nested includes"));

    QFile fin(fileName);
    if (!fin.open(QFile::ReadOnly | QFile::Text)) {
        fin.setFileName(fileName + ".qdoc");
        if (!fin.open(QFile::ReadOnly | QFile::Text))
            location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
    }

    QString text = fin.readAll();
    text += QLatin1String("\n\n");
    text += QChar('\0');
    fin.close();

    location.push(fileName);
    location.start();

    int i = 0;
    QChar c = text.at(0);
    uint cc = c.unicode();
    while (i < (int) text.length()) {
        if (cc == 0)
            ++i;
        else if (c.isSpace()) {
            SKIP_CHAR();
        }
        else if (cc == '#') {
            do {
                SKIP_CHAR();
            } while (cc != '\n');
        }
        else if (isMetaKeyChar(c)) {
            Location keyLoc = location;
            bool plus = false;
            QString stringValue;
            QStringList stringListValue;
            QString word;
            bool inQuote = false;
            bool prevWordQuoted = true;
            bool metWord = false;

            MetaStack stack;
            do {
                stack.process(c, location);
                SKIP_CHAR();
            } while (isMetaKeyChar(c));

            QStringList keys = stack.getExpanded(location);
            SKIP_SPACES();

            if (keys.count() == 1 && keys.first() == "include") {
                QString includeFile;

                if (cc != '(')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();
                while (!c.isSpace() && cc != '#' && cc != ')') {
                    includeFile += c;
                    SKIP_CHAR();
                }
                SKIP_SPACES();
                if (cc != ')')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();
                if (cc != '#' && cc != '\n')
                    location.fatal(tr("Trailing garbage"));

                /*
                  Here is the recursive call.
                 */
                load(location,
                      QFileInfo(QFileInfo(fileName).dir(), includeFile)
                      .filePath());
            }
            else {
                /*
                  It wasn't an include statement, so it;s something else.
                 */
                if (cc == '+') {
                    plus = true;
                    SKIP_CHAR();
                }
                if (cc != '=')
                    location.fatal(tr("Expected '=' or '+=' after key"));
                SKIP_CHAR();
                SKIP_SPACES();

                for (;;) {
                    if (cc == '\\') {
                        int metaCharPos;

                        SKIP_CHAR();
                        if (cc == '\n') {
                            SKIP_CHAR();
                        }
                        else if (cc > '0' && cc < '8') {
                            word += QChar(c.digitValue());
                            SKIP_CHAR();
                        }
                        else if ((metaCharPos = QString(QLatin1String("abfnrtv")).indexOf(c)) != -1) {
                            word += "\a\b\f\n\r\t\v"[metaCharPos];
                            SKIP_CHAR();
                        }
                        else {
                            PUT_CHAR();
                        }
                    }
                    else if (c.isSpace() || cc == '#') {
                        if (inQuote) {
                            if (cc == '\n')
                                location.fatal(tr("Unterminated string"));
                            PUT_CHAR();
                        }
                        else {
                            if (!word.isEmpty()) {
                                if (metWord)
                                    stringValue += QLatin1Char(' ');
                                stringValue += word;
                                stringListValue << word;
                                metWord = true;
                                word.clear();
                                prevWordQuoted = false;
                            }
                            if (cc == '\n' || cc == '#')
                                break;
                            SKIP_SPACES();
                        }
                    }
                    else if (cc == '"') {
                        if (inQuote) {
                            if (!prevWordQuoted)
                                stringValue += QLatin1Char(' ');
                            stringValue += word;
                            if (!word.isEmpty())
                                stringListValue << word;
                            metWord = true;
                            word.clear();
                            prevWordQuoted = true;
                        }
                        inQuote = !inQuote;
                        SKIP_CHAR();
                    }
                    else if (cc == '$') {
                        QString var;
                        SKIP_CHAR();
                        while (c.isLetterOrNumber() || cc == '_') {
                            var += c;
                            SKIP_CHAR();
                        }
                        if (!var.isEmpty()) {
                            char *val = getenv(var.toLatin1().data());
                            if (val == 0) {
                                location.fatal(tr("Environment variable '%1' undefined").arg(var));
                            }
                            else {
                                word += QString(val);
                            }
                        }
                    }
                    else {
                        if (!inQuote && cc == '=')
                            location.fatal(tr("Unexpected '='"));
                        PUT_CHAR();
                    }
                }

                QStringList::ConstIterator key = keys.begin();
                while (key != keys.end()) {
                    if (!keySyntax.exactMatch(*key))
                        keyLoc.fatal(tr("Invalid key '%1'").arg(*key));

                    if (plus) {
                        if (locMap[*key].isEmpty()) {
                            locMap[*key] = keyLoc;
                        }
                        else {
                            locMap[*key].setEtc(true);
                        }
                        if (stringValueMap[*key].isEmpty()) {
                            stringValueMap[*key] = stringValue;
                        }
                        else {
                            stringValueMap[*key] +=
                                QLatin1Char(' ') + stringValue;
                        }
                        stringListValueMap[*key] += stringListValue;
                    }
                    else {
                        locMap[*key] = keyLoc;
                        stringValueMap[*key] = stringValue;
                        stringListValueMap[*key] = stringListValue;
                    }
                    ++key;
                }
            }
        }
        else {
            location.fatal(tr("Unexpected character '%1' at beginning of line")
                            .arg(c));
        }
    }
}
Exemplo n.º 29
0
int RegExpTokenizer::lex()
{
    lexemStart = pos;
    lexemLength = 0;
    int lastAcceptingPos = -1;
    int token = -1;
    QChar ch;
    
    // initial state
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 33)
            goto state_1;
        if (ch.unicode() == 34)
            goto state_2;
        if (ch.unicode() >= 35 && ch.unicode() <= 39)
            goto state_1;
        if (ch.unicode() == 40) {
            token = RE2NFA::TOK_LPAREN;
            goto found;
        }
        if (ch.unicode() == 41) {
            token = RE2NFA::TOK_RPAREN;
            goto found;
        }
        if (ch.unicode() == 42) {
            token = RE2NFA::TOK_STAR;
            goto found;
        }
        if (ch.unicode() == 43) {
            token = RE2NFA::TOK_PLUS;
            goto found;
        }
        if (ch.unicode() == 44) {
            token = RE2NFA::TOK_COMMA;
            goto found;
        }
        if (ch.unicode() == 45)
            goto state_1;
        if (ch.unicode() == 46) {
            token = RE2NFA::TOK_DOT;
            goto found;
        }
        if (ch.unicode() >= 47 && ch.unicode() <= 62)
            goto state_1;
        if (ch.unicode() == 63) {
            token = RE2NFA::TOK_QUESTION;
            goto found;
        }
        if (ch.unicode() >= 64 && ch.unicode() <= 90)
            goto state_1;
        if (ch.unicode() == 91)
            goto state_10;
        if (ch.unicode() == 92)
            goto state_11;
        if (ch.unicode() >= 93 && ch.unicode() <= 122)
            goto state_1;
        if (ch.unicode() == 123) {
            token = RE2NFA::TOK_LBRACE;
            goto found;
        }
        if (ch.unicode() == 124) {
            token = RE2NFA::TOK_OR;
            goto found;
        }
        if (ch.unicode() == 125) {
            token = RE2NFA::TOK_RBRACE;
            goto found;
        }
        if (ch.unicode() >= 126)
            goto state_1;
        goto out;
    state_1:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_STRING;
        goto out;
    state_2:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_STRING;
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 33)
            goto state_15;
        if (ch.unicode() == 34)
            goto state_16;
        if (ch.unicode() >= 35)
            goto state_15;
        goto out;
    state_10:
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 91)
            goto state_17;
        if (ch.unicode() == 92)
            goto state_18;
        if (ch.unicode() == 93)
            goto state_19;
        if (ch.unicode() >= 94)
            goto state_17;
        goto out;
    state_11:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_STRING;
        ch = next();
        if (ch.unicode() >= 1)
            goto state_20;
        goto out;
    state_15:
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 33)
            goto state_15;
        if (ch.unicode() == 34)
            goto state_16;
        if (ch.unicode() >= 35)
            goto state_15;
        goto out;
    state_16:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_QUOTED_STRING;
        goto out;
    state_17:
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 91)
            goto state_17;
        if (ch.unicode() == 92)
            goto state_18;
        if (ch.unicode() == 93)
            goto state_19;
        if (ch.unicode() >= 94)
            goto state_17;
        goto out;
    state_18:
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 91)
            goto state_17;
        if (ch.unicode() == 92)
            goto state_18;
        if (ch.unicode() == 93)
            goto state_21;
        if (ch.unicode() >= 94)
            goto state_17;
        goto out;
    state_19:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_SEQUENCE;
        goto out;
    state_20:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_STRING;
        goto out;
    state_21:
        lastAcceptingPos = pos;
        token = RE2NFA::TOK_SEQUENCE;
        ch = next();
        if (ch.unicode() >= 1 && ch.unicode() <= 91)
            goto state_17;
        if (ch.unicode() == 92)
            goto state_18;
        if (ch.unicode() == 93)
            goto state_19;
        if (ch.unicode() >= 94)
            goto state_17;
        goto out;
    found:
    lastAcceptingPos = pos;
    
    out:
    if (lastAcceptingPos != -1) {
        lexemLength = lastAcceptingPos - lexemStart;
        pos = lastAcceptingPos;
    }
    return token;
}
Exemplo n.º 30
0
inline bool parseOutChar(const QString& txt, uint from, int *skip, Chunk **tail, bool interpretNewLine) {
  // STOP! Changes you make here should be made into cclineedit.cpp as well for completion.
  QChar c = txt[from];
  bool upper = false;
  *skip = 1;
  short x = 0;

#if DEBUG_PARSING
  qDebug() << "----- parsing " << txt;
#endif

  switch (c.unicode()) {
    EXPAND_GREEK('B', 'b', "eta",  4, 0x392)
    EXPAND_GREEK('D', 'd', "elta", 5, 0x394)
    EXPAND_GREEK('Z', 'z', "eta",  4, 0x396)
    EXPAND_GREEK('K', 'k', "appa", 5, 0x39a)
    EXPAND_GREEK('M', 'm', "u",    2, 0x39c)
    EXPAND_GREEK('X', 'x', "i",    2, 0x39e)
    EXPAND_GREEK('R', 'r', "ho",   3, 0x3a1)

    case 'a':
      x = 0x20;
    case 'A':
      if (txt.mid(from + 1).startsWith("lpha")) {
        *skip = 5;
        setNormalChar(QChar(0x391+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("pprox")) {
        *skip = 6;
        setNormalChar(QChar(0x2248), tail);
        return true;
      }
      break;


    case 'c':
      x = 0x20;
    case 'C':
      if (txt.mid(from + 1).startsWith("hi")) {
        *skip = 3;
        setNormalChar(QChar(0x3a7+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("dot")) {
        *skip = 4;
        setNormalChar(QChar(0x2219), tail);
        return true;
      }
      break;

    case 'e':
      x = 0x20;
    case 'E':
      if (txt.mid(from + 1).startsWith("psilon")) {
        *skip = 7;
        setNormalChar(QChar(0x395+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("ta")) {
        *skip = 3;
        setNormalChar(QChar(0x397+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("ll")) {
        *skip = 3;
        setNormalChar(QChar(0x2113), tail);
        return true;
      }
      break;

    case 'g':
      x = 0x20;
    case 'G':
      if (txt.mid(from + 1).startsWith("amma")) {
        *skip = 5;
        setNormalChar(QChar(0x393+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("eq")) {
        *skip = 3;
        setNormalChar(QChar(0x2265), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith('e')) {
        *skip = 2;
        setNormalChar(QChar(0x2265), tail);
        return true;
      }
      break;

    case 'i':
      x = 0x20;
    case 'I':
      if (txt.mid(from + 1).startsWith("ota")) {
        *skip = 4;
        setNormalChar(QChar(0x399+x), tail);
        return true;
      } else if (!upper && txt.mid(from + 1).startsWith("nf")) {
        *skip = 3;
        setNormalChar(QChar(0x221E), tail);
        return true;
      } else if (!upper && txt.mid(from + 1).startsWith("nt")) {
        *skip = 3;
        setNormalChar(QChar(0x222B), tail);
        return true;
      }
      break;

    case 'l':
      x = 0x20;
    case 'L':
      if (txt.mid(from + 1).startsWith("ambda")) {
        *skip = 6;
        setNormalChar(QChar(0x39b+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("eq")) {
        *skip = 3;
        setNormalChar(QChar(0x2264), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith('e')) {
        *skip = 2;
        setNormalChar(QChar(0x2264), tail);
        return true;
      }
      break;

    case 'n':
      x = 0x20;
    case 'N':
      if (txt.mid(from + 1).startsWith('u')) {
        *skip = 2;
        setNormalChar(QChar(0x39D+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith('e')) {
        *skip = 2;
        setNormalChar(QChar(0x2260), tail);
        return true;
      } else if (interpretNewLine) {
        *skip = 1;
        if (!*tail || !(*tail)->text.isEmpty() || (*tail)->locked()) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        (*tail)->linebreak = true;
        *tail = new Chunk(*tail, Chunk::None, false, true);
        return true;
      } else {
        *skip = 1;
        setNormalChar(QChar(0x20), tail);  
        return true;      
      }
      break;

    case 'o':
      x = 0x20;
    case 'O':
      if (txt.mid(from + 1).startsWith("verline{")) {
        if ((*tail)->group) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        Chunk *working = new Chunk(*tail, Chunk::None, true, true);
        dumpattr(working, "start group for overline");
        uint parseStart = from + 9;
        working->attributes.overline = true;
        parseInternal(working, txt, parseStart, txt.length(), interpretNewLine);
        *skip = parseStart - from + 1;
        dumpattr(working, "end group for overline");
        return true;
      } else if (txt.mid(from + 1).startsWith("micron")) {
        *skip = 7;
        setNormalChar(QChar(0x39F+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("mega")) {
        *skip = 5;
        setNormalChar(QChar(0x3A9+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("dot")) {
        *skip = 4;
        setNormalChar(QChar(0x2299), tail);
        return true;
      }
      break;

    case 'p':
      x = 0x20;
    case 'P':
      if (txt.mid(from + 1).startsWith('i')) {
        *skip = 2;
        setNormalChar(QChar(0x3a0+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("hi")) {
        *skip = 3;
        setNormalChar(QChar(0x3A6+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("si")) {
        *skip = 3;
        setNormalChar(QChar(0x3A8+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("artial")) {
        *skip = 7;
        setNormalChar(QChar(0x2202), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("rod")) {
        *skip = 4;
        setNormalChar(QChar(0x220F), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith('m')) {
        *skip = 2;
        setNormalChar(QChar(0xb1), tail);
        return true;
      }
      break;

    case 't':
      x = 0x20;
    case 'T':
      if (txt.mid(from + 1).startsWith("extcolor{")) { // \textcolor{color}{text}
        if ((*tail)->group) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        Chunk *working = new Chunk(*tail, Chunk::None, true, true);
        dumpattr(working, "start group for textcolor");
        uint parseStart = from + 10;
        int firstSkip = 0;
        working->attributes.color = parseColor(txt.mid(parseStart), &firstSkip);
        if (!working->attributes.color.isValid() || txt[parseStart + firstSkip + 1] != '{') {
          return false;
        }
        parseStart += firstSkip + 2;
        parseInternal(working, txt, parseStart, txt.length(), interpretNewLine);
        *skip = parseStart - from + 1;
        dumpattr(working, "end group for textcolor");
        return true;
      } else if (txt.mid(from + 1).startsWith("extbf{")) {
        if ((*tail)->group) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        Chunk *working = new Chunk(*tail, Chunk::None, true, true);
        dumpattr(working, "start group for textbf");
        uint parseStart = from + 7;
        working->attributes.bold = true;
        parseInternal(working, txt, parseStart, txt.length(), interpretNewLine);
        *skip = parseStart - from + 1;
        dumpattr(working, "end group for textbf");
        return true;
      } else if (txt.mid(from + 1).startsWith("extit{")) {
        if ((*tail)->group) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        Chunk *working = new Chunk(*tail, Chunk::None, true, true);
        dumpattr(working, "start group for textit");
        uint parseStart = from + 7;
        working->attributes.italic = true;
        parseInternal(working, txt, parseStart, txt.length(), interpretNewLine);
        *skip = parseStart - from + 1;
        dumpattr(working, "end group for textit");
        return true;
      } else if (txt.mid(from + 1).startsWith("heta")) {
        *skip = 5;
        setNormalChar(QChar(0x398+x), tail);
        return true;
      } else if (txt.mid(from + 1).startsWith("au")) {
        *skip = 3;
        setNormalChar(QChar(0x3A4+x), tail);
        return true;
      } else {
        *skip = 1;
        if (!*tail || !(*tail)->text.isEmpty() || (*tail)->locked()) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        (*tail)->tab = true;
        *tail = new Chunk(*tail, Chunk::None, false, true);
        return true;
      }
      break;

    case 's':
      x = 0x20;
    case 'S':
      if (txt.mid(from + 1).startsWith("igma")) {
        *skip = 5;
        setNormalChar(QChar(0x3A3+x), tail);
        return true;
      } else if (!upper && txt.mid(from + 1).startsWith("um")) {
        *skip = 3;
        setNormalChar(QChar(0x2211), tail);
        return true;
      } else if (!upper && txt.mid(from + 1).startsWith("qrt")) {
        *skip = 4;
        setNormalChar(QChar(0x221A), tail);
        return true;
      }
      break;

    case 'u':
      x = 0x20;
    case 'U':
      if (txt.mid(from + 1).startsWith("nderline{")) {
        if ((*tail)->group) {
          *tail = new Chunk(*tail, Chunk::None, false, true);
        }
        Chunk *working = new Chunk(*tail, Chunk::None, true, true);
        dumpattr(working, "start group for underline");
        uint parseStart = from + 10;
        working->attributes.underline = true;
        parseInternal(working, txt, parseStart, txt.length(), interpretNewLine);
        *skip = parseStart - from + 1;
        dumpattr(working, "end group for underline");
        return true;
      } else if (txt.mid(from + 1).startsWith("psilon")) {
        *skip = 7;
        setNormalChar(QChar(0x3A5+x), tail);
        return true;
      }
      break;

    default:
      break;
  }

  return false;
}