void RequestParser::parseHeaders(const Item& aItem, Headers& aHeaders) { Item lKey; String lName; String lValue; zorba::Iterator_t lIterator = aItem.getObjectKeys(); lIterator->open(); while (lIterator->next(lKey)) { lName = lKey.getStringValue(); getString(aItem, lName, true, lValue); aHeaders.push_back(std::pair<String, String>(lName, lValue)); } lIterator->close(); }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- size_t ChValidation::ReadDataFile(const std::string& filename, char delim, Headers& headers, Data& data) { std::ifstream ifile(filename.c_str()); std::string line; // Count the number of lines in the file then rewind the input file stream. size_t num_lines = std::count(std::istreambuf_iterator<char>(ifile), std::istreambuf_iterator<char>(), '\n'); ifile.seekg(0, ifile.beg); size_t num_data_points = num_lines - 3; // Skip the first two lines. std::getline(ifile, line); std::getline(ifile, line); // Read the line with column headers. std::getline(ifile, line); std::stringstream iss1(line); std::string col_header = ""; while (std::getline(iss1, col_header, delim)) headers.push_back(col_header); size_t num_cols = headers.size(); // Resize data data.resize(num_cols); for (size_t col = 0; col < num_cols; col++) data[col].resize(num_data_points); // Read the actual data, one line at a time. size_t row = 0; while (std::getline(ifile, line)) { std::stringstream iss(line); for (size_t col = 0; col < num_cols; col++) iss >> data[col][row]; row++; } return row; }
int main(int argc, char *argv[]) { // Parse command line arguments. boost::filesystem::path output("."); if (argc >= 2) output = argv[1]; // Create the output directory if required. if (!boost::filesystem::exists(output)) { cout << "Creating output directory " << output << '\n'; boost::filesystem::create_directories(output); } // Build the AST. Builder builder; buildAST(builder); // Determine implemented interfaces and child nodes. determineImplementedInterfaces(builder); determineChildNodes(builder); // Generate the code for the nodes. Headers headerFileNames; Headers sourceFileNames; for (Builder::Nodes::iterator it = builder.nodes.begin(); it != builder.nodes.end(); it++) { const std::string &name = it->first; Node &node = it->second; //cout << "- Generating \033[36;1m" << name << "\033[0m" << '\n'; std::string headerName = name + ".hpp"; std::string sourceName = name + ".cpp"; // Generate the header and source file. boost::filesystem::path hpath = output, spath = output; hpath /= headerName; spath /= sourceName; std::ofstream h(hpath.c_str()); std::ofstream s(spath.c_str()); h << "/* Automatically generated by ast-gen. DO NOT MODIFY. */\n"; h << "#pragma once\n"; h << "#include \"maxwell/ast/Node.hpp\"\n"; h << "#include \"maxwell/ast/nodes/interfaces.hpp\"\n"; h << "#include \"maxwell/ast/nodes/types.hpp\"\n"; if (node.parent != "Node") h << "#include \"maxwell/ast/nodes/" << node.parent << ".hpp\"\n"; h << '\n'; s << "/* Automatically generated by ast-gen. DO NOT MODIFY. */\n"; s << "#include \"maxwell/ast/nodes/" << headerName << "\"\n"; s << "#include \"maxwell/ast/Coder.hpp\"\n"; s << "#include <cstdio>\n"; s << "#include <sstream>\n"; s << "#include <stdexcept>\n"; s << "using ast::" << name << ";\n"; s << "using ast::NodePtr;\n"; s << "using ast::NodeVector;\n\n"; h << "namespace ast {\n\n"; h << "class Encoder;\n"; h << "class Decoder;\n\n"; h << "class " << name << " : public Node\n{\npublic:\n"; // Generate the constructor. h << "\t// constructor\n"; h << "\t" << name << "();\n\n"; s << name << "::" << name << "() : Node()"; for (Node::Interfaces::iterator it = node.interfaces.begin(); it != node.interfaces.end(); it++) { const Node& intf = **it; s << ",\n\tinterface" << intf.name << "(this)"; } s << " {}\n\n"; // Generate auxiliary functions. h << "\t// auxiliary functions\n"; h << "\tvirtual bool isKindOf(Kind k);\n"; h << "\tvirtual bool implements(Interface i);\n"; h << "\tvirtual std::string getClassName() const { return \"" << node.name << "\"; }\n"; h << "\tvirtual NodePtr copy();\n"; h << "\tvirtual bool equalTo(const NodePtr& o);\n"; h << "\tvirtual std::string describe(int depth = -1);\n"; h << '\n'; // isKindOf s << "bool " << name << "::isKindOf(Kind k) {\n"; s << "\tif (" << node.parent << "::isKindOf(k)) return true;\n"; s << "\treturn k == k" << node.name << ";\n"; s << "}\n\n"; // implements s << "bool " << name << "::implements(Interface i) {\n"; s << "\tif (" << node.parent << "::implements(i)) return true;\n"; for (Node::Interfaces::iterator it = node.interfaces.begin(); it != node.interfaces.end(); it++) { const Node& intf = **it; s << "\tif (i == k" << intf.intfName << ") return true;\n"; } s << "\treturn false;\n"; s << "}\n\n"; // copy s << "NodePtr " << name << "::copy() {\n"; s << "\tPtr c (new " << name << ");\n"; for (Node::Fields::iterator f = node.attributes.begin(); f != node.attributes.end(); f++) { s << "\tNode::copy(this->" << (*f).name << ", c->" << (*f).name << ");\n"; } s << "\treturn c;\n"; s << "}\n\n"; // equalTo s << "bool " << name << "::equalTo(const NodePtr& o) {\n"; s << "\tconst shared_ptr<" << node.name << ">& other = boost::dynamic_pointer_cast<" << node.name << ">(o);\n"; s << "\tif (!other) return false;\n"; for (Node::Fields::iterator fit = node.attributes.begin(); fit != node.attributes.end(); fit++) { Node::Field& f = *fit; s << "\tif (!equal(this->" << f.name << ", other->" << f.name << ")) return false;\n"; } s << "\treturn true;\n"; s << "}\n\n"; // describe s << "std::string " << name << "::describe(int depth) {\n"; s << "\tstd::stringstream str, b;\n"; if (node.descriptionBody.empty()) { s << "\tif (depth == 0) return \"" << name << "{…}\";\n"; s << "\tstr << \"" << name << "{\";\n"; for (Node::Fields::iterator fit = node.attributes.begin(); fit != node.attributes.end(); fit++) { Node::Field& f = *fit; // Don't print empty strings and arrays. s << "\t"; if (f.isString || f.isArray) s << "if (!this->" <<f.name<< ".empty()) "; if (f.isNode) s << "if (this->" << f.name << ") "; // Print the field name. s << "b << \"\\n \\033[1m" << f.name << "\\033[0m = "; // Print the actual data. if (f.isString) s << "\\033[33m\\\"\" << this->" << f.name << " << \"\\\"\\033[0m\";"; if (f.isBool) s << "\\033[34m\" << (this->" << f.name << " ? \"true\" : \"false\") << \"\\033[0m\";"; if (f.isInt) s << "\\033[35m\" << this->" << f.name << " << \"\\033[0m\";"; if (f.isNode) { if (f.ref) { s << "\\033[36m\" << this->" << f.name << ".id << \"\\033[0m\";"; } else { s << "\" << indent(this->" << f.name << "->describe(depth-1));"; } } if (f.isArray) s << "\" << indent(describeVector(this->" << f.name << ", depth-1));"; s << "\n"; } s << "\tstring bs = b.str();\n"; s << "\tif (!bs.empty()) str << bs << '\\n';\n"; s << "\tstr << \"}\";\n"; } else { string body(node.descriptionBody); boost::algorithm::replace_all(body, "\n", "\n\t\t"); s << "\t" << body << "\n"; } s << "\treturn str.str();\n"; s << "}\n\n"; s << '\n'; // Generate the accessor functions. h << "\t// accessor functions\n"; for (Node::Fields::iterator fit = node.attributes.begin(); fit != node.attributes.end(); fit++) { Node::Field& f = *fit; string ref = "const " + f.cpp_type + "&"; string upper = f.name; if (!upper.empty()) upper[0] = toupper(upper[0]); h << "\tvoid set" << upper << "(" << ref << " v);\n"; s << "void " << name << "::set" << upper << "(" << ref << " v) {\n"; vector<string> ifcomponents; string allowedNodes; string allowedInterfaces; for (unsigned i = 0; i < f.allowedNodes.size(); i++) { ifcomponents.push_back("!v->isKindOf(k" + f.allowedNodes[i] + ")"); if (!allowedNodes.empty()) allowedNodes += ", "; allowedNodes += f.allowedNodes[i]; } for (unsigned i = 0; i < f.allowedInterfaces.size(); i++) { ifcomponents.push_back("!v->implements(k" + builder.interfaces[f.allowedInterfaces[i]].intfName + ")"); if (!allowedInterfaces.empty()) allowedInterfaces += ", "; allowedInterfaces += f.allowedInterfaces[i]; } if (!ifcomponents.empty()) { s << "\tif (v"; for (unsigned i = 0; i < ifcomponents.size(); i++) { s << " && " << ifcomponents[i]; } s << ") {\n"; s << "\t\tthrow std::runtime_error(\"'" << f.name << "' of \" + id.str() + \" needs to be of kind {" << allowedNodes << "} or implement interface {" << allowedInterfaces << "}, got \" + v->getClassName() + \" (\" + v->getId().str() + \") instead.\");\n"; s << "\t}\n"; } if (f.ref) { s << "\tif (!v && " << f.name << ") {\n"; s << "\t\tmodify(\"" << f.name << "\");\n"; s << "\t\t" << f.name << ".reset();\n"; s << "\t}\n"; s << "\tif (!" << f.name << " || v->getId() != " << f.name << ".id) {\n"; } else { s << "\tif (!equal(v, " << f.name << ")) {\n"; } s << "\t\tmodify(\"" << f.name << "\");\n"; if (f.ref) { s << "\t\t" << f.name << ".set(v);\n"; } else { s << "\t\t" << f.name << " = v;\n"; } s << "\t}\n"; s << "}\n\n"; // special setter for references if (f.ref) { h << "\tvoid set" << upper << "(const NodeId& v);\n"; s << "void " << name << "::set" << upper << "(const NodeId& v) {\n"; s << "\tif (v != " << f.name << ".id) {\n"; s << "\t\tmodify(\"" << f.name << "\");\n"; s << "\t\t" << f.name << ".set(v);\n"; s << "\t}\n"; s << "}\n\n"; } h << "\t" << ref << " get" << upper << "(bool required = true);\n\n"; s << ref << " " << name << "::get" << upper << "(bool required) {\n"; s << "\tconst " << f.cpp_type << "& v = "; if (f.ref) { s << f.name << ".get(repository);\n"; } else { s << f.name << ";\n"; } if (f.isNode) { s << "\tif (required && !v) {\n"; s << "\t\tthrow std::runtime_error(\"Node \" + getId().str() + \" is required to have " << f.name << " set to a non-null value.\");\n"; s << "\t}\n"; } else if (f.isString) { s << "\tif (required && v.empty()) {\n"; s << "\t\tthrow std::runtime_error(\"Node \" + getId().str() + \" is required to have a non-empty string " << f.name << " set.\");\n"; s << "\t}\n"; } s << "\treturn v;\n"; s << "}\n\n\n"; } // Generate the encode() and decode() function. h << "\t// encoding and decoding\n"; h << "\tvirtual void encode(Encoder& e);\n"; h << "\tvirtual void decode(Decoder& d);\n"; h << '\n'; s << "void " << name << "::encode(Encoder& e) {\n"; s << "\te.encode(this->range);\n"; s << "\te.encode(this->referenceRange);\n"; for (Node::Fields::iterator f = node.attributes.begin(); f != node.attributes.end(); f++) { s << "\te.encode(this->" << (*f).name << ");\n"; } s << "}\n\n"; s << "void " << name << "::decode(Decoder& d) {\n"; s << "\td.decode(this->range);\n"; s << "\td.decode(this->referenceRange);\n"; for (Node::Fields::iterator f = node.attributes.begin(); f != node.attributes.end(); f++) { s << "\td.decode(this->" << (*f).name << ");\n"; } s << "}\n\n"; s << '\n'; // Generate the hierarchy functions. h << "\t// hierarchy functions\n"; h << "\tvirtual void updateHierarchyOfChildren();\n"; h << "\tvirtual const NodePtr& resolvePath(const std::string& path);\n"; // updateHierarchy s << "void " << name << "::updateHierarchyOfChildren() {\n"; for (Node::Fields::iterator fit = node.attributes.begin(); fit != node.attributes.end(); fit++) { Node::Field& f = *fit; if (f.isNode && !f.ref) { s << "\tif (this->"<<f.name<<") this->"<<f.name<<"->updateHierarchy(id + \""<<f.name<<"\", repository, this);\n"; } else if (f.isNodeArray) { s << "\tfor (unsigned i = 0; i < this->"<<f.name<<".size(); i++) {\n"; s << "\t\tchar buf[32]; snprintf(buf, 31, \"%i\", i);\n"; s << "\t\tthis->"<<f.name<<"[i]->updateHierarchy((id + \""<<f.name<<"\") + buf, repository, this);\n"; s << "\t}\n"; } } s << "}\n\n"; // resolvePath s << "const NodePtr& " << name << "::resolvePath(const std::string& path) {\n"; FieldNames fields, arrayFields; for (Node::Fields::iterator fit = node.attributes.begin(); fit != node.attributes.end(); fit++) { Node::Field& f = *fit; if (f.isNode) { fields.insert(f.name); } else if (f.isNodeArray) { fields.insert(f.name); arrayFields.insert(f.name); } } if (!fields.empty()) { s << "\tsize_t size = path.size();\n"; generateResolvePathBody(s, fields, arrayFields, 1); } s << "\tthrow std::runtime_error(\"Node path '\" + path + \"' does not point to a node or array of nodes.\");\n"; s << "}\n\n"; // getChildren if (!node.children.empty()) { h << "\tvirtual NodeVector getChildren();\n"; s << "NodeVector " << name << "::getChildren() {\n"; s << "\tNodeVector v;\n"; for (Node::Children::iterator c = node.children.begin(); c != node.children.end(); c++) { Node::Field& f = **c; if (f.isNode) { string upper = (char)toupper(f.name[0]) + f.name.substr(1); s << "\tif (const NodePtr& n = this->get" << upper << "(false)) v.push_back(n);\n"; } else if (f.isArray) { s << "\tv.insert(v.end(), this->" << f.name << ".begin(), this->" << f.name << ".end());\n"; } } s << "\treturn v;\n"; s << "}\n\n"; } h << '\n'; // Generate the interface accessors. if (!node.interfaces.empty()) { h << "\t// interfaces\n"; for (Node::Interfaces::iterator it = node.interfaces.begin(); it != node.interfaces.end(); it++) { const Node& intf = **it; h << "\tvirtual " << intf.intfName << "* as" << intf.name << "() { return &this->interface" << intf.name << "; }\n"; } h << "\n"; } // Generate boost::shared_ptr convenience typedef. h << "\t// shared_ptr convenience\n"; h << "\ttypedef boost::shared_ptr<" << node.name << "> Ptr;\n"; h << "\ttemplate<typename T> static Ptr from(const T& n) { return boost::dynamic_pointer_cast<" << node.name << ">(n); }\n"; h << "\ttemplate<typename T> static Ptr needFrom(const T& n) {\n"; h << "\t\tPtr r = boost::dynamic_pointer_cast<" << node.name << ">(n);\n"; h << "\t\tif (!r)\n"; h << "\t\t\tthrow std::runtime_error(\"Node \" + n->getId().str() + \" (a \" + n->getClassName() + \") cannot be dynamically cast to " << node.name << ".\");\n"; h << "\t\treturn r;\n"; h << "\t}\n"; h << '\n'; h << "protected:\n"; for (Node::Fields::iterator f = node.attributes.begin(); f != node.attributes.end(); f++) { if ((*f).ref) { h << "\tNodeRef " << (*f).name << ";\n"; } else { h << "\t" << (*f).cpp_type << " " << (*f).name << ";\n"; } } if (!node.interfaces.empty()) { h << "\n\t// interfaces\n"; for (Node::Interfaces::iterator it = node.interfaces.begin(); it != node.interfaces.end(); it++) { const Node& intf = **it; h << "\t" << intf.intfName << "Impl<" << node.name << "> interface" << intf.name << ";\n"; } } h << "};\n\n"; h << "} // namespace ast\n"; headerFileNames.push_back(headerName); sourceFileNames.push_back(sourceName); } // Generate the header file containing general typedefs. makeTypesHeader(output, builder); makeNodesHeader(output, builder, headerFileNames); makeInterfacesHeader(output, builder); // Generate the base header file for ast::Node which implements default interface accessors. makeBaseNodeHeader(output, builder); // Generate the header file aggregating all AST things. boost::filesystem::path ahpath = output; ahpath /= "ast.hpp"; ofstream ah(ahpath.c_str()); ah << "/* Automatically generated by ast-gen. DO NOT MODIFY. */\n"; ah << "#pragma once\n\n"; ah << "#include \"maxwell/ast/nodes/types.hpp\"\n"; ah << "#include \"maxwell/ast/nodes/nodes.hpp\"\n"; ah << "#include \"maxwell/ast/nodes/interfaces.hpp\"\n"; return 0; }