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_mem.cc
20 
21 // implementation file for class CCCC_Member
22 
23 #include "cccc.h"
24 
25 #include "cccc_itm.h"
26 #include "cccc_mem.h"
27 #include "cccc_db.h"
28 
CCCC_Member()29 CCCC_Member::CCCC_Member()
30   : parent(NULL)
31 {
32   visibility=vDONTKNOW;
33 }
34 
get_count(const char * count_tag)35 int CCCC_Member::get_count(const char* count_tag) {
36   int retval=0;
37   string count_tag_str=count_tag;
38 
39   if(count_tag_str=="WMC1")
40     {
41       retval=1;
42     }
43   else if(count_tag_str=="WMCv")
44     {
45       switch(get_visibility())
46 	{
47 	case vPUBLIC:
48 	case vPROTECTED:
49 	  retval=1;
50 	  break;
51 	default:
52 	  NULL;
53 	}
54     }
55   else
56     {
57       retval=extent_table.get_count(count_tag);
58     }
59 
60   return retval;
61 }
62 
63 
ToFile(ofstream & ofstr)64 int CCCC_Member::ToFile(ofstream& ofstr)
65 {
66   int retval=FALSE;
67 
68   CCCC_Item member_line;
69   member_line.Insert(MEMBER_PREFIX);
70   member_line.Insert(parent->key());
71   member_line.Insert(member_name);
72   member_line.Insert(member_type);
73   member_line.Insert(param_list);
74   member_line.ToFile(ofstr);
75 
76   CCCC_Extent *extent_ptr=extent_table.first_item();
77   while(extent_ptr!=NULL)
78     {
79       CCCC_Item extent_line;
80       extent_line.Insert(MEMEXT_PREFIX);
81       extent_line.Insert(parent->key());
82       extent_line.Insert(member_name);
83       extent_line.Insert(member_type);
84       extent_line.Insert(param_list);
85       extent_ptr->AddToItem(extent_line);
86       extent_line.ToFile(ofstr);
87 
88       extent_ptr=extent_table.next_item();
89     }
90 
91   if(ofstr.good())
92     {
93       retval=TRUE;
94     }
95 
96   return retval;
97 }
98 
name(int name_level) const99 string CCCC_Member::name(int name_level) const
100 {
101   string namestr;
102 
103   switch(name_level)
104     {
105     case nlRANK:
106     case nlSEARCH:
107       // there is no scoping for C-style functions ...
108       if(parent==NULL)
109 	{
110           namestr.append("<NULL>::");
111         }
112       else if(
113 	      (parent->name(nlMODULE_NAME)!="") &&
114 	      (parent->name(nlMODULE_TYPE)!="file")
115 	      )
116 	{
117 	  namestr.append(parent->name(nlMODULE_NAME));
118           namestr.append("::");
119 	}
120       namestr.append(member_name);
121       namestr.append(param_list);
122       break;
123 
124     case nlMEMBER_NAME:
125     case nlSIMPLE:
126       namestr=member_name;
127       break;
128 
129     case nlMEMBER_TYPE:
130       namestr=member_type;
131       break;
132 
133     case nlMEMBER_PARAMS:
134       namestr=param_list;
135       break;
136     case nlLOCAL:
137       namestr.append(member_name);
138       namestr.append(param_list);
139       break;
140 
141     default:
142       cerr << "unexpected name level" << endl;
143     }
144 
145   return namestr.c_str();
146 }
147 
FromFile(ifstream & ifstr)148 int CCCC_Member::FromFile(ifstream& ifstr)
149 {
150   int retval=RECORD_ERROR;
151   enum MemberFromFileStatuses { MEMBER_RECORD_NO_PARENT_FOUND=3 };
152 
153   CCCC_Item next_line;
154   next_line.FromFile(ifstr);
155   ifstr_line++;
156 
157   string line_keyword_dummy;
158   string parent_name;
159 
160   CCCC_Member *found_mptr=NULL;
161 
162   if(
163      next_line.Extract(line_keyword_dummy) &&
164      next_line.Extract(parent_name) &&
165      next_line.Extract(this->member_name) &&
166      next_line.Extract(this->member_type) &&
167      next_line.Extract(this->param_list)
168      )
169     {
170       parent=current_loading_project->module_table.find(parent_name);
171       if(parent!=NULL)
172 	{
173 	  found_mptr=
174 	    current_loading_project->member_table.find_or_insert(this);
175 	  if(found_mptr==this)
176 	    {
177 	      // the newly created instance of the module is the first
178 	      // and has taken its place in the database, so we protect
179 	      // it from deletion
180 	      retval=RECORD_ADDED;
181 	    }
182 	  else
183 	    {
184 	      retval=RECORD_TRANSCRIBED;
185 	    }
186 
187 	  // process extent records
188 	  while(PeekAtNextLinePrefix(ifstr,MEMEXT_PREFIX))
189 	    {
190 	      CCCC_Extent *new_extent=new CCCC_Extent;
191 	      next_line.FromFile(ifstr);
192 	      ifstr_line++;
193 	      string parent_key_dummy, member_name_dummy,
194 		member_type_dummy, param_list_dummy;
195 
196 	      if(
197 		 next_line.Extract(line_keyword_dummy) &&
198 		 next_line.Extract(parent_key_dummy) &&
199 		 next_line.Extract(member_name_dummy) &&
200 		 next_line.Extract(member_type_dummy) &&
201 		 next_line.Extract(param_list_dummy) &&
202 		 new_extent->GetFromItem(next_line)
203 		 )
204 		{
205 		  // We don't ever expect to find duplicated extent records
206 		  // but just in case...
207 		  CCCC_Extent *found_eptr=
208 		    found_mptr->extent_table.find_or_insert(new_extent);
209 		  if(found_eptr!=new_extent)
210 		    {
211 		      cerr << "Failed to add extent for member "
212 			   << found_mptr->key() << " at line " << ifstr_line
213 			   << endl;
214 		      delete new_extent;
215 		    }
216 		}
217 	    }
218 
219 	}
220       else // parent record not found
221 	{
222 	  retval=MEMBER_RECORD_NO_PARENT_FOUND;
223 	}
224     }
225   else // extraction of module intial line failed
226     {
227       // unexpected problem with the input
228       retval=RECORD_ERROR;
229     }
230 
231   // If the import was successful, we will also have imported all dependent
232   // extent records following the main record.
233   // If not, we must skip them.
234   while(PeekAtNextLinePrefix(ifstr,MEMEXT_PREFIX))
235     {
236       CCCC_Item next_line;
237       next_line.FromFile(ifstr);
238       ifstr_line++;
239       cerr << "Ignoring member extent on line " << ifstr_line << endl;
240     }
241 
242   return retval;
243 }
244 
get_visibility()245 Visibility CCCC_Member::get_visibility()
246 {
247   return visibility;
248 }
249 
250 
251 
252