#include "smat.h" #include #include #include #include #include #include #include #include #ifdef linux #include #endif static void report_simple(char *name, std::map& m) { unsigned mov, cmp, arith; mov = m[SMAT_MOV] + m[SMAT_CCTOR] + m[SMAT_BCTOR]; cmp = (m[SMAT_EQ] + m[SMAT_NEQ] + m[SMAT_GT] + m[SMAT_GEQ] + m[SMAT_LT] + m[SMAT_LEQ] + m[SMAT_IEQ] + m[SMAT_INEQ] + m[SMAT_IGT] + m[SMAT_IGEQ] + m[SMAT_ILT] + m[SMAT_ILEQ]); arith = (m[SMAT_ADD] + m[SMAT_SUB] + m[SMAT_MUL] + m[SMAT_DIV] + m[SMAT_MOD] + m[SMAT_LSHIFT] + m[SMAT_RSHIFT] + m[SMAT_INC] + m[SMAT_DEC] + m[SMAT_MINUS] + m[SMAT_IADD] + m[SMAT_ISUB] + m[SMAT_IMUL] + m[SMAT_IDIV] + m[SMAT_IMOD] + m[SMAT_ILSHIFT] + m[SMAT_IRSHIFT] + m[SMAT_AND] + m[SMAT_OR] + m[SMAT_XOR] + m[SMAT_IAND] + m[SMAT_IOR] + m[SMAT_IXOR] + m[SMAT_CMPL]); std::cout << name << ":\n Assignment\t " << mov << "\n Comparison\t " << cmp << "\n Arithmetic\t " << arith << "\n\n"; } static void report(char *name, std::map& m, int verbose) { struct tbl { char *heading; int i1, i2; }; static tbl t[] = { { "Ctor (default) ", SMAT_CTOR, SMAT_END }, { "Ctor (copy)\t ", SMAT_CCTOR, SMAT_END }, { "Ctor (base type) ", SMAT_BCTOR, SMAT_END }, { "Dtor\t\t ", SMAT_DTOR, SMAT_END }, { "=\t\t ", SMAT_MOV, SMAT_END }, { "+\t\t ", SMAT_ADD, SMAT_IADD }, { "-\t\t ", SMAT_SUB, SMAT_ISUB }, { "*\t\t ", SMAT_MUL, SMAT_IMUL }, { "/\t\t ", SMAT_DIV, SMAT_IDIV }, { "%\t\t ", SMAT_MOD, SMAT_IMOD }, { "<<\t\t ", SMAT_LSHIFT, SMAT_ILSHIFT }, { ">>\t\t ", SMAT_RSHIFT, SMAT_IRSHIFT }, { "==\t\t ", SMAT_EQ, SMAT_IEQ }, { "!=\t\t ", SMAT_NEQ, SMAT_INEQ }, { "<\t\t ", SMAT_LT, SMAT_ILT }, { ">\t\t ", SMAT_GT, SMAT_IGT }, { "<=\t\t ", SMAT_LEQ, SMAT_ILEQ }, { ">=\t\t ", SMAT_GEQ, SMAT_IGEQ }, { "&\t\t ", SMAT_AND, SMAT_IAND }, { "|\t\t ", SMAT_OR, SMAT_IOR }, { "^\t\t ", SMAT_XOR, SMAT_IXOR }, { "++\t\t ", SMAT_INC, SMAT_END }, { "--\t\t ", SMAT_DEC, SMAT_END }, { "~\t\t ", SMAT_CMPL, SMAT_END }, { "- (unary)\t ", SMAT_MINUS, SMAT_END } }; std::cout << name << ":\n"; for (unsigned i = 0; i < sizeof(t)/sizeof(t[0]); ++i) { if (verbose == 2 || m[t[i].i1] + m[t[i].i2] > 0) std::cout << " " << t[i].heading << (m[t[i].i1] + m[t[i].i2]) << '\n'; } std::cout << '\n'; } static void usage(char *progname, int status) { if (status != 0) std::cerr << "Try `" << progname << " -h' for more information.\n"; else { std::cout << "Usage: " << progname << " [OPTION]... < TRACEFILE\n\ Count and report the number of operations in a trace file.\n\ \n\ If one of options I, D, V, P, and T is specified, the program enters\n\ a selective mode, in which the only specified types are reported.\n\ Otherwise, types with non-zero operation counts are reported.\n\ \n\ -I output iterator type operations\n\ -D output difference type operations\n\ -V output value type operations\n\ -P output pointer type operations\n\ -T output total operations\n\ \n\ -v report verbosely (-vv gives you more)\n\ \n\ -h display this help and exit\n"; } exit(status); } int main(int argc, char *argv[]) { int c, verbose = 0; bool show[5] = { false, false, false, false, false }; char *title[] = { "Iterator", "Value type", "Difference type", "Pointer type", "Total" }; std::ios::sync_with_stdio(false); std::cin.tie(0); while ((c = getopt(argc, argv, "DhIPTVv")) != -1) { switch (c) { case 'I': show[0] = true; break; case 'V': show[1] = true; break; case 'D': show[2] = true; break; case 'P': show[3] = true; break; case 'T': show[4] = true; break; case 'v': ++verbose; break; case 'h': usage(argv[0], EXIT_SUCCESS); break; default: usage(argv[0], EXIT_FAILURE); break; } } if (optind != argc) usage(argv[0], EXIT_FAILURE); std::map cnt[5]; // i, v, d, p, all for (std::istream_iterator i(std::cin), e; i != e; ++i) { ++cnt[(*i).type][(*i).code]; ++cnt[4][(*i).code]; } if (show[0] || show[1] || show[2] || show[3] || show[4]) { for (int i = 0; i < 5; ++i) { if (show[i]) { if (verbose) report(title[i], cnt[i], verbose); else report_simple(title[i], cnt[i]); } } } else { for (int i = 0; i < 5; ++i) { if (cnt[i].size() == 0) continue; if (verbose) report(title[i], cnt[i], verbose); else report_simple(title[i], cnt[i]); } } return 0; }