/*$Id: c_attach.cc,v 26.19 2007/03/21 01:30:28 al Exp $ -*- C++ -*- * Copyright (C) 2007 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ */ //testing=informal #include "ap.h" #include "e_cardlist.h" #include "c_comand.h" #include "l_dispatcher.h" extern DISPATCHER command_dispatcher; /*--------------------------------------------------------------------------*/ namespace { /*--------------------------------------------------------------------------*/ std::map attach_list; /*--------------------------------------------------------------------------*/ class CMD_ATTACH : public CMD { public: void do_it(CS& cmd) { int here = cmd.cursor(); int scope = RTLD_LOCAL; int check = RTLD_NOW; // RTLD_NOW means to resolve symbols on loading // RTLD_LOCAL means symbols defined in a plugin are local do { if (cmd.icmatch("PUBLIC")) { scope = RTLD_GLOBAL; // RTLD_GLOBAL means symbols defined in a plugin are global // Use this when a plugin depends on another. }else if (cmd.icmatch("LAZY")) { check = RTLD_LAZY; // RTLD_LAZY means to defer resolving symbols until needed // Use when a plugin will not load because of unresolved symbols, // but it may work without it. }else{ } } while (cmd.more() && !cmd.stuck(&here)); std::string s; cmd >> s; void* handle = attach_list[s]; if (handle) { if (CARD_LIST::card_list.is_empty()) { cmd.warn(bDANGER, here, "already loaded, replacing"); dlclose(handle); attach_list[s] = NULL; }else{ cmd.warn(bERROR, here, "already loaded, cannot replace when there is a circuit\n"); } }else{ } handle = dlopen(s.c_str(), check | scope); if (handle) { attach_list[s] = handle; }else{ cmd.warn(bERROR, here, dlerror()); } } } p1; DISPATCHER::INSTALL d1(&command_dispatcher, "attach", &p1); /*--------------------------------------------------------------------------*/ class CMD_DETACH : public CMD { public: void do_it(CS& cmd) { if (CARD_LIST::card_list.is_empty()) { int here = cmd.cursor(); std::string s; cmd >> s; void* handle = attach_list[s]; if (handle) { dlclose(handle); attach_list[s] = NULL; }else{ cmd.warn(bERROR, here, "plugin not attached"); } }else{ cmd.warn(bERROR, "detach prohibited when there is a circuit\n"); } } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "detach", &p2); /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/