diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 865502e9..dbdef0ec 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -777,63 +777,6 @@ RamseyConstraintsStatement::writeJsonOutput(ostream &output) const output << "}"; } -// Statement * -// RamseyConstraintsStatement::cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) -// { -// vector errors; -// SymbolList new_symbol_list, new_options_symbol_list; -// OptionsList new_options_list = options_list; -// SymbolTable *new_symbol_table = dynamic_datatree.getSymbolTable(); -// vector symbols = symbol_list.get_symbols(); - -// for (vector::const_iterator it = symbols.begin(); it != symbols.end(); it++) -// try -// { -// new_symbol_table->getID(*it); -// new_symbol_list.addSymbol(*it); -// } -// catch (SymbolTable::UnknownSymbolIDException &e) -// { -// errors.push_back(orig_symbol_table.getName(e.id)); -// } -// catch (SymbolTable::UnknownSymbolNameException &e) -// { -// errors.push_back(e.name); -// } - -// OptionsList::symbol_list_options_t::const_iterator it = options_list.symbol_list_options.find("instruments"); -// if (it != options_list.symbol_list_options.end()) -// { -// symbols = it->second.get_symbols(); -// for (vector::const_iterator it1 = symbols.begin(); it1 != symbols.end(); it1++) -// try -// { -// new_symbol_table->getID(*it1); -// new_options_symbol_list.addSymbol(*it1); -// } -// catch (SymbolTable::UnknownSymbolIDException &e) -// { -// errors.push_back(orig_symbol_table.getName(e.id)); -// } -// catch (SymbolTable::UnknownSymbolNameException &e) -// { -// errors.push_back(e.name); -// } -// new_options_list.symbol_list_options["instruments"] = new_options_symbol_list; -// } - -// if (!errors.empty()) -// { -// cerr << endl -// << "ERROR: The following vars were used in the ramsey_policy statement(s) but were not declared." << endl -// << " This likely means that you declared them as varexo and that they're not in the model" << endl; -// for (vector::const_iterator it = errors.begin(); it != errors.end(); it++) -// cerr << *it << endl; -// exit(EXIT_FAILURE); -// } -// return new RamseyPolicyStatement(new_symbol_list, options_list); -// } - RamseyPolicyStatement::RamseyPolicyStatement(const SymbolTable &symbol_table_arg, const vector &ramsey_policy_list_arg, const OptionsList &options_list_arg) : diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 09e25f4e..3f09c1a7 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -213,7 +213,6 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeJsonOutput(ostream &output) const; - // virtual Statement *cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table); }; class RamseyPolicyStatement : public Statement diff --git a/DynareMain.cc b/DynareMain.cc index 8176d6f9..d37b2314 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -48,9 +48,8 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple ); -void main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file, - bool no_line_macro, - map &defines, vector &path, stringstream ¯o_output); +void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file, + bool no_line_macro, map &defines, vector &path, stringstream ¯o_output); void usage() @@ -339,9 +338,34 @@ main(int argc, char **argv) // Construct basename (i.e. remove file extension if there is one) string basename = argv[1]; - size_t pos = basename.find_last_of('.'); - if (pos != string::npos) - basename.erase(pos); + string modfile, modfiletxt; + size_t fsc = basename.find_first_of(';'); + if (fsc != string::npos) + { + // If a semicolon is found in argv[1], treat it as the text of the modfile + modfile = "mod_file_passed_as_string.mod"; + basename = "mod_file_passed_as_string"; + modfiletxt = argv[1]; + } + else + { + // If a semicolon is NOT found in argv[1], treat it as the name of the modfile + modfile = argv[1]; + size_t pos = basename.find_last_of('.'); + if (pos != string::npos) + basename.erase(pos); + + ifstream modfile(argv[1], ios::binary); + if (modfile.fail()) + { + cerr << "ERROR: Could not open file: " << argv[1] << endl; + exit(EXIT_FAILURE); + } + + stringstream buffer; + buffer << modfile.rdbuf(); + modfiletxt = buffer.str(); + } WarningConsolidation warnings(no_warn); @@ -360,7 +384,7 @@ main(int argc, char **argv) // Do macro processing stringstream macro_output; - main1(argv[1], basename, debug, save_macro, save_macro_file, no_line_macro, defines, path, macro_output); + main1(modfile, basename, modfiletxt, debug, save_macro, save_macro_file, no_line_macro, defines, path, macro_output); if (only_macro) return EXIT_SUCCESS; diff --git a/DynareMain1.cc b/DynareMain1.cc index 3cbd33f3..fe87ba83 100644 --- a/DynareMain1.cc +++ b/DynareMain1.cc @@ -23,13 +23,13 @@ #include "macro/MacroDriver.hh" void -main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file, bool no_line_macro, - map &defines, vector &path, stringstream ¯o_output) +main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file, + bool no_line_macro, map &defines, vector &path, stringstream ¯o_output) { // Do macro processing MacroDriver m; - m.parse(modfile, macro_output, debug, no_line_macro, defines, path); + m.parse(modfile, modfiletxt, macro_output, debug, no_line_macro, defines, path); if (save_macro) { if (save_macro_file.empty()) diff --git a/ExprNode.cc b/ExprNode.cc index 80063559..66b479d2 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -2147,11 +2147,14 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "exp"; break; case oLog: - output << "log"; + if (IS_LATEX(output_type)) + output << "\\log"; + else + output << "log"; break; case oLog10: if (IS_LATEX(output_type)) - output << "log_{10}"; + output << "\\log_{10}"; else output << "log10"; break; diff --git a/ModFile.cc b/ModFile.cc index c7b45ac3..2ab5a4b7 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -413,6 +413,23 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs) mod_file_struct.ramsey_eq_nbr = dynamic_model.equation_number() - mod_file_struct.orig_eq_nbr; } + // Workaround for #1193 + if (!mod_file_struct.hist_vals_wrong_lag.empty()) + { + bool err = false; + for (map::const_iterator it = mod_file_struct.hist_vals_wrong_lag.begin(); + it != mod_file_struct.hist_vals_wrong_lag.end(); it++) + if (dynamic_model.minLagForSymbol(it->first) > it->second - 1) + { + cerr << "ERROR: histval: variable " << symbol_table.getName(it->first) + << " does not appear in the model with the lag " << it->second - 1 + << " (see the reference manual for the timing convention in 'histval')" << endl; + err = true; + } + if (err) + exit(EXIT_FAILURE); + } + if (mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present || mod_file_struct.osr_present diff --git a/NumericalInitialization.cc b/NumericalInitialization.cc index 84302651..ad199014 100644 --- a/NumericalInitialization.cc +++ b/NumericalInitialization.cc @@ -308,9 +308,11 @@ EndValStatement::writeJsonOutput(ostream &output) const } HistValStatement::HistValStatement(const hist_values_t &hist_values_arg, + const hist_vals_wrong_lag_t hist_vals_wrong_lag_arg, const SymbolTable &symbol_table_arg, const bool &all_values_required_arg) : hist_values(hist_values_arg), + hist_vals_wrong_lag(hist_vals_wrong_lag_arg), symbol_table(symbol_table_arg), all_values_required(all_values_required_arg) { @@ -356,6 +358,7 @@ HistValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat if (unused_endo.size() > 0 || unused_exo.size() > 0) exit(EXIT_FAILURE); } + mod_file_struct.hist_vals_wrong_lag = hist_vals_wrong_lag; } void diff --git a/NumericalInitialization.hh b/NumericalInitialization.hh index 58a7e6e0..16f5acd1 100644 --- a/NumericalInitialization.hh +++ b/NumericalInitialization.hh @@ -107,12 +107,15 @@ public: Maps pairs (symbol_id, lag) to expr_t */ typedef map, expr_t> hist_values_t; + typedef map hist_vals_wrong_lag_t; private: const hist_values_t hist_values; + const hist_vals_wrong_lag_t hist_vals_wrong_lag; const SymbolTable &symbol_table; const bool all_values_required; public: HistValStatement(const hist_values_t &hist_values_arg, + const hist_vals_wrong_lag_t hist_vals_wrong_lag_arg, const SymbolTable &symbol_table_arg, const bool &all_values_required_arg); //! Workaround for trac ticket #157 diff --git a/ParsingDriver.cc b/ParsingDriver.cc index e95db642..fbade4c5 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -712,14 +712,13 @@ ParsingDriver::hist_val(string *name, string *lag, expr_t rhs) error("histval: " + *name + " should be an endogenous or exogenous variable"); int ilag = atoi(lag->c_str()); + if (ilag > 0) + error("histval: the lag on " + *name + " should be less than or equal to 0"); + pair key(symb_id, ilag); if (mod_file->dynamic_model.minLagForSymbol(symb_id) > ilag - 1) - { - ostringstream s; - s << ilag-1; - error("histval: variable " + *name + " does not appear in the model with the lag " + s.str() + " (see the reference manual for the timing convention in 'histval')"); - } + hist_vals_wrong_lag[symb_id] = ilag; if (hist_values.find(key) != hist_values.end()) error("hist_val: (" + *name + ", " + *lag + ") declared twice"); @@ -835,7 +834,7 @@ ParsingDriver::end_endval(bool all_values_required) void ParsingDriver::end_histval(bool all_values_required) { - mod_file->addStatement(new HistValStatement(hist_values, mod_file->symbol_table, all_values_required)); + mod_file->addStatement(new HistValStatement(hist_values, hist_vals_wrong_lag, mod_file->symbol_table, all_values_required)); hist_values.clear(); } diff --git a/ParsingDriver.hh b/ParsingDriver.hh index 1ebfff5c..252d79ee 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -157,6 +157,8 @@ private: InitOrEndValStatement::init_values_t init_values; //! Temporary storage for histval blocks HistValStatement::hist_values_t hist_values; + //! Temporary storage for histval blocks + HistValStatement::hist_vals_wrong_lag_t hist_vals_wrong_lag; //! Temporary storage for homotopy_setup blocks HomotopyStatement::homotopy_values_t homotopy_values; //! Temporary storage for moment_calibration diff --git a/Statement.hh b/Statement.hh index db7d5606..a6a1d5c3 100644 --- a/Statement.hh +++ b/Statement.hh @@ -123,6 +123,8 @@ public: bool steady_state_model_present; //! Whether there is a write_latex_steady_state_model statement present bool write_latex_steady_state_model_present; + //! Histval values that do not have the appropriate lag + map hist_vals_wrong_lag; }; class Statement diff --git a/SymbolTable.cc b/SymbolTable.cc index 9a04d4ca..c7f22dbf 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -38,7 +38,7 @@ AuxVarInfo::AuxVarInfo(int symb_id_arg, aux_var_t type_arg, int orig_symb_id_arg { } -SymbolTable::SymbolTable() : frozen(false), size(0) +SymbolTable::SymbolTable() : frozen(false) { } @@ -78,7 +78,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na else non_long_name_partition_exists = true; - int id = size++; + int id = symbol_table.size(); symbol_table[name] = id; type_table.push_back(type); @@ -110,7 +110,7 @@ SymbolTable::freeze() throw (FrozenException) frozen = true; - for (int i = 0; i < size; i++) + for (int i = 0; i < symbol_table.size(); i++) { int tsi; switch (getType(i)) @@ -156,8 +156,7 @@ SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDExcept if (frozen) throw FrozenException(); - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); + validateSymbID(id); type_table[id] = newtype; } @@ -790,8 +789,8 @@ SymbolTable::getAuxiliaryVarsExprNode(int symb_id) const throw (SearchFailedExce void SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException) { - if (symb_id < 0 || symb_id >= size) - throw UnknownSymbolIDException(symb_id); + validateSymbID(symb_id); + if (frozen) throw FrozenException(); @@ -803,9 +802,7 @@ SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, Fro bool SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException) { - if (symb_id < 0 || symb_id >= size) - throw UnknownSymbolIDException(symb_id); - + validateSymbID(symb_id); return (predetermined_variables.find(symb_id) != predetermined_variables.end()); } @@ -818,9 +815,7 @@ SymbolTable::predeterminedNbr() const void SymbolTable::addObservedVariable(int symb_id) throw (UnknownSymbolIDException) { - if (symb_id < 0 || symb_id >= size) - throw UnknownSymbolIDException(symb_id); - + validateSymbID(symb_id); assert(getType(symb_id) == eEndogenous); varobs.push_back(symb_id); } @@ -848,9 +843,7 @@ SymbolTable::getObservedVariableIndex(int symb_id) const void SymbolTable::addObservedExogenousVariable(int symb_id) throw (UnknownSymbolIDException) { - if (symb_id < 0 || symb_id >= size) - throw UnknownSymbolIDException(symb_id); - + validateSymbID(id); assert(getType(symb_id) != eEndogenous); varexobs.push_back(symb_id); } diff --git a/SymbolTable.hh b/SymbolTable.hh index cf09c59a..8bb11220 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -112,9 +112,6 @@ private: //! Has method freeze() been called? bool frozen; - //! Number of symbols contained in the table - int size; - typedef map symbol_table_type; //! Maps strings to symbol IDs symbol_table_type symbol_table; @@ -226,6 +223,8 @@ private: int addLeadAuxiliaryVarInternal(bool endo, int index, expr_t arg) throw (FrozenException); //! Factorized code for Json writing void writeJsonVarVector(ostream &output, const vector &varvec) const; + //! Factorized code for asserting that 0 <= symb_id <= symbol_table.size() + inline void validateSymbID(int symb_id) const throw (UnknownSymbolIDException); public: //! Add a symbol /*! Returns the symbol ID */ @@ -382,6 +381,13 @@ public: set getOrigEndogenous() const; }; +inline void +SymbolTable::validateSymbID(int symb_id) const throw (UnknownSymbolIDException) +{ + if (symb_id < 0 || symb_id > symbol_table.size()) + throw UnknownSymbolIDException(symb_id); +} + inline bool SymbolTable::exists(const string &name) const { @@ -392,37 +398,29 @@ SymbolTable::exists(const string &name) const inline string SymbolTable::getName(int id) const throw (UnknownSymbolIDException) { - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); - else - return name_table[id]; + validateSymbID(id); + return name_table[id]; } inline string SymbolTable::getTeXName(int id) const throw (UnknownSymbolIDException) { - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); - else - return tex_name_table[id]; + validateSymbID(id); + return tex_name_table[id]; } inline string SymbolTable::getLongName(int id) const throw (UnknownSymbolIDException) { - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); - else - return long_name_table[id]; + validateSymbID(id); + return long_name_table[id]; } inline SymbolType SymbolTable::getType(int id) const throw (UnknownSymbolIDException) { - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); - else - return type_table[id]; + validateSymbID(id); + return type_table[id]; } inline SymbolType @@ -447,8 +445,7 @@ SymbolTable::getTypeSpecificID(int id) const throw (UnknownSymbolIDException, No if (!frozen) throw NotYetFrozenException(); - if (id < 0 || id >= size) - throw UnknownSymbolIDException(id); + validateSymbID(id); return type_specific_ids[id]; } @@ -498,7 +495,7 @@ SymbolTable::param_nbr() const throw (NotYetFrozenException) inline int SymbolTable::maxID() { - return (size-1); + return symbol_table.size() - 1; } inline int diff --git a/macro/MacroDriver.cc b/macro/MacroDriver.cc index 71d53b9c..4d2399ec 100644 --- a/macro/MacroDriver.cc +++ b/macro/MacroDriver.cc @@ -37,18 +37,11 @@ MacroDriver::~MacroDriver() } void -MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro, +MacroDriver::parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, map defines, vector path) { file = f; - ifstream in(f.c_str(), ios::binary); - if (in.fail()) - { - cerr << "ERROR: Could not open file: " << f << endl; - exit(EXIT_FAILURE); - } - /* Copy the file into a stringstream, and add an extra end-of-line. This is a workaround for trac ticket #73: with this workaround, MOD files ending with @@ -66,7 +59,7 @@ MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro { file_with_endl << "@#define " << it->first << " = \"" << it->second << "\"" << endl; } - file_with_endl << in.rdbuf() << endl; + file_with_endl << modfiletxt << endl; lexer = new MacroFlex(&file_with_endl, &out, no_line_macro, path); lexer->set_debug(debug); diff --git a/macro/MacroDriver.hh b/macro/MacroDriver.hh index 773a99dc..c76947de 100644 --- a/macro/MacroDriver.hh +++ b/macro/MacroDriver.hh @@ -182,7 +182,7 @@ public: //! Starts parsing a file, returns output in out /*! \param no_line_macro should we omit the @#line statements ? */ - void parse(const string &f, ostream &out, bool debug, bool no_line_macro, + void parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, map defines, vector path); //! Name of main file being parsed