1 /*
2  * (C) Copyright 2001-2015 Diomidis Spinellis
3  *
4  * This file is part of CScout.
5  *
6  * CScout is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * CScout is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with CScout.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *
20  * Encapsulates a (user interface) function query
21  *
22  */
23 
24 #ifndef FUNQUERY_
25 #define FUNQUERY_
26 
27 #include <string>
28 
29 using namespace std;
30 
31 #include "query.h"
32 #include "mquery.h"
33 #include "fileid.h"
34 #include "call.h"
35 
36 class FunQuery : public Query {
37 private:
38 	// Regular expression match specs
39 	string str_fnre;	// Function name RE
40 	string str_fdre;	// Called function name RE (down)
41 	string str_fure;	// Calling function name RE (up)
42 	string str_fre;		// Filename RE
43 	// Compiled REs
44 	CompiledRE fnre;	// Function name RE
45 	CompiledRE fdre;	// Called function name RE (down)
46 	CompiledRE fure;	// Calling function name RE (up)
47 	CompiledRE fre;		// Filename RE
48 	// Match rules
49 	bool match_fnre;	// Function name RE
50 	bool match_fdre;	// Called function name RE (down)
51 	bool match_fure;	// Calling function name RE (up)
52 	bool match_fre;		// Filename RE
53 	// Exclude options
54 	bool exclude_fnre;	// Function name RE
55 	bool exclude_fdre;	// Called function name RE (down)
56 	bool exclude_fure;	// Calling function name RE (up)
57 	bool exclude_fre;	// Filename RE
58 	// Query arguments
59 	char match_type;	// Type of boolean match
60 	bool cfun;		// True if C function
61 	bool macro;		// True if function-like macro
62 	bool writable;		// True if writable
63 	bool ro;		// True if read-only
64 	bool pscope;		// True if project scoped
65 	bool fscope;		// True if file scoped
66 	bool defined;		// True if a definition was found
67 	Fileid fid;		// Match from this file
68 	bool match_fid;		// True to use the above
69 	int ncallers;		// Number of callers
70 	int ncallerop;		// Operator for comparing them
71 
72 	Eclass *id_ec;		// True if identifier EC matches
73 				// No other evaluation takes place
74 
75 	Call *call;		// True if call matches
76 				// No other evaluation takes place
77 
78 	string name;		// Query name
79 	Attributes::size_type current_project;	// Restrict evaluation to this project
80 	// The query part for the metrics
81 	MQuery<FunMetrics, Call &> mquery;
82 public:
83 	// Construct object based on URL parameters
84 	FunQuery(FILE *f, bool icase, Attributes::size_type current_project, bool e = true, bool r = true);
85 	// Default
FunQuery()86 	FunQuery() : Query(), match_fnre(false), match_fdre(false), match_fure(false), match_fre(false), match_fid(false)  {}
87 
88 	// Destructor
~FunQuery()89 	virtual ~FunQuery() {}
90 
91 	// Perform a query
92 	bool eval(Call *c);
93 	// Return the URL for re-executing this query
94 	string base_url() const;
95 	// Return the query's parameters as a URL
96 	string param_url() const;
97 	//
98 	// Container comparison functor
99 	class specified_order : public binary_function <const Call &, const Call &, bool> {
100 	private:
101 		/*
102 		 * Can only be an instance variable (per C++ PL 17.1.4.5)
103 		 * only when the corresponding constructor is passed a
104 		 * compile-time constant.
105 		 * This hack works around the limitation.
106 		 */
107 		static int order;
108 		static bool reverse;
109 	public:
110 		// Should be called exactly once before instantiating the set
set_order(int o,bool r)111 		static void set_order(int o, bool r) { order = o; reverse = r; }
operator()112 		bool operator()(const Call *a, const Call *b) const {
113 			bool val;
114 			if (order == -1)
115 				// Order by name
116 				val = Query::string_bi_compare(a->get_name(), b->get_name());
117 			else
118 				val = (a->const_metrics().get_metric(order) < b->const_metrics().get_metric(order));
119 			return reverse ? !val : val;
120 		}
121 	};
get_sort_order()122 	int get_sort_order() const { return mquery.get_sort_order(); }
123 	// Return true if the query's URL can be bookmarked across CScout invocations
bookmarkable()124 	bool bookmarkable() const { return id_ec == NULL; }
125 };
126 
127 typedef multiset <const Call *, FunQuery::specified_order> Sfuns;
128 
129 #endif // FUNQUERY_
130