void generate_switch( FILE *file, struct function *f, int do_static ) { struct entry *r; if( f->options->also ) { fprintf(file,"/* %s has additional code from 'also' statement */\n",f->name->text); fprintf(file,"%s\n",f->options->also->text); } if( f->options->instead ) { fprintf(file,"/* %s generated instead of %s */\n\n",f->options->instead->name->text,f->name->text); generate_switch( file, f->options->instead, do_static ); return; } if( f->options->switch_code ) { fprintf(file,"/* manual switch code for %s */\n\n",f->name->text); fprintf(file,"%s\n\n",f->options->switch_code->text); return; } for( r=f->options->entrys; r; r=r->next ) { generate_entry(file,f,pattern_complete(r->name->text,f->name->text)); } }
void generate(const std::string& source_executable, std::ostream& o) { o << "#include <string>\n"; o << "#include <unordered_map>\n\n"; o << "extern \"C\" {\n\n" << "auto " << HPHP::detail::kMemberReflectionTableName << " =\n" " std::unordered_map<\n" " std::string,\n" " const char*(*)(const void*, const void*)\n" " >\n" "{\n"; if (actually_run) { auto reflectables = std::unordered_set<std::string> { #define X(name) "HPHP::"#name, HPHP_REFLECTABLES #undef X }; auto const parser = TypeParser::make(source_executable); auto first = true; for (auto const& type : parser->getAllObjects()) { if (type.incomplete) continue; if (type.name.linkage != ObjectTypeName::Linkage::external) continue; // Assume the first, complete, external definition is the canonical one. if (!reflectables.count(type.name.name)) continue; reflectables.erase(type.name.name); if (first) { first = false; } else { o << ",\n"; } generate_entry(parser->getObject(type.key), o, parser); } } o << "\n};\n\n"; o << "}"; }
address InterpreterGenerator::generate_normal_entry(bool synchronized) { assert(synchronized == false, "should be"); return generate_entry((address) CppInterpreter::normal_entry); }
address InterpreterGenerator::generate_accessor_entry() { if (!UseFastAccessorMethods) return NULL; return generate_entry((address) CppInterpreter::accessor_entry); }
address InterpreterGenerator::generate_empty_entry() { if (!UseFastEmptyMethods) return NULL; return generate_entry((address) CppInterpreter::empty_entry); }
// // Generate indexes using our own internal method: // void generate_indexes() { for(boost::tiny_xml::element_list::const_iterator i = indexes.begin(); i != indexes.end(); ++i) { boost::tiny_xml::element_ptr node = *i; const std::string* category = find_attr(node, "type"); bool has_title = false; for(boost::tiny_xml::element_list::const_iterator k = (*i)->elements.begin(); k != (*i)->elements.end(); ++k) { if((**k).name == "title") { has_title = true; break; } } boost::tiny_xml::element_ptr navbar = make_element("para"); node->elements.push_back(navbar); index_entry_set::const_iterator m = index_entries.begin(); index_entry_set::const_iterator n = m; boost::tiny_xml::element_ptr vlist = make_element("variablelist"); node->elements.push_back(vlist); while(n != index_entries.end()) { char current_letter = std::toupper((*n)->key[0]); std::string id_name = get_next_index_id(); boost::tiny_xml::element_ptr entry = add_attribute(make_element("varlistentry"), "id", id_name); boost::tiny_xml::element_ptr term = make_element("term"); term->content = std::string(1, current_letter); entry->elements.push_back(term); boost::tiny_xml::element_ptr item = make_element("listitem"); entry->elements.push_back(item); while((n != index_entries.end()) && (std::toupper((*n)->key[0]) == current_letter)) ++n; std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> range(m, n); item->elements.push_back(generate_entry(range, category)); if(item->elements.size() && (*item->elements.begin())->elements.size()) { vlist->elements.push_back(entry); boost::tiny_xml::element_ptr p = make_element(""); p->content = " "; if(navbar->elements.size()) { navbar->elements.push_back(p); } p = add_attribute(make_element("link"), "linkend", id_name); p->content = current_letter; navbar->elements.push_back(p); } m = n; } node->name = internal_index_type; boost::tiny_xml::element_ptr p(node->parent); while(p->name.empty()) p = boost::tiny_xml::element_ptr(p->parent); check_index_type_and_placement(p->name, node->name); node->attributes.clear(); if(!has_title) { boost::tiny_xml::element_ptr t = make_element("title"); t->content = "Index"; node->elements.push_front(t); } } }
boost::tiny_xml::element_ptr generate_entry(const Range& range, const std::string* pcategory, int level = 0, const boost::regex* primary_key = 0) { boost::tiny_xml::element_ptr list = add_attribute(add_attribute(::add_attribute(make_element("itemizedlist"), "mark", "none"), "spacing", "compact"), "role", "index"); for(typename boost::range_iterator<Range>::type i = boost::begin(range); i != boost::end(range);) { std::string key = (*i)->key; index_entry_set entries; bool preferred = false; std::string id; bool collapse = false; // // Create a regular expression for comparing key to other key's: // boost::regex key_regex; if(level == 0) { key_regex = make_primary_key_matcher(key); primary_key = &key_regex; } // // Begin by consolidating entries with identical keys but possibly different categories: // while((i != boost::end(range)) && ((*i)->key == key)) { if((0 == pcategory) || (pcategory->size() == 0) || (pcategory && (**i).category == *pcategory)) { entries.insert((*i)->sub_keys.begin(), (*i)->sub_keys.end()); if((*i)->preferred) preferred = true; if((*i)->id.size()) { if(id.size()) { std::cerr << "WARNING: two identical index terms have different link destinations!!" << std::endl; } id = (*i)->id; } } ++i; } // // Only actually generate content if we have anything in the entries set: // if(entries.size() || id.size()) { // // See if we can collapse any sub-entries into this one: // if(entries.size() == 1) { if((regex_match((*entries.begin())->key, *primary_key) || ((*entries.begin())->key == key)) && ((*entries.begin())->id.size()) && ((*entries.begin())->id != id)) { collapse = true; id = (*entries.begin())->id; } } // // See if this key is the same as the primary key, if it is then make it prefered: // if(level && regex_match(key, *primary_key)) { preferred = true; } boost::tiny_xml::element_ptr item = make_element("listitem"); boost::tiny_xml::element_ptr para = make_element("para"); item->elements.push_back(para); list->elements.push_back(item); if(preferred) { para->elements.push_back(make_element("emphasis")); para = para->elements.back(); } if(id.size()) { boost::tiny_xml::element_ptr link = add_attribute(make_element("link"), "linkend", id); para->elements.push_back(link); para = link; } std::string classname = (boost::format("index-entry-level-%1%") % level).str(); para->elements.push_back(add_attribute(make_element("phrase"), "role", classname)); para = para->elements.back(); para->content = key; if(!collapse && entries.size()) { std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> subrange(entries.begin(), entries.end()); item->elements.push_back(generate_entry(subrange, 0, level+1, primary_key)); } } } return list; }
address InterpreterGenerator::generate_normal_entry(bool synchronized) { return generate_entry((address) CppInterpreter::normal_entry); }