summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2016-10-27 09:42:56 +0200
committerLars Knoll <lars.knoll@qt.io>2016-11-15 13:59:51 +0000
commitc442244907a7246ee1e0cff3827e874d50d6da11 (patch)
treece122fb6d3f8880f04d0dc1c62f2d8a8c2eea0c0 /src/gui/opengl
parent01c3565d3e484af0451060cdbdfc42f5d10dfb9a (diff)
Fixes for findVersionDirectivePosition()
The old code was wrong as it used QString::fromUtf8() to convert the char * array to a QString. This could lead to wrong positions when trying to find the #version directive, as any valid utf8 sequence in a comment before could have lead to wrong offsets compared to the 8 bit data. Fix this and optimize the code at the same time to avoid creating a copy of the data and using QRegularExpression. Also fixes building Qt with -no-feature-regularexpression Change-Id: I2d84875ef59b3a0fb4d8b069bf56f4372c57ccdc Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/gui/opengl')
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp81
1 files changed, 46 insertions, 35 deletions
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index 61343e5f5a..cd582c5285 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -432,73 +432,84 @@ static QVersionDirectivePosition findVersionDirectivePosition(const char *source
{
Q_ASSERT(source);
- QString working = QString::fromUtf8(source);
-
// According to the GLSL spec the #version directive must not be
// preceded by anything but whitespace and comments.
// In order to not get confused by #version directives within a
- // multiline comment, we need to run a minimal preprocessor first.
+ // multiline comment, we need to do some minimal comment parsing
+ // while searching for the directive.
enum {
Normal,
+ StartOfLine,
+ PreprocessorDirective,
CommentStarting,
MultiLineComment,
SingleLineComment,
CommentEnding
- } state = Normal;
+ } state = StartOfLine;
- for (QChar *c = working.begin(); c != working.end(); ++c) {
+ const char *c = source;
+ while (*c) {
switch (state) {
+ case PreprocessorDirective:
+ if (*c == ' ' || *c == '\t')
+ break;
+ if (!strncmp(c, "version", strlen("version"))) {
+ // Found version directive
+ c += strlen("version");
+ while (*c && *c != '\n')
+ ++c;
+ int splitPosition = c - source + 1;
+ int linePosition = int(std::count(source, c, '\n')) + 1;
+ return QVersionDirectivePosition(splitPosition, linePosition);
+ } else if (*c == '/')
+ state = CommentStarting;
+ else if (*c == '\n')
+ state = StartOfLine;
+ else
+ state = Normal;
+ break;
+ case StartOfLine:
+ if (*c == ' ' || *c == '\t')
+ break;
+ else if (*c == '#') {
+ state = PreprocessorDirective;
+ break;
+ }
+ state = Normal;
+ // fall through
case Normal:
- if (*c == QLatin1Char('/'))
+ if (*c == '/')
state = CommentStarting;
+ else if (*c == '\n')
+ state = StartOfLine;
break;
case CommentStarting:
- if (*c == QLatin1Char('*'))
+ if (*c == '*')
state = MultiLineComment;
- else if (*c == QLatin1Char('/'))
+ else if (*c == '/')
state = SingleLineComment;
else
state = Normal;
break;
case MultiLineComment:
- if (*c == QLatin1Char('*'))
+ if (*c == '*')
state = CommentEnding;
- else if (*c == QLatin1Char('#'))
- *c = QLatin1Char('_');
break;
case SingleLineComment:
- if (*c == QLatin1Char('\n'))
+ if (*c == '\n')
state = Normal;
- else if (*c == QLatin1Char('#'))
- *c = QLatin1Char('_');
break;
case CommentEnding:
- if (*c == QLatin1Char('/')) {
+ if (*c == '/')
state = Normal;
- } else {
- if (*c == QLatin1Char('#'))
- *c = QLatin1Char('_');
- if (*c != QLatin1Char('*'))
- state = MultiLineComment;
- }
+ else if (*c != QLatin1Char('*'))
+ state = MultiLineComment;
break;
}
+ ++c;
}
- // Search for #version directive
- int splitPosition = 0;
- int linePosition = 1;
-
- static const QRegularExpression pattern(QStringLiteral("^\\s*#\\s*version.*(\\n)?"),
- QRegularExpression::MultilineOption
- | QRegularExpression::OptimizeOnFirstUsageOption);
- QRegularExpressionMatch match = pattern.match(working);
- if (match.hasMatch()) {
- splitPosition = match.capturedEnd();
- linePosition += int(std::count(working.begin(), working.begin() + splitPosition, QLatin1Char('\n')));
- }
-
- return QVersionDirectivePosition(splitPosition, linePosition);
+ return QVersionDirectivePosition(0, 1);
}
/*!