1 /*
2  * (C) Copyright 2003-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 the common parts of a (user interface) query
21  *
22  */
23 
24 #ifndef QUERY_
25 #define QUERY_
26 
27 #include <iostream>
28 
29 using namespace std;
30 
31 #include "attr.h"
32 #include "option.h"
33 #include "compiledre.h"
34 #include "debug.h"
35 
36 class Query {
37 protected:
38 	bool lazy;		// Do not evaluate
39 	bool return_val;	// Default return value
40 	bool valid;		// True if query is valid
41 	string name;		// Query name
42 	Attributes::size_type current_project;	// Restrict evaluation to this project
Query()43 	Query() : valid(false) {}
Query(bool l,bool r,bool v)44 	Query(bool l, bool r, bool v) : lazy(l), return_val(r), valid(v) {}
45 	/*
46 	 * Compile a regular expression name name, stored in SWILL varname
47 	 * into re.
48 	 * Set match to true if it was compiled and str to the RE string.
49 	 * Compflags can supply additional compilation flags.
50 	 * Return true if OK, false on error
51 	 * Errors are sent to of
52 	 */
53 	bool compile_re(FILE *of, const char *name, const char *varname, CompiledRE &re, bool &match,  string &str, int compflags = 0);
54 public:
55 	// Comparisson constants used for selections
56 	enum e_cmp {
57 		ec_ignore,
58 		ec_eq,
59 		ec_ne,
60 		ec_lt,
61 		ec_gt
62 	};
63 	// Display an equality selection box
64 	static void equality_selection(FILE *of);
65 	// Return the result of applying operator op on a, b
66 	static inline bool apply(int op, double a, double b);
67 	// URL-encode the given string
68 	static string url(const string &s);
69 
~Query()70 	virtual ~Query() {}
71 	// Accessor functions
is_valid()72 	bool is_valid() { return valid; }
need_eval()73 	bool need_eval() { return !lazy; }
74 	// Return the URL for listing a file based on this query
75 	virtual string param_url() const = 0;
76 	// Return true if the query's URL can be bookmarked across CScout invocations
77 	virtual bool bookmarkable() const = 0;
78 	// Return the URL for re-executing this query
79 	virtual string base_url() const = 0;
80 	// Compare two strings from end to start or start to end
string_bi_compare(const string & s1,const string & s2)81 	static bool string_bi_compare(const string &s1, const string &s2) {
82 		if (Option::sort_rev->get()) {
83 			string::const_reverse_iterator j1, j2;
84 
85 			for (j1 = s1.rbegin(), j2 = s2.rbegin();
86 			     j1 != s1.rend() && j2 != s2.rend(); j1++, j2++)
87 				if (*j1 != *j2)
88 					return *j1 < *j2;
89 			return j1 == s1.rend() && j2 != s2.rend();
90 		} else
91 			return s1.compare(s2) < 0;
92 	}
93 };
94 
95 /*
96  * Return the result of applying operator op on a, b
97  * Apparently doing this with the standard equal_to, etc functors would require a
98  * 5-template function.
99  * Attempting to store all functors in a vector <binary_function <..> > is useless
100  * since because the polymorphic binary_function does not define the appropriate () operators.
101  */
102 inline bool
apply(int op,double a,double b)103 Query::apply(int op, double a, double b)
104 {
105 	if (DP()) {
106 		cout << a;
107 		switch (op) {
108 		case ec_eq: cout << " == "; break;
109 		case ec_ne: cout << " != "; break;
110 		case ec_lt: cout << " < "; break;
111 		case ec_gt: cout << " > "; break;
112 		}
113 		cout << b << "\n";
114 	}
115 	switch (op) {
116 	case ec_eq: return a == b;
117 	case ec_ne: return a != b;
118 	case ec_lt: return a < b;
119 	case ec_gt: return a > b;
120 	default: return false;
121 	}
122 }
123 
124 #endif // QUERY_
125