15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/**
25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * @file opreport_options.cpp
35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Options for opreport tool
45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * @remark Copyright 2003 OProfile authors
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * @remark Read the file COPYING
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * @author John Levon
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * @author Philippe Elie
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <vector>
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <list>
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <iostream>
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <algorithm>
165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <iterator>
175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <fstream>
185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "profile_spec.h"
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "arrange_profiles.h"
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "opreport_options.h"
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "popt_options.h"
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "string_filter.h"
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "file_manip.h"
255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "xml_output.h"
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "xml_utils.h"
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "cverb.h"
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerusing namespace std;
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerprofile_classes classes;
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerprofile_classes classes2;
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnernamespace options {
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	demangle_type demangle = dmt_normal;
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool symbols;
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool callgraph;
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool debug_info;
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool details;
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool exclude_dependent;
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	string_filter symbol_filter;
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	sort_options sort_by;
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	merge_option merge_by;
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool show_header = true;
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool long_filenames;
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool show_address;
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool accumulated;
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool reverse_sort;
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool global_percent;
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool xml;
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	string xml_options;
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnernamespace {
56eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
57074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkinestring outfile;
58b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinevector<string> mergespec;
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervector<string> sort;
60318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkinevector<string> exclude_symbols;
615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervector<string> include_symbols;
62b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkinestring demangle_option = "normal";
63b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
64b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkinepopt::option options_array[] = {
65b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine	popt::option(options::callgraph, "callgraph", 'c',
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	             "show call graph"),
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::details, "details", 'd',
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "output detailed samples for each symbol"),
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::symbols, "symbols", 'l',
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "list all symbols"),
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(outfile, "output-file", 'o',
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	             "output to the given filename", "file"),
742c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(sort, "sort", 's',
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "sort by", "sample,image,app-name,symbol,debug,vma"),
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::reverse_sort, "reverse-sort", 'r',
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "use reverse sort"),
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(mergespec, "merge", 'm',
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "comma separated list", "cpu,lib,tid,tgid,unitmask,all"),
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::exclude_dependent, "exclude-dependent", 'x',
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "exclude libs, kernel, and module samples for applications"),
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(exclude_symbols, "exclude-symbols", 'e',
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "exclude these comma separated symbols", "symbols"),
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(include_symbols, "include-symbols", 'i',
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "include these comma separated symbols", "symbols"),
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::threshold_opt, "threshold", 't',
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "minimum percentage needed to produce output",
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "percent"),
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(demangle_option, "demangle", 'D',
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "demangle GNU C++ symbol names (default normal)",
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	             "none|normal|smart"),
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	// PP:5
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::debug_info, "debug-info", 'g',
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "add source file and line number to output"),
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::show_header, "no-header", 'n',
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "remove all headers from output"),
992c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner	popt::option(options::show_address, "show-address", 'w',
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	             "show VMA address of each symbol"),
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::long_filenames, "long-filenames", 'f',
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "show the full path of filenames"),
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::accumulated, "accumulated", 'a',
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "percentage field show accumulated count"),
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::global_percent, "global-percent", '%',
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "percentage are not relative to symbol count or image "
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "count but total sample count"),
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	popt::option(options::xml, "xml", 'X',
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "XML output"),
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid handle_sort_option()
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (options::xml && !sort.empty()) {
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		cerr << "warning: sort options ignored because they "
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     << "are incompatible with --xml" << endl;
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		// don't allow any other sorting, except the default below,
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		// to mess up symbol traversal for XML
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sort.clear();
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (sort.empty() || options::xml) {
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		// PP:5.14 sort default to sample
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (options::xml) {
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			// implicitly sort by app-name,image so that in the
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			// symbol traversal all library module symbols are
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			// grouped together with their application
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sort.push_back("app-name");
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sort.push_back("image");
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		} else
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sort.push_back("sample");
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	vector<string>::const_iterator cit = sort.begin();
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	vector<string>::const_iterator end = sort.end();
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (; cit != end; ++cit)
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		options::sort_by.add_sort_option(*cit);
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid handle_output_file()
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (outfile.empty())
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return;
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	static ofstream os(outfile.c_str());
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (!os) {
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		cerr << "Couldn't open \"" << outfile
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     << "\" for writing." << endl;
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		exit(EXIT_FAILURE);
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	cout.rdbuf(os.rdbuf());
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner///  Check incompatible or meaningless options.
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid check_options(bool diff)
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	using namespace options;
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bool do_exit = false;
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (callgraph) {
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		symbols = true;
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (details) {
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--callgraph is incompatible with --details" << endl;
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (diff) {
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "differential profiles are incompatible with --callgraph" << endl;
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (xml) {
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (accumulated) {
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--accumulated is incompatible with --xml" << endl;
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (global_percent) {
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--global_percent is incompatible with --xml" << endl;
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
190b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine		}
191b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine	}
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
193eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
194eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine	if (details && diff) {
195eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine		cerr << "differential profiles are incompatible with --details" << endl;
196eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine		do_exit = true;
197eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine	}
19843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (!symbols) {
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (diff) {
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "different profiles are meaningless "
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				"without --symbols" << endl;
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (show_address) {
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--show-address is meaningless "
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				"without --symbols" << endl;
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (debug_info || accumulated) {
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--debug-info and --accumulated are "
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     << "meaningless without --symbols" << endl;
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (!exclude_symbols.empty() || !include_symbols.empty()) {
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--exclude-symbols and --include-symbols are "
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     << "meaningless without --symbols" << endl;
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (find(sort_by.options.begin(), sort_by.options.end(),
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			 sort_options::vma) != sort_by.options.end()) {
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "--sort=vma is "
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     << "meaningless without --symbols" << endl;
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			do_exit = true;
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (global_percent && symbols && !(details || callgraph)) {
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		cerr << "--global-percent is meaningless with --symbols "
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		        "and without --details or --callgraph" << endl;
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		do_exit = true;
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (do_exit)
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		exit(EXIT_FAILURE);
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/// process a spec into classes
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid process_spec(profile_classes & classes, list<string> const & spec)
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	using namespace options;
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	copy(spec.begin(), spec.end(),
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	     ostream_iterator<string>(cverb << vsfile, " "));
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	cverb << vsfile << "\n\n";
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	profile_spec const pspec =
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		profile_spec::create(spec, options::image_path,
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				     options::root_path);
255a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	list<string> sample_files = pspec.generate_file_list(exclude_dependent,
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	                                                     !options::callgraph);
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	cverb << vsfile << "Archive: " << pspec.get_archive_path() << endl;
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	cverb << vsfile << "Matched sample files: " << sample_files.size()
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	      << endl;
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	copy(sample_files.begin(), sample_files.end(),
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	     ostream_iterator<string>(cverb << vsfile, "\n"));
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	classes = arrange_profiles(sample_files, merge_by,
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				   pspec.extra_found_images);
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	cverb << vsfile << "profile_classes:\n" << classes << endl;
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (classes.v.empty()) {
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		cerr << "error: no sample files found: profile specification "
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		     "too strict ?" << endl;
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		exit(EXIT_FAILURE);
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} // namespace anon
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid handle_options(options::spec const & spec)
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	using namespace options;
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (details) {
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		symbols = true;
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		show_address = true;
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (options::xml) {
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (spec.common.size() != 0)
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(SESSION, spec.common);
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (debug_info)
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(DEBUG_INFO, true);
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (details)
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(DETAILS, true);
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (!image_path.empty())
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(IMAGE_PATH, image_path);
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (!mergespec.empty())
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(MERGE, mergespec);
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (exclude_dependent)
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(EXCLUDE_DEPENDENT, true);
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (!exclude_symbols.empty())
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(EXCLUDE_SYMBOLS, exclude_symbols);
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (!include_symbols.empty())
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			xml_utils::add_option(INCLUDE_SYMBOLS, include_symbols);
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	handle_sort_option();
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	merge_by = handle_merge_option(mergespec, true, exclude_dependent);
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	handle_output_file();
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	demangle = handle_demangle_option(demangle_option);
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	check_options(spec.first.size());
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	symbol_filter = string_filter(include_symbols, exclude_symbols);
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (!spec.first.size()) {
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		process_spec(classes, spec.common);
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
321b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine		if (options::xml) {
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			cerr << "differential profiles are incompatible with --xml" << endl;
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			exit(EXIT_FAILURE);
324d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine		}
325d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine		cverb << vsfile << "profile spec 1:" << endl;
326d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine		process_spec(classes, spec.first);
327d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine		cverb << vsfile << "profile spec 2:" << endl;
32843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine		process_spec(classes2, spec.second);
32943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
330d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine		if (!classes.matches(classes2)) {
331dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine			cerr << "profile classes are incompatible" << endl;
332dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine			exit(EXIT_FAILURE);
333dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine		}
334074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine	}
335074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine}
336074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine