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  * File dependency monitoring
21  *
22  */
23 
24 #ifndef FDEP_
25 #define FDEP_
26 
27 #include <set>
28 #include <map>
29 #include <string>
30 #include <vector>
31 #include <list>
32 
33 using namespace std;
34 
35 #include "attr.h"
36 #include "metrics.h"
37 #include "fileid.h"
38 #include "tokid.h"
39 
40 class Sql;
41 
42 // A container for file dependencies
43 class Fdep {
44 private:
45 	typedef map <Fileid, set <Fileid> > FSFMap;	// A map from Fileid to set of Fileid
46 	static FSFMap definers;				// Files containing definitions needed in a given file
47 	static FSFMap includers;			// Files including a given file
48 	static set <Fileid> providers;			// Files providing code and data
49 	static Fileid last_provider;			// Cache last value entered
50 	typedef pair<Fileid, Fileid> include_trigger_domain;	// Definition, reference
51 	typedef pair<streampos, int> include_trigger_element;
52 	typedef set<include_trigger_element> include_trigger_value;
53 	typedef map <include_trigger_domain, include_trigger_value> ITMap;
54 	static ITMap include_triggers;			// Symbols for which a given file is included
55 	static void mark_required_transitive(Fileid f);
56 public:
57 	// File def contains a definition needed by file ref
add_def_ref(Tokid def,Tokid ref,int len)58 	static void add_def_ref(Tokid def, Tokid ref, int len) {
59 		if (def.get_fileid() == ref.get_fileid())
60 			return;
61 		definers[ref.get_fileid()].insert(def.get_fileid());
62 		include_triggers[include_trigger_domain(def.get_fileid(), ref.get_fileid())].insert(
63 			include_trigger_element(def.get_streampos(), len));
64 	}
65 
66 	// File includer includes the file included
add_include(Fileid includer,Fileid included,int lnum)67 	static void add_include(Fileid includer, Fileid included, int lnum) {
68 		includers[included].insert(includer);
69 		includer.includes(included, /* directly included = */ true, /* used = */ false, lnum);
70 	}
71 
72 	// File f provides code or data
add_provider(Fileid f)73 	static void add_provider(Fileid f) {
74 		if (f == last_provider)
75 			return;
76 		providers.insert(f);
77 		last_provider = f;
78 	}
79 
80 	/*
81 	 * Mark as used:
82 	 * - the passed file (the file currently being processed)
83 	 * - all files that provided code and data to it
84 	 * Transitively:
85 	 * - all the files that contain definitions for the above
86 	 * - all files that include the above
87 	 */
88 	static void mark_required(Fileid f);
89 	// Clear definers and providers starting another round
90 	static void reset();
91 	// Create SQL dump
92 	static void dumpSql(Sql *db, Fileid cu);
93 };
94 
95 
96 #endif /* FDEP_ */
97