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; }
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; }
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; } }
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; }
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; }
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; }
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())); }
/* 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; }
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 }
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; }
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(); } }
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; }
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() ); }
// 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; } }
bool Text::isLdc(const QChar& c) const { return (c.unicode()>=begin && c.unicode()<=end); }
// 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)); }
/*! 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; }
static inline QChar convertHex(QChar c1, QChar c2) { return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode())); }
/*! 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()); }
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; }
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 == '_'; }
// force encoding of '>'. this function is needed for XMPP-Core, which // requires the '>' character to be encoded as ">" 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 += ">"; } 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; }
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; }
/* 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; }
static inline bool isValidNumber(const QChar &c) { register ushort u = c.unicode(); return (u >= '0' && u <= '9'); }
// 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; }
/*! 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)); } } }
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; }
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; }