main() { Tokid a(Fileid("tokid.cpp"), 10); Tokid b(Fileid("./tokid.cpp"), 15); // Need pointer so that the delete in merge will work Eclass *e1 = new Eclass(5); e1->add_tokid(a); e1->add_tokid(b); cout << "e1:\n" << *e1; Eclass *e2 = new Eclass(5); Tokid c(Fileid("tokid.h"), 1); Tokid d(Fileid("./tokid.h"), 5); e2->add_tokid(c); e2->add_tokid(d); cout << "e2:\n" << *e2; Eclass *enew = merge(e1, e2); cout << "merged:\n" << *enew; Eclass *es = enew->split(2); cout << "split 0:\n" << *enew << "\n"; cout << "split 2:\n" << *es << "\n"; return (0); }
void GlobObj::dumpSql(Sql *db, ostream &of) { // First define all functions for (const_fmap_iterator_type i = fbegin(); i != fend(); i++) { Call *fun = i->second; Tokid t = fun->get_site(); of << "INSERT INTO FUNCTIONS VALUES(" << ptr_offset(fun) << ", '" << fun->name << "', " << db->boolval(fun->is_macro()) << ',' << db->boolval(fun->is_defined()) << ',' << db->boolval(fun->is_declared()) << ',' << db->boolval(fun->is_file_scoped()) << ',' << t.get_fileid().get_id() << ',' << (unsigned)(t.get_streampos()) << ',' << fun->get_num_caller(); of << ");\n"; if (fun->is_defined()) { of << "INSERT INTO FUNCTIONMETRICS VALUES(" << ptr_offset(fun); for (int j = 0; j < FunMetrics::metric_max; j++) if (!Metrics::is_internal<FunMetrics>(j)) cout << ',' << fun->metrics().get_metric(j); of << ',' << fun->get_begin().get_tokid().get_fileid().get_id() << ',' << (unsigned)(fun->get_begin().get_tokid().get_streampos()) << ',' << fun->get_end().get_tokid().get_fileid().get_id() << ',' << (unsigned)(fun->get_end().get_tokid().get_streampos()); of << ");\n"; } int start = 0, ord = 0; for (dequeTpart::const_iterator j = fun->get_token().get_parts_begin(); j != fun->get_token().get_parts_end(); j++) { Tokid t2 = j->get_tokid(); int len = j->get_len() - start; int pos = 0; while (pos < len) { Eclass *ec = t2.get_ec(); of << "INSERT INTO FUNCTIONID VALUES(" << ptr_offset(fun) << ',' << ord << ',' << ptr_offset(ec) << ");\n"; pos += ec->get_len(); t2 += ec->get_len(); ord++; } start += j->get_len(); } } // Then their calls to satisfy integrity constraints for (const_fmap_iterator_type i = fbegin(); i != fend(); i++) { Call *fun = i->second; for (Call::const_fiterator_type dest = fun->call_begin(); dest != fun->call_end(); dest++) of << "INSERT INTO FCALLS VALUES(" << ptr_offset(fun) << ',' << ptr_offset(*dest) << ");\n"; } }
// Split an equivalence class after the (0-based) character position // pos returning the new EC receiving the split Tokids Eclass * Eclass::split(int pos) { int oldchars = pos + 1; // Characters to retain in the old EC if (DP()) cout << "Split " << this << " pos=" << pos << *this; csassert(oldchars < len); Eclass *e = new Eclass(len - oldchars); for (setTokid::const_iterator i = members.begin(); i != members.end(); i++) e->add_tokid(*i + oldchars); e->attr = attr; len = oldchars; if (DP()) { cout << "Split A: " << *e; cout << "Split B: " << *this; } return (e); }
/* Given two Tokid sequences corresponding to two tokens * make these correspond to equivalence classes of same lengths. * Getting the Token constituents again will return Tokids that * satisfy the above postcondition. * The operation only modifies the underlying equivalence classes */ void Tpart::homogenize(const dequeTpart &a, const dequeTpart &b) { dequeTpart::const_iterator ai = a.begin(); dequeTpart::const_iterator bi = b.begin(); Eclass *ae = (*ai).get_tokid().get_ec(); Eclass *be = (*bi).get_tokid().get_ec(); int alen, blen; if (DP()) cout << "Homogenize a:" << a << " b: " << b << "\n"; while (ai != a.end() && bi != b.end()) { alen = ae->get_len(); blen = be->get_len(); if (DP()) cout << "alen=" << alen << " blen=" << blen << "\n"; if (blen < alen) { ae = ae->split(blen - 1); bi++; if (bi != b.end()) be = (*bi).get_tokid().get_ec(); } else if (alen < blen) { be = be->split(alen - 1); ai++; if (ai != a.end()) ae = (*ai).get_tokid().get_ec(); } else if (alen == blen) { ai++; if (ai != a.end()) ae = (*ai).get_tokid().get_ec(); bi++; if (bi != b.end()) be = (*bi).get_tokid().get_ec(); } } }
// Evaluate the object's identifier query against i // return true if it matches bool FunQuery::eval(Call *c) { if (lazy) return return_val; if (call) return (c == call); if (id_ec) { if (!c->is_span_valid()) return false; const setTokid &m = id_ec->get_members(); for (setTokid::const_iterator i = m.begin(); i != m.end(); i++) if (*i >= c->get_begin().get_tokid() && *i <= c->get_end().get_tokid()) return true; return false; } if (match_fid && c->get_begin().get_tokid().get_fileid() != fid) return false; Eclass *ec = c->get_tokid().get_ec(); if (current_project && !ec->get_attribute(current_project)) return false; bool add = mquery.eval(*c); switch (match_type) { case 'Y': // anY match add = (add || (cfun && c->is_cfun())); add = (add || (macro && c->is_macro())); add = (add || (writable && !ec->get_attribute(is_readonly))); add = (add || (ro && ec->get_attribute(is_readonly))); add = (add || (pscope && !c->is_file_scoped())); add = (add || (fscope && c->is_file_scoped())); add = (add || (defined && c->is_defined())); break; case 'L': // alL match add = (add && (!cfun || c->is_cfun())); add = (add && (!macro || c->is_macro())); add = (add && (!writable || !ec->get_attribute(is_readonly))); add = (add && (!ro || ec->get_attribute(is_readonly))); add = (add && (!pscope || !c->is_file_scoped())); add = (add && (!fscope || c->is_file_scoped())); add = (add && (!defined || c->is_defined())); break; case 'E': // excludE match add = (add && (!cfun || !c->is_cfun())); add = (add && (!macro || !c->is_macro())); add = (add && (!writable || ec->get_attribute(is_readonly))); add = (add && (!ro || !ec->get_attribute(is_readonly))); add = (add && (!pscope || c->is_file_scoped())); add = (add && (!fscope || !c->is_file_scoped())); add = (add && (!defined || !c->is_defined())); break; case 'T': // exactT match add = (add && (cfun == c->is_cfun())); add = (add && (macro == c->is_macro())); add = (add && (writable == !ec->get_attribute(is_readonly))); add = (add && (ro == ec->get_attribute(is_readonly))); add = (add && (pscope == !c->is_file_scoped())); add = (add && (fscope == c->is_file_scoped())); add = (add && (defined == c->is_defined())); break; } if (!add) return false; if (ncallerop && !Query::apply(ncallerop, c->get_num_caller(), ncallers)) return false; int retval = exclude_fnre ? 0 : REG_NOMATCH; if (match_fnre && fnre.exec(c->get_name()) == retval) return false; retval = exclude_fre ? 0 : REG_NOMATCH; if (match_fre && fre.exec(c->get_fileid().get_path()) == retval) return false; Call::const_fiterator_type c2; if (match_fdre) { for (c2 = c->call_begin(); c2 != c->call_end(); c2++) if (fdre.exec((*c2)->get_name()) == 0) { if (exclude_fdre) return false; else break; } if (!exclude_fdre && c2 == c->call_end()) return false; } if (match_fure) { for (c2 = c->caller_begin(); c2 != c->caller_end(); c2++) if (fure.exec((*c2)->get_name()) == 0) { if (exclude_fure) return false; else break; } if (!exclude_fure && c2 == c->caller_end()) return false; } return true; }
main(int argc, char *argv[]) { int i; int parse_parse(); Debug::db_read(); // Pass 1: scan files Block::enter(); // Linkage unit for (i = 1; i < argc; i++) { if (argv[i] == "-") { // Linkage unit separator Block::exit(); Block::enter(); continue; } Block::enter(); // Compilation unit Fchar::set_input(argv[i]); Fchar::push_input("/dds/src/research/ie/refactor/wdefs.h"); Fchar::push_input("/dds/src/research/ie/refactor/wincs.h"); Pdtoken::macros_clear(); if (parse_parse() != 0) exit(1); Block::exit(); // Compilation unit } Block::exit(); // Linkage unit // Pass 2: go through the files annotating identifiers deque_string color_names; // Some nice HTML colors color_names.push_back("ff0000"); color_names.push_back("bf0000"); color_names.push_back("00af00"); color_names.push_back("00ef00"); color_names.push_back("0000ff"); color_names.push_back("bfbf00"); color_names.push_back("00ffff"); color_names.push_back("ff00ff"); ifstream in; Fileid fi; Colormap cm; deque_string::const_iterator c = color_names.begin(); cout << "<html><title>Identifier groups</title>\n" "<body bgcolor=\"#ffffff\">\n"; for (i = 1; i < argc; i++) { if (argv[i] == "-") { // Linkage unit separator cout << "<p><hr><p>\n"; continue; } if (in.is_open()) in.close(); in.clear(); // Otherwise flags are dirty and open fails in.open(argv[i], ios::binary); if (in.fail()) { perror(argv[i]); exit(1); } cout << "<h2>" << argv[i] << "</h2>\n"; fi = Fileid(argv[i]); // Go through the file character by character for (;;) { Tokid ti; int val, len; ti = Tokid(fi, in.tellg()); if ((val = in.get()) == EOF) break; Eclass *ec; if ((ec = ti.check_ec()) && ec->get_size() > 1) { Colormap::const_iterator ci; ci = cm.find(ec); if (ci == cm.end()) { // Allocate new color cm[ec] = (*c); c++; if (c == color_names.end()) c = color_names.begin(); ci = cm.find(ec); } cout << "<font color=\"#" << (*ci).second << "\">"; int len = ec->get_len(); cout << (char)val; for (int j = 1; j < len; j++) cout << html((char)in.get()); cout << "</font>"; continue; } cout << html((char)val); } } cout << "</body></html>\n"; return (0); }