35 bool takeLine = (*
data ==
'#');
36 if (*
data ==
'%' && *(
data+1) ==
':') {
48 if (*(
data + 1) ==
'\r') {
58 }
else if (*
data ==
'\r' && *(
data + 1) ==
'\n') {
147 if (
static_cast<signed char>(*
data) < 0) {
155 else if (!
state || nextindex)
168 if (
token == NOTOKEN) {
180 if (
token > SPECIAL_TREATMENT_MARK) {
184 token = STRING_LITERAL;
205 && *(
data-2)!=
'\\')))
209 token = CHARACTER_LITERAL;
218 bool hasSeenTokenSeparator =
false;;
222 token = INTEGER_LITERAL;
230 }
else if (*
data ==
'L')
232 if (!hasSeenTokenSeparator) {
240 token = FLOATING_LITERAL;
244 case FLOATING_LITERAL:
282 const char *rewind =
data;
307 while (*
data && (*(
data-1) !=
'/' || *(
data-2) !=
'*')) {
342 if (
static_cast<signed char>(*
data) < 0) {
350 else if (!
state || nextindex)
389 && *(
data-2)!=
'\\')))
406 }
else if (*
data ==
'L')
460 while (*
data && (*(
data-1) !=
'/' || *(
data-2) !=
'*')) {
481 const char *rewind =
data;
510 int lineNum,
bool one,
const QSet<QByteArray> &excludeSymbols)
516 sf.excludedSymbols = excludeSymbols;
519 if (toExpand.isEmpty())
526 if (macro.isEmpty()) {
535 sf.expandedMacro = macro;
559 const Macro ¯o = that->macros.value(
s);
560 *macroName =
s.lexem();
563 if (!macro.isFunction) {
564 expansion = macro.symbols;
566 bool haveSpace =
false;
574 syms.last().lineNum = lineNum;
583 bool vararg = macro.isVariadic && (
arguments.
size() == macro.arguments.size() - 1);
592 }
else if (
t ==
PP_COMMA && nesting == 0) {
603 that->error(
"missing ')' in macro usage");
607 if (macro.isVariadic &&
arguments.
size() == macro.arguments.size() - 1)
617 const auto end = macro.symbols.
cend();
619 const auto lastSym = std::prev(macro.symbols.cend(), !macro.symbols.isEmpty() ? 1 : 0);
622 if (
s.token == HASH ||
s.token == PP_HASHHASH) {
623 mode = (
s.token == HASH ? Hash : HashHash);
630 if (
it == lastSym || std::next(
it)->token != PP_HASHHASH) {
640 }
else if (
mode == Hash) {
642 that->error(
"'#' is not followed by a macro parameter");
645 that->error(
"Macro invoked with too few parameters for a use of '#'");
652 stringified += sym.lexem();
654 stringified.
replace(
'"',
"\\\"");
657 expansion +=
Symbol(lineNum, STRING_LITERAL, stringified);
658 }
else if (
mode == HashHash){
659 if (
s.token == WHITESPACE)
662 while (expansion.size() && expansion.constLast().token ==
PP_WHITESPACE)
663 expansion.pop_back();
668 if (
arg.size() == 0) {
675 if (!expansion.isEmpty() && expansion.constLast().token ==
s.token
676 && expansion.constLast().token != STRING_LITERAL) {
677 Symbol last = expansion.takeLast();
688 expansion.append(
arg.cbegin() + 1,
arg.cend());
694 that->error(
"'#' or '##' found at the end of a macro argument");
707 }
else if (
token == PP_DEFINED) {
711 definedOrNotDefined.token =
macros.
contains(definedOrNotDefined)? PP_MOC_TRUE : PP_MOC_FALSE;
712 substituted += definedOrNotDefined;
754 return value ? alt1 : alt2;
876 return remainder ?
value % remainder : 0;
881 return div ?
value / div : 0;
899 return ~unary_expression();
933 value = lexView.toInt(
nullptr, 0);
956 return expression.
value();
962 char *rawInput =
reinterpret_cast<char*
>(
file->
map(0,
size));
969 for (Symbols::iterator
i = symbols.
begin();
i != symbols.
end(); ++
i) {
970 if (
i->token == STRING_LITERAL) {
972 qsizetype literalsLength = mergeSymbol->len;
973 while (++
i != symbols.
end() &&
i->token == STRING_LITERAL)
974 literalsLength +=
i->len - 2;
976 if (literalsLength != mergeSymbol->len) {
977 QByteArray mergeSymbolOriginalLexem = mergeSymbol->unquotedLexem();
978 QByteArray &mergeSymbolLexem = mergeSymbol->lex;
979 mergeSymbolLexem.
resize(0);
980 mergeSymbolLexem.reserve(literalsLength);
981 mergeSymbolLexem.append(
'"');
982 mergeSymbolLexem.append(mergeSymbolOriginalLexem);
983 for (Symbols::iterator
j = mergeSymbol + 1;
j !=
i; ++
j)
984 mergeSymbolLexem.append(
j->lex.constData() +
j->from + 1,
j->len - 2);
985 mergeSymbolLexem.append(
'"');
986 mergeSymbol->len = mergeSymbol->lex.size();
987 mergeSymbol->from = 0;
988 i = symbols.
erase(mergeSymbol + 1,
i);
990 if (
i == symbols.
end())
998 const bool debugIncludes)
1003 fprintf(stderr,
"debug-includes: searching for '%s'\n", include.
constData());
1010 if (
p.isFrameworkPath) {
1021 const auto candidate = fi.filePath().toLocal8Bit();
1022 fprintf(stderr,
"debug-includes: considering '%s'\n", candidate.constData());
1033 if (!fi.exists() || fi.isDir()) {
1035 fprintf(stderr,
"debug-includes: can't find '%s'\n", include.
constData());
1040 const auto result = fi.canonicalFilePath().toLocal8Bit();
1043 fprintf(stderr,
"debug-includes: found '%s'\n",
result.constData());
1051 if (!relativeTo.isEmpty()) {
1054 if (fi.exists() && !fi.isDir())
1055 return fi.canonicalFilePath().toLocal8Bit();
1103 if (
input.isEmpty())
1137 macro.isFunction =
true;
1140 macro.isFunction =
false;
1151 if (
token == WHITESPACE) {
1152 if (lastToken == PP_HASH || lastToken == HASH ||
1153 lastToken == PP_HASHHASH ||
1154 lastToken == WHITESPACE)
1156 }
else if (
token == PP_HASHHASH) {
1157 if (!macro.symbols.isEmpty() &&
1158 lastToken == WHITESPACE)
1159 macro.symbols.pop_back();
1165 while (!macro.symbols.isEmpty() &&
1166 (macro.symbols.constLast().token ==
PP_WHITESPACE || macro.symbols.constLast().token == WHITESPACE))
1167 macro.symbols.pop_back();
1169 if (!macro.symbols.isEmpty()) {
1170 if (macro.symbols.constFirst().token == PP_HASHHASH ||
1171 macro.symbols.constLast().token == PP_HASHHASH) {
1172 error(
"'##' cannot appear at either end of a macro expansion");
1199 if (
test(PP_ELIF)) {
1219 sym.
token = IDENTIFIER;
1221 sym.
token = (
token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN);
1237 if (
input.isEmpty())
1249 fprintf(stderr,
"line %d: %s(%s)\n",
1261 preprocess(filename,
result);
1266 fprintf(stderr,
"line %d: %s(%s)\n",
1286 m->isVariadic =
true;
1290 error(
"missing ')' in macro argument list");
1293 error(
"Unexpected character in macro argument list.");
1299 error(
"Duplicate macro parameter.");
1308 if (
lexem() ==
"...") {
1311 m->isVariadic =
true;
1314 error(
"missing ')' in macro argument list");
1317 error(
"Unexpected character in macro argument list.");
1323void Preprocessor::until(
Token t)
1331 debugIncludes =
value;
int relational_expression()
int exclusive_OR_expression()
bool unary_expression_lookup()
int logical_OR_expression()
int equality_expression()
int logical_AND_expression()
int additive_expression()
int multiplicative_expression()
int conditional_expression()
bool primary_expression_lookup()
int inclusive_OR_expression()
QList< IncludePath > includes
std::stack< QByteArray, QByteArrayList > currentFilenames
QByteArray unquotedLexem()
QSet< QByteArray > preprocessedIncludes
void setDebugIncludes(bool value)
void parseDefineArguments(Macro *m)
QHash< QByteArray, QByteArray > nonlocalIncludePathResolutionCache
Symbols preprocessed(const QByteArray &filename, QFile *device)
void substituteUntilNewline(Symbols &substituted)
static bool preprocessOnly
static Symbols macroExpandIdentifier(Preprocessor *that, SymbolStack &symbols, int lineNum, QByteArray *macroName)
QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo)
static Symbols tokenize(const QByteArray &input, int lineNum=1, TokenizeMode mode=TokenizeCpp)
static void macroExpand(Symbols *into, Preprocessor *that, const Symbols &toExpand, qsizetype &index, int lineNum, bool one, const QSet< QByteArray > &excludeSymbols=QSet< QByteArray >())
@ PreparePreprocessorStatement
@ TokenizePreprocessorStatement
bool endsWith(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray & prepend(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QByteArray left(qsizetype n) const &
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool startsWith(QByteArrayView bv) const
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray mid(qsizetype index, qsizetype len=-1) const &
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
uchar * map(qint64 offset, qint64 size, MemoryMapFlags flags=NoOptions)
Maps size bytes of the file into memory starting at offset.
void close() override
Calls QFileDevice::flush() and closes the file.
void setFile(const QString &file)
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
qint64 size() const override
\reimp
bool remove(const Key &key)
Removes the item that has the key from the hash.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const T & constLast() const noexcept
iterator erase(const_iterator begin, const_iterator end)
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
iterator insert(const T &value)
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QSet< QString >::iterator it
QList< QVariant > arguments
bool is_ident_start(char s)
static const short keyword_trans[][128]
static const struct @480 keywords[]
bool is_identifier(const char *s, qsizetype len)
const char * skipQuote(const char *data)
Combined button and popup list for selecting options.
constexpr bool isAsciiDigit(char32_t c) noexcept
constexpr bool isHexDigit(char32_t c) noexcept
static const short pp_keyword_trans[][128]
static const struct @482 pp_keywords[]
static QByteArray readOrMapFile(QFile *file)
static void mergeStringLiterals(Symbols *_symbols)
static QByteArray searchIncludePaths(const QList< Parser::IncludePath > &includepaths, const QByteArray &include, const bool debugIncludes)
static QByteArray cleaned(const QByteArray &input)
DBusConnection const char DBusError * error
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void GLsizei void * column
GLenum GLenum GLenum input
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QT_BEGIN_NAMESPACE typedef uchar * output
bool contains(const AT &t) const noexcept
QByteArray unquotedLexem() const