/* * Reads a token from a given preprocessing context, expands it if macro, and * returns it. */ static Token *expand_one(CppContext *ctx) { Token *tok = read_cpp_token(ctx); if (!tok) return NULL; if (tok->toktype != TOKTYPE_IDENT) return tok; String *name = tok->val.str; Macro *macro = dict_get(ctx->defs, name); if (!macro) return tok; if (list_in(tok->hideset, name)) return tok; switch (macro->type) { case MACRO_OBJ: { List *ts = subst(ctx, macro, make_list(), list_union1(tok->hideset, name)); pushback(ctx, ts); return expand_one(ctx); } case MACRO_FUNC: { List *args = read_args(ctx, macro); Token *rparen = read_cpp_token(ctx); List *hideset = list_union1(list_intersect(tok->hideset, rparen->hideset), name); List *ts = subst(ctx, macro, args, hideset); pushback(ctx, ts); return expand_one(ctx); } case MACRO_SPECIAL: macro->fn(ctx, tok); return expand_one(ctx); } panic("should not reach here"); }
void CornerSequence::placeFixedMacros() { for (int i = 0; i < fixedMacros->size(); ++i) { Macro *macro = fixedMacros->at(i); for (int iRectangle = 0; iRectangle < macro->getRectangles()->size(); ++iRectangle) { Rectangle *rectangle = macro->getRectangles()->at(iRectangle); int tileXStart = rectangle->getXStart(); int tileYStart = rectangle->getYStart(); int tileXEnd = rectangle->getXEnd(); int tileYEnd = rectangle->getYEnd(); Tile *horizontalTile = new Tile(tileXStart, tileYStart, tileXEnd, tileYEnd, true); Tile *verticalTile = new Tile(tileXStart, tileYStart, tileXEnd, tileYEnd, true); Tile *startHorizontalTile = cornerHorizontalTilePlane->findTile(tileXStart, tileYStart, cornerHorizontalTilePlane->getTopLeftMostTile()); Tile *startVerticalTile = cornerVerticalTilePlane->findTile(tileXStart, tileYStart, cornerVerticalTilePlane->getTopLeftMostTile()); cornerHorizontalTilePlane->placeSolidTileGivenBothStartTiles(horizontalTile, startHorizontalTile, startVerticalTile); startHorizontalTile = horizontalTile; cornerVerticalTilePlane->placeSolidTileGivenBothStartTiles(verticalTile, startVerticalTile, startHorizontalTile); cornerHorizontalTilePlane->calculateCurrentCornersWidthAndHeight(); cornerVerticalTilePlane->calculateCurrentCornersWidthAndHeight(); updateQuadtrees(); } } }
int main() { Macro macro; macro.add(new Hello); macro.add(new World); macro.add(new IAm); macro.run(); }
// CppMacro CppMacro::CppMacro(const Macro ¯o) : CppElement() { setHelpCategory(TextEditor::HelpItem::Macro); setHelpIdCandidates(QStringList(macro.name())); setHelpMark(macro.name()); setLink(CPPEditorWidget::Link(macro.fileName(), macro.line())); setTooltip(macro.toStringWithLineBreaks()); }
void Driver::removeAllMacrosInFile( const QString& fileName ) { QMap<QString, Macro>::Iterator it = m_macros.begin(); while( it != m_macros.end() ){ Macro m = *it++; if( m.fileName() == fileName ) removeMacro( m.name() ); } }
explicit CppMacro(const Macro ¯o) { helpCategory = Core::HelpItem::Macro; const QString macroName = QString::fromUtf8(macro.name(), macro.name().size()); helpIdCandidates = QStringList(macroName); helpMark = macroName; link = Utils::Link(macro.fileName(), macro.line()); tooltip = macro.toStringWithLineBreaks(); }
// CppMacro CppMacro::CppMacro(const Macro ¯o) { helpCategory = TextEditor::HelpItem::Macro; const QString macroName = QLatin1String(macro.name()); helpIdCandidates = QStringList(macroName); helpMark = macroName; link = CPPEditorWidget::Link(macro.fileName(), macro.line()); tooltip = macro.toStringWithLineBreaks(); }
bool SQLScriptRunner::ExecuteScript(shared_ptr<DALConnection> connectionObject, const String &sFile, String &sErrorMessage) { SQLScriptParser oParser(connectionObject->GetSettings(), sFile); if (!oParser.Parse(sErrorMessage)) { sErrorMessage = "Parsing of SQL script failed: " + sFile + "\r\nError:" + sErrorMessage; return false; } if (oParser.GetNoOfCommands() == 0) { sErrorMessage = "Found no SQL commands in file : " + sFile; return false; } // 30 minute timeout per statement. Should hopefully never be needed. connectionObject->SetTimeout(60 * 30); for (int i = 0; i < oParser.GetNoOfCommands(); i++) { String sCommand = oParser.GetCommand(i); if (sCommand.StartsWith(_T("@@@"))) { // Remove leading @@@. sCommand = sCommand.Mid(3); // Remove trailing @@@ sCommand = sCommand.Mid(0, sCommand.Find(_T("@@@"))); MacroParser parser(sCommand); Macro macro = parser.Parse(); if (macro.GetType() == Macro::Unknown) { sErrorMessage = "Parsing of SQL script failed. Unknown macro. " + sFile + "\r\nMacro:" + sCommand; return false; } shared_ptr<IMacroExpander> macroExpander = connectionObject->CreateMacroExpander(); if (!macroExpander->ProcessMacro(connectionObject, macro, sErrorMessage)) return false; } else { if (connectionObject->TryExecute(SQLCommand(sCommand), sErrorMessage, 0, 0) != DALConnection::DALSuccess) { return false; } } } connectionObject->SetTimeout(30); return true; }
void Driver::removeAllMacrosInFile( const QString& fileName ) { MacroMap::iterator it = m_macros.begin(); while ( it != m_macros.end() ) { Macro m = ( *it ).second; if ( m.fileName() == fileName ) { m_macros.erase( it++ ); } else { ++it; } } }
int main(int argc, char* argv[]) { cout << argc << endl; for (int h = 0; h<argc; h++) cout << argv[h] << endl; cout << endl; Recorder* rec = Recorder::GetInstance(); //One of each device TestDevice* dev = new TestDevice("dev"); Relay* rel = new Relay(); SpeedController* ctrl = new SpeedController(); Servo* serv = new Servo(); DoubleSolenoid* ds = new DoubleSolenoid(); Solenoid* sol = new Solenoid(); //Add all devices to recorder rec->AddDevice("Relay",rel); rec->AddDevice("Speed Controller",ctrl); rec->AddDevice("Servo",serv); rec->AddDevice("Double Solenoid",ds); rec->AddDevice("Solenoid",sol); rec->AddDevice(dev); //Creates macro cout << dev->GetName() << endl; Macro* mac = rec -> macro(); int iterations = 5; for (int i = 0; i<iterations; i++) { mac->Record(); } mac->WriteFile("auto.csv"); mac->Reset(); mac->ReadFile("auto.csv"); while (!mac->IsFinished()) { mac->PlayBack(); } cout << "plz work" << endl; mac->Reset(); Command* recCom = mac->NewRecordFileCommand("auto2.csv"); recCom->Initialize(); for (int i = 0; i < 30; i ++) recCom->Execute(); recCom->End(); return 0; }
void MainWindow::handleTimClick(QTreeWidgetItem* item,int) { ui->currentMacroTE->clear(); QString selectedMacro = item->text(0); Macro macro = guiMacro->getStorage().getMacro(selectedMacro); const ParameterStorage& params=macro.getParameterStorage(); ui->parametersTextEdit->setText(params.toString()); foreach(const QStringList& line, macro.getContent()) { ui->currentMacroTE->insertPlainText(line.join("\t") + "\n"); } }
void MacroManager::MacroManagerPrivate::initialize() { macros.clear(); QDir dir(q->macrosDirectory()); QStringList filter; filter << QString("*.")+Constants::M_EXTENSION; QStringList files = dir.entryList(filter, QDir::Files); foreach (const QString &name, files) { QString fileName = dir.absolutePath() + '/' + name; Macro *macro = new Macro; macro->loadHeader(fileName); addMacro(macro); }
FullSourceRef SourceManager::getOrigin(const FullMacroRef &ref) { Macro *macro = ref.macro; if (!macro->definedAt.isSet()) return FullSourceRef(); assert(!macro->start().isInMacro()); size_t loc_index; if (!findLocation(macro->start(), &loc_index)) return FullSourceRef(); FullSourceRef origin = fullSourceRef(locations_[loc_index], macro->start()); origin.col += ref.offset; return origin; }
static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, const Macro ¯o) { Macro newMacro(macro); newMacro.setFileRevision(s.get(macro.fileName()).second); return newMacro; }
void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) { if (!m_currentDoc) return; m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, QVector<MacroArgumentReference>()); }
bool MySQLMacroExpander::ProcessMacro(std::shared_ptr<DALConnection> connection, const Macro ¯o, String &sErrorMessage) { switch (macro.GetType()) { case Macro::DropColumnKeys: // MySQL4 doesn't support WHERE clauses in SHOW INDEX so // we must manually sort the result below. String sql; sql.Format(_T("SHOW INDEX IN %s"), macro.GetTableName().c_str()); MySQLRecordset rec; if (!rec.Open(connection, SQLCommand(sql))) { sErrorMessage = "It was not possible to execute the below SQL statement. Please see hMailServer error log for details.\r\n" + sql; return false; } while (!rec.IsEOF()) { String columnName = rec.GetStringValue("Column_name"); if (columnName.CompareNoCase(macro.GetColumnName()) != 0) { // Wrong column rec.MoveNext(); continue; } String constraintName = rec.GetStringValue("Key_name"); String sqlUpdate; sqlUpdate.Format(_T("ALTER TABLE %s DROP INDEX %s"), macro.GetTableName().c_str(), constraintName.c_str()); DALConnection::ExecutionResult execResult = connection->TryExecute(SQLCommand(sqlUpdate), sErrorMessage, 0, 0); if (execResult != DALConnection::DALSuccess) return false; rec.MoveNext(); } break; } return true; }
void Driver::addMacro( const Macro & macro ) { std::pair< MacroMap::iterator, MacroMap::iterator > range = m_macros.equal_range( macro.name() ); if ( range.first == range.second ) { m_macros.insert( std::make_pair( deepCopy( macro.name() ), macro ) ); } else { ///Insert behind the other macros m_macros.insert( range.second, std::make_pair( deepCopy( macro.name() ), macro ) ); Macro cp = this->macro( macro.name() ); assert( macro == cp ); } #ifdef CACHELEXER if( m_currentLexerCache ) m_currentLexerCache->addDefinedMacro( macro ); #endif }
void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line, const Macro ¯o, const QVector<MacroArgumentReference> &actuals) { if (!m_currentDoc) return; m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, actuals); }
/* --------------------------------------------------------------- Second part of macro definiton. Actually store the macro in the table. To this point lines for the macro have been collected in macrobuf. --------------------------------------------------------------- */ void Assembler::endm() { String bdy2; char *bdy; Macro *mac; int ii; // First check if in the macro definition process if (!CollectingMacro) { Err(E_ENDM); return; } CollectingMacro = false; if (pass < 2) { try { mac = new Macro; if (mac == NULL) throw Err(E_MEMORY); macrobuf.rtrim(); // Strip out spaces on the first line because these will be // supplied where the macro is to be substituted. // ltrim(macrobuf.buf()+1); macrobuf += "\r\n"; //printf("macrobuf:%s|\r\n",macrobuf.buf()); mac->setBody(macrobuf); mac->setArgCount(gMacro.Nargs()); mac->setName(gMacro.getName().buf()); mac->setFileLine(gMacro.getFile(), gMacro.getLine()); bdy = mac->initBody(parmlist); // put parameter markers into body bdy2 = bdy; mac->setBody(bdy2); // save body with markers } catch (char *msg) { printf(":%s\r\n", msg); getchar(); } } // we don't need parms any more so free them up for (ii = 0; ii < MAX_MACRO_PARMS; ii++) { delete parmlist[ii]; parmlist[ii] = NULL; } // Reset macro buffer macrobuf = ""; if (pass < 2) macroTbl->insert(mac); }
Bool* comparison(Variable* A, Variable* B, OperatorEnum oper) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in assignment.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); bool mismatch = false; if(a == STRING) { if(b != STRING) mismatch = true; else { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == INT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Int* C = static_cast<Int*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == FLOAT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Float* C = static_cast<Float*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == BOOL) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Bool* C = static_cast<Bool*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == MACRO) { if(b != MACRO) mismatch = true; else { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == ARRAY) { if(b != ARRAY) mismatch = true; else { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = C->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == LIST) { if(b != LIST) mismatch = true; else { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == FUNCTION) { if(b != FUNCTION) mismatch = true; else { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == PROCEDURE) { if(b != PROCEDURE) mismatch = true; else { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } //if(mismatch) { interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } return NULL; }
/* * Substitute the arguments args appearing in the input sequence is * Result is created in the output sequence os and finally has the specified * hide set added to it, before getting returned. */ static PtokenSequence subst(const Macro &m, dequePtoken is, const mapArgval &args, HideSet hs, bool skip_defined, const Macro *caller) { PtokenSequence os; // output sequence while (!is.empty()) { if (DP()) cout << "subst: is=" << is << " os=" << os << endl; const Ptoken head(is.front()); is.pop_front(); // is is now the tail dequePtoken::iterator ti, ti2; mapArgval::const_iterator ai; switch (head.get_code()) { case '#': // Stringizing operator ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); os.push_back(stringize(ai->second)); continue; } break; case CPP_CONCAT: ti = find_nonspace(is.begin(), is.end()); if (ti != is.end()) { if ((ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); if (ai->second.size() != 0) // Only if actuals can be empty os = glue(os, ai->second); } else { PtokenSequence t(ti, ti + 1); is.erase(is.begin(), ++ti); os = glue(os, t); } continue; } break; default: ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && ti->get_code() == CPP_CONCAT) { /* * Implement the following gcc extension: * "`##' before a * rest argument that is empty discards the preceding sequence of * non-whitespace characters from the macro definition. (If another macro * argument precedes, none of it is discarded.)" * Otherwise, break to process a non-formal argument in the default way */ if ((ai = find_formal_argument(args, head)) == args.end()) { if (m.get_is_vararg()) { ti2 = find_nonspace(ti + 1, is.end()); if (ti2 != is.end() && (ai = find_formal_argument(args, *ti2)) != args.end() && ai->second.size() == 0) { // All conditions satisfied; discard elements: // <non-formal> <##> <empty-formal> is.erase(is.begin(), ++ti2); continue; } } break; // Non-formal arguments don't deserve special treatment } // Paste but not expand LHS, RHS if (ai->second.size() == 0) { // Only if actuals can be empty is.erase(is.begin(), ++ti); // Erase including ## ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); // Erase the ## RHS PtokenSequence actual(ai->second); os.splice(os.end(), actual); } } else { is.erase(is.begin(), ti); // Erase up to ## PtokenSequence actual(ai->second); os.splice(os.end(), actual); } continue; } if ((ai = find_formal_argument(args, head)) == args.end()) break; // Othewise expand head PtokenSequence expanded(macro_expand(ai->second, false, skip_defined, caller)); os.splice(os.end(), expanded); continue; } os.push_back(head); } return (hsadd(hs, os)); }
void Lexer::processDefine( Macro& m ) { m.setFileName( m_driver->currentFileName() ); m.setLine( m_currentLine ); m.setColumn( m_currentColumn ); readWhiteSpaces( false ); int startMacroName = currentPosition(); readIdentifier(); QString macroName = m_source.mid( startMacroName, int(currentPosition()-startMacroName) ); m.setName( macroName ); if( currentChar() == '(' ){ m.setHasArguments( true ); nextChar(); readWhiteSpaces( false ); while( currentChar() && currentChar() != ')' ){ readWhiteSpaces( false ); int startArg = currentPosition(); if( currentChar() == '.' && peekChar() == '.' && peekChar(2) == '.' ) nextChar( 3 ); else readIdentifier(); QString arg = m_source.mid( startArg, int(currentPosition()-startArg) ); m.addArgument( Macro::Argument(arg) ); readWhiteSpaces( false ); if( currentChar() != ',' ) break; nextChar(); // skip ',' } if( currentChar() == ')' ) nextChar(); // skip ')' } setPreprocessorEnabled( true ); QString body; while( currentChar() && currentChar() != '\n' ){ if( currentChar().isSpace() ){ readWhiteSpaces( false ); body += " "; } else { Token tk(m_source); nextToken( tk, true ); //Do not ignore c-style comments, those may be useful in the body, and ignoring them using this check causes problems if( tk.type() != -1 && (tk.type() != Token_comment || ( tk.text().length() >= 2 && tk.text()[1] == '*') ) ){ QString s = tk.text(); body += s; } } } m.setBody( body ); m_driver->addMacro( m ); }
void DirectiveParser::parseDefine(Token *token) { assert(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, token->text); return; } if (isMacroNameReserved(token->text)) { mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } Macro macro; macro.type = Macro::kTypeObj; macro.name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. macro.type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; macro.parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. } while (token->type == ','); if (token->type != ')') { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. } while ((token->type != '\n') && (token->type != Token::LAST)) { // Reset the token location because it is unnecessary in replacement // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); macro.replacements.push_back(*token); mTokenizer->lex(token); } if (!macro.replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. macro.replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. MacroSet::const_iterator iter = mMacroSet->find(macro.name); if (iter != mMacroSet->end() && !macro.equals(iter->second)) { mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro.name); return; } mMacroSet->insert(std::make_pair(macro.name, macro)); }
Macro *Macro::find(const String& n) { for (Macro *it = next(); !it->isRoot(); it = it->next()) if (it->_name == n) return it; return NULL; }
const char *MacroExpander::expand(const char *__first, const char *__last, QByteArray *__result) { const char *start = __first; __first = skip_blanks (__first, __last); lines = skip_blanks.lines; while (__first != __last) { if (*__first == '\n') { __result->append("\n# "); __result->append(QByteArray::number(env->currentLine)); __result->append(' '); __result->append('"'); __result->append(env->currentFile.toUtf8()); __result->append('"'); __result->append('\n'); ++lines; __first = skip_blanks (++__first, __last); lines += skip_blanks.lines; if (__first != __last && *__first == '#') break; } else if (*__first == '#') { __first = skip_blanks (++__first, __last); lines += skip_blanks.lines; const char *end_id = skip_identifier (__first, __last); const QByteArray fast_name(__first, end_id - __first); __first = end_id; if (const QByteArray *actual = resolve_formal (fast_name)) { __result->append('\"'); const char *actual_begin = actual->constData (); const char *actual_end = actual_begin + actual->size (); for (const char *it = skip_whitespaces (actual_begin, actual_end); it != actual_end; ++it) { if (*it == '"' || *it == '\\') { __result->append('\\'); __result->append(*it); } else if (*it == '\n') { __result->append('"'); __result->append('\n'); __result->append('"'); } else __result->append(*it); } __result->append('\"'); } else __result->append('#'); // ### warning message? } else if (*__first == '\"') { const char *next_pos = skip_string_literal (__first, __last); lines += skip_string_literal.lines; __result->append(__first, next_pos - __first); __first = next_pos; } else if (*__first == '\'') { const char *next_pos = skip_char_literal (__first, __last); lines += skip_char_literal.lines; __result->append(__first, next_pos - __first); __first = next_pos; } else if (comment_p (__first, __last)) { __first = skip_comment_or_divop (__first, __last); int n = skip_comment_or_divop.lines; lines += n; while (n-- > 0) __result->append('\n'); } else if (pp_isspace (*__first)) { for (; __first != __last; ++__first) { if (*__first == '\n' || !pp_isspace (*__first)) break; } __result->append(' '); } else if (pp_isdigit (*__first)) { const char *next_pos = skip_number (__first, __last); lines += skip_number.lines; __result->append(__first, next_pos - __first); __first = next_pos; } else if (pp_isalpha (*__first) || *__first == '_') { const char *name_begin = __first; const char *name_end = skip_identifier (__first, __last); __first = name_end; // advance // search for the paste token const char *next = skip_blanks (__first, __last); bool paste = false; if (next != __last && *next == '#') { paste = true; ++next; if (next != __last && *next == '#') __first = skip_blanks(++next, __last); } const QByteArray fast_name(name_begin, name_end - name_begin); if (const QByteArray *actual = resolve_formal (fast_name)) { const char *begin = actual->constData (); const char *end = begin + actual->size (); if (paste) { for (--end; end != begin - 1; --end) { if (! pp_isspace(*end)) break; } ++end; } __result->append(begin, end - begin); continue; } Macro *macro = env->resolve (fast_name); if (! macro || macro->isHidden() || env->hideNext) { if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined") env->hideNext = true; else env->hideNext = false; if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_') { if (fast_name == "__LINE__") { __result->append(QByteArray::number(env->currentLine + lines)); continue; } else if (fast_name == "__FILE__") { __result->append('"'); __result->append(env->currentFile.toUtf8()); __result->append('"'); continue; } else if (fast_name == "__DATE__") { __result->append('"'); __result->append(QDate::currentDate().toString().toUtf8()); __result->append('"'); continue; } else if (fast_name == "__TIME__") { __result->append('"'); __result->append(QTime::currentTime().toString().toUtf8()); __result->append('"'); continue; } } __result->append(name_begin, name_end - name_begin); continue; } if (! macro->isFunctionLike()) { Macro *m = 0; if (! macro->definition().isEmpty()) { macro->setHidden(true); QByteArray __tmp; __tmp.reserve (256); MacroExpander expand_macro (env); expand_macro(macro->definition(), &__tmp); if (! __tmp.isEmpty ()) { const char *__tmp_begin = __tmp.constBegin(); const char *__tmp_end = __tmp.constEnd(); const char *__begin_id = skip_whitespaces (__tmp_begin, __tmp_end); const char *__end_id = skip_identifier (__begin_id, __tmp_end); if (__end_id == __tmp_end) { const QByteArray __id (__begin_id, __end_id - __begin_id); m = env->resolve (__id); } if (! m) *__result += __tmp; } macro->setHidden(false); } if (! m) continue; macro = m; } // function like macro const char *arg_it = skip_whitespaces (__first, __last); if (arg_it == __last || *arg_it != '(') { __result->append(name_begin, name_end - name_begin); lines += skip_whitespaces.lines; __first = arg_it; continue; } QVector<QByteArray> actuals; QVector<MacroArgumentReference> actuals_ref; actuals.reserve (5); ++arg_it; // skip '(' MacroExpander expand_actual (env, frame); const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); if (arg_it != arg_end) { actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it)); const QByteArray actual (arg_it, arg_end - arg_it); QByteArray expanded; expand_actual (actual.constBegin (), actual.constEnd (), &expanded); actuals.push_back (expanded); arg_it = arg_end; } while (arg_it != __last && *arg_end == ',') { ++arg_it; // skip ',' arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it)); const QByteArray actual (arg_it, arg_end - arg_it); QByteArray expanded; expand_actual (actual.constBegin (), actual.constEnd (), &expanded); actuals.push_back (expanded); arg_it = arg_end; } if (! (arg_it != __last && *arg_it == ')')) return __last; ++arg_it; // skip ')' __first = arg_it; pp_frame frame (macro, actuals); MacroExpander expand_macro (env, &frame); macro->setHidden(true); expand_macro (macro->definition(), __result); macro->setHidden(false); } else __result->append(*__first++); } return __first; }
Variable* assign(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in assignment.\n"); return NULL; } if(!A->reference) { interpreter.error("Error: Assigning value to a non-reference variable.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); bool mismatch = false; if(a == STRING) { if(b != STRING) mismatch = true; else { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); C->setValue(D->getValue()); } } else if(a == INT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Int* C = static_cast<Int*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == FLOAT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Float* C = static_cast<Float*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == BOOL) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Bool* C = static_cast<Bool*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == MACRO) { if(b != MACRO) mismatch = true; else { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); C->setValue(D->getValue()); } } else if(a == ARRAY) { if(b != ARRAY) mismatch = true; else { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = D->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } C->setValue(D->getValue()); } } else if(a == LIST) { if(b != LIST) mismatch = true; else { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); C->setValue(D->getValue()); } } else if(a == FUNCTION) { if(b != FUNCTION) mismatch = true; else { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); C->setValue(D->getValue()); } } else if(a == PROCEDURE) { if(b != PROCEDURE) mismatch = true; else { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); C->setValue(D->getValue()); } } if(mismatch) { interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } return A; }
Variable* add(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in addition.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a != b && !(a == FLOAT && b == INT) && !(b == FLOAT && a == INT)) { interpreter.error("Error: Types do not match in addition: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } if(a == STRING) { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); String* R = new String("<temp>"); R->setValue(C->getValue() + D->getValue()); return R; } else if(a == INT) { Int* C = static_cast<Int*>(A); if(b == INT) { Int* D = static_cast<Int*>(B); Int* R = new Int; R->setValue(C->getValue() + D->getValue()); return R; } else { Float* D = static_cast<Float*>(B); Float* R = new Float; R->setValue(C->getValue() + D->getValue()); return R; } } else if(a == FLOAT) { Float* C = static_cast<Float*>(A); Float* R = new Float; if(b == INT) { Int* D = static_cast<Int*>(B); R->setValue(C->getValue() + D->getValue()); } else { Float* D = static_cast<Float*>(B); R->setValue(C->getValue() + D->getValue()); } return R; } else if(a == BOOL) { interpreter.error("Error: Addition operation not defined for type 'bool'.\n"); return NULL; } else if(a == MACRO) { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); Macro* R = new Macro; R->setValue(C->getValue() + D->getValue()); return R; } else if(a == ARRAY) { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = D->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in addition: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } vector<Variable*> va = C->getValue(); vector<Variable*>& vb = D->getValue(); for(vector<Variable*>::iterator e = vb.begin(); e != vb.end(); e++) { va.push_back(*e); } Array* arr = new Array("<temp>", va, a); return arr; } else if(a == LIST) { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); list<Variable*> va = C->getValue(); list<Variable*>& vb = D->getValue(); for(list<Variable*>::iterator e = vb.begin(); e != vb.end(); e++) { va.push_back(*e); } List* lst = new List("<temp>", va); return lst; } else if(a == FUNCTION) { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); Function* R = new Function("<temp>", FN_NONE); R->setValue(C->getValue() + D->getValue()); return R; } else if(a == PROCEDURE) { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); Procedure* R = new Procedure("<temp>"); R->setValue(C->getValue() + D->getValue()); return R; } return A; }
void Driver::addMacro( const Macro & macro ) { m_macros.insert( macro.name(), macro ); }
Macro MacroParser::Parse() { if (_macroString.StartsWith(_T("HM_DROP_COLUMN_OBJECTS"))) { int pos = _macroString.Find(_T(" ")); String columnSpecifier = _macroString.Mid(pos); int separator = columnSpecifier.Find(_T(".")); String tableName = columnSpecifier.Mid(0, separator); String columnName = columnSpecifier.Mid(separator+1); tableName.Trim(); columnName.Trim(); Macro macro; macro.SetType(Macro::DropColumnKeys); macro.SetTableName(tableName); macro.SetColumnName(columnName); return macro; } else if (_macroString == _T("UPDATE_MESSAGES_SET_FOLDER_INBOX")) { Macro macro; macro.SetType(Macro::SQLCEUPDATE_MESSAGES_SET_FOLDER_INBOX); return macro; } else if (_macroString == _T("UPDATE_FOLDERS_SET_CURRENT_UID")) { Macro macro; macro.SetType(Macro::SQLCEUPDATE_FOLDERS_SET_CURRENT_UID); return macro; } else if (_macroString == _T("UPDATE_FOLDERS_SET_NEW_PARENTFOLDERID_WHERE_ZERO")) { Macro macro; macro.SetType(Macro::SQLCEUPDATE_FOLDERS_SET_NEW_PARENTFOLDERID_WHERE_ZERO); return macro; } else if (_macroString == _T("SQLCE_UPDATE_IMAP_HIERARCHY_DELIMITER")) { Macro macro; macro.SetType(Macro::SQLCE_UPDATE_IMAP_HIERARCHY_DELIMITER); return macro; } Macro unknownMacro; return unknownMacro; }
void DirectiveParser::parseDefine(Token *token) { assert(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, token->text); return; } if (isMacroNameReserved(token->text)) { mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } // Using double underscores is allowed, but may result in unintended // behavior, so a warning is issued. At the time of writing this was // specified in ESSL 3.10, but the intent judging from Khronos // discussions and dEQP tests was that double underscores should be // allowed in earlier ESSL versions too. if (hasDoubleUnderscores(token->text)) { mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location, token->text); } Macro macro; macro.type = Macro::kTypeObj; macro.name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. macro.type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end()) { mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES, token->location, token->text); return; } macro.parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. } while (token->type == ','); if (token->type != ')') { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. } while ((token->type != '\n') && (token->type != Token::LAST)) { // Reset the token location because it is unnecessary in replacement // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); macro.replacements.push_back(*token); mTokenizer->lex(token); } if (!macro.replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. macro.replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. MacroSet::const_iterator iter = mMacroSet->find(macro.name); if (iter != mMacroSet->end() && !macro.equals(iter->second)) { mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro.name); return; } mMacroSet->insert(std::make_pair(macro.name, macro)); }