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 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArArgumentBuilder.h"
00029 #include "ArLog.h"
00030 #include <stdarg.h>
00031 #include <ctype.h>
00032 #include <math.h>
00033
00040 AREXPORT ArArgumentBuilder::ArArgumentBuilder(size_t argvLen,
00041 char extraSpaceChar)
00042 {
00043 myArgc = 0;
00044 myOrigArgc = 0;
00045 myArgvLen = argvLen;
00046 myArgv = new char *[myArgvLen];
00047 myFirstAdd = true;
00048 myExtraSpace = extraSpaceChar;
00049 }
00050
00051 AREXPORT ArArgumentBuilder::ArArgumentBuilder(const ArArgumentBuilder & builder)
00052 {
00053 size_t i;
00054 myFullString = builder.myFullString;
00055 myExtraString = builder.myExtraString;
00056 myArgc = builder.getArgc();
00057 myArgvLen = builder.getArgvLen();
00058 myOrigArgc = myArgc;
00059 myArgv = new char *[myArgvLen];
00060 for (i = 0; i < myArgc; i++)
00061 myArgv[i] = strdup(builder.getArg(i));
00062 }
00063
00064 AREXPORT ArArgumentBuilder::~ArArgumentBuilder()
00065 {
00066 size_t i;
00067 if (myOrigArgc > 0)
00068 {
00069 for (i = 0; i < myOrigArgc; ++i)
00070 delete[] myArgv[i];
00071 }
00072 delete[] myArgv;
00073 }
00074
00075
00076 AREXPORT void ArArgumentBuilder::removeArg(size_t which)
00077 {
00078 size_t i;
00079 char *temp;
00080
00081 if (which > myArgc - 1)
00082 {
00083 ArLog::log(ArLog::Terse, "ArArgumentBuilder::removeArg: %d is greater than the number of arguments which is %d", which, myArgc);
00084 return;
00085 }
00086
00087 temp = myArgv[which];
00088
00089 for (i = which; i < myArgc - 1; i++)
00090 myArgv[i] = myArgv[i+1];
00091 myArgc -= 1;
00092 myArgv[i] = temp;
00093
00094 }
00095
00096 AREXPORT void ArArgumentBuilder::add(const char *str, ...)
00097 {
00098 char buf[2048];
00099 va_list ptr;
00100 va_start(ptr, str);
00101 vsprintf(buf, str, ptr);
00102 internalAdd(buf, -1);
00103 va_end(ptr);
00104 }
00105
00115 AREXPORT void ArArgumentBuilder::internalAdd(const char *str, int position)
00116 {
00117 char buf[2048];
00118 int i;
00119 int j;
00120 size_t k;
00121 bool findingSpace = true;
00122 int startNonSpace;
00123 int len;
00124 bool addAtEnd;
00125
00126
00127 if (position < 0 || (size_t)position > myArgc)
00128 addAtEnd = true;
00129 else
00130 addAtEnd = false;
00131
00132 strncpy(buf, str, sizeof(buf));
00133 len = strlen(buf);
00134
00135
00136
00137 for (i = 0; i < len; ++i)
00138 {
00139 if (!isspace(buf[i]) || (myExtraSpace != '\0' && buf[i] == myExtraSpace))
00140 break;
00141 }
00142
00143 if (i == len)
00144 {
00145 ArLog::log(ArLog::Verbose, "All white space add for argument builder.");
00146 return;
00147 }
00148
00149
00150
00151
00152
00153
00154 for (startNonSpace = i; ; ++i)
00155 {
00156
00157 if (buf[i] == '\\' && i + 1 < len && buf[i + 1] == ' ')
00158 {
00159 for (j = i; j < len && j != '\0'; j++)
00160 {
00161 buf[j] = buf[j + 1];
00162 }
00163 --len;
00164 }
00165
00166
00167 else if (!findingSpace &&
00168 !(i == len || isspace(buf[i]) || buf[i] == '\0' ||
00169 (myExtraSpace != '\0' && buf[i] == myExtraSpace)))
00170 {
00171 startNonSpace = i;
00172 findingSpace = true;
00173 }
00174
00175
00176 else if (findingSpace &&
00177 (i == len || isspace(buf[i]) || buf[i] == '\0' ||
00178 (myExtraSpace != '\0' && buf[i] == myExtraSpace)))
00179 {
00180
00181 if (myArgc + 1 >= myArgvLen)
00182 {
00183 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);
00184 }
00185 else
00186 {
00187
00188
00189 if (addAtEnd)
00190 {
00191 myArgv[myArgc] = new char[i - startNonSpace + 1];
00192 strncpy(myArgv[myArgc], &buf[startNonSpace], i - startNonSpace);
00193 myArgv[myArgc][i - startNonSpace] = '\0';
00194
00195
00196 if (!myFirstAdd && myExtraSpace == '\0')
00197 myFullString += " ";
00198 else if (!myFirstAdd)
00199 myFullString += myExtraSpace;
00200
00201 myFullString += myArgv[myArgc];
00202 myFirstAdd = false;
00203
00204 myArgc++;
00205 myOrigArgc = myArgc;
00206 }
00207
00208 else
00209 {
00210
00211 for (k = myArgc + 1; k > (size_t)position; k--)
00212 {
00213 myArgv[k] = myArgv[k - 1];
00214 }
00215 myArgc++;
00216 myOrigArgc = myArgc;
00217
00218 myArgv[position] = new char[i - startNonSpace + 1];
00219 strncpy(myArgv[position], &buf[startNonSpace], i - startNonSpace);
00220 myArgv[position][i - startNonSpace] = '\0';
00221 position++;
00222
00223 myFullString = "";
00224 for (k = 0; k < myArgc; k++)
00225 {
00226 myFullString += myArgv[k];
00227 myFullString += " ";
00228 }
00229 myFirstAdd = false;
00230 }
00231
00232 }
00233 findingSpace = false;
00234 }
00235
00236 if (i == len || buf[i] == '\0')
00237 break;
00238 }
00239 }
00240
00248 AREXPORT void ArArgumentBuilder::addPlain(const char *str, int position)
00249 {
00250 internalAdd(str, position);
00251 }
00252
00260 AREXPORT void ArArgumentBuilder::addStrings(char **argv, int argc,
00261 int position)
00262 {
00263 addStrings(argc, argv, position);
00264 }
00265
00273 AREXPORT void ArArgumentBuilder::addStrings(int argc, char **argv,
00274 int position)
00275 {
00276 int i;
00277 for (i = 0; i < argc; i++)
00278 add(argv[i], position + i);
00279 }
00280
00288 AREXPORT void ArArgumentBuilder::addStringsAsIs(int argc, char **argv,
00289 int position)
00290 {
00291 int i;
00292 for (i = 0; i < argc; i++)
00293 internalAddAsIs(argv[i], position + i);
00294 }
00295
00303 AREXPORT void ArArgumentBuilder::addPlainAsIs(const char *str, int position)
00304 {
00305 internalAddAsIs(str, position);
00306 }
00307
00308 AREXPORT void ArArgumentBuilder::internalAddAsIs(const char *str, int position)
00309 {
00310 myArgv[myArgc] = new char[strlen(str) + 1];
00311 strcpy(myArgv[myArgc], str);
00312 myArgv[myArgc][strlen(str)] = '\0';
00313
00314
00315
00316 if (!myFirstAdd && myExtraSpace == '\0')
00317 myFullString += " ";
00318 else if (!myFirstAdd)
00319 myFullString += myExtraSpace;
00320
00321 myFullString += myArgv[myArgc];
00322 myFirstAdd = false;
00323
00324 myArgc++;
00325 myOrigArgc = myArgc;
00326 }
00327
00328 AREXPORT size_t ArArgumentBuilder::getArgc(void) const
00329 {
00330 return myArgc;
00331 }
00332
00333 AREXPORT char** ArArgumentBuilder::getArgv(void) const
00334 {
00335 return myArgv;
00336 }
00337
00338 AREXPORT const char *ArArgumentBuilder::getFullString(void) const
00339 {
00340 return myFullString.c_str();
00341 }
00342
00343 AREXPORT const char *ArArgumentBuilder::getExtraString(void) const
00344 {
00345 return myExtraString.c_str();
00346 }
00347
00348 AREXPORT void ArArgumentBuilder::setExtraString(const char *str)
00349 {
00350 myExtraString = str;
00351 }
00352
00353 AREXPORT void ArArgumentBuilder::setFullString(const char *str)
00354 {
00355 myFullString = str;
00356 }
00357
00358 AREXPORT const char* ArArgumentBuilder::getArg(size_t whichArg) const
00359 {
00360 if (whichArg >= myArgc)
00361 return NULL;
00362 else
00363 return myArgv[whichArg];
00364 }
00365
00366 AREXPORT void ArArgumentBuilder::log(void) const
00367 {
00368 size_t i;
00369 ArLog::log(ArLog::Terse, "Num arguments: %d", myArgc);
00370 for (i = 0; i < myArgc; ++i)
00371 ArLog::log(ArLog::Terse, "Arg %d: %s", i, myArgv[i]);
00372 }
00373
00374 AREXPORT bool ArArgumentBuilder::isArgBool(size_t whichArg) const
00375 {
00376 if (whichArg > myArgc || getArg(whichArg) == NULL)
00377 return false;
00378
00379 if (strcasecmp(getArg(whichArg), "true") == 0 ||
00380 strcasecmp(getArg(whichArg), "1") == 0 ||
00381 strcasecmp(getArg(whichArg), "false") == 0 ||
00382 strcasecmp(getArg(whichArg), "0") == 0)
00383 return true;
00384 else
00385 return false;
00386 }
00387
00388 AREXPORT bool ArArgumentBuilder::getArgBool(size_t whichArg) const
00389 {
00390 if (whichArg > myArgc || getArg(whichArg) == NULL)
00391 return false;
00392
00393 if (strcasecmp(getArg(whichArg), "true") == 0 ||
00394 strcasecmp(getArg(whichArg), "1") == 0)
00395 return true;
00396 else
00397 return false;
00398 }
00399
00400 AREXPORT bool ArArgumentBuilder::isArgInt(size_t whichArg) const
00401 {
00402 const char *str;
00403 int ret;
00404 char *endPtr;
00405 if (whichArg > myArgc || getArg(whichArg) == NULL)
00406 return false;
00407
00408 str = getArg(whichArg);
00409 ret = strtol(str, &endPtr, 10);
00410 if (endPtr[0] == '\0' && endPtr != str)
00411 return true;
00412 else
00413 return false;
00414 }
00415
00416 AREXPORT int ArArgumentBuilder::getArgInt(size_t whichArg) const
00417 {
00418 const char *str;
00419 int ret;
00420 char *endPtr;
00421 if (whichArg > myArgc || getArg(whichArg) == NULL)
00422 return 0;
00423
00424 str = getArg(whichArg);
00425 ret = strtol(str, &endPtr, 10);
00426 if (endPtr[0] == '\0' && endPtr != str)
00427 return ret;
00428 else
00429 return 0;
00430 }
00431
00432 AREXPORT bool ArArgumentBuilder::isArgDouble(size_t whichArg) const
00433 {
00434 const char *str;
00435 double ret;
00436 char *endPtr;
00437 if (whichArg > myArgc || getArg(whichArg) == NULL)
00438 return false;
00439
00440 str = getArg(whichArg);
00441 if (strcmp(str, "-INF") == 0)
00442 {
00443 return true;
00444 }
00445 else if (strcmp(str, "INF") == 0)
00446 {
00447 return true;
00448 }
00449 else
00450 {
00451 ret = strtod(str, &endPtr);
00452 if (endPtr[0] == '\0' && endPtr != str)
00453 return true;
00454 else
00455 return false;
00456 }
00457
00458 }
00459
00460 AREXPORT double ArArgumentBuilder::getArgDouble(size_t whichArg) const
00461 {
00462 const char *str;
00463 double ret;
00464 char *endPtr;
00465 if (whichArg > myArgc || getArg(whichArg) == NULL)
00466 return 0;
00467
00468 str = getArg(whichArg);
00469 if (strcmp(str, "-INF") == 0)
00470 {
00471 ret = -HUGE_VAL;
00472 return ret;
00473 }
00474 else if (strcmp(str, "INF") == 0)
00475 {
00476 ret = HUGE_VAL;
00477 return ret;
00478 }
00479 else
00480 {
00481 ret = strtod(str, &endPtr);
00482 if (endPtr[0] == '\0' && endPtr != str)
00483 return ret;
00484 else
00485 return 0;
00486 }
00487 }
00488
00489 AREXPORT void ArArgumentBuilder::compressQuoted(bool stripQuotationMarks)
00490 {
00491 size_t argLen;
00492 size_t i;
00493 std::string myNewArg;
00494
00495 for (i = 0; i < myArgc; i++)
00496 {
00497 argLen = strlen(myArgv[i]);
00498 if (stripQuotationMarks && argLen >= 2 &&
00499 myArgv[i][0] == '"' && myArgv[i][argLen - 1] == '"')
00500 {
00501 myNewArg = &myArgv[i][1];
00502 myNewArg[myNewArg.size() - 1] = '\0';
00503 delete myArgv[i];
00504
00505 myArgv[i] = strdup(myNewArg.c_str());
00506 continue;
00507 }
00508
00509 if (argLen >= 2 && myArgv[i][0] == '"' && myArgv[i][argLen - 1] != '"')
00510 {
00511
00512
00513 if (stripQuotationMarks)
00514 myNewArg = &myArgv[i][1];
00515 else
00516 myNewArg = myArgv[i];
00517
00518 bool isEndQuoteFound = false;
00519
00520
00521
00522 while ((i + 1 < myArgc) && !isEndQuoteFound) {
00523
00524 int nextArgLen = strlen(myArgv[i+1]);
00525
00526
00527 if ((nextArgLen > 0) &&
00528 (myArgv[i+1][nextArgLen - 1] == '"'))
00529 {
00530 isEndQuoteFound = true;
00531 }
00532
00533
00534 myNewArg += " ";
00535 myNewArg += myArgv[i+1];
00536
00537 if (stripQuotationMarks && myNewArg.size() > 0 && isEndQuoteFound)
00538 myNewArg[myNewArg.size() - 1] = '\0';
00539
00540 removeArg(i+1);
00541
00542 delete myArgv[i];
00543
00544
00545 myArgv[i] = strdup(myNewArg.c_str());
00546 }
00547 }
00548 }
00549 }