Home | History | Annotate | Download | only in pp
      1 /**
      2  * @file oparchive_options.cpp
      3  * Options for oparchive tool
      4  *
      5  * @remark Copyright 2002, 2003, 2004 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author William Cohen
      9  * @author Philippe Elie
     10  */
     11 
     12 #include <vector>
     13 #include <list>
     14 #include <iostream>
     15 #include <algorithm>
     16 #include <iterator>
     17 #include <fstream>
     18 
     19 #include "profile_spec.h"
     20 #include "arrange_profiles.h"
     21 #include "oparchive_options.h"
     22 #include "popt_options.h"
     23 #include "string_filter.h"
     24 #include "file_manip.h"
     25 #include "cverb.h"
     26 
     27 
     28 using namespace std;
     29 
     30 profile_classes classes;
     31 list<string> sample_files;
     32 
     33 namespace options {
     34 	demangle_type demangle = dmt_normal;
     35 	bool exclude_dependent;
     36 	merge_option merge_by;
     37 	string outdirectory;
     38 	bool list_files;
     39 }
     40 
     41 
     42 namespace {
     43 
     44 vector<string> mergespec;
     45 
     46 popt::option options_array[] = {
     47 	popt::option(options::outdirectory, "output-directory", 'o',
     48 	             "output to the given directory", "directory"),
     49 	popt::option(options::exclude_dependent, "exclude-dependent", 'x',
     50 		     "exclude libs, kernel, and module samples for applications"),
     51 	popt::option(options::list_files, "list-files", 'l',
     52 		     "just list the files necessary, don't produce the archive")
     53 };
     54 
     55 
     56 /**
     57  * check incompatible or meaningless options
     58  *
     59  */
     60 void check_options()
     61 {
     62 	using namespace options;
     63 
     64 	/* output directory is required */
     65 	if (!list_files) {
     66 		if (outdirectory.size() == 0) {
     67 			cerr << "Requires --output-directory option." << endl;
     68 			exit(EXIT_FAILURE);
     69 		}
     70 		string realpath = op_realpath(outdirectory);
     71 		if (realpath == "/") {
     72 			cerr << "Invalid --output-directory: /" << endl;
     73 			exit(EXIT_FAILURE);
     74 		}
     75 	}
     76 }
     77 
     78 }  // anonymous namespace
     79 
     80 
     81 void handle_options(options::spec const & spec)
     82 {
     83 	using namespace options;
     84 
     85 	if (spec.first.size()) {
     86 		cerr << "differential profiles not allowed" << endl;
     87 		exit(EXIT_FAILURE);
     88 	}
     89 
     90 	// merging doesn't occur in oparchive but we must allow it to avoid
     91 	// triggering sanity checking in arrange_profiles()
     92 	merge_by.cpu = true;
     93 	merge_by.lib = true;
     94 	merge_by.tid = true;
     95 	merge_by.tgid = true;
     96 	merge_by.unitmask = true;
     97 	check_options();
     98 
     99 	profile_spec const pspec =
    100 		profile_spec::create(spec.common, image_path, root_path);
    101 
    102 	sample_files = pspec.generate_file_list(exclude_dependent, false);
    103 
    104 	cverb << vsfile << "Matched sample files: " << sample_files.size()
    105 	      << endl;
    106 	copy(sample_files.begin(), sample_files.end(),
    107 	     ostream_iterator<string>(cverb << vsfile, "\n"));
    108 
    109 	classes = arrange_profiles(sample_files, merge_by,
    110 				   pspec.extra_found_images);
    111 
    112 	cverb << vsfile << "profile_classes:\n" << classes << endl;
    113 
    114 	if (classes.v.empty()) {
    115 		cerr << "error: no sample files found: profile specification "
    116 		     "too strict ?" << endl;
    117 		exit(EXIT_FAILURE);
    118 	}
    119 }
    120