• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
check_options()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 
handle_options(options::spec const & spec)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