pelib  2.0.0
src/argument_parsing.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 <cstdlib>
00022 #include <string>
00023 #include <iostream>
00024 
00025 #include <string.h>
00026 
00027 #include <pelib/argument_parsing.hpp>
00028 
00029 #ifdef debug
00030 #undef debug
00031 #endif
00032 
00033 #define debug(expr) cerr << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #expr << " = \"" << expr << "\"." << endl;
00034 
00035 using namespace std;
00036 
00037 void
00038 pelib_argument_stream_init(pelib_argument_stream_t *pelib_argument_stream)
00039 {
00040         pelib_argument_stream->library = NULL;
00041         pelib_argument_stream->argv = (char**)malloc(sizeof(char*) * 1);
00042         pelib_argument_stream->argv[0] = NULL;
00043         pelib_argument_stream->argc = 0;
00044         pelib_argument_stream->filename = NULL;
00045         pelib_argument_stream->name = NULL;
00046         pelib_argument_stream->stream = STREAM_NOTHING;
00047 }
00048 
00049 void
00050 pelib_argument_stream_destroy(const pelib_argument_stream_t pelib_argument_stream)
00051 {
00052         free(pelib_argument_stream.argv);
00053 
00054         if(pelib_argument_stream.library != NULL)
00055         {
00056                 free(pelib_argument_stream.library);
00057         }
00058 
00059         if(pelib_argument_stream.filename != NULL)
00060         {
00061                 free(pelib_argument_stream.filename);
00062         }
00063 
00064         if(pelib_argument_stream.name != NULL)
00065         {
00066                 free(pelib_argument_stream.name);
00067         }
00068 }
00069 
00070 static bool
00071 is_reserved(char* str)
00072 {
00073         // Anything starting with a dash (-) is an option name and invalid as an option argument
00074         if(str == NULL || string(str).compare("-") == 0)
00075         {
00076                 return true;
00077         }
00078         
00079         // Nothing wrong was found with this option argument
00080         return false;
00081 }
00082 
00083 static void
00084 add_argument(pelib_argument_stream *stream, char *argv)
00085 {
00086                         // Make room for another argument
00087                         char **stuff = (char**)malloc(sizeof(char*) * (stream->argc + 2));
00088                         memcpy(stuff, stream->argv, (stream->argc + 1) * sizeof(char*));
00089                         free(stream->argv);
00090                         stream->argv = stuff;
00091 
00092                         stream->argv[stream->argc] = (char*)malloc(sizeof(char) * (strlen(argv) + 1));
00093                         strcpy(stream->argv[stream->argc], argv);
00094                         stream->argc++;
00095                         stream->argv[stream->argc] = NULL;
00096 }
00097 
00098 unsigned int
00099 pelib_argument_stream_parse(char **argv, pelib_argument_stream_t* stream)
00100 {
00101         unsigned int parsed = 0;
00102         while((void*)argv[0] != NULL && string(argv[0]).compare("--") != 0)
00103         {
00104                 if(string(*argv).compare("--library") == 0 || string(*argv).compare("-l") == 0)
00105                 {
00106                         argv++;
00107                         parsed++;
00108                         
00109                         if(is_reserved(*argv))
00110                         {
00111                                 return parsed;
00112                         }
00113                         else
00114                         {
00115                                 stream->library = (char*)malloc(sizeof(char) * (strlen(*argv) + 1));
00116                                 strcpy(stream->library, *argv);
00117                                 argv++;
00118                                 parsed++;
00119                         }
00120                         
00121                         // proceed with next argument
00122                         continue;
00123                 }
00124 
00125                 if(string(*argv).compare("--lib") == 0 || string(*argv).compare("-m") == 0)
00126                 {
00127                         argv++;
00128                         parsed++;
00129                         
00130                         if(is_reserved(*argv))
00131                         {
00132                                 return parsed;
00133                         }
00134                         else
00135                         {
00136                                 #define LIBPELIB "libpelib-"
00137                                 #define SO ".so"
00138                                 stream->library = (char*)malloc(sizeof(char) * (strlen(LIBPELIB) + strlen(*argv) + strlen(SO) + 1));
00139                                 strcpy(stream->library, LIBPELIB);
00140                                 strcpy(stream->library + strlen(LIBPELIB), *argv);
00141                                 strcpy(stream->library + strlen(LIBPELIB) + strlen(*argv), SO);
00142 
00143                                 argv++;
00144                                 parsed++;
00145                         }
00146                         
00147                         // proceed with next argument
00148                         continue;
00149                 }
00150 
00151                 if(string(*argv).compare("--name") == 0 || string(*argv).compare("-n") == 0)
00152                 {
00153                         argv++;
00154                         parsed++;
00155                         
00156                         if(is_reserved(*argv))
00157                         {
00158                                 return parsed;
00159                         }
00160                         else
00161                         {
00162                                 stream->name = (char*)malloc(sizeof(char) * (strlen(*argv) + 1));
00163                                 strcpy(stream->name, *argv);
00164 
00165                                 argv++;
00166                                 parsed++;
00167                         }
00168                         
00169                         // proceed with next argument
00170                         continue;
00171                 }
00172 
00173                 if(string(*argv).compare("--file") == 0 || string(*argv).compare("-f") == 0)
00174                 {
00175                         argv++;
00176                         parsed++;
00177                         
00178                         if(is_reserved(*argv))
00179                         {
00180                                 return parsed;
00181                         }
00182                         else
00183                         {
00184                                 stream->stream = STREAM_FILE;
00185                                 stream->filename = (char*)malloc(sizeof(char) * (strlen(*argv) + 1));
00186                                 strcpy(stream->filename, *argv);
00187                                 argv++;
00188                                 parsed++;
00189                         }
00190                         
00191                         // proceed with next argument
00192                         continue;
00193                 }
00194 
00195                 if(string(*argv).compare("--stdin") == 0)
00196                 {
00197                         argv++;
00198                         parsed++;
00199                         stream->stream = STREAM_STDIN;
00200                         
00201                         // proceed with next argument
00202                         continue;
00203                 }
00204 
00205                 if(string(*argv).compare("--stdout") == 0)
00206                 {
00207                         argv++;
00208                         parsed++;
00209                         stream->stream = STREAM_STDOUT;
00210                         
00211                         // proceed with next argument
00212                         continue;
00213                 }
00214 
00215                 if(string(*argv).compare("--stderr") == 0)
00216                 {
00217                         argv++;
00218                         parsed++;
00219                         stream->stream = STREAM_STDERR;
00220                         
00221                         // proceed with next argument
00222                         continue;
00223                 }
00224 
00225                 if(string(*argv).compare("--args") == 0)
00226                 {
00227                         argv++;
00228                         parsed++;
00229         
00230                         size_t args_counter = 1;
00231                         while(*argv != NULL)
00232                         {
00233                                 if(string(*argv).compare("--args") == 0)
00234                                 {
00235                                         args_counter++;
00236                                 }       
00237                                 
00238                                 if(string(*argv).compare("--") == 0)
00239                                 {
00240                                         args_counter--;
00241                                         if(args_counter == 0)
00242                                         {
00243                                                 break;
00244                                         }
00245                                 }
00246 
00247                                 add_argument(stream, *argv);
00248                                 argv++;
00249                                 parsed++;
00250                         }
00251                         
00252                         // Skip the last "--"
00253                         if(*argv != NULL)
00254                         {
00255                                 if(string(*argv).compare("--") == 0)
00256                                 {
00257                                         argv++;
00258                                         parsed++;       
00259                                 }
00260                         }
00261 
00262                         continue;
00263                 }
00264 
00265                 if(string(*argv).compare("-o") == 0)
00266                 {
00267                         argv++;
00268                         parsed++;
00269 
00270                         add_argument(stream, *argv);
00271                         argv++;
00272                         parsed++;
00273 
00274                         continue;
00275                 }
00276                 
00277                 // This is not a valid option; exit now
00278                 return parsed;
00279         }
00280 
00281         // Not parsed anything
00282         return parsed;
00283 }
00284