00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FST_MAIN_H__
00023 #define FST_MAIN_H__
00024
00025 #include <map>
00026 #include <string>
00027 #include <utility>
00028
00029 #include <fst/fst.h>
00030
00031 extern "C" {
00032 typedef void (*ArcInitFunc)();
00033 }
00034
00035 namespace fst {
00036
00037
00038
00039
00040 class FstMainRegister {
00041 public:
00042 typedef int (*Main)(int argc, char **argv, istream &strm,
00043 const FstReadOptions &opts);
00044
00045 static FstMainRegister*GetRegister() {
00046 FstOnceInit(®ister_init_, &FstMainRegister::Init);
00047 return register_;
00048 }
00049
00050 const Main LookupMain(const string &mtype, const string &atype) const {
00051 MutexLock l(register_lock_);
00052 map<pair<string, string>, Main>::const_iterator it =
00053 main_table_.find(make_pair(mtype, atype));
00054 return it != main_table_.end() ? it->second : 0;
00055 }
00056
00057 const Main GetMain(const string &mtype, const string &atype) const {
00058 Main main = LookupMain(mtype, atype);
00059 if (main)
00060 return main;
00061 string so_file = atype + "-arc.so";
00062 void *handle = dlopen(so_file.c_str(), RTLD_LAZY);
00063 if (handle == 0) {
00064 LOG(ERROR) << "FstMainRegister::GetMain: " << dlerror();
00065 return 0;
00066 }
00067 string init_name = atype + "_arc_init";
00068 ArcInitFunc init_func =
00069 reinterpret_cast<ArcInitFunc>(dlsym(handle, init_name.c_str()));
00070 if (init_func == 0) {
00071 LOG(ERROR) << "FstMainRegister::GetMain: " << dlerror();
00072 return 0;
00073 }
00074 (*init_func)();
00075 return LookupMain(mtype, atype);
00076 }
00077
00078 void SetMain(const string &mtype, const string &atype, Main mfunc) {
00079 MutexLock l(register_lock_);
00080 main_table_.insert(make_pair(make_pair(mtype, atype), mfunc));
00081 }
00082
00083 private:
00084 static void Init() {
00085 register_lock_ = new Mutex;
00086 register_ = new FstMainRegister;
00087 }
00088
00089 static FstOnceType register_init_;
00090 static Mutex* register_lock_;
00091 static FstMainRegister *register_;
00092
00093 map<pair<string, string>, Main> main_table_;
00094 };
00095
00096
00097 template <class A>
00098 class FstMainRegisterer {
00099 public:
00100 typedef typename FstMainRegister::Main Main;
00101
00102 FstMainRegisterer(const string &mtype, Main mfunc) {
00103 FstMainRegister *registr = FstMainRegister::GetRegister();
00104 registr->SetMain(mtype, A::Type(), mfunc);
00105 }
00106 };
00107
00108
00109 #define REGISTER_FST_MAIN(M, A) \
00110 static fst::FstMainRegisterer<A> M ## _ ## A ## _registerer(#M, M<A>)
00111
00112
00113
00114 int CallFstMain(const string &mtype, int argc, char **argv, string atype = "");
00115
00116
00117 #define CALL_FST_MAIN(M, ac, av) fst::CallFstMain(#M, ac, av)
00118
00119 }
00120
00121 #endif // FST_MAIN_H__