#include "main.ih"

namespace
{
    Arg::LongOption longOptions[] =
    {
        {"arg",                 'a'},
        {"called-by",           'c'},
        {"full-symbol",         'f'},
        {"help",                'h'},
        {"no-xref",             'X'},
        {"objdump",             Arg::Required},
        {"object-files",        'o'},
        {"replace",             'R'},       // single replacements
        {"replace-file",        'r'},       // replacements on file
        {"select",              Arg::Required},
        {"select-pattern",      Arg::Required},
        {"source-files",        's'},
        {"tree",                't'},
        {"version",             'v'},
        {"xref-source-files",   'x'},
    };

    Arg::LongOption const *const longEnd = longOptions + size(longOptions);
}

int main(int argc, char **argv)
try
{
    Arg &arg = Arg::initialize("a:c:fhor:R:st:vxX", longOptions, longEnd, 
                                                    argc, argv);
    arg.versionHelp(usage, version, 1);

    ObjDump odump;
    Storage storage;


    odump.start();          // generate objdump's output

                            // insert objdump's lines into Storage, whose
                            // push_back member does all the hard work.
    copy(odump.begin(), odump.end(), back_inserter(storage));

    header(argc, argv);     // output the program's header

    storage.xref();         // maybe show the cross-reference info
    storage.tree();         // maybe show the call-tree
    storage.calledBy();     // maybe show the called-by hierarchy
}
catch (std::exception const &e)
{
    cout << e.what() << '\n';
    return 1;
}
catch (int x)
{
    return Arg::instance().option("hv") ? 0 : x;
}
catch (...)
{
    cout << "Caught unaccounted for exception\n";
    return 1;
}

