pelib  2.0.0
src/generate.cpp
Go to the documentation of this file.
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