nativeimportbase.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "nativeimportbase.h"
00014
00015
00016 #include <qfile.h>
00017 #include <qtextstream.h>
00018 #include <qregexp.h>
00019 #include <klocale.h>
00020 #include <kdebug.h>
00021
00022 #include "import_utils.h"
00023
00024 NativeImportBase::NativeImportBase(const QString &singleLineCommentIntro) {
00025 m_singleLineCommentIntro = singleLineCommentIntro;
00026 m_srcIndex = 0;
00027 m_scopeIndex = 0;
00028 m_klass = NULL;
00029 m_currentAccess = Uml::Visibility::Public;
00030 m_isAbstract = false;
00031 m_inComment = false;
00032 }
00033
00034 NativeImportBase::~NativeImportBase() {
00035 }
00036
00037 void NativeImportBase::setMultiLineComment(const QString &intro, const QString &end) {
00038 m_multiLineCommentIntro = intro;
00039 m_multiLineCommentEnd = end;
00040 }
00041
00042 void NativeImportBase::setMultiLineAltComment(const QString &intro, const QString &end) {
00043 m_multiLineAltCommentIntro = intro;
00044 m_multiLineAltCommentEnd = end;
00045 }
00046
00047 void NativeImportBase::skipStmt(QString until ) {
00048 const uint srcLength = m_source.count();
00049 while (m_srcIndex < srcLength && m_source[m_srcIndex] != until)
00050 m_srcIndex++;
00051 }
00052
00053 bool NativeImportBase::skipToClosing(QChar opener) {
00054 QString closing;
00055 switch (opener) {
00056 case '{':
00057 closing = "}";
00058 break;
00059 case '[':
00060 closing = "]";
00061 break;
00062 case '(':
00063 closing = ")";
00064 break;
00065 case '<':
00066 closing = ">";
00067 break;
00068 default:
00069 kError() << "NativeImportBase::skipToClosing(" << opener
00070 << "): " << "illegal input character" << endl;
00071 return false;
00072 }
00073 const QString opening(opener);
00074 skipStmt(opening);
00075 const uint srcLength = m_source.count();
00076 int nesting = 0;
00077 while (m_srcIndex < srcLength) {
00078 QString nextToken = advance();
00079 if (nextToken.isEmpty())
00080 break;
00081 if (nextToken == closing) {
00082 if (nesting <= 0)
00083 break;
00084 nesting--;
00085 } else if (nextToken == opening) {
00086 nesting++;
00087 }
00088 }
00089 if (m_srcIndex == srcLength)
00090 return false;
00091 return true;
00092 }
00093
00094 QString NativeImportBase::advance() {
00095 while (m_srcIndex < m_source.count() - 1) {
00096 if (m_source[++m_srcIndex].startsWith(m_singleLineCommentIntro))
00097 m_comment += m_source[m_srcIndex];
00098 else
00099 break;
00100 }
00101 if (m_srcIndex >= m_source.count() - 1 ||
00102
00103 (m_srcIndex == m_source.count() - 1 &&
00104 m_source[m_srcIndex].startsWith(m_singleLineCommentIntro))) {
00105 return QString();
00106 }
00107 return m_source[m_srcIndex];
00108 }
00109
00110 bool NativeImportBase::preprocess(QString& line) {
00111 if (m_multiLineCommentIntro.isEmpty())
00112 return false;
00113
00114 if (m_inComment) {
00115 int delimiterLen = 0;
00116 int pos = line.find(m_multiLineCommentEnd);
00117 if (pos == -1) {
00118 if (! m_multiLineAltCommentEnd.isEmpty())
00119 pos = line.find(m_multiLineAltCommentEnd);
00120 if (pos == -1) {
00121 m_comment += line + "\n";
00122 return true;
00123 }
00124 delimiterLen = m_multiLineAltCommentEnd.length();
00125 } else {
00126 delimiterLen = m_multiLineCommentEnd.length();
00127 }
00128 if (pos > 0) {
00129 QString text = line.mid(0, pos - 1);
00130 m_comment += text.stripWhiteSpace();
00131 }
00132 m_source.append(m_singleLineCommentIntro + m_comment);
00133 m_srcIndex++;
00134 m_comment = "";
00135 m_inComment = false;
00136 pos += delimiterLen;
00137 if (pos == (int)line.length())
00138 return true;
00139 line = line.mid(pos);
00140 }
00141
00142
00143 int delimIntroLen = 0;
00144 int delimEndLen = 0;
00145 int pos = line.find(m_multiLineCommentIntro);
00146 if (pos != -1) {
00147 delimIntroLen = m_multiLineCommentIntro.length();
00148 } else if (!m_multiLineAltCommentIntro.isEmpty()) {
00149 pos = line.find(m_multiLineAltCommentIntro);
00150 if (pos != -1)
00151 delimIntroLen = m_multiLineAltCommentIntro.length();
00152 }
00153 if (pos != -1) {
00154 int endpos = line.find(m_multiLineCommentEnd);
00155 if (endpos != -1) {
00156 delimEndLen = m_multiLineCommentEnd.length();
00157 } else if (!m_multiLineAltCommentEnd.isEmpty()) {
00158 endpos = line.find(m_multiLineAltCommentEnd);
00159 if (endpos != -1)
00160 delimEndLen = m_multiLineAltCommentEnd.length();
00161 }
00162 if (endpos == -1) {
00163 m_inComment = true;
00164 if (pos + delimIntroLen < (int)line.length()) {
00165 QString cmnt = line.mid(pos + delimIntroLen);
00166 m_comment += cmnt.stripWhiteSpace() + "\n";
00167 }
00168 if (pos == 0)
00169 return true;
00170 line = line.left(pos);
00171 } else {
00172 if (endpos > pos + delimIntroLen) {
00173 QString cmnt = line.mid(pos + delimIntroLen, endpos - pos - delimIntroLen);
00174 cmnt = cmnt.stripWhiteSpace();
00175 if (!cmnt.isEmpty())
00176 m_source.append(m_singleLineCommentIntro + cmnt);
00177 }
00178 endpos++;
00179 QString pre;
00180 if (pos > 0)
00181 pre = line.left(pos);
00182 QString post;
00183 if (endpos + delimEndLen < (int)line.length())
00184 post = line.mid(endpos + 1);
00185 line = pre + post;
00186 }
00187 }
00188 return false;
00189 }
00190
00193 QStringList NativeImportBase::split(const QString& lin) {
00194 QStringList list;
00195 QString listElement;
00196 QChar stringIntro = 0;
00197 bool seenSpace = false;
00198 QString line = lin.stripWhiteSpace();
00199 for (uint i = 0; i < line.length(); i++) {
00200 const QChar& c = line[i];
00201 if (stringIntro) {
00202 listElement += c;
00203 if (c == stringIntro) {
00204 if (line[i - 1] != '\\') {
00205 list.append(listElement);
00206 listElement = QString();
00207 stringIntro = 0;
00208 }
00209 }
00210 } else if (c == '"' || c == '\'') {
00211 if (!listElement.isEmpty()) {
00212 list.append(listElement);
00213 }
00214 listElement = stringIntro = c;
00215 seenSpace = false;
00216 } else if (c == ' ' || c == '\t') {
00217 if (seenSpace)
00218 continue;
00219 seenSpace = true;
00220 if (!listElement.isEmpty()) {
00221 list.append(listElement);
00222 listElement = QString();
00223 }
00224 } else {
00225 listElement += c;
00226 seenSpace = false;
00227 }
00228 }
00229 if (!listElement.isEmpty())
00230 list.append(listElement);
00231 return list;
00232 }
00233
00236 void NativeImportBase::scan(QString line) {
00237 if (preprocess(line))
00238 return;
00239
00240 int pos = line.find(m_singleLineCommentIntro);
00241 if (pos != -1) {
00242 QString cmnt = line.mid(pos);
00243 m_source.append(cmnt);
00244 if (pos == 0)
00245 return;
00246 line = line.left(pos);
00247 }
00248 if (line.contains(QRegExp("^\\s*$")))
00249 return;
00250 QStringList words = split(line);
00251 for (QStringList::Iterator it = words.begin(); it != words.end(); ++it) {
00252 QString word = *it;
00253 if (word[0] == '"' || word[0] == '\'')
00254 m_source.append(word);
00255 else
00256 fillSource(word);
00257 }
00258 }
00259
00260 void NativeImportBase::initVars() {
00261 }
00262
00263 void NativeImportBase::parseFile(const QString& filename) {
00264 QString nameWithoutPath = filename;
00265 nameWithoutPath.remove(QRegExp("^.*/"));
00266 if (m_parsedFiles.contains(nameWithoutPath))
00267 return;
00268 m_parsedFiles.append(nameWithoutPath);
00269 QString fname = filename;
00270 const QString msgPrefix = "NativeImportBase::parseFile(" + filename + "): ";
00271 if (filename.contains('/')) {
00272 QString path = filename;
00273 path.remove( QRegExp("/[^/]+$") );
00274 kDebug() << msgPrefix << "adding path " << path << endl;
00275 Import_Utils::addIncludePath(path);
00276 }
00277 if (! QFile::exists(filename)) {
00278 if (filename.startsWith("/")) {
00279 kError() << msgPrefix << "cannot find file" << endl;
00280 return;
00281 }
00282 bool found = false;
00283 QStringList includePaths = Import_Utils::includePathList();
00284 for (QStringList::Iterator pathIt = includePaths.begin();
00285 pathIt != includePaths.end(); ++pathIt) {
00286 QString path = (*pathIt);
00287 if (! path.endsWith("/")) {
00288 path.append("/");
00289 }
00290 if (QFile::exists(path + filename)) {
00291 fname.prepend(path);
00292 found = true;
00293 break;
00294 }
00295 }
00296 if (! found) {
00297 kError() << msgPrefix << "cannot find file" << endl;
00298 return;
00299 }
00300 }
00301 QFile file(fname);
00302 if (! file.open(IO_ReadOnly)) {
00303 kError() << msgPrefix << "cannot open file" << endl;
00304 return;
00305 }
00306 kDebug() << msgPrefix << "parsing." << endl;
00307
00308 m_source.clear();
00309 m_srcIndex = 0;
00310 initVars();
00311 QTextStream stream(&file);
00312 while (! stream.atEnd()) {
00313 QString line = stream.readLine();
00314 scan(line);
00315 }
00316 file.close();
00317
00318 m_klass = NULL;
00319 m_currentAccess = Uml::Visibility::Public;
00320 m_scopeIndex = 0;
00321 m_scope[0] = NULL;
00322 const uint srcLength = m_source.count();
00323 for (m_srcIndex = 0; m_srcIndex < srcLength; m_srcIndex++) {
00324 const QString& firstToken = m_source[m_srcIndex];
00325
00326 if (firstToken.startsWith(m_singleLineCommentIntro)) {
00327 m_comment = firstToken.mid(m_singleLineCommentIntro.length());
00328 continue;
00329 }
00330 if (! parseStmt())
00331 skipStmt();
00332 m_comment = QString();
00333 }
00334 kDebug() << msgPrefix << "end of parse." << endl;
00335 }
00336
00337 void NativeImportBase::initialize() {
00338 m_parsedFiles.clear();
00339 }
00340
This file is part of the documentation for umbrello Version 3.1.0.