pelib
2.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot 00003 00004 This file is part of Pelib. 00005 00006 Pelib is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Pelib is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with Pelib. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 00021 #include <iostream> 00022 #include <cstdlib> 00023 #include <vector> 00024 #include <map> 00025 00026 #include <pelib/Taskgraph.hpp> 00027 #include <pelib/Platform.hpp> 00028 #include <pelib/Record.hpp> 00029 00030 #include <pelib/process.h> 00031 #include <pelib/argument_parsing.hpp> 00032 #include <pelib/dl.h> 00033 00034 #ifdef debug 00035 #undef debug 00036 #endif 00037 00038 #define debug(expr) cerr << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #expr << " = \"" << expr << "\"." << endl; 00039 00040 using namespace std; 00041 using namespace pelib; 00042 00043 #ifdef __cplusplus 00044 extern "C" { 00045 #endif 00046 00047 struct args 00048 { 00049 bool showDescription; 00050 string name; 00051 pelib_argument_stream lib; 00052 }; 00053 typedef struct args args_t; 00054 00055 static 00056 args_t 00057 parse(char** arg) 00058 { 00059 args_t args; 00060 args.showDescription = false; 00061 args.name = ""; 00062 pelib_argument_stream_init(&args.lib); 00063 00064 for(; arg[0] != NULL && string(arg[0]).compare("--") != 0; arg++) 00065 { 00066 if(strcmp(arg[0], "--description") == 0) 00067 { 00068 args.showDescription = true; 00069 continue; 00070 } 00071 00072 if(strcmp(arg[0], "--name") == 0) 00073 { 00074 arg++; 00075 args.name = string(arg[0]); 00076 continue; 00077 } 00078 00079 // Nothing else, try to parse a library 00080 arg += pelib_argument_stream_parse(arg, &args.lib) - 1; 00081 continue; 00082 } 00083 00084 return args; 00085 } 00086 00087 // TODO: find a way to use libdl to invoke the library that created the object 00088 char *library; 00089 00090 std::map<const char*, pelib::Record*> 00091 pelib_process(std::map<const char*, pelib::Record*> records, size_t argc, char** argv) 00092 { 00093 // Parse extra arguments and skip them 00094 args_t args = parse(argv); 00095 00096 if(args.lib.library == NULL) 00097 { 00098 cerr << "[ERROR] No generator specified. Aborting" << endl; 00099 return map<const char*, Record*>(); 00100 } 00101 00102 // Load library 00103 library = args.lib.library; 00104 void *libGenerator = load_lib(library); 00105 map<const char*, Record*> output; 00106 00107 for(map<const char*, Record*>::const_iterator i = records.begin(); i != records.end(); i++) 00108 { 00109 output.insert(pair<const char*, Record*>(i->first, i->second->clone())); 00110 } 00111 00112 if(!args.showDescription) 00113 { 00114 Record* (*generate)(size_t argc, char **argv) = (Record* (*)(size_t argc, char **argv))load_function(libGenerator, "pelib_generate"); 00115 00116 // Prepare output collection and fill it with schedule generated by library 00117 Record *rec = generate(args.lib.argc, args.lib.argv); 00118 output.insert(pair<const char*, Record*>(args.name.compare("") == 0 ? typeid(*rec).name() : args.name.c_str(), rec)); 00119 } 00120 else 00121 { 00122 string (*description)(size_t argc, char **argv) = (string (*)(size_t argc, char **argv))load_function(libGenerator, "pelib_description"); 00123 cout << description(args.lib.argc, args.lib.argv) << endl; 00124 } 00125 00126 destroy_lib(libGenerator); 00127 00128 return output; 00129 } 00130 00131 void 00132 pelib_delete(pelib::Record* obj) 00133 { 00134 void *libGenerator = load_lib(library); 00135 void (*del)(const Record*) = (void (*)(const Record*))load_function(libGenerator, "pelib_delete"); 00136 00137 if(string(typeid(Record).name()).compare(typeid(*obj).name()) == 0) 00138 { 00139 del((Record*)obj); 00140 } 00141 else 00142 { 00143 delete obj; 00144 } 00145 } 00146 00147 #ifdef __cplusplus 00148 } 00149 #endif 00150