|  | /** | 
|  | * @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 <string.h> | 
|  |  | 
|  | #include "op_config.h" | 
|  | #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); | 
|  |  | 
|  | if (!was_session_dir_supplied()) | 
|  | cerr << "Using " << op_samples_dir << " for session-dir" << endl; | 
|  |  | 
|  | 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); | 
|  | } | 
|  |  | 
|  | if (strncmp(op_session_dir, "/var/lib/oprofile", strlen("/var/lib/oprofile"))) | 
|  | cerr << "NOTE: The sample data in this archive is located at " << op_session_dir << endl | 
|  | << "instead of the standard location of /var/lib/oprofile.  Hence, when using opreport" << endl | 
|  | << "and other post-processing tools on this archive, you must pass the following option:" << endl | 
|  | << "\t--session-dir=" << op_session_dir << endl; | 
|  | } |