Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * clips_inifin.cpp - Fawkes CLIPSAspect initializer/finalizer 00004 * 00005 * Created: Sat Jun 16 14:34:27 2012 00006 * Copyright 2006-2012 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <plugins/clips/aspect/clips_inifin.h> 00025 #include <core/threading/thread_finalizer.h> 00026 #include <logging/logger.h> 00027 #include <clipsmm.h> 00028 00029 extern "C" { 00030 #include <clips/clips.h> 00031 } 00032 00033 namespace fawkes { 00034 #if 0 /* just to make Emacs auto-indent happy */ 00035 } 00036 #endif 00037 00038 /// @cond INTERNALS 00039 00040 class CLIPSLogger 00041 { 00042 public: 00043 CLIPSLogger(Logger *logger) 00044 { 00045 logger_ = logger; 00046 } 00047 00048 void log(const char *str) 00049 { 00050 if (strcmp(str, "\n") == 0) { 00051 logger_->log_info("CLIPS", "%s", buffer_.c_str()); 00052 buffer_.clear(); 00053 } else { 00054 buffer_ += str; 00055 } 00056 } 00057 00058 private: 00059 Logger *logger_; 00060 std::string buffer_; 00061 }; 00062 00063 static int 00064 log_router_query(void *env, char *logical_name) 00065 { 00066 if (strcmp(logical_name, "l") == 0) return TRUE; 00067 if (strcmp(logical_name, "stdout") == 0) return TRUE; 00068 return FALSE; 00069 } 00070 00071 static int 00072 log_router_print(void *env, char *logical_name, char *str) 00073 { 00074 void *rc = GetEnvironmentRouterContext(env); 00075 CLIPSLogger *logger = static_cast<CLIPSLogger *>(rc); 00076 logger->log(str); 00077 return TRUE; 00078 } 00079 00080 static int 00081 log_router_exit(void *env, int exit_code) 00082 { 00083 return TRUE; 00084 } 00085 00086 /// @endcond 00087 00088 /** @class CLIPSAspectIniFin <plugins/clips/aspect/clips_inifin.h> 00089 * CLIPSAspect initializer/finalizer. 00090 * This initializer/finalizer will provide the CLIPS node handle to 00091 * threads with the CLIPSAspect. 00092 * @author Tim Niemueller 00093 */ 00094 00095 /** Constructor. */ 00096 CLIPSAspectIniFin::CLIPSAspectIniFin() 00097 : AspectIniFin("CLIPSAspect") 00098 { 00099 logger_ = NULL; 00100 } 00101 00102 /** Destructor. */ 00103 CLIPSAspectIniFin::~CLIPSAspectIniFin() 00104 { 00105 delete logger_; 00106 } 00107 00108 void 00109 CLIPSAspectIniFin::init(Thread *thread) 00110 { 00111 CLIPSAspect *clips_thread; 00112 clips_thread = dynamic_cast<CLIPSAspect *>(thread); 00113 if (clips_thread == NULL) { 00114 throw CannotInitializeThreadException("Thread '%s' claims to have the " 00115 "CLIPSAspect, but RTTI says it " 00116 "has not. ", thread->name()); 00117 } 00118 00119 // CLIPS overwrites the SIGINT handler, restore it after 00120 // initializing the environment 00121 struct sigaction oldact; 00122 if (sigaction(SIGINT, NULL, &oldact) == 0) { 00123 LockPtr<CLIPS::Environment> clips(new CLIPS::Environment()); 00124 00125 void *env = clips->cobj(); 00126 EnvAddRouterWithContext(env, (char *)"fawkeslog", 00127 /* exclusive */ 50, 00128 log_router_query, 00129 log_router_print, 00130 /* getc */ NULL, 00131 /* ungetc */ NULL, 00132 log_router_exit, 00133 logger_); 00134 00135 clips_thread->init_CLIPSAspect(clips); 00136 // restore old action 00137 sigaction(SIGINT, &oldact, NULL); 00138 } else { 00139 throw CannotInitializeThreadException("CLIPS for %s: Unable to backup " 00140 "SIGINT sigaction for restoration.", 00141 thread->name()); 00142 } 00143 } 00144 00145 void 00146 CLIPSAspectIniFin::finalize(Thread *thread) 00147 { 00148 CLIPSAspect *clips_thread; 00149 clips_thread = dynamic_cast<CLIPSAspect *>(thread); 00150 if (clips_thread == NULL) { 00151 throw CannotFinalizeThreadException("Thread '%s' claims to have the " 00152 "CLIPSAspect, but RTTI says it " 00153 "has not. ", thread->name()); 00154 } 00155 clips_thread->finalize_CLIPSAspect(); 00156 } 00157 00158 00159 00160 /** Set the logger to use for logging (print to "l" output). 00161 * @param logger logger to use 00162 */ 00163 void 00164 CLIPSAspectIniFin::set_logger(Logger *logger) 00165 { 00166 logger_ = new CLIPSLogger(logger); 00167 } 00168 00169 } // end namespace fawkes