Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / apps / soreduce / Library.cpp
blobf6142e0e46af3be3164c5aab5c8fc3fdeeb7e820
1 // -*- C++ -*-
2 // File: Library.cpp
4 // Author: Phil Mesnier
6 // This file contains the implementation of the classes responsible for
7 // generating specialized mpc files for individual libraries, as well as
8 // outputting usage metrics for the various object modules contained in the
9 // library.
11 #include "ace/OS_NS_dirent.h"
12 #include "ace/OS_NS_stdlib.h"
13 #include "ace/OS_NS_string.h"
14 #include "ace/OS_NS_unistd.h"
15 #include "ace/OS_NS_sys_stat.h"
16 #include "ace/OS_NS_ctype.h"
17 #include "ace/Log_Msg.h"
19 #include "Library.h"
21 MPC_Generator::MPC_Generator (const ACE_CString& libname)
22 : mpcfile_(),
23 libname_(libname),
24 mpcfilename_()
26 mpcfilename_ = libname_ + "_subset.mpc";
29 MPC_Generator::~MPC_Generator ()
33 void
34 MPC_Generator::write_file (const ACE_CString& file)
36 mpcfile_ << " " << file << ".cpp" << endl;
39 void
40 MPC_Generator::write_prolog (const ACE_CString& path)
42 ACE_CString fname (path + "/" + mpcfilename_);
43 ACE_DEBUG ((LM_DEBUG, "writing file %s\n",fname.c_str()));
44 mpcfile_.open(fname.c_str());
45 if (!mpcfile_)
46 ACE_DEBUG ((LM_DEBUG,"mpc file open failed\n"));
48 mpcfile_
49 << "// Generated mpc file for producing a subset of the "
50 << libname_ << " library " << endl << endl
51 << "project(" << libname_ << "_subset)";
53 this->write_baseprojects ();
55 mpcfile_
56 << " {" << endl
57 << " sharedname = " << libname_ << "_subset" << endl
58 << " pch_header = " << endl
59 << " pch_source = " << endl;
61 this->write_projectinfo ();
63 mpcfile_ << endl
64 << " Source_Files {" << endl;
67 void
68 MPC_Generator::write_epilog ()
70 mpcfile_ << " }" << endl
71 << "}" << endl;
72 mpcfile_.close();
75 void
76 MPC_Generator::write_baseprojects()
78 mpcfile_ << ": acedefaults, core";
81 void
82 MPC_Generator::write_projectinfo()
84 mpcfile_ << " libout = $(ACE_ROOT)/lib" << endl
85 << " dynamicflags = ACE_BUILD_DLL ACE_OS_BUILD_DLL" << endl;
88 //-----------------------------------------------------------------------------
89 MPC_ACE_Dep_Lib::MPC_ACE_Dep_Lib (const ACE_CString& libname)
90 : MPC_Generator(libname)
93 void
94 MPC_ACE_Dep_Lib::write_baseprojects()
96 mpcfile_ << ": acedefaults, aceversion";
99 void
100 MPC_ACE_Dep_Lib::write_projectinfo()
102 mpcfile_ << " libout = $(ACE_ROOT)/lib" << endl
103 << " libs += ACE_subset" << endl
104 << " after += ACE_subset" << endl;
107 //-----------------------------------------------------------------------------
108 MPC_TAO_Lib::MPC_TAO_Lib (const ACE_CString& libname)
109 : MPC_ACE_Dep_Lib(libname)
112 void
113 MPC_TAO_Lib::write_baseprojects()
115 MPC_ACE_Dep_Lib::write_baseprojects ();
116 mpcfile_ << ", core, tao_output, taodefaults";
119 void
120 MPC_TAO_Lib::write_projectinfo()
122 MPC_ACE_Dep_Lib::write_projectinfo();
123 mpcfile_ << " dynamicflags = TAO_BUILD_DLL" << endl;
126 //-----------------------------------------------------------------------------
127 MPC_TAO_Dep_Lib::MPC_TAO_Dep_Lib (const ACE_CString& libname)
128 : MPC_TAO_Lib(libname)
131 void
132 MPC_TAO_Dep_Lib::write_baseprojects()
134 MPC_TAO_Lib::write_baseprojects ();
135 mpcfile_ << ", taoidldefaults";
138 void
139 MPC_TAO_Dep_Lib::write_projectinfo()
141 // Try our best to generate the dynamicflags
142 ACE_CString dflags;
143 for(size_t i = 0; i < this->libname_.length (); ++i) {
144 dflags += static_cast<char>(ACE_OS::ace_toupper (this->libname_[i]));
146 dflags += "_BUILD_DLL";
148 MPC_ACE_Dep_Lib::write_projectinfo();
149 mpcfile_ << " dynamicflags = " << dflags.c_str () << endl
150 << " libs += TAO_subset" << endl
151 << " after += TAO_subset" << endl
152 << " includes += $(TAO_ROOT)/orbsvcs" << endl
153 << " idlflags += -I$(TAO_ROOT)/orbsvcs" << endl;
156 //-----------------------------------------------------------------------------
158 Library::Library (const char *name)
159 : name_(name),
160 path_(),
161 num_modules_(0),
162 num_exports_(0),
163 num_extrefs_(0),
164 modules_(0),
165 exported_(0),
166 mpcfile_(0)
168 if (name_ == "ACE")
169 mpcfile_ = new MPC_Generator(name_);
170 else if (name_.find ("ACE_") == 0)
171 mpcfile_ = new MPC_ACE_Dep_Lib (name_);
172 else if (name_ == "TAO")
173 mpcfile_ = new MPC_TAO_Lib (name_);
174 else
175 mpcfile_ = new MPC_TAO_Dep_Lib (name_);
178 Library::~Library ()
180 delete mpcfile_;
181 int i;
183 for (i = 0; i < num_modules_; delete modules_[i++])
185 // No action.
188 delete [] modules_;
191 void
192 Library::set_path (const char *p)
194 char abspath[1000];
195 ACE_OS::memset (abspath,0,1000);
196 ssize_t abspathlen = ACE_OS::readlink(p,abspath,999);
197 ACE_CString path (p);
198 if (abspathlen > 0) {
199 abspath[abspathlen] = 0;
200 path = abspath;
203 ACE_CString::size_type pathsep = path.rfind('/');
205 if (pathsep == ACE_CString::npos) {
206 path_ = ".";
207 } else {
208 path_ = path.substr(0,pathsep);
212 const ACE_CString &
213 Library::name () const
215 return name_;
219 Library::has_modules () const
221 return num_modules_ > 0;
224 extern "C" {
225 static int
226 selector (const dirent *d)
228 return ACE_OS::strstr (d->d_name, ACE_TEXT (".o")) != 0;
231 static int
232 comparator (const dirent **d1, const dirent **d2)
234 return ACE_OS::strcmp ((*d1)->d_name, (*d2)->d_name);
237 } /* extern "C" */
239 void
240 Library::load_modules ()
242 ACE_CString subdir = path_ + "/.shobj";
244 struct dirent **dent;
245 num_modules_ = ACE_OS::scandir(ACE_TEXT_CHAR_TO_TCHAR (subdir.c_str()),
246 &dent,selector,comparator);
248 if (num_modules_ > 0) {
249 modules_ = new Obj_Module * [num_modules_];
250 for (int i = 0; i < num_modules_; i++) {
251 ACE_CString ent_name (ACE_TEXT_ALWAYS_CHAR (dent[i]->d_name));
252 modules_[i] = new Obj_Module(ent_name);
253 modules_[i]->add_source (ACE_CString(subdir + "/" + ent_name).c_str());
254 ACE_OS::free(dent[i]);
258 if (num_modules_ > -1)
259 ACE_OS::free(dent);
262 void
263 Library::resolve (Sig_List &undefs)
265 if (num_modules_ < 1)
266 return;
268 for (const Signature *uname = undefs.first();
269 undefs.hasmore();
270 uname = undefs.next()) {
271 if (exported_.index_of(uname) != -1) {
272 undefs.remove_current();
274 else
275 for (int i = 0; i < num_modules_; i++)
276 if (modules_[i]->extref() == 0 &&
277 modules_[i]->exports().index_of(uname) != -1)
279 undefs.remove_current();
280 exported_.add (modules_[i]->exports());
281 for (const Signature *needed = modules_[i]->imports().first();
282 modules_[i]->imports().hasmore();
283 needed = modules_[i]->imports().next())
284 if (exported_.index_of(needed) == -1)
285 undefs.add (needed->name());
286 modules_[i]->add_extref();
287 num_extrefs_++;
288 break;
293 void
294 Library::write_export_list (int show_ref_counts)
296 if (num_modules_ < 1)
297 return;
299 ACE_CString excludedfilename = path_ + "/excluded_modules";
300 ACE_CString rcpath = path_ + "/usage_metrics";
302 ofstream exclusions (excludedfilename.c_str());
303 if (!exclusions) {
304 ACE_ERROR ((LM_ERROR, "%p\n", "open exclusions list"));
307 if (show_ref_counts) {
308 ACE_DEBUG ((LM_DEBUG, "Making directory %s\n",rcpath.c_str()));
309 if (ACE_OS::mkdir(ACE_TEXT_CHAR_TO_TCHAR (rcpath.c_str())) == -1 &&
310 errno != EEXIST)
311 ACE_ERROR ((LM_ERROR, "%p\n", "mkdir"));
314 ACE_DEBUG ((LM_DEBUG,"%s: %d out of %d modules required\n",
315 name_.c_str(), num_extrefs_, num_modules_));
317 mpcfile_->write_prolog(path_);
319 for (int i = 0; i < num_modules_ ; i++)
320 if (modules_[i]->extref()) {
321 if (show_ref_counts) {
322 ACE_CString fname = rcpath + "/" + modules_[i]->name();
323 ofstream countfile (fname.c_str());
324 countfile << "Exported symbols:" << endl;
325 for (const Signature *sig = modules_[i]->exports().first();
326 modules_[i]->exports().hasmore();
327 sig = modules_[i]->exports().next())
329 countfile.width(5);
330 countfile << sig->used_count() << " " << sig->name() << endl;
332 countfile << "\nImported symbols:" << endl;
333 for (const Signature *n_sig = modules_[i]->imports().first();
334 modules_[i]->imports().hasmore();
335 n_sig = modules_[i]->imports().next())
336 countfile << n_sig->name() << endl;
338 mpcfile_->write_file(modules_[i]->name().substring(0,modules_[i]->name().length()-2));
339 } else {
340 // const char * modname = modules_[i]->name().c_str();
341 exclusions
342 << modules_[i]->name().substring(0,modules_[i]->name().length()-2)
343 << endl;
346 mpcfile_->write_epilog();