summaryrefslogtreecommitdiff
path: root/ACE/apps/soreduce/Obj_Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/apps/soreduce/Obj_Module.cpp')
-rw-r--r--ACE/apps/soreduce/Obj_Module.cpp207
1 files changed, 207 insertions, 0 deletions
diff --git a/ACE/apps/soreduce/Obj_Module.cpp b/ACE/apps/soreduce/Obj_Module.cpp
new file mode 100644
index 00000000000..ca2d6eac8d1
--- /dev/null
+++ b/ACE/apps/soreduce/Obj_Module.cpp
@@ -0,0 +1,207 @@
+// -*- C++ -*-
+// $Id$
+
+// File: Obj_Module.cpp
+
+// Author: Phil Mesnier
+
+// This file contains the implementation of the classes responsible for
+// managing the contents of a single object module (.o file).
+
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/Process.h"
+#include "ace/Pipe.h"
+#include "ace/Message_Block.h"
+#include "ace/Log_Msg.h"
+
+#include "Obj_Module.h"
+
+//----------------------------------------------------------------------------
+
+Obj_Module::Obj_Module (const ACE_CString &name, int cap)
+ : name_ (name),
+ imports_(cap),
+ exports_(cap),
+ extrefs_(0)
+{
+}
+
+ACE_CString &
+Obj_Module::name()
+{
+ return name_;
+}
+
+Sig_List &
+Obj_Module::exports()
+{
+ return exports_;
+}
+
+Sig_List &
+Obj_Module::imports()
+{
+ return imports_;
+}
+
+int
+Obj_Module::extref()
+{
+ return extrefs_;
+}
+
+void
+Obj_Module::add_extref()
+{
+ extrefs_ ++;
+}
+
+void
+Obj_Module::remove_extref()
+{
+ extrefs_ --;
+}
+
+int
+Obj_Module::read_line (ACE_HANDLE src, ACE_Message_Block **buf)
+{
+ int eoln = 0;
+ // ACE_Time_Value timeout (1,0);
+ if (buf == 0 || *buf == 0) {
+ char dummy;
+ while (!eoln && ACE_OS::read(src,&dummy,1) == 1) {
+ eoln = (dummy == '\n');
+ }
+ return eoln;
+ }
+ // while (!eoln && ACE::recv(src,buf->wr_ptr(),1,&timeout) == 1) {
+ while (!eoln && ACE_OS::read(src,(*buf)->wr_ptr(),1) == 1) {
+ eoln = (*(*buf)->wr_ptr() == '\n');
+ (*buf)->wr_ptr(1);
+ if ((*buf)->space() == 0) {
+ (*buf)->cont(new ACE_Message_Block(102400));
+ *buf = (*buf)->cont();
+ }
+ }
+ return eoln;
+}
+
+void
+Obj_Module::add_source(const char *p, int imports_only)
+{
+ ACE_Process nmproc;
+ ACE_Process_Options nm_opts;
+ ACE_CString path (p);
+
+ ACE_CString::size_type pathsep = path.rfind('/');
+
+ ACE_CString src_name;
+ ACE_CString workpath;
+
+ if (pathsep == ACE_CString::npos) {
+ src_name = path;
+ workpath = ".";
+ } else {
+ src_name = path.substr(pathsep+1);
+ workpath= path.substr(0,pathsep);
+ }
+
+ ACE_HANDLE pipe[2];
+ ACE_Pipe io(pipe);
+
+ nm_opts.working_directory (workpath.c_str());
+ nm_opts.set_handles (ACE_STDIN,pipe[1]);
+
+ // Options for the command line shown here are for the GNU nm 2.9.5
+
+ int result = nm_opts.command_line ("nm -C %s",src_name.c_str());
+ // Prevent compiler warning about "unused variable" if ACE_ASSERT is
+ // an empty macro.
+ ACE_UNUSED_ARG (result);
+ ACE_ASSERT (result == 0);
+
+ nmproc.spawn (nm_opts);
+ if (ACE_OS::close(pipe[1]) == -1)
+ ACE_DEBUG ((LM_DEBUG, "%p\n", "close"));
+ nm_opts.release_handles();
+
+ int import_lines = 0;
+ int export_lines = 0;
+ ACE_Message_Block im_buffer (102400);
+ ACE_Message_Block ex_buffer (102400);
+ ACE_Message_Block *im_buf_cur = &im_buffer;
+ ACE_Message_Block *ex_buf_cur = &ex_buffer;
+ char dummy;
+ int eoln = 1;
+ // ACE_Time_Value timeout (1,0);
+ int is_import = 1;
+ int is_export = 1;
+
+ while (eoln == 1) {
+ for (int i = 0; i < 10; i++) {
+ if (ACE_OS::read(pipe[0],&dummy,1) != 1) {
+ eoln = 2;
+ break;
+ }
+ }
+ if (eoln == 2)
+ break;
+ is_import = dummy == 'U';
+ is_export = !imports_only && (ACE_OS::strchr("BCDRTVW",dummy) != 0);
+
+ // if (ACE::recv(pipe[0],&dummy,1,&timeout) != 1)
+ if (ACE_OS::read(pipe[0],&dummy,1) != 1)
+ break;
+
+ eoln = this->read_line (pipe[0], is_import ? &im_buf_cur :
+ (is_export ? &ex_buf_cur : 0));
+ import_lines += is_import;
+ export_lines += is_export;
+ }
+ // ACE_DEBUG ((LM_DEBUG, "read %d import lines and %d export lines\n",
+ // import_lines, export_lines));
+
+ nmproc.wait ();
+ ACE_OS::close (pipe[0]);
+
+ this->populate_sig_list (imports_,import_lines,&im_buffer);
+ if (!imports_only)
+ this->populate_sig_list (exports_,export_lines,&ex_buffer);
+}
+
+void
+Obj_Module::populate_sig_list (Sig_List &siglist,
+ int lines,
+ ACE_Message_Block *buf)
+{
+ char *c;
+ ACE_CString temp;
+
+ for (int i = 0; i < lines; i++)
+ {
+ for (c = buf->rd_ptr (); c != buf->wr_ptr () && *c != '\n'; ++c)
+ {
+ // No action.
+ }
+
+ temp += ACE_CString (buf->rd_ptr (), (c - buf->rd_ptr ()));
+ buf->rd_ptr (c + 1);
+
+ if (*c == '\n')
+ {
+ // ACE_DEBUG ((LM_DEBUG, "%s\n",temp.c_str()));
+ siglist.add (temp);
+ temp.clear ();
+ }
+ else
+ {
+ buf = buf->cont ();
+
+ if (buf == 0)
+ {
+ siglist.add (temp);
+ }
+ }
+ }
+}