summaryrefslogtreecommitdiffstats
path: root/library/msgcat
Commit message (Expand)AuthorAgeFilesLines
* * doc/ParseCmd.3, doc/Tcl.n, doc/eval.n, doc/exec.n:hobbs2006-11-031-5/+5
* * library/msgcat/msgcat.tcl: Removed some unneeded [uplevel]s.dgp2006-09-111-5/+4
* * library/msgcat/msgcat.tcl: Bump to version msgcat 1.4.2 to accountdgp2006-09-102-3/+3
* * library/msgcat/msgcat.tcl (msgcat::Init): on Darwin, add fallback ofdas2006-09-101-127/+140
* * library/msgcat/msgcat.tcl: Added checks to prevent [mclocale]dgp2004-08-131-2/+7
* * doc/msgcat.n: Clarified message catalog file encodings. [Bug 811457]dgp2004-03-311-7/+15
* * library/msgcat/msgcat.tcl: Updated internals to make use ofdgp2004-03-312-36/+53
* update msgcat version to 1.4dgp2003-10-211-1/+1
* TIP #156: Language-Neutral Root Locale for MsgcatKevin B Kenny2003-10-211-2/+6
* * library/msgcat/msgcat.tcl: Added escape so that non-Windowsdgp2003-08-062-5/+12
* * README: Bumped version number to 8.4b3 to distinguishdgp2002-08-201-1/+3
* Fix a comment that was causing problems for programs (like "mktclapp") thatdrh2002-07-171-3/+3
* * More Windows Registry locale codes from Bruno Haible.dgp2002-06-171-15/+127
* * Revised locale initialization to interpretdgp2002-06-172-81/+112
* * [mcmax] wasn't using the caller'sdgp2002-04-201-21/+29
* * Added [mcload] to the export listdgp2002-04-192-4/+5
* Added checks for package dependencies.dgp2001-08-092-3/+5
* 2000-12-10 Don Porter <dgp@users.sourceforge.net>dgp2000-12-112-8/+8
* * library/msgcat1.0/pkgIndex.tcl: Bumped version number to 1.2ericm2000-08-112-3/+3
* * library/msgcat1.0/msgcat.tcl: Removed erroneous [package forget]ericm2000-08-101-2/+1
* * library/msgcat1.0/msgcat.tcl:ericm2000-07-171-4/+84
* * tests/msgcat.test:ericm2000-07-061-4/+11
* * doc/msgcat.n: Doc's for mcmax function.ericm2000-06-301-4/+26
* * msgcat.n: Added docs for new behavior from patch in [Bug: 4158].ericm2000-04-111-7/+25
* 1999-08-18 Jeff Hobbs <hobbs@scriptics.com>hobbs1999-08-191-4/+3
* merged tcl 8.1 branch back into the main trunkstanton1999-04-162-0/+178
>; QList<InputType> keys = transitions.keys(); qSort(keys); int i = 0; Generator::TransitionSequence sequence; sequence.first = keys.at(0); ++i; for (; i < keys.count(); ++i) { if (adjacentKeys(keys.at(i - 1), keys.at(i)) && transitions.value(keys.at(i)) == transitions.value(keys.at(i - 1))) { continue; } sequence.last = keys.at(i - 1); sequence.transition = transitions.value(sequence.last); sequences.append(sequence); sequence.first = keys.at(i); } sequence.last = keys.at(i - 1); sequence.transition = transitions.value(sequence.last); sequences.append(sequence); return sequences; } QDebug &operator<<(QDebug &debug, const Generator::TransitionSequence &seq) { return debug << "[first:" << seq.first << "; last:" << seq.last << "; transition:" << seq.transition << (seq.testFunction.isEmpty() ? QString() : QString(QString("; testfunction:" + seq.testFunction))) << "]"; } bool Generator::isSingleReferencedFinalState(int i) const { return backReferenceMap.value(i) == 1 && dfa.at(i).transitions.isEmpty() && !dfa.at(i).symbol.isEmpty(); } void Generator::generateTransitions(CodeBlock &body, const TransitionMap &transitions) { if (transitions.isEmpty()) return; QVector<TransitionSequence> sequences = convertToSequences(transitions); bool needsCharFunction = false; if (!charFunctionRanges.isEmpty()) { int i = 0; while (i < sequences.count()) { const TransitionSequence &seq = sequences.at(i); if (!seq.testFunction.isEmpty()) { ++i; continue; } foreach (TransitionSequence range, charFunctionRanges) if (range.first >= seq.first && range.last <= seq.last) { needsCharFunction = true; TransitionSequence left, middle, right; left.first = seq.first; left.last = range.first - 1; left.transition = seq.transition; middle = range; middle.transition = seq.transition; right.first = range.last + 1; right.last = seq.last; right.transition = seq.transition; sequences.remove(i); if (left.last >= left.first) { sequences.insert(i, left); ++i; } sequences.insert(i, middle); ++i; if (right.last >= right.first) { sequences.insert(i, right); ++i; } i = -1; break; } ++i; } } //qDebug() << "sequence count" << sequences.count(); //qDebug() << sequences; if (sequences.count() < 10 || sequences.last().last == maxInput || needsCharFunction) { foreach (TransitionSequence seq, sequences) { const bool embedFinalState = isSingleReferencedFinalState(seq.transition); QString brace; if (embedFinalState) brace = " {"; if (!seq.testFunction.isEmpty()) { body << "if (" << seq.testFunction << ")" << brace; } else if (seq.first == seq.last) { body << "if (ch.unicode() == " << seq.first << ")" << brace; } else { if (seq.last < maxInput) body << "if (ch.unicode() >= " << seq.first << " && ch.unicode() <= " << seq.last << ")" << brace; else body << "if (ch.unicode() >= " << seq.first << ")" << brace; } body.indent(); if (embedFinalState) { body << "token = " << dfa.at(seq.transition).symbol << ";"; body << "goto found;"; body.outdent(); body << "}"; } else { body << "goto state_" << seq.transition << ";"; body.outdent(); } } } else { QList<InputType> keys = transitions.keys(); qSort(keys); body << "switch (ch.unicode()) {"; body.indent(); for (int k = 0; k < keys.count(); ++k) { const InputType key = keys.at(k); const int trans = transitions.value(key); QString keyStr; if (key == '\\') keyStr = QString("\'\\\\\'"); else if (key >= 48 && key < 127) keyStr = QString('\'') + QChar::fromLatin1(char(key)) + QChar('\''); else keyStr = QString::number(key); if (k < keys.count() - 1 && transitions.value(keys.at(k + 1)) == trans) { body << "case " << keyStr << ":"; } else { if (isSingleReferencedFinalState(trans)) { body << "case " << keyStr << ": token = " << dfa.at(trans).symbol << "; goto found;"; } else { body << "case " << keyStr << ": goto state_" << trans << ";"; } } } body.outdent(); body << "}"; } } QString Generator::generate() { Class klass(cfg.className); klass.addMember(Class::PublicMember, "QString input"); klass.addMember(Class::PublicMember, "int pos"); klass.addMember(Class::PublicMember, "int lexemStart"); klass.addMember(Class::PublicMember, "int lexemLength"); { CodeBlock body; body << "input = inp;"; body << "pos = 0;"; body << "lexemStart = 0;"; body << "lexemLength = 0;"; klass.addConstructor(Class::PublicMember, body, "const QString &inp"); } { Function next("QChar", "next()"); next.setInline(true); if (cfg.caseSensitivity == Qt::CaseSensitive) next.addBody("return (pos < input.length()) ? input.at(pos++) : QChar();"); else next.addBody("return (pos < input.length()) ? input.at(pos++).toLower() : QChar();"); klass.addMember(Class::PublicMember, next); } /* { Function lexem("QString", "lexem()"); lexem.setConst(true); lexem.setInline(true); lexem.addBody("return input.mid(lexemStart, lexemLength);"); klass.addMember(Class::PublicMember, lexem); } */ for (int i = 0; i < dfa.count(); ++i) if (dfa.at(i).symbol.endsWith(QLatin1String("()"))) { Function handlerFunc("int", dfa.at(i).symbol); klass.addMember(Class::PublicMember, handlerFunc); } Function lexFunc; lexFunc.setReturnType("int"); lexFunc.setName("lex()"); CodeBlock body; body << "lexemStart = pos;"; body << "lexemLength = 0;"; body << "int lastAcceptingPos = -1;"; body << "int token = -1;"; body << "QChar ch;"; body.addNewLine(); backReferenceMap.clear(); foreach (State s, dfa) foreach (int state, s.transitions) backReferenceMap[state]++; bool haveSingleReferencedFinalState = false; for (int i = 0; i < dfa.count(); ++i) { if (isSingleReferencedFinalState(i)) { haveSingleReferencedFinalState = true; continue; } if (i > 0) body << "state_" << i << ":"; else body << "// initial state"; body.indent(); if (!dfa.at(i).symbol.isEmpty()) { body << "lastAcceptingPos = pos;"; body << "token = " << dfa.at(i).symbol << ";"; } body.outdent(); body.indent(); if (!dfa.at(i).transitions.isEmpty()) { body << "ch = next();"; generateTransitions(body, dfa.at(i).transitions); } body << "goto out;"; body.outdent(); } if (haveSingleReferencedFinalState) { body << "found:"; body << "lastAcceptingPos = pos;"; body.addNewLine(); } body << "out:"; body << "if (lastAcceptingPos != -1) {"; body.indent(); body << "lexemLength = lastAcceptingPos - lexemStart;"; body << "pos = lastAcceptingPos;"; body.outdent(); body << "}"; body << "return token;"; lexFunc.addBody(body); klass.addMember(Class::PublicMember, lexFunc); QString header; QFile headerFile(headerFileName); if (!headerFileName.isEmpty() && headerFile.exists() && headerFile.open(QIODevice::ReadOnly)) { header = QString::fromUtf8(headerFile.readAll()); } header += QLatin1String("// auto generated. DO NOT EDIT.\n"); return header + klass.declaration() + klass.definition(); }