blob: 4b33aecd8af8d0e004a79b3817173d6e0e20bda7 [file] [log] [blame]
/**
* @file oparchive_options.cpp
* Options for oparchive tool
*
* @remark Copyright 2002, 2003, 2004 OProfile authors
* @remark Read the file COPYING
*
* @author William Cohen
* @author Philippe Elie
*/
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <fstream>
#include "profile_spec.h"
#include "arrange_profiles.h"
#include "oparchive_options.h"
#include "popt_options.h"
#include "string_filter.h"
#include "file_manip.h"
#include "cverb.h"
using namespace std;
profile_classes classes;
list<string> sample_files;
namespace options {
demangle_type demangle = dmt_normal;
bool exclude_dependent;
merge_option merge_by;
string outdirectory;
bool list_files;
}
namespace {
vector<string> mergespec;
popt::option options_array[] = {
popt::option(options::outdirectory, "output-directory", 'o',
"output to the given directory", "directory"),
popt::option(options::exclude_dependent, "exclude-dependent", 'x',
"exclude libs, kernel, and module samples for applications"),
popt::option(options::list_files, "list-files", 'l',
"just list the files necessary, don't produce the archive")
};
/**
* check incompatible or meaningless options
*
*/
void check_options()
{
using namespace options;
/* output directory is required */
if (!list_files) {
if (outdirectory.size() == 0) {
cerr << "Requires --output-directory option." << endl;
exit(EXIT_FAILURE);
}
string realpath = op_realpath(outdirectory);
if (realpath == "/") {
cerr << "Invalid --output-directory: /" << endl;
exit(EXIT_FAILURE);
}
}
}
} // anonymous namespace
void handle_options(options::spec const & spec)
{
using namespace options;
if (spec.first.size()) {
cerr << "differential profiles not allowed" << endl;
exit(EXIT_FAILURE);
}
// merging doesn't occur in oparchive but we must allow it to avoid
// triggering sanity checking in arrange_profiles()
merge_by.cpu = true;
merge_by.lib = true;
merge_by.tid = true;
merge_by.tgid = true;
merge_by.unitmask = true;
check_options();
profile_spec const pspec =
profile_spec::create(spec.common, image_path, root_path);
sample_files = pspec.generate_file_list(exclude_dependent, false);
cverb << vsfile << "Matched sample files: " << sample_files.size()
<< endl;
copy(sample_files.begin(), sample_files.end(),
ostream_iterator<string>(cverb << vsfile, "\n"));
classes = arrange_profiles(sample_files, merge_by,
pspec.extra_found_images);
cverb << vsfile << "profile_classes:\n" << classes << endl;
if (classes.v.empty()) {
cerr << "error: no sample files found: profile specification "
"too strict ?" << endl;
exit(EXIT_FAILURE);
}
}