1 /*
2 CCCC - C and C++ Code Counter
3 Copyright (C) 1994-2005 Tim Littlefair (tim_littlefair@hotmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 // cccc_use.cc
20
21 // implementation of CCCC_UseRelationship class
22
23 #include "cccc.h"
24
25 #include "cccc_itm.h"
26 #include "cccc_use.h"
27 #include "cccc_db.h"
28
29
CCCC_UseRelationship(CCCC_Item & is)30 CCCC_UseRelationship::CCCC_UseRelationship(CCCC_Item& is)
31 {
32 is.Extract(client);
33 is.Extract(member);
34 is.Extract(supplier);
35 visible=abDONTKNOW;
36 concrete=abDONTKNOW;
37 ut=utDONTKNOW;
38 }
39
name(int name_level) const40 string CCCC_UseRelationship::name(int name_level) const
41 {
42 string namestr;
43
44 switch(name_level)
45 {
46 case nlRANK:
47 case nlSIMPLE:
48 namestr.append(client);
49 namestr.append(" uses ");
50 namestr.append(supplier);
51 break;
52
53 case nlSUPPLIER:
54 namestr=supplier;
55 break;
56
57 case nlCLIENT:
58 namestr=client;
59 break;
60
61 default:
62 cerr << "unexpected name level" << endl;
63 }
64
65 return namestr.c_str();
66 }
67
add_extent(CCCC_Item & is)68 void CCCC_UseRelationship::add_extent(CCCC_Item& is)
69 {
70 // processing is similar to the CCCC_Record method, except that we update
71 // the visibility and concreteness data members
72 // but do not do merge_flags
73 CCCC_Extent *new_extent=new CCCC_Extent(is);
74 CCCC_Extent *inserted_extent=extent_table.find_or_insert(new_extent);
75
76 switch(new_extent->get_visibility())
77 {
78 case vPUBLIC:
79 case vPROTECTED:
80 visible=abTRUE;
81 break;
82 case vPRIVATE:
83 case vIMPLEMENTATION:
84 visible=abFALSE;
85 break;
86
87 default:
88 // nothing required
89 ;;
90 }
91
92 // a single relationship record represents all connections between two
93 // modules, hence it may have multiple extents which are of different use
94 // types
95 // the use type attached to the relationship record is used only to identify
96 // inheritance relationships
97 UseType new_ut=new_extent->get_usetype();
98 if(new_ut==utINHERITS)
99 {
100 ut=utINHERITS;
101 }
102
103 switch(new_ut)
104 {
105 case utINHERITS:
106 case utHASBYVAL:
107 case utPARBYVAL:
108 case utVARBYVAL:
109 concrete=abTRUE;
110 break;
111 default:
112 // no change required
113 ;;
114 }
115
116 if(new_extent != inserted_extent)
117 {
118 delete new_extent;
119 }
120 }
121
get_count(const char * count_tag)122 int CCCC_UseRelationship::get_count(const char* count_tag)
123 {
124 int retval=0;
125
126 if( (strncmp(count_tag,"FI",2)==0) || (strncmp(count_tag,"FO",2)==0) )
127 {
128 char suffix=count_tag[2];
129 switch(suffix)
130 {
131 case 0:
132 retval=1;
133 break;
134
135 case 'v':
136 if(visible!=abFALSE)
137 {
138 retval=1;
139 }
140 break;
141
142 case 'c':
143 if(concrete!=abFALSE)
144 {
145 retval=1;
146 }
147 break;
148
149 default:
150 cerr << "Unexpected count tag suffix" << count_tag << endl;
151 }
152 }
153 else
154 {
155 cerr << "Unexpected count tag " << count_tag << endl;
156 }
157
158
159 return retval;
160 }
161
162
163
supplier_module_ptr(CCCC_Project * prj)164 CCCC_Module* CCCC_UseRelationship::supplier_module_ptr(CCCC_Project *prj)
165 {
166 return prj->module_table.find(supplier.c_str());
167 }
168
client_module_ptr(CCCC_Project * prj)169 CCCC_Module* CCCC_UseRelationship::client_module_ptr(CCCC_Project *prj)
170 {
171 return prj->module_table.find(client.c_str());
172 }
173
174
ToFile(ofstream & ofstr)175 int CCCC_UseRelationship::ToFile(ofstream& ofstr)
176 {
177 int retval=FALSE;
178
179 CCCC_Item line;
180 line.Insert(USEREL_PREFIX);
181 line.Insert(supplier);
182 line.Insert(client);
183 line.ToFile(ofstr);
184
185 CCCC_Extent *extent_ptr=extent_table.first_item();
186 while(extent_ptr!=NULL)
187 {
188 CCCC_Item extent_line;
189 extent_line.Insert(USEEXT_PREFIX);
190 extent_line.Insert(supplier);
191 extent_line.Insert(client);
192 extent_ptr->AddToItem(extent_line);
193 extent_line.ToFile(ofstr);
194
195 extent_ptr=extent_table.next_item();
196 }
197
198 if(ofstr.good())
199 {
200 retval=TRUE;
201 }
202
203 return retval;
204 }
205
FromFile(ifstream & ifstr)206 int CCCC_UseRelationship::FromFile(ifstream& ifstr)
207 {
208 int retval;
209 CCCC_Item next_line;
210 next_line.FromFile(ifstr);
211 ifstr_line++;
212
213 string line_keyword_dummy;
214
215 CCCC_UseRelationship *found_uptr=NULL;
216
217 if(
218 next_line.Extract(line_keyword_dummy) &&
219 next_line.Extract(this->supplier) &&
220 next_line.Extract(this->client)
221 )
222 {
223 found_uptr=
224 current_loading_project->userel_table.find_or_insert(this);
225 if(found_uptr==this)
226 {
227 // the newly created instance of the module is the first
228 // and has taken its place in the database, so we protect
229 // it from deletion
230 retval=RECORD_ADDED;
231 }
232 else
233 {
234 retval=RECORD_TRANSCRIBED;
235 }
236
237 // process extent records
238 while(PeekAtNextLinePrefix(ifstr,USEEXT_PREFIX))
239 {
240 CCCC_Extent *new_extent=new CCCC_Extent;
241 next_line.FromFile(ifstr);
242 ifstr_line++;
243 string supplier_dummy, client_dummy;
244
245 if(
246 next_line.Extract(line_keyword_dummy) &&
247 next_line.Extract(supplier_dummy) &&
248 next_line.Extract(client_dummy) &&
249 new_extent->GetFromItem(next_line)
250 )
251 {
252 // We don't ever expect to find duplicated extent records
253 // but just in case...
254 CCCC_Extent *found_eptr=
255 found_uptr->extent_table.find_or_insert(new_extent);
256 if(found_eptr!=new_extent)
257 {
258 cerr << "Failed to add extent for relationship "
259 << found_uptr->key() << " at line " << ifstr_line
260 << endl;
261 delete new_extent;
262 }
263 }
264 }
265
266 }
267 else // extraction of module intial line failed
268 {
269 // unexpected problem with the input
270 retval=RECORD_ERROR;
271 }
272
273 // If the import was successful, we will also have imported all dependent
274 // extent records following the main record.
275 // If not, we must skip them.
276 while(PeekAtNextLinePrefix(ifstr,USEEXT_PREFIX))
277 {
278 CCCC_Item next_line;
279 next_line.FromFile(ifstr);
280 ifstr_line++;
281 cerr << "Ignoring userel extent on line " << ifstr_line << endl;
282 }
283
284 return retval;
285 }
286
287
288
289
290