/***** * * TOra - An Oracle Toolkit for DBA's and developers * Copyright (C) 2003-2005 Quest Software, Inc * Portions Copyright (C) 2005 Other Contributors * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; only version 2 of * the License is valid for this program. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception, you have permission to link this program * with the Oracle Client libraries and distribute executables, as long * as you follow the requirements of the GNU GPL in regard to all of the * software in the executable aside from Oracle client libraries. * * Specifically you are not permitted to link this program with the * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. * And you are not permitted to distribute binaries compiled against * these libraries without written consent from Quest Software, Inc. * Observe that this does not disallow linking to the Qt Free Edition. * * You may link this product with any GPL'd Qt library such as Qt/Free * * All trademarks belong to their respective owners. * *****/ #include "toconf.h" #include "tomain.h" #include "tohtml.h" #include #include #include #include toHtml::toHtml(const QCString &data) { Length = strlen(data); Data = new char[Length + 1]; strcpy(Data, data); Position = 0; LastChar = 0; } toHtml::~toHtml() { delete[] Data; } void toHtml::skipSpace(void) { if (Position >= Length) return ; char c = LastChar; if (!c) c = Data[Position]; if (isspace(c)) { Position++; LastChar = 0; while (Position < Length && isspace(Data[Position])) Position++; } } bool toHtml::eof(void) { if (Position > Length) throw qApp->translate("toHtml", "Invalidly went beyond end of file"); return Position == Length; } void toHtml::nextToken(void) { if (eof()) throw qApp->translate("toHtml", "Reading HTML after eof"); QualifierNum = 0; char c = LastChar; if (!c) c = Data[Position]; if (c == '<') { IsTag = true; Position++; LastChar = 0; skipSpace(); if (Position >= Length) throw qApp->translate("toHtml", "Lone < at end"); if (Data[Position] != '/') { Open = true; } else { Open = false; Position++; } skipSpace(); { size_t start = Position; while (Position < Length && !isspace(Data[Position]) && Data[Position] != '>') { Data[Position] = tolower(Data[Position]); Position++; } Tag = mid(start, Position - start); } for (;;) { skipSpace(); if (Position >= Length) throw qApp->translate("toHtml", "Unended tag at end"); c = LastChar; if (!c) c = Data[Position]; if (c == '>') { LastChar = 0; Position++; break; } // Must always be an empty char here, so LastChar not needed to be checked. { size_t start = Position; while (Position < Length && !isspace(Data[Position]) && Data[Position] != '=' && Data[Position] != '>') { Data[Position] = tolower(Data[Position]); Position++; } Qualifiers[QualifierNum].Name = mid(start, Position - start); } skipSpace(); if (Position >= Length) throw qApp->translate("toHtml", "Unended tag qualifier at end"); c = LastChar; if (!c) c = Data[Position]; if (c == '=') { LastChar = 0; Position++; skipSpace(); if (Position >= Length) throw qApp->translate("toHtml", "Unended tag qualifier data at end"); c = Data[Position]; if (c == '\'' || c == '\"') { Position++; size_t start = Position; while (Data[Position] != c) { Position++; if (Position >= Length) throw qApp->translate("toHtml", "Unended quoted string at end"); } Qualifiers[QualifierNum].Value = mid(start, Position - start); Position++; LastChar = 0; } else { size_t start = Position; while (!isspace(Data[Position]) && Data[Position] != '>') { Position++; if (Position >= Length) throw qApp->translate("toHtml", "Unended qualifier data at end"); } Qualifiers[QualifierNum].Value = mid(start, Position - start); } } QualifierNum++; if (QualifierNum >= TO_HTML_MAX_QUAL) throw qApp->translate("toHtml", "Exceded qualifier max in toHtml"); } } else { IsTag = false; size_t start = Position; Position++; LastChar = 0; while (Position < Length) { if (Data[Position] == '<') break; Position++; } Text = mid(start, Position - start); } } const char *toHtml::value(const QCString &q) { for (int i = 0;i < QualifierNum;i++) { if (q == Qualifiers[i].Name) return Qualifiers[i].Value; } return NULL; } QCString toHtml::text() { QCString ret; for (const char *cur = Text;*cur;cur++) { char c = *cur; if (c == '&') { const char *start = cur + 1; while (*cur && *cur != ';') cur++; QCString tmp(start, cur - start); if (tmp[0] == '#') { tmp = tmp.right(tmp.length() - 1); ret += char(tmp.toInt()); } else if (tmp == "auml") ret += "å"; // The rest of the & codes... } else ret += c; } return ret; } const char *toHtml::mid(size_t start, size_t size) { if (size == 0) return ""; if (start >= Length) throw qApp->translate("toHtml", "Tried to access string out of bounds in mid (start=%1)").arg(start); if (size > Length) throw qApp->translate("toHtml", "Tried to access string out of bounds in mid (size=%1)").arg(size); if (start + size > Length) throw qApp->translate("toHtml", "Tried to access string out of bounds in mid (total=%1+%2>%3)"). arg(start). arg(size). arg(Length); LastChar = Data[start + size]; Data[start + size] = 0; return Data + start; } bool toHtml::search(const QCString &all, const QString &str) { QCString data(str.lower().latin1()); enum { beginning, inTag, inString, inWord } lastState = beginning, state = beginning; unsigned int pos = 0; char endString = 0; for (size_t i = 0;i < all.length();i++) { char c = tolower(all.at(i)); if (c == '\'' || c == '\"') { endString = c; state = inString; } else if (c == '<') { state = inTag; } else { switch (state) { case inString: if (c == endString) state = lastState; break; case beginning: if (data.at(pos) != c) { pos = 0; state = inWord; } else { pos++; if (pos >= data.length()) { if (i + 1 >= all.length() || !isalnum(all.at(i + 1))) return true; pos = 0; } break; } // Intentionally no break here case inWord: if (!isalnum(c)) state = beginning; break; case inTag: if (c == '>') state = beginning; break; } } } return false; } QString toHtml::escape(const QString &html) { QString ret = html; static QRegExp amp(QString::fromLatin1("\\&")); static QRegExp lt(QString::fromLatin1("\\<")); static QRegExp gt(QString::fromLatin1("\\>")); #if 0 ret.replace(amp, "&"); ret.replace(lt, "<"); ret.replace(gt, ">"); #endif return ret; }