diff options
Diffstat (limited to 'qmake/generators/makefiledeps.cpp')
-rw-r--r-- | qmake/generators/makefiledeps.cpp | 564 |
1 files changed, 362 insertions, 202 deletions
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp index 79e017a560..047d17f18a 100644 --- a/qmake/generators/makefiledeps.cpp +++ b/qmake/generators/makefiledeps.cpp @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE +// FIXME: a line ending in CRLF gets counted as two lines. #if 1 #define qmake_endOfLine(c) (c == '\r' || c == '\n') #else @@ -387,6 +388,121 @@ QFileInfo QMakeSourceFileInfo::findFileInfo(const QMakeLocalFileName &dep) return QFileInfo(dep.real()); } +static int skipEscapedLineEnds(const char *buffer, int buffer_len, int offset, int *lines) +{ + // Join physical lines to make logical lines, as in the C preprocessor + while (offset + 1 < buffer_len + && buffer[offset] == '\\' + && qmake_endOfLine(buffer[offset + 1])) { + offset += 2; + ++*lines; + if (offset < buffer_len + && buffer[offset - 1] == '\r' + && buffer[offset] == '\n') // CRLF + offset++; + } + return offset; +} + +static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start, + const char *needle, int needle_len, + int *matchlen, int *lines) +{ + int x = start; + for (int n = 0; n < needle_len && x < buffer_len; + n++, x = skipEscapedLineEnds(buffer, buffer_len, x + 1, lines)) { + if (buffer[x] != needle[n]) + return false; + } + // That also skipped any remaining BSNLs immediately after the match. + + // Tell caller how long the match was: + *matchlen = x - start; + + return true; +} + +/* Advance from an opening quote at buffer[offset] to the matching close quote. */ +static int scanPastString(char *buffer, int buffer_len, int offset, int *lines) +{ + // It might be a C++11 raw string. + bool israw = false; + if (buffer[offset] == '"' && offset > 0) { + int explore = offset - 1; + while (explore > 0 && buffer[explore] != 'R') { + if (buffer[explore] == '8' || buffer[explore] == 'u' || buffer[explore] == 'U') { + explore--; + } else if (explore > 1 && qmake_endOfLine(buffer[explore]) + && buffer[explore - 1] == '\\') { + explore -= 2; + } else if (explore > 2 && buffer[explore] == '\n' + && buffer[explore - 1] == '\r' + && buffer[explore - 2] == '\\') { + explore -= 3; + } else { + break; + } + } + israw = (buffer[explore] == 'R'); + } + + if (israw) { +#define SKIP_BSNL(pos) skipEscapedLineEnds(buffer, buffer_len, (pos), lines) + + offset = SKIP_BSNL(offset + 1); + const char *const delim = buffer + offset; + int clean = offset; + while (offset < buffer_len && buffer[offset] != '(') { + if (clean < offset) + buffer[clean++] = buffer[offset]; + else + clean++; + + offset = SKIP_BSNL(offset + 1); + } + /* + Not checking correctness (trust real compiler to do that): + - no controls, spaces, '(', ')', '\\' or (presumably) '"' in delim; + - at most 16 bytes in delim + + Raw strings are surely defined after phase 2, when BSNLs are resolved; + so the delimiter's exclusion of '\\' and space (including newlines) + applies too late to save us the need to cope with BSNLs in it. + */ + + const int delimlen = buffer + clean - delim; + int matchlen = delimlen, extralines = 0; + while ((offset = SKIP_BSNL(offset + 1)) < buffer_len + && (buffer[offset] != ')' + || (delimlen > 0 && + !matchWhileUnsplitting(buffer, buffer_len, + offset + 1, delim, delimlen, + &matchlen, &extralines)) + || buffer[offset + 1 + matchlen] != '"')) { + // skip, but keep track of lines + if (qmake_endOfLine(buffer[offset])) + ++*lines; + extralines = 0; + } + *lines += extralines; // from the match + // buffer[offset] is ')' + offset += 1 + matchlen; // 1 for ')', then delim + // buffer[offset] is '"' + +#undef SKIP_BSNL + } else { // Traditional string or char literal: + const char term = buffer[offset]; + while (++offset < buffer_len && buffer[offset] != term) { + if (buffer[offset] == '\\') + ++offset; + else if (qmake_endOfLine(buffer[offset])) + ++*lines; + } + } + + return offset; +} + bool QMakeSourceFileInfo::findDeps(SourceFile *file) { if(file->dep_checked || file->type == TYPE_UNKNOWN) @@ -425,215 +541,255 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file) file->deps = new SourceDependChildren; int line_count = 1; + enum { + /* + States of C preprocessing (for TYPE_C only), after backslash-newline + elimination and skipping comments and spaces (i.e. in ANSI X3.159-1989 + section 2.1.1.2's phase 4). We're about to study buffer[x] to decide + on which transition to do. + */ + AtStart, // start of logical line; a # may start a preprocessor directive + HadHash, // saw a # at start, looking for preprocessor keyword + WantName, // saw #include or #import, waiting for name + InCode // after directive, parsing non-#include directive or in actual code + } cpp_state = AtStart; for(int x = 0; x < buffer_len; ++x) { bool try_local = true; char *inc = 0; if(file->type == QMakeSourceFileInfo::TYPE_UI) { // skip whitespaces - while(x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t')) + while (x < buffer_len && (buffer[x] == ' ' || buffer[x] == '\t')) ++x; - if(*(buffer + x) == '<') { + if (buffer[x] == '<') { ++x; - if(buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) && - (*(buffer + x + 11) == ' ' || *(buffer + x + 11) == '>')) { - for(x += 11; *(buffer + x) != '>'; ++x) ; + if (buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) && + (buffer[x + 11] == ' ' || buffer[x + 11] == '>')) { + for (x += 11; buffer[x] != '>'; ++x) {} // skip int inc_len = 0; - for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ; - *(buffer + x + inc_len) = '\0'; + for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip + buffer[x + inc_len] = '\0'; inc = buffer + x; - } else if(buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) && - (*(buffer + x + 12) == ' ' || *(buffer + x + 12) == '>')) { - for(x += 13; *(buffer + x) != '>'; ++x) ; //skip up to > + } else if (buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) && + (buffer[x + 12] == ' ' || buffer[x + 12] == '>')) { + for (x += 13; buffer[x] != '>'; ++x) {} // skip up to > while(x < buffer_len) { - for(x++; *(buffer + x) != '<'; ++x) ; //skip up to < + for (x++; buffer[x] != '<'; ++x) {} // skip up to < x++; if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) && - (*(buffer + x + 6) == ' ' || *(buffer + x + 6) == '>')) { - for(x += 7; *(buffer + x) != '>'; ++x) ; //skip up to > + (buffer[x + 6] == ' ' || buffer[x + 6] == '>')) { + for (x += 7; buffer[x] != '>'; ++x) {} // skip up to > int inc_len = 0; - for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ; - *(buffer + x + inc_len) = '\0'; + for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip + buffer[x + inc_len] = '\0'; inc = buffer + x; break; } else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) && - (*(buffer + x + 13) == ' ' || *(buffer + x + 13) == '>')) { + (buffer[x + 13] == ' ' || buffer[x + 13] == '>')) { x += 14; break; } } } else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) && - (*(buffer + x + 7) == ' ' || *(buffer + x + 7) == '>')) { - for(x += 8; *(buffer + x) != '>'; ++x) { - if(buffer_len >= x + 9 && *(buffer + x) == 'i' && - !strncmp(buffer + x, "impldecl", 8)) { - for(x += 8; *(buffer + x) != '='; ++x) ; - if(*(buffer + x) != '=') + (buffer[x + 7] == ' ' || buffer[x + 7] == '>')) { + for (x += 8; buffer[x] != '>'; ++x) { + if (buffer_len >= x + 9 && buffer[x] == 'i' && + !strncmp(buffer + x, "impldecl", 8)) { + for (x += 8; buffer[x] != '='; ++x) {} // skip + if (buffer[x] != '=') continue; - for(++x; *(buffer+x) == '\t' || *(buffer+x) == ' '; ++x) ; + for (++x; buffer[x] == '\t' || buffer[x] == ' '; ++x) {} // skip char quote = 0; - if(*(buffer+x) == '\'' || *(buffer+x) == '"') { - quote = *(buffer + x); + if (buffer[x] == '\'' || buffer[x] == '"') { + quote = buffer[x]; ++x; } int val_len; for(val_len = 0; true; ++val_len) { if(quote) { - if(*(buffer+x+val_len) == quote) + if (buffer[x + val_len] == quote) break; - } else if(*(buffer + x + val_len) == '>' || - *(buffer + x + val_len) == ' ') { + } else if (buffer[x + val_len] == '>' || + buffer[x + val_len] == ' ') { break; } } -//? char saved = *(buffer + x + val_len); - *(buffer + x + val_len) = '\0'; +//? char saved = buffer[x + val_len]; + buffer[x + val_len] = '\0'; if(!strcmp(buffer+x, "in implementation")) { //### do this } } } int inc_len = 0; - for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ; - *(buffer + x + inc_len) = '\0'; + for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip + buffer[x + inc_len] = '\0'; inc = buffer + x; } } //read past new line now.. - for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ; + for (; x < buffer_len && !qmake_endOfLine(buffer[x]); ++x) {} // skip ++line_count; } else if(file->type == QMakeSourceFileInfo::TYPE_QRC) { } else if(file->type == QMakeSourceFileInfo::TYPE_C) { - for(int beginning=1; x < buffer_len; ++x) { - // whitespace comments and line-endings + // We've studied all buffer[i] for i < x + for (; x < buffer_len; ++x) { + // How to handle backslash-newline (BSNL) pairs: +#define SKIP_BSNL(pos) skipEscapedLineEnds(buffer, buffer_len, (pos), &line_count) + + // Seek code or directive, skipping comments and space: for(; x < buffer_len; ++x) { - if(*(buffer+x) == ' ' || *(buffer+x) == '\t') { + x = SKIP_BSNL(x); + if (buffer[x] == ' ' || buffer[x] == '\t') { // keep going - } else if(*(buffer+x) == '/') { - ++x; - if(buffer_len >= x) { - if(*(buffer+x) == '/') { //c++ style comment - for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ; - beginning = 1; - } else if(*(buffer+x) == '*') { //c style comment - for(++x; x < buffer_len; ++x) { - if(*(buffer+x) == '*') { - if(x+1 < buffer_len && *(buffer + (x+1)) == '/') { - ++x; - break; - } - } else if(qmake_endOfLine(*(buffer+x))) { - ++line_count; + } else if (buffer[x] == '/') { + int extralines = 0; + int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &extralines); + if (buffer[y] == '/') { // C++-style comment + line_count += extralines; + x = SKIP_BSNL(y + 1); + while (x < buffer_len && !qmake_endOfLine(buffer[x])) + x = SKIP_BSNL(x + 1); // skip + + cpp_state = AtStart; + ++line_count; + } else if (buffer[y] == '*') { // C-style comment + line_count += extralines; + x = y; + while (++x < buffer_len) { + x = SKIP_BSNL(x); + if (buffer[x] == '*') { + extralines = 0; + y = skipEscapedLineEnds(buffer, buffer_len, + x + 1, &extralines); + if (y < buffer_len && buffer[y] == '/') { + line_count += extralines; + x = y; // for loop shall step past this + break; } + } else if (qmake_endOfLine(buffer[x])) { + ++line_count; } } + } else { + // buffer[x] is the division operator + break; } - } else if(qmake_endOfLine(*(buffer+x))) { + } else if (qmake_endOfLine(buffer[x])) { ++line_count; - beginning = 1; + cpp_state = AtStart; } else { + /* Drop out of phases 1, 2, 3, into phase 4 */ break; } } + // Phase 4 study of buffer[x]: if(x >= buffer_len) break; - // preprocessor directive - if(beginning && *(buffer+x) == '#') + switch (cpp_state) { + case HadHash: + { + // Read keyword; buffer[x] starts first preprocessing token after # + const char *const keyword = buffer + x; + int clean = x; + while (x < buffer_len && buffer[x] >= 'a' && buffer[x] <= 'z') { + // skip over keyword, consolidating it if it contains BSNLs + // (see WantName's similar code consolidating inc, below) + if (clean < x) + buffer[clean++] = buffer[x]; + else + clean++; + + x = SKIP_BSNL(x + 1); + } + const int keyword_len = buffer + clean - keyword; + x--; // Still need to study buffer[x] next time round for loop. + + cpp_state = + ((keyword_len == 7 && !strncmp(keyword, "include", 7)) // C & Obj-C + || (keyword_len == 6 && !strncmp(keyword, "import", 6))) // Obj-C + ? WantName : InCode; break; + } - // quoted strings - if(*(buffer+x) == '\'' || *(buffer+x) == '"') { - const char term = *(buffer+(x++)); - for(; x < buffer_len; ++x) { - if(*(buffer+x) == term) { - ++x; - break; - } else if(*(buffer+x) == '\\') { - ++x; - } else if(qmake_endOfLine(*(buffer+x))) { + case WantName: + { + char term = buffer[x]; + if (term == '<') { + try_local = false; + term = '>'; + } else if (term != '"') { + /* + Possibly malformed, but this may be something like: + #include IDENTIFIER + which does work, if #define IDENTIFIER "filename" is + in effect. This is beyond this noddy preprocessor's + powers of tracking. So give up and resume searching + for a directive. We haven't made sense of buffer[x], + so back up to ensure we do study it (now as code) next + time round the loop. + */ + x--; + cpp_state = InCode; + continue; + } + + x = SKIP_BSNL(x + 1); + inc = buffer + x; + int clean = x; // offset if we need to clear \-newlines + for (; x < buffer_len && buffer[x] != term; x = SKIP_BSNL(x + 1)) { + if (qmake_endOfLine(buffer[x])) { // malformed + cpp_state = AtStart; ++line_count; + break; } - } - } - beginning = 0; - } - if(x >= buffer_len) - break; - //got a preprocessor symbol - ++x; - while(x < buffer_len) { - if(*(buffer+x) != ' ' && *(buffer+x) != '\t') - break; - ++x; - } + /* + If we do skip any BSNLs, we need to consolidate the + surviving text by copying to lower indices. For that + to be possible, we also have to keep 'clean' advanced + in step with x even when we've yet to see any BSNLs. + */ + if (clean < x) + buffer[clean++] = buffer[x]; + else + clean++; + } + if (cpp_state == WantName) + buffer[clean] = '\0'; + else // i.e. malformed + inc = 0; - int keyword_len = 0; - const char *keyword = buffer+x; - while(x+keyword_len < buffer_len) { - if(((*(buffer+x+keyword_len) < 'a' || *(buffer+x+keyword_len) > 'z')) && - *(buffer+x+keyword_len) != '_') { - for(x+=keyword_len; //skip spaces after keyword - x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t'); - x++) ; - break; - } else if(qmake_endOfLine(*(buffer+x+keyword_len))) { - x += keyword_len-1; - keyword_len = 0; + cpp_state = InCode; // hereafter break; } - keyword_len++; - } - if((keyword_len == 7 && !strncmp(keyword, "include", 7)) // C & Obj-C - || (keyword_len == 6 && !strncmp(keyword, "import", 6))) { // Obj-C - char term = *(buffer + x); - if(term == '<') { - try_local = false; - term = '>'; - } else if(term != '"') { //wtf? - continue; - } - x++; - - int inc_len; - for(inc_len = 0; *(buffer + x + inc_len) != term && !qmake_endOfLine(*(buffer + x + inc_len)); ++inc_len) ; - *(buffer + x + inc_len) = '\0'; - inc = buffer + x; - x += inc_len; - } else if(keyword_len == 13 && !strncmp(keyword, "qmake_warning", keyword_len)) { - char term = 0; - if(*(buffer + x) == '"') - term = '"'; - if(*(buffer + x) == '\'') - term = '\''; - if(term) - x++; - - int msg_len; - for(msg_len = 0; (term && *(buffer + x + msg_len) != term) && - !qmake_endOfLine(*(buffer + x + msg_len)); ++msg_len) ; - *(buffer + x + msg_len) = '\0'; - debug_msg(0, "%s:%d %s -- %s", file->file.local().toLatin1().constData(), line_count, keyword, buffer+x); - x += msg_len; - } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') { - const char term = *(buffer+(x++)); - while(x < buffer_len) { - if(*(buffer+x) == term) + case AtStart: + // Preprocessor directive? + if (buffer[x] == '#') { + cpp_state = HadHash; break; - if(*(buffer+x) == '\\') { - x+=2; - } else { - if(qmake_endOfLine(*(buffer+x))) - ++line_count; - ++x; } + cpp_state = InCode; + // ... and fall through to handle buffer[x] as such. + case InCode: + // matching quotes (string literals and character literals) + if (buffer[x] == '\'' || buffer[x] == '"') { + x = scanPastString(buffer, buffer_len, x, &line_count); + // for loop's ++x shall step over the closing quote. + } + // else: buffer[x] is just some code; move on. + break; } - } else { - --x; + + if (inc) // We were in WantName and found a name. + break; +#undef SKIP_BSNL } + if(x >= buffer_len) + break; } if(inc) { @@ -702,6 +858,13 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file) return true; } +static bool isCWordChar(char c) { + return c == '_' + || (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9'); +} + bool QMakeSourceFileInfo::findMocs(SourceFile *file) { if(file->moc_checked) @@ -709,7 +872,7 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file) files_changed = true; file->moc_checked = true; - int buffer_len; + int buffer_len = 0; char *buffer = 0; { struct stat fst; @@ -727,104 +890,101 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file) return false; //shouldn't happen } buffer = getBuffer(fst.st_size); - for(int have_read = buffer_len = 0; - (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)); - buffer_len += have_read) ; + while (int have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)) + buffer_len += have_read; + QT_CLOSE(fd); } debug_msg(2, "findMocs: %s", file->file.local().toLatin1().constData()); int line_count = 1; - bool ignore_qobject = false, ignore_qgadget = false; + bool ignore[2] = { false, false }; // [0] for Q_OBJECT, [1] for Q_GADGET /* qmake ignore Q_GADGET */ /* qmake ignore Q_OBJECT */ for(int x = 0; x < buffer_len; x++) { - if(*(buffer + x) == '/') { - ++x; - if(buffer_len >= x) { - if(*(buffer + x) == '/') { //c++ style comment - for(;x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ; - } else if(*(buffer + x) == '*') { //c style comment - for(++x; x < buffer_len; ++x) { - if(*(buffer + x) == 't' || *(buffer + x) == 'q') { //ignore +#define SKIP_BSNL(pos) skipEscapedLineEnds(buffer, buffer_len, (pos), &line_count) + x = SKIP_BSNL(x); + if (buffer[x] == '/') { + int extralines = 0; + int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &extralines); + if (buffer_len > y) { + // If comment, advance to the character that ends it: + if (buffer[y] == '/') { // C++-style comment + line_count += extralines; + x = y; + do { + x = SKIP_BSNL(x + 1); + } while (x < buffer_len && !qmake_endOfLine(buffer[x])); + + } else if (buffer[y] == '*') { // C-style comment + line_count += extralines; + x = SKIP_BSNL(y + 1); + for (; x < buffer_len; x = SKIP_BSNL(x + 1)) { + if (buffer[x] == 't' || buffer[x] == 'q') { // ignore if(buffer_len >= (x + 20) && !strncmp(buffer + x + 1, "make ignore Q_OBJECT", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"", file->file.real().toLatin1().constData(), line_count); x += 20; - ignore_qobject = true; + ignore[0] = true; } else if(buffer_len >= (x + 20) && !strncmp(buffer + x + 1, "make ignore Q_GADGET", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_GADGET\"", file->file.real().toLatin1().constData(), line_count); x += 20; - ignore_qgadget = true; + ignore[1] = true; } - } else if(*(buffer + x) == '*') { - if(buffer_len >= (x+1) && *(buffer + (x+1)) == '/') { - ++x; + } else if (buffer[x] == '*') { + extralines = 0; + y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &extralines); + if (buffer_len > y && buffer[y] == '/') { + line_count += extralines; + x = y; break; } - } else if(Option::debug_level && qmake_endOfLine(*(buffer + x))) { + } else if (Option::debug_level && qmake_endOfLine(buffer[x])) { ++line_count; } } } + // else: don't update x, buffer[x] is just the division operator. } - } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') { - const char term = *(buffer+(x++)); - while(x < buffer_len) { - if(*(buffer+x) == term) - break; - if(*(buffer+x) == '\\') { - x+=2; - } else { - if(qmake_endOfLine(*(buffer+x))) - ++line_count; - ++x; - } - } + } else if (buffer[x] == '\'' || buffer[x] == '"') { + x = scanPastString(buffer, buffer_len, x, &line_count); + // Leaves us on closing quote; for loop's x++ steps us past it. } - if(Option::debug_level && qmake_endOfLine(*(buffer+x))) + + if (x < buffer_len && Option::debug_level && qmake_endOfLine(buffer[x])) ++line_count; - if (buffer_len > x + 2 && buffer[x + 1] == 'Q' && buffer[x + 2] == '_' && - *(buffer + x) != '_' && - (*(buffer + x) < 'a' || *(buffer + x) > 'z') && - (*(buffer + x) < 'A' || *(buffer + x) > 'Z') && - (*(buffer + x) < '0' || *(buffer + x) > '9')) { - ++x; - int match = 0; - static const char *interesting[] = { "OBJECT", "GADGET" }; - for (int interest = 0, m1, m2; interest < 2; ++interest) { - if(interest == 0 && ignore_qobject) - continue; - else if(interest == 1 && ignore_qgadget) - continue; - for(m1 = 0, m2 = 0; *(interesting[interest]+m1); ++m1) { - if(*(interesting[interest]+m1) != *(buffer+x+2+m1)) { - m2 = -1; - break; + if (buffer_len > x + 8 && !isCWordChar(buffer[x])) { + int morelines = 0; + int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &morelines); + if (buffer[y] == 'Q') { + static const char interesting[][9] = { "Q_OBJECT", "Q_GADGET" }; + for (int interest = 0; interest < 2; ++interest) { + if (ignore[interest]) + continue; + + int matchlen = 0, extralines = 0; + if (matchWhileUnsplitting(buffer, buffer_len, y, + interesting[interest], + strlen(interesting[interest]), + &matchlen, &extralines) + && y + matchlen < buffer_len + && !isCWordChar(buffer[y + matchlen])) { + if (Option::debug_level) { + buffer[y + matchlen] = '\0'; + debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", + file->file.real().toLatin1().constData(), + line_count + morelines, buffer + y); + } + file->mocable = true; + return true; } - ++m2; - } - if(m1 == m2) { - match = m2 + 2; - break; - } - } - if(match && *(buffer+x+match) != '_' && - (*(buffer+x+match) < 'a' || *(buffer+x+match) > 'z') && - (*(buffer+x+match) < 'A' || *(buffer+x+match) > 'Z') && - (*(buffer+x+match) < '0' || *(buffer+x+match) > '9')) { - if(Option::debug_level) { - *(buffer+x+match) = '\0'; - debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", file->file.real().toLatin1().constData(), - line_count, buffer+x); } - file->mocable = true; - return true; } } +#undef SKIP_BSNL } return true; } |