PageRenderTime 35ms CodeModel.GetById 24ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/System/Link/dyn_link.cpp

#
C++ | 185 lines | 146 code | 21 blank | 18 comment | 42 complexity | 772ccf4be3d5a15156a4e3a18aca93e4 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1
  2/******************************************************************************
  3* MODULE     : dyn_link.cpp
  4* DESCRIPTION: Dynamic linking of extern routines
  5* COPYRIGHT  : (C) 1999  Joris van der Hoeven
  6*******************************************************************************
  7* This software falls under the GNU general public license version 3 or later.
  8* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  9* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 10******************************************************************************/
 11
 12#include "dyn_link.hpp"
 13#include "url.hpp"
 14#include "hashmap.hpp"
 15#ifndef __MINGW32__
 16#include <dlfcn.h>
 17#endif
 18#include <TeXmacs.h>
 19
 20static hashmap<string,pointer> dyn_linked (NULL);
 21
 22/******************************************************************************
 23* Linking symbols from dynamic libraries
 24******************************************************************************/
 25
 26string
 27symbol_install (string lib, string symb, pointer& f) {
 28#ifndef __MINGW32__
 29  // f becomes NULL in case of failure
 30  // status message returned
 31  string out;
 32
 33  if (!dyn_linked->contains (lib)) {
 34    url name= resolve (url ("$LD_LIBRARY_PATH", lib));
 35    if (is_none (name)) out= "Library '" * lib * "' not found";
 36    else {
 37      lib= concretize (name);
 38      char* _lib = as_charp (lib);
 39      dyn_linked (lib)= dlopen (_lib, RTLD_LAZY);
 40      if (dyn_linked [lib] == NULL) {
 41	const char *err = dlerror();
 42	if (err != NULL) out= string ((char *) err);
 43      }
 44      tm_delete_array (_lib);
 45    }
 46  }
 47
 48  pointer handle= dyn_linked [lib];
 49  if (handle) {
 50    char* _symb= as_charp (symb);
 51    string tag= lib * ":" * symb;
 52    if (!dyn_linked->contains (tag))
 53      dyn_linked (tag)= dlsym (handle, _symb);
 54    f= dyn_linked [tag];
 55    if (f != NULL) out= "Dynamically linked symbol '" * symb * "'";
 56    else out= "Can not find symbol '" * symb * "' in  '" * lib * "'";
 57    tm_delete_array (_symb);
 58  }
 59  else {
 60    f= NULL;
 61    if (out == "") out= "Couldn't find dynamic library '" * lib * "'";
 62  }
 63
 64  if (DEBUG_AUTO) cout << "TeXmacs] " << out << "\n";
 65  return out;
 66#else
 67  return "Dynamic linking not implemented";
 68#endif
 69}
 70
 71string
 72symbols_install (string lib, string* symb, pointer* f, int n) {
 73#ifndef __MINGW32__
 74  int i;
 75  for (i=0; i<n; i++) f[i]= NULL;
 76  for (i=0; i<n; i++) {
 77    string message= symbol_install (lib, symb[i], f[i]);
 78    if (f[i] == NULL) return message;
 79  }
 80  return "Symbols installed for library '" * lib * "'";
 81#else
 82  return "Dynamic linking not implemented";
 83#endif
 84}
 85
 86/******************************************************************************
 87* Dynamic links
 88******************************************************************************/
 89
 90dyn_link_rep::dyn_link_rep (string l, string s, string i, string ses):
 91  lib (l), symbol (s), init (i), routs (NULL), session (ses)
 92{
 93  alive= false;
 94}
 95
 96dyn_link_rep::~dyn_link_rep () {
 97  // FIXME: should we 'unlink' the package?
 98}
 99
100tm_link
101make_dynamic_link (string lib, string symb, string init, string session) {
102  return tm_new<dyn_link_rep> (lib, symb, init, session);
103}
104
105static TeXmacs_exports_1 TeXmacs= {
106  const_cast<char*> ("TeXmacs communication protocol 1"),
107  const_cast<char*> ("TeXmacs " TEXMACS_VERSION),
108};
109
110string
111dyn_link_rep::start () {
112#ifndef __MINGW32__
113  string name= lib * ":" * symbol * "-package";
114  if (dyn_linked->contains (name))
115    routs= dyn_linked [name];
116  if (routs != NULL)
117    return "continuation of#'" * lib * "'";
118  if (DEBUG_AUTO)
119    cout << "TeXmacs] Installing dynamic link '" << lib << "'\n";
120
121  string message= symbol_install (lib, symbol, routs);
122  if (routs != NULL) {
123    dyn_linked (name)= routs;
124    package_exports_1* pack= (package_exports_1*) routs;
125    char* _init  = as_charp (init);
126    char* _errors= NULL;
127    char* _message= pack->install (&TeXmacs, _init, &_errors);
128    if (_errors != NULL) {
129      routs= NULL;
130      ret= "Error: " * string (_errors);
131    }
132    else {
133      ret= string (_message == NULL? ((char*) ""): _message);
134      alive= true;
135    }
136    tm_delete_array (_init);
137    return ret;
138  }
139  else return message;
140#else
141  return "Error: dynamic linking not implemented";
142#endif
143}
144
145void
146dyn_link_rep::write (string s, int channel) {
147#ifndef __MINGW32__
148  if ((!alive) || (channel != LINK_IN)) return;
149  if (routs==NULL) {
150    cerr << "Library= " << lib << "\n";
151    FAILED ("library not installed");
152  }
153  package_exports_1* pack= (package_exports_1*) routs;
154
155  char* _session= as_charp (session);
156  char* _s= as_charp (s);
157  char* _errors= NULL;
158  char* _r= pack->evaluate (_s, _session, &_errors);
159  ret= string (_r==NULL? (_errors==NULL? ((char*) "Error"): _errors): _r);
160  tm_delete_array (_s);
161  tm_delete_array (_session);
162  if (!is_nil (this->feed_cmd)) this->feed_cmd->apply ();
163#endif
164}
165
166string&
167dyn_link_rep::watch (int channel) {
168  static string empty_string= "";
169  if (channel == LINK_OUT) return ret;
170  else return empty_string;
171}
172
173string
174dyn_link_rep::read (int channel) {
175  if (channel == LINK_OUT) {
176    string r= ret;
177    ret= "";
178    return r;
179  }
180  else return "";
181}
182
183void dyn_link_rep::listen (int msecs) { (void) msecs; }
184void dyn_link_rep::interrupt () {}
185void dyn_link_rep::stop () {}