CommandLineArguments.cxx 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
  3. #include "kwsysPrivate.h"
  4. #include KWSYS_HEADER(CommandLineArguments.hxx)
  5. #include KWSYS_HEADER(Configure.hxx)
  6. #include KWSYS_HEADER(String.hxx)
  7. // Work-around CMake dependency scanning limitation. This must
  8. // duplicate the above list of headers.
  9. #if 0
  10. #include "CommandLineArguments.hxx.in"
  11. #include "Configure.hxx.in"
  12. #include "String.hxx.in"
  13. #endif
  14. #include <iostream>
  15. #include <map>
  16. #include <set>
  17. #include <sstream>
  18. #include <vector>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #ifdef _MSC_VER
  23. #pragma warning(disable : 4786)
  24. #endif
  25. #if defined(__sgi) && !defined(__GNUC__)
  26. #pragma set woff 1375 /* base class destructor not virtual */
  27. #endif
  28. #if 0
  29. #define CommandLineArguments_DEBUG(x) \
  30. std::cout << __LINE__ << " CLA: " << x << std::endl
  31. #else
  32. #define CommandLineArguments_DEBUG(x)
  33. #endif
  34. namespace KWSYS_NAMESPACE {
  35. //----------------------------------------------------------------------------
  36. //============================================================================
  37. struct CommandLineArgumentsCallbackStructure
  38. {
  39. const char* Argument;
  40. int ArgumentType;
  41. CommandLineArguments::CallbackType Callback;
  42. void* CallData;
  43. void* Variable;
  44. int VariableType;
  45. const char* Help;
  46. };
  47. class CommandLineArgumentsVectorOfStrings : public std::vector<kwsys::String>
  48. {
  49. };
  50. class CommandLineArgumentsSetOfStrings : public std::set<kwsys::String>
  51. {
  52. };
  53. class CommandLineArgumentsMapOfStrucs
  54. : public std::map<kwsys::String, CommandLineArgumentsCallbackStructure>
  55. {
  56. };
  57. class CommandLineArgumentsInternal
  58. {
  59. public:
  60. CommandLineArgumentsInternal()
  61. {
  62. this->UnknownArgumentCallback = 0;
  63. this->ClientData = 0;
  64. this->LastArgument = 0;
  65. }
  66. typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
  67. typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
  68. typedef kwsys::String String;
  69. typedef CommandLineArgumentsSetOfStrings SetOfStrings;
  70. VectorOfStrings Argv;
  71. String Argv0;
  72. CallbacksMap Callbacks;
  73. CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
  74. void* ClientData;
  75. VectorOfStrings::size_type LastArgument;
  76. VectorOfStrings UnusedArguments;
  77. };
  78. //============================================================================
  79. //----------------------------------------------------------------------------
  80. //----------------------------------------------------------------------------
  81. CommandLineArguments::CommandLineArguments()
  82. {
  83. this->Internals = new CommandLineArguments::Internal;
  84. this->Help = "";
  85. this->LineLength = 80;
  86. this->StoreUnusedArgumentsFlag = false;
  87. }
  88. //----------------------------------------------------------------------------
  89. CommandLineArguments::~CommandLineArguments()
  90. {
  91. delete this->Internals;
  92. }
  93. //----------------------------------------------------------------------------
  94. void CommandLineArguments::Initialize(int argc, const char* const argv[])
  95. {
  96. int cc;
  97. this->Initialize();
  98. this->Internals->Argv0 = argv[0];
  99. for (cc = 1; cc < argc; cc++) {
  100. this->ProcessArgument(argv[cc]);
  101. }
  102. }
  103. //----------------------------------------------------------------------------
  104. void CommandLineArguments::Initialize(int argc, char* argv[])
  105. {
  106. this->Initialize(argc, static_cast<const char* const*>(argv));
  107. }
  108. //----------------------------------------------------------------------------
  109. void CommandLineArguments::Initialize()
  110. {
  111. this->Internals->Argv.clear();
  112. this->Internals->LastArgument = 0;
  113. }
  114. //----------------------------------------------------------------------------
  115. void CommandLineArguments::ProcessArgument(const char* arg)
  116. {
  117. this->Internals->Argv.push_back(arg);
  118. }
  119. //----------------------------------------------------------------------------
  120. bool CommandLineArguments::GetMatchedArguments(
  121. std::vector<std::string>* matches, const std::string& arg)
  122. {
  123. matches->clear();
  124. CommandLineArguments::Internal::CallbacksMap::iterator it;
  125. // Does the argument match to any we know about?
  126. for (it = this->Internals->Callbacks.begin();
  127. it != this->Internals->Callbacks.end(); it++) {
  128. const CommandLineArguments::Internal::String& parg = it->first;
  129. CommandLineArgumentsCallbackStructure* cs = &it->second;
  130. if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
  131. cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT) {
  132. if (arg == parg) {
  133. matches->push_back(parg);
  134. }
  135. } else if (arg.find(parg) == 0) {
  136. matches->push_back(parg);
  137. }
  138. }
  139. return !matches->empty();
  140. }
  141. //----------------------------------------------------------------------------
  142. int CommandLineArguments::Parse()
  143. {
  144. std::vector<std::string>::size_type cc;
  145. std::vector<std::string> matches;
  146. if (this->StoreUnusedArgumentsFlag) {
  147. this->Internals->UnusedArguments.clear();
  148. }
  149. for (cc = 0; cc < this->Internals->Argv.size(); cc++) {
  150. const std::string& arg = this->Internals->Argv[cc];
  151. CommandLineArguments_DEBUG("Process argument: " << arg);
  152. this->Internals->LastArgument = cc;
  153. if (this->GetMatchedArguments(&matches, arg)) {
  154. // Ok, we found one or more arguments that match what user specified.
  155. // Let's find the longest one.
  156. CommandLineArguments::Internal::VectorOfStrings::size_type kk;
  157. CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
  158. CommandLineArguments::Internal::String::size_type maxlen = 0;
  159. for (kk = 0; kk < matches.size(); kk++) {
  160. if (matches[kk].size() > maxlen) {
  161. maxlen = matches[kk].size();
  162. maxidx = kk;
  163. }
  164. }
  165. // So, the longest one is probably the right one. Now see if it has any
  166. // additional value
  167. CommandLineArgumentsCallbackStructure* cs =
  168. &this->Internals->Callbacks[matches[maxidx]];
  169. const std::string& sarg = matches[maxidx];
  170. if (cs->Argument != sarg) {
  171. abort();
  172. }
  173. switch (cs->ArgumentType) {
  174. case NO_ARGUMENT:
  175. // No value
  176. if (!this->PopulateVariable(cs, 0)) {
  177. return 0;
  178. }
  179. break;
  180. case SPACE_ARGUMENT:
  181. if (cc == this->Internals->Argv.size() - 1) {
  182. this->Internals->LastArgument--;
  183. return 0;
  184. }
  185. CommandLineArguments_DEBUG("This is a space argument: "
  186. << arg << " value: "
  187. << this->Internals->Argv[cc + 1]);
  188. // Value is the next argument
  189. if (!this->PopulateVariable(cs,
  190. this->Internals->Argv[cc + 1].c_str())) {
  191. return 0;
  192. }
  193. cc++;
  194. break;
  195. case EQUAL_ARGUMENT:
  196. if (arg.size() == sarg.size() || arg.at(sarg.size()) != '=') {
  197. this->Internals->LastArgument--;
  198. return 0;
  199. }
  200. // Value is everythng followed the '=' sign
  201. if (!this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1)) {
  202. return 0;
  203. }
  204. break;
  205. case CONCAT_ARGUMENT:
  206. // Value is whatever follows the argument
  207. if (!this->PopulateVariable(cs, arg.c_str() + sarg.size())) {
  208. return 0;
  209. }
  210. break;
  211. case MULTI_ARGUMENT:
  212. // Suck in all the rest of the arguments
  213. CommandLineArguments_DEBUG("This is a multi argument: " << arg);
  214. for (cc++; cc < this->Internals->Argv.size(); ++cc) {
  215. const std::string& marg = this->Internals->Argv[cc];
  216. CommandLineArguments_DEBUG(
  217. " check multi argument value: " << marg);
  218. if (this->GetMatchedArguments(&matches, marg)) {
  219. CommandLineArguments_DEBUG("End of multi argument "
  220. << arg << " with value: " << marg);
  221. break;
  222. }
  223. CommandLineArguments_DEBUG(
  224. " populate multi argument value: " << marg);
  225. if (!this->PopulateVariable(cs, marg.c_str())) {
  226. return 0;
  227. }
  228. }
  229. if (cc != this->Internals->Argv.size()) {
  230. CommandLineArguments_DEBUG("Again End of multi argument " << arg);
  231. cc--;
  232. continue;
  233. }
  234. break;
  235. default:
  236. std::cerr << "Got unknown argument type: \"" << cs->ArgumentType
  237. << "\"" << std::endl;
  238. this->Internals->LastArgument--;
  239. return 0;
  240. }
  241. } else {
  242. // Handle unknown arguments
  243. if (this->Internals->UnknownArgumentCallback) {
  244. if (!this->Internals->UnknownArgumentCallback(
  245. arg.c_str(), this->Internals->ClientData)) {
  246. this->Internals->LastArgument--;
  247. return 0;
  248. }
  249. return 1;
  250. } else if (this->StoreUnusedArgumentsFlag) {
  251. CommandLineArguments_DEBUG("Store unused argument " << arg);
  252. this->Internals->UnusedArguments.push_back(arg);
  253. } else {
  254. std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl;
  255. this->Internals->LastArgument--;
  256. return 0;
  257. }
  258. }
  259. }
  260. return 1;
  261. }
  262. //----------------------------------------------------------------------------
  263. void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
  264. {
  265. CommandLineArguments::Internal::VectorOfStrings::size_type size =
  266. this->Internals->Argv.size() - this->Internals->LastArgument + 1;
  267. CommandLineArguments::Internal::VectorOfStrings::size_type cc;
  268. // Copy Argv0 as the first argument
  269. char** args = new char*[size];
  270. args[0] = new char[this->Internals->Argv0.size() + 1];
  271. strcpy(args[0], this->Internals->Argv0.c_str());
  272. int cnt = 1;
  273. // Copy everything after the LastArgument, since that was not parsed.
  274. for (cc = this->Internals->LastArgument + 1;
  275. cc < this->Internals->Argv.size(); cc++) {
  276. args[cnt] = new char[this->Internals->Argv[cc].size() + 1];
  277. strcpy(args[cnt], this->Internals->Argv[cc].c_str());
  278. cnt++;
  279. }
  280. *argc = cnt;
  281. *argv = args;
  282. }
  283. //----------------------------------------------------------------------------
  284. void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv)
  285. {
  286. CommandLineArguments::Internal::VectorOfStrings::size_type size =
  287. this->Internals->UnusedArguments.size() + 1;
  288. CommandLineArguments::Internal::VectorOfStrings::size_type cc;
  289. // Copy Argv0 as the first argument
  290. char** args = new char*[size];
  291. args[0] = new char[this->Internals->Argv0.size() + 1];
  292. strcpy(args[0], this->Internals->Argv0.c_str());
  293. int cnt = 1;
  294. // Copy everything after the LastArgument, since that was not parsed.
  295. for (cc = 0; cc < this->Internals->UnusedArguments.size(); cc++) {
  296. kwsys::String& str = this->Internals->UnusedArguments[cc];
  297. args[cnt] = new char[str.size() + 1];
  298. strcpy(args[cnt], str.c_str());
  299. cnt++;
  300. }
  301. *argc = cnt;
  302. *argv = args;
  303. }
  304. //----------------------------------------------------------------------------
  305. void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv)
  306. {
  307. int cc;
  308. for (cc = 0; cc < argc; ++cc) {
  309. delete[](*argv)[cc];
  310. }
  311. delete[] * argv;
  312. }
  313. //----------------------------------------------------------------------------
  314. void CommandLineArguments::AddCallback(const char* argument,
  315. ArgumentTypeEnum type,
  316. CallbackType callback, void* call_data,
  317. const char* help)
  318. {
  319. CommandLineArgumentsCallbackStructure s;
  320. s.Argument = argument;
  321. s.ArgumentType = type;
  322. s.Callback = callback;
  323. s.CallData = call_data;
  324. s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
  325. s.Variable = 0;
  326. s.Help = help;
  327. this->Internals->Callbacks[argument] = s;
  328. this->GenerateHelp();
  329. }
  330. //----------------------------------------------------------------------------
  331. void CommandLineArguments::AddArgument(const char* argument,
  332. ArgumentTypeEnum type,
  333. VariableTypeEnum vtype, void* variable,
  334. const char* help)
  335. {
  336. CommandLineArgumentsCallbackStructure s;
  337. s.Argument = argument;
  338. s.ArgumentType = type;
  339. s.Callback = 0;
  340. s.CallData = 0;
  341. s.VariableType = vtype;
  342. s.Variable = variable;
  343. s.Help = help;
  344. this->Internals->Callbacks[argument] = s;
  345. this->GenerateHelp();
  346. }
  347. //----------------------------------------------------------------------------
  348. #define CommandLineArgumentsAddArgumentMacro(type, ctype) \
  349. void CommandLineArguments::AddArgument(const char* argument, \
  350. ArgumentTypeEnum type, \
  351. ctype* variable, const char* help) \
  352. { \
  353. this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, \
  354. variable, help); \
  355. }
  356. CommandLineArgumentsAddArgumentMacro(BOOL, bool)
  357. CommandLineArgumentsAddArgumentMacro(INT, int)
  358. CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
  359. CommandLineArgumentsAddArgumentMacro(STRING, char*)
  360. CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string)
  361. CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>)
  362. CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>)
  363. CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE,
  364. std::vector<double>)
  365. CommandLineArgumentsAddArgumentMacro(VECTOR_STRING,
  366. std::vector<char*>)
  367. CommandLineArgumentsAddArgumentMacro(
  368. VECTOR_STL_STRING, std::vector<std::string>)
  369. //----------------------------------------------------------------------------
  370. #define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
  371. void CommandLineArguments::AddBooleanArgument( \
  372. const char* argument, ctype* variable, const char* help) \
  373. { \
  374. this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
  375. CommandLineArguments::type##_TYPE, variable, help); \
  376. }
  377. CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
  378. CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
  379. CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE,
  380. double)
  381. CommandLineArgumentsAddBooleanArgumentMacro(STRING,
  382. char*)
  383. CommandLineArgumentsAddBooleanArgumentMacro(
  384. STL_STRING, std::string)
  385. //----------------------------------------------------------------------------
  386. void CommandLineArguments::SetClientData(void* client_data)
  387. {
  388. this->Internals->ClientData = client_data;
  389. }
  390. //----------------------------------------------------------------------------
  391. void CommandLineArguments::SetUnknownArgumentCallback(
  392. CommandLineArguments::ErrorCallbackType callback)
  393. {
  394. this->Internals->UnknownArgumentCallback = callback;
  395. }
  396. //----------------------------------------------------------------------------
  397. const char* CommandLineArguments::GetHelp(const char* arg)
  398. {
  399. CommandLineArguments::Internal::CallbacksMap::iterator it =
  400. this->Internals->Callbacks.find(arg);
  401. if (it == this->Internals->Callbacks.end()) {
  402. return 0;
  403. }
  404. // Since several arguments may point to the same argument, find the one this
  405. // one point to if this one is pointing to another argument.
  406. CommandLineArgumentsCallbackStructure* cs = &(it->second);
  407. for (;;) {
  408. CommandLineArguments::Internal::CallbacksMap::iterator hit =
  409. this->Internals->Callbacks.find(cs->Help);
  410. if (hit == this->Internals->Callbacks.end()) {
  411. break;
  412. }
  413. cs = &(hit->second);
  414. }
  415. return cs->Help;
  416. }
  417. //----------------------------------------------------------------------------
  418. void CommandLineArguments::SetLineLength(unsigned int ll)
  419. {
  420. if (ll < 9 || ll > 1000) {
  421. return;
  422. }
  423. this->LineLength = ll;
  424. this->GenerateHelp();
  425. }
  426. //----------------------------------------------------------------------------
  427. const char* CommandLineArguments::GetArgv0()
  428. {
  429. return this->Internals->Argv0.c_str();
  430. }
  431. //----------------------------------------------------------------------------
  432. unsigned int CommandLineArguments::GetLastArgument()
  433. {
  434. return static_cast<unsigned int>(this->Internals->LastArgument + 1);
  435. }
  436. //----------------------------------------------------------------------------
  437. void CommandLineArguments::GenerateHelp()
  438. {
  439. std::ostringstream str;
  440. // Collapse all arguments into the map of vectors of all arguments that do
  441. // the same thing.
  442. CommandLineArguments::Internal::CallbacksMap::iterator it;
  443. typedef std::map<CommandLineArguments::Internal::String,
  444. CommandLineArguments::Internal::SetOfStrings>
  445. MapArgs;
  446. MapArgs mp;
  447. MapArgs::iterator mpit, smpit;
  448. for (it = this->Internals->Callbacks.begin();
  449. it != this->Internals->Callbacks.end(); it++) {
  450. CommandLineArgumentsCallbackStructure* cs = &(it->second);
  451. mpit = mp.find(cs->Help);
  452. if (mpit != mp.end()) {
  453. mpit->second.insert(it->first);
  454. mp[it->first].insert(it->first);
  455. } else {
  456. mp[it->first].insert(it->first);
  457. }
  458. }
  459. for (it = this->Internals->Callbacks.begin();
  460. it != this->Internals->Callbacks.end(); it++) {
  461. CommandLineArgumentsCallbackStructure* cs = &(it->second);
  462. mpit = mp.find(cs->Help);
  463. if (mpit != mp.end()) {
  464. mpit->second.insert(it->first);
  465. smpit = mp.find(it->first);
  466. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  467. for (sit = smpit->second.begin(); sit != smpit->second.end(); sit++) {
  468. mpit->second.insert(*sit);
  469. }
  470. mp.erase(smpit);
  471. } else {
  472. mp[it->first].insert(it->first);
  473. }
  474. }
  475. // Find the length of the longest string
  476. CommandLineArguments::Internal::String::size_type maxlen = 0;
  477. for (mpit = mp.begin(); mpit != mp.end(); mpit++) {
  478. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  479. for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) {
  480. CommandLineArguments::Internal::String::size_type clen = sit->size();
  481. switch (this->Internals->Callbacks[*sit].ArgumentType) {
  482. case CommandLineArguments::NO_ARGUMENT:
  483. clen += 0;
  484. break;
  485. case CommandLineArguments::CONCAT_ARGUMENT:
  486. clen += 3;
  487. break;
  488. case CommandLineArguments::SPACE_ARGUMENT:
  489. clen += 4;
  490. break;
  491. case CommandLineArguments::EQUAL_ARGUMENT:
  492. clen += 4;
  493. break;
  494. }
  495. if (clen > maxlen) {
  496. maxlen = clen;
  497. }
  498. }
  499. }
  500. // Create format for that string
  501. char format[80];
  502. sprintf(format, " %%-%us ", static_cast<unsigned int>(maxlen));
  503. maxlen += 4; // For the space before and after the option
  504. // Print help for each option
  505. for (mpit = mp.begin(); mpit != mp.end(); mpit++) {
  506. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  507. for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) {
  508. str << std::endl;
  509. char argument[100];
  510. sprintf(argument, "%s", sit->c_str());
  511. switch (this->Internals->Callbacks[*sit].ArgumentType) {
  512. case CommandLineArguments::NO_ARGUMENT:
  513. break;
  514. case CommandLineArguments::CONCAT_ARGUMENT:
  515. strcat(argument, "opt");
  516. break;
  517. case CommandLineArguments::SPACE_ARGUMENT:
  518. strcat(argument, " opt");
  519. break;
  520. case CommandLineArguments::EQUAL_ARGUMENT:
  521. strcat(argument, "=opt");
  522. break;
  523. case CommandLineArguments::MULTI_ARGUMENT:
  524. strcat(argument, " opt opt ...");
  525. break;
  526. }
  527. char buffer[80];
  528. sprintf(buffer, format, argument);
  529. str << buffer;
  530. }
  531. const char* ptr = this->Internals->Callbacks[mpit->first].Help;
  532. size_t len = strlen(ptr);
  533. int cnt = 0;
  534. while (len > 0) {
  535. // If argument with help is longer than line length, split it on previous
  536. // space (or tab) and continue on the next line
  537. CommandLineArguments::Internal::String::size_type cc;
  538. for (cc = 0; ptr[cc]; cc++) {
  539. if (*ptr == ' ' || *ptr == '\t') {
  540. ptr++;
  541. len--;
  542. }
  543. }
  544. if (cnt > 0) {
  545. for (cc = 0; cc < maxlen; cc++) {
  546. str << " ";
  547. }
  548. }
  549. CommandLineArguments::Internal::String::size_type skip = len;
  550. if (skip > this->LineLength - maxlen) {
  551. skip = this->LineLength - maxlen;
  552. for (cc = skip - 1; cc > 0; cc--) {
  553. if (ptr[cc] == ' ' || ptr[cc] == '\t') {
  554. break;
  555. }
  556. }
  557. if (cc != 0) {
  558. skip = cc;
  559. }
  560. }
  561. str.write(ptr, static_cast<std::streamsize>(skip));
  562. str << std::endl;
  563. ptr += skip;
  564. len -= skip;
  565. cnt++;
  566. }
  567. }
  568. /*
  569. // This can help debugging help string
  570. str << endl;
  571. unsigned int cc;
  572. for ( cc = 0; cc < this->LineLength; cc ++ )
  573. {
  574. str << cc % 10;
  575. }
  576. str << endl;
  577. */
  578. this->Help = str.str();
  579. }
  580. //----------------------------------------------------------------------------
  581. void CommandLineArguments::PopulateVariable(bool* variable,
  582. const std::string& value)
  583. {
  584. if (value == "1" || value == "ON" || value == "on" || value == "On" ||
  585. value == "TRUE" || value == "true" || value == "True" ||
  586. value == "yes" || value == "Yes" || value == "YES") {
  587. *variable = true;
  588. } else {
  589. *variable = false;
  590. }
  591. }
  592. //----------------------------------------------------------------------------
  593. void CommandLineArguments::PopulateVariable(int* variable,
  594. const std::string& value)
  595. {
  596. char* res = 0;
  597. *variable = static_cast<int>(strtol(value.c_str(), &res, 10));
  598. // if ( res && *res )
  599. // {
  600. // Can handle non-int
  601. // }
  602. }
  603. //----------------------------------------------------------------------------
  604. void CommandLineArguments::PopulateVariable(double* variable,
  605. const std::string& value)
  606. {
  607. char* res = 0;
  608. *variable = strtod(value.c_str(), &res);
  609. // if ( res && *res )
  610. // {
  611. // Can handle non-double
  612. // }
  613. }
  614. //----------------------------------------------------------------------------
  615. void CommandLineArguments::PopulateVariable(char** variable,
  616. const std::string& value)
  617. {
  618. if (*variable) {
  619. delete[] * variable;
  620. *variable = 0;
  621. }
  622. *variable = new char[value.size() + 1];
  623. strcpy(*variable, value.c_str());
  624. }
  625. //----------------------------------------------------------------------------
  626. void CommandLineArguments::PopulateVariable(std::string* variable,
  627. const std::string& value)
  628. {
  629. *variable = value;
  630. }
  631. //----------------------------------------------------------------------------
  632. void CommandLineArguments::PopulateVariable(std::vector<bool>* variable,
  633. const std::string& value)
  634. {
  635. bool val = false;
  636. if (value == "1" || value == "ON" || value == "on" || value == "On" ||
  637. value == "TRUE" || value == "true" || value == "True" ||
  638. value == "yes" || value == "Yes" || value == "YES") {
  639. val = true;
  640. }
  641. variable->push_back(val);
  642. }
  643. //----------------------------------------------------------------------------
  644. void CommandLineArguments::PopulateVariable(std::vector<int>* variable,
  645. const std::string& value)
  646. {
  647. char* res = 0;
  648. variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
  649. // if ( res && *res )
  650. // {
  651. // Can handle non-int
  652. // }
  653. }
  654. //----------------------------------------------------------------------------
  655. void CommandLineArguments::PopulateVariable(std::vector<double>* variable,
  656. const std::string& value)
  657. {
  658. char* res = 0;
  659. variable->push_back(strtod(value.c_str(), &res));
  660. // if ( res && *res )
  661. // {
  662. // Can handle non-int
  663. // }
  664. }
  665. //----------------------------------------------------------------------------
  666. void CommandLineArguments::PopulateVariable(std::vector<char*>* variable,
  667. const std::string& value)
  668. {
  669. char* var = new char[value.size() + 1];
  670. strcpy(var, value.c_str());
  671. variable->push_back(var);
  672. }
  673. //----------------------------------------------------------------------------
  674. void CommandLineArguments::PopulateVariable(std::vector<std::string>* variable,
  675. const std::string& value)
  676. {
  677. variable->push_back(value);
  678. }
  679. //----------------------------------------------------------------------------
  680. bool CommandLineArguments::PopulateVariable(
  681. CommandLineArgumentsCallbackStructure* cs, const char* value)
  682. {
  683. // Call the callback
  684. if (cs->Callback) {
  685. if (!cs->Callback(cs->Argument, value, cs->CallData)) {
  686. this->Internals->LastArgument--;
  687. return 0;
  688. }
  689. }
  690. CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to "
  691. << value);
  692. if (cs->Variable) {
  693. std::string var = "1";
  694. if (value) {
  695. var = value;
  696. }
  697. switch (cs->VariableType) {
  698. case CommandLineArguments::INT_TYPE:
  699. this->PopulateVariable(static_cast<int*>(cs->Variable), var);
  700. break;
  701. case CommandLineArguments::DOUBLE_TYPE:
  702. this->PopulateVariable(static_cast<double*>(cs->Variable), var);
  703. break;
  704. case CommandLineArguments::STRING_TYPE:
  705. this->PopulateVariable(static_cast<char**>(cs->Variable), var);
  706. break;
  707. case CommandLineArguments::STL_STRING_TYPE:
  708. this->PopulateVariable(static_cast<std::string*>(cs->Variable), var);
  709. break;
  710. case CommandLineArguments::BOOL_TYPE:
  711. this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
  712. break;
  713. case CommandLineArguments::VECTOR_BOOL_TYPE:
  714. this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable),
  715. var);
  716. break;
  717. case CommandLineArguments::VECTOR_INT_TYPE:
  718. this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable),
  719. var);
  720. break;
  721. case CommandLineArguments::VECTOR_DOUBLE_TYPE:
  722. this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable),
  723. var);
  724. break;
  725. case CommandLineArguments::VECTOR_STRING_TYPE:
  726. this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable),
  727. var);
  728. break;
  729. case CommandLineArguments::VECTOR_STL_STRING_TYPE:
  730. this->PopulateVariable(
  731. static_cast<std::vector<std::string>*>(cs->Variable), var);
  732. break;
  733. default:
  734. std::cerr << "Got unknown variable type: \"" << cs->VariableType
  735. << "\"" << std::endl;
  736. this->Internals->LastArgument--;
  737. return 0;
  738. }
  739. }
  740. return 1;
  741. }
  742. } // namespace KWSYS_NAMESPACE