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 <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