00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArArgumentBuilder.h"
00030 #include "ArLog.h"
00031 #include <stdarg.h>
00032 #include <ctype.h>
00033 #include <math.h>
00034
00035 ArArgumentBuilder::ArArgumentBuilder(size_t argvLen)
00036 {
00037 myArgc = 0;
00038 myOrigArgc = 0;
00039 myArgvLen = argvLen;
00040 myArgv = new char *[myArgvLen];
00041 myFirstAdd = true;
00042 }
00043
00044 ArArgumentBuilder::ArArgumentBuilder(const ArArgumentBuilder & builder)
00045 {
00046 size_t i;
00047 myFullString = builder.myFullString;
00048 myExtraString = builder.myExtraString;
00049 myArgc = builder.getArgc();
00050 myArgvLen = builder.getArgvLen();
00051 myOrigArgc = myArgc;
00052 myArgv = new char *[myArgvLen];
00053 for (i = 0; i < myArgc; i++)
00054 myArgv[i] = strdup(builder.getArg(i));
00055 }
00056
00057 ArArgumentBuilder::~ArArgumentBuilder()
00058 {
00059 size_t i;
00060 if (myOrigArgc > 0)
00061 {
00062 for (i = 0; i < myOrigArgc; ++i)
00063 delete[] myArgv[i];
00064 }
00065 delete[] myArgv;
00066 }
00067
00068
00069 void ArArgumentBuilder::removeArg(size_t which)
00070 {
00071 size_t i;
00072 char *temp;
00073
00074 if (which > myArgc - 1)
00075 {
00076 ArLog::log(ArLog::Terse, "ArArgumentBuilder::removeArg: %d is greater than the number of arguments which is %d", which, myArgc);
00077 return;
00078 }
00079
00080 temp = myArgv[which];
00081
00082 for (i = which; i < myArgc - 1; i++)
00083 myArgv[i] = myArgv[i+1];
00084 myArgc -= 1;
00085 myArgv[i] = temp;
00086
00087 }
00088
00089 void ArArgumentBuilder::add(const char *str, ...)
00090 {
00091 char buf[2048];
00092 va_list ptr;
00093 va_start(ptr, str);
00094 vsprintf(buf, str, ptr);
00095 internalAdd(buf, -1);
00096 va_end(ptr);
00097 }
00098
00108 void ArArgumentBuilder::internalAdd(const char *str, int position)
00109 {
00110 char buf[2048];
00111 int i;
00112 int j;
00113 size_t k;
00114 bool findingSpace = true;
00115 int startNonSpace;
00116 int len;
00117 bool addAtEnd;
00118
00119
00120 if (position < 0 || (size_t)position > myArgc)
00121 addAtEnd = true;
00122 else
00123 addAtEnd = false;
00124
00125 strncpy(buf, str, sizeof(buf));
00126 len = strlen(buf);
00127
00128
00129
00130 for (i = 0; i < len; ++i)
00131 {
00132 if (!isspace(buf[i]))
00133 break;
00134 }
00135
00136 if (i == len)
00137 {
00138 ArLog::log(ArLog::Verbose, "All white space add for argument builder.");
00139 return;
00140 }
00141
00142
00143
00144
00145
00146
00147 for (startNonSpace = i; ; ++i)
00148 {
00149
00150 if (buf[i] == '\\' && i + 1 < len && buf[i + 1] == ' ')
00151 {
00152 for (j = i; j < len && j != '\0'; j++)
00153 {
00154 buf[j] = buf[j + 1];
00155 }
00156 --len;
00157 }
00158
00159
00160 else if (!findingSpace &&
00161 !(i == len || isspace(buf[i]) || buf[i] == '\0'))
00162 {
00163 startNonSpace = i;
00164 findingSpace = true;
00165 }
00166
00167
00168 else if (findingSpace &&
00169 (i == len || isspace(buf[i]) || buf[i] == '\0'))
00170 {
00171
00172 if (myArgc + 1 >= myArgvLen)
00173 {
00174 ArLog::log(ArLog::Terse, "ArArgumentBuilder::Add: could not add argument since argc (%u) has grown beyond the argv given in the conbufuctor (%u)", myArgc, myArgvLen);
00175 }
00176 else
00177 {
00178
00179
00180 if (addAtEnd)
00181 {
00182 myArgv[myArgc] = new char[i - startNonSpace + 1];
00183 strncpy(myArgv[myArgc], &buf[startNonSpace], i - startNonSpace);
00184 myArgv[myArgc][i - startNonSpace] = '\0';
00185
00186
00187 if (!myFirstAdd)
00188 myFullString += " ";
00189
00190 myFullString += myArgv[myArgc];
00191 myFirstAdd = false;
00192
00193 myArgc++;
00194 myOrigArgc = myArgc;
00195 }
00196
00197 else
00198 {
00199
00200 for (k = myArgc + 1; k > (size_t)position; k--)
00201 {
00202 myArgv[k] = myArgv[k - 1];
00203 }
00204 myArgc++;
00205 myOrigArgc = myArgc;
00206
00207 myArgv[position] = new char[i - startNonSpace + 1];
00208 strncpy(myArgv[position], &buf[startNonSpace], i - startNonSpace);
00209 myArgv[position][i - startNonSpace] = '\0';
00210 position++;
00211
00212 myFullString = "";
00213 for (k = 0; k < myArgc; k++)
00214 {
00215 myFullString += myArgv[k];
00216 myFullString += " ";
00217 }
00218 myFirstAdd = false;
00219 }
00220
00221 }
00222 findingSpace = false;
00223 }
00224
00225 if (i == len || buf[i] == '\0')
00226 break;
00227 }
00228 }
00229
00237 void ArArgumentBuilder::addPlain(const char *str, int position)
00238 {
00239 internalAdd(str, position);
00240 }
00241
00249 void ArArgumentBuilder::addStrings(char **argv, int argc,
00250 int position)
00251 {
00252 addStrings(argc, argv, position);
00253 }
00254
00262 void ArArgumentBuilder::addStrings(int argc, char **argv,
00263 int position)
00264 {
00265 int i;
00266 for (i = 0; i < argc; i++)
00267 add(argv[i], position + i);
00268 }
00269
00270 size_t ArArgumentBuilder::getArgc(void) const
00271 {
00272 return myArgc;
00273 }
00274
00275 char** ArArgumentBuilder::getArgv(void) const
00276 {
00277 return myArgv;
00278 }
00279
00280 const char *ArArgumentBuilder::getFullString(void) const
00281 {
00282 return myFullString.c_str();
00283 }
00284
00285 const char *ArArgumentBuilder::getExtraString(void) const
00286 {
00287 return myExtraString.c_str();
00288 }
00289
00290 void ArArgumentBuilder::setExtraString(const char *str)
00291 {
00292 myExtraString = str;
00293 }
00294
00295 void ArArgumentBuilder::setFullString(const char *str)
00296 {
00297 myFullString = str;
00298 }
00299
00300 const char* ArArgumentBuilder::getArg(size_t whichArg) const
00301 {
00302 if (whichArg >= myArgc)
00303 return NULL;
00304 else
00305 return myArgv[whichArg];
00306 }
00307
00308 void ArArgumentBuilder::log(void) const
00309 {
00310 size_t i;
00311 ArLog::log(ArLog::Terse, "Num arguments: %d", myArgc);
00312 for (i = 0; i < myArgc; ++i)
00313 ArLog::log(ArLog::Terse, "Arg %d: %s", i, myArgv[i]);
00314 }
00315
00316 bool ArArgumentBuilder::isArgBool(size_t whichArg) const
00317 {
00318 if (whichArg > myArgc || getArg(whichArg) == NULL)
00319 return false;
00320
00321 if (strcasecmp(getArg(whichArg), "true") == 0 ||
00322 strcasecmp(getArg(whichArg), "1") == 0 ||
00323 strcasecmp(getArg(whichArg), "false") == 0 ||
00324 strcasecmp(getArg(whichArg), "0") == 0)
00325 return true;
00326 else
00327 return false;
00328 }
00329
00330 bool ArArgumentBuilder::getArgBool(size_t whichArg) const
00331 {
00332 if (whichArg > myArgc || getArg(whichArg) == NULL)
00333 return false;
00334
00335 if (strcasecmp(getArg(whichArg), "true") == 0 ||
00336 strcasecmp(getArg(whichArg), "1") == 0)
00337 return true;
00338 else
00339 return false;
00340 }
00341
00342 bool ArArgumentBuilder::isArgInt(size_t whichArg) const
00343 {
00344 const char *str;
00345 int ret;
00346 char *endPtr;
00347 if (whichArg > myArgc || getArg(whichArg) == NULL)
00348 return false;
00349
00350 str = getArg(whichArg);
00351 ret = strtol(str, &endPtr, 10);
00352 if (endPtr[0] == '\0' && endPtr != str)
00353 return true;
00354 else
00355 return false;
00356 }
00357
00358 int ArArgumentBuilder::getArgInt(size_t whichArg) const
00359 {
00360 const char *str;
00361 int ret;
00362 char *endPtr;
00363 if (whichArg > myArgc || getArg(whichArg) == NULL)
00364 return 0;
00365
00366 str = getArg(whichArg);
00367 ret = strtol(str, &endPtr, 10);
00368 if (endPtr[0] == '\0' && endPtr != str)
00369 return ret;
00370 else
00371 return 0;
00372 }
00373
00374 bool ArArgumentBuilder::isArgDouble(size_t whichArg) const
00375 {
00376 const char *str;
00377 double ret;
00378 char *endPtr;
00379 if (whichArg > myArgc || getArg(whichArg) == NULL)
00380 return false;
00381
00382 str = getArg(whichArg);
00383 if (strcmp(str, "-INF") == 0)
00384 {
00385 return true;
00386 }
00387 else if (strcmp(str, "INF") == 0)
00388 {
00389 return true;
00390 }
00391 else
00392 {
00393 ret = strtod(str, &endPtr);
00394 if (endPtr[0] == '\0' && endPtr != str)
00395 return true;
00396 else
00397 return false;
00398 }
00399
00400 }
00401
00402 double ArArgumentBuilder::getArgDouble(size_t whichArg) const
00403 {
00404 const char *str;
00405 double ret;
00406 char *endPtr;
00407 if (whichArg > myArgc || getArg(whichArg) == NULL)
00408 return 0;
00409
00410 str = getArg(whichArg);
00411 if (strcmp(str, "-INF") == 0)
00412 {
00413 ret = -HUGE_VAL;
00414 return ret;
00415 }
00416 else if (strcmp(str, "INF") == 0)
00417 {
00418 ret = HUGE_VAL;
00419 return ret;
00420 }
00421 else
00422 {
00423 ret = strtod(str, &endPtr);
00424 if (endPtr[0] == '\0' && endPtr != str)
00425 return ret;
00426 else
00427 return 0;
00428 }
00429 }
00430
00431 void ArArgumentBuilder::compressQuoted(bool stripQuotationMarks)
00432 {
00433 size_t argLen;
00434 size_t i;
00435 std::string myNewArg;
00436
00437 for (i = 0; i < myArgc; i++)
00438 {
00439 argLen = strlen(myArgv[i]);
00440 if (stripQuotationMarks && argLen >= 2 &&
00441 myArgv[i][0] == '"' && myArgv[i][argLen - 1] == '"')
00442 {
00443 myNewArg = &myArgv[i][1];
00444 myNewArg[myNewArg.size() - 1] = '\0';
00445 delete myArgv[i];
00446
00447 myArgv[i] = strdup(myNewArg.c_str());
00448 continue;
00449 }
00450
00451 if (argLen >= 2 && myArgv[i][0] == '"' && myArgv[i][argLen - 1] != '"')
00452 {
00453
00454
00455 if (stripQuotationMarks)
00456 myNewArg = &myArgv[i][1];
00457 else
00458 myNewArg = myArgv[i];
00459
00460 bool isEndQuoteFound = false;
00461
00462
00463
00464 while ((i + 1 < myArgc) && !isEndQuoteFound) {
00465
00466 int nextArgLen = strlen(myArgv[i+1]);
00467
00468
00469 if ((nextArgLen > 0) &&
00470 (myArgv[i+1][nextArgLen - 1] == '"'))
00471 {
00472 isEndQuoteFound = true;
00473 }
00474
00475
00476 myNewArg += " ";
00477 myNewArg += myArgv[i+1];
00478
00479 if (stripQuotationMarks && myNewArg.size() > 0 && isEndQuoteFound)
00480 myNewArg[myNewArg.size() - 1] = '\0';
00481
00482 removeArg(i+1);
00483
00484 delete myArgv[i];
00485
00486
00487 myArgv[i] = strdup(myNewArg.c_str());
00488 }
00489 }
00490 }
00491 }