CommandLineArguments.cxx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
  5. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  8. PURPOSE. See the above copyright notices for more information.
  9. =========================================================================*/
  10. #include "kwsysPrivate.h"
  11. #include KWSYS_HEADER(CommandLineArguments.hxx)
  12. #include KWSYS_HEADER(Configure.hxx)
  13. #include KWSYS_HEADER(stl/vector)
  14. #include KWSYS_HEADER(stl/map)
  15. #include KWSYS_HEADER(stl/set)
  16. #include KWSYS_HEADER(ios/sstream)
  17. #include KWSYS_HEADER(ios/iostream)
  18. // Work-around CMake dependency scanning limitation. This must
  19. // duplicate the above list of headers.
  20. #if 0
  21. # include "CommandLineArguments.hxx.in"
  22. # include "Configure.hxx.in"
  23. # include "kwsys_stl.hxx.in"
  24. # include "kwsys_ios_sstream.h.in"
  25. # include "kwsys_ios_iostream.h.in"
  26. #endif
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #ifdef _MSC_VER
  31. # pragma warning (disable: 4786)
  32. #endif
  33. #if defined(__sgi) && !defined(__GNUC__)
  34. # pragma set woff 1375 /* base class destructor not virtual */
  35. #endif
  36. namespace KWSYS_NAMESPACE
  37. {
  38. //----------------------------------------------------------------------------
  39. //============================================================================
  40. class CommandLineArgumentsString : public kwsys_stl::string
  41. {
  42. public:
  43. typedef kwsys_stl::string StdString;
  44. CommandLineArgumentsString(): StdString() {}
  45. CommandLineArgumentsString(const value_type* s): StdString(s) {}
  46. CommandLineArgumentsString(const value_type* s, size_type n): StdString(s, n) {}
  47. CommandLineArgumentsString(const StdString& s, size_type pos=0, size_type n=npos):
  48. StdString(s, pos, n) {}
  49. };
  50. struct CommandLineArgumentsCallbackStructure
  51. {
  52. const char* Argument;
  53. int ArgumentType;
  54. CommandLineArguments::CallbackType Callback;
  55. void* CallData;
  56. void* Variable;
  57. int VariableType;
  58. const char* Help;
  59. };
  60. class CommandLineArgumentsVectorOfStrings :
  61. public kwsys_stl::vector<CommandLineArgumentsString> {};
  62. class CommandLineArgumentsSetOfStrings :
  63. public kwsys_stl::set<CommandLineArgumentsString> {};
  64. class CommandLineArgumentsMapOfStrucs :
  65. public kwsys_stl::map<CommandLineArgumentsString,
  66. CommandLineArgumentsCallbackStructure> {};
  67. class CommandLineArgumentsInternal
  68. {
  69. public:
  70. CommandLineArgumentsInternal()
  71. {
  72. this->UnknownArgumentCallback = 0;
  73. this->ClientData = 0;
  74. this->LastArgument = 0;
  75. }
  76. typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
  77. typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
  78. typedef CommandLineArgumentsString String;
  79. typedef CommandLineArgumentsSetOfStrings SetOfStrings;
  80. VectorOfStrings Argv;
  81. String Argv0;
  82. CallbacksMap Callbacks;
  83. CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
  84. void* ClientData;
  85. VectorOfStrings::size_type LastArgument;
  86. };
  87. //============================================================================
  88. //----------------------------------------------------------------------------
  89. //----------------------------------------------------------------------------
  90. CommandLineArguments::CommandLineArguments()
  91. {
  92. this->Internals = new CommandLineArguments::Internal;
  93. this->Help = "";
  94. this->LineLength = 80;
  95. }
  96. //----------------------------------------------------------------------------
  97. CommandLineArguments::~CommandLineArguments()
  98. {
  99. delete this->Internals;
  100. }
  101. //----------------------------------------------------------------------------
  102. void CommandLineArguments::Initialize(int argc, const char* const argv[])
  103. {
  104. int cc;
  105. this->Initialize();
  106. this->Internals->Argv0 = argv[0];
  107. for ( cc = 1; cc < argc; cc ++ )
  108. {
  109. this->ProcessArgument(argv[cc]);
  110. }
  111. }
  112. //----------------------------------------------------------------------------
  113. void CommandLineArguments::Initialize(int argc, char* argv[])
  114. {
  115. this->Initialize(argc, static_cast<const char* const*>(argv));
  116. }
  117. //----------------------------------------------------------------------------
  118. void CommandLineArguments::Initialize()
  119. {
  120. this->Internals->Argv.clear();
  121. this->Internals->LastArgument = 0;
  122. }
  123. //----------------------------------------------------------------------------
  124. void CommandLineArguments::ProcessArgument(const char* arg)
  125. {
  126. this->Internals->Argv.push_back(arg);
  127. }
  128. //----------------------------------------------------------------------------
  129. int CommandLineArguments::Parse()
  130. {
  131. CommandLineArguments::Internal::VectorOfStrings::size_type cc;
  132. CommandLineArguments::Internal::VectorOfStrings matches;
  133. for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
  134. {
  135. this->Internals->LastArgument = cc;
  136. matches.clear();
  137. CommandLineArguments::Internal::String& arg = this->Internals->Argv[cc];
  138. CommandLineArguments::Internal::CallbacksMap::iterator it;
  139. // Does the argument match to any we know about?
  140. for ( it = this->Internals->Callbacks.begin();
  141. it != this->Internals->Callbacks.end();
  142. it ++ )
  143. {
  144. const CommandLineArguments::Internal::String& parg = it->first;
  145. CommandLineArgumentsCallbackStructure *cs = &it->second;
  146. if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
  147. cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
  148. {
  149. if ( arg == parg )
  150. {
  151. matches.push_back(parg);
  152. }
  153. }
  154. else if ( arg.find( parg ) == 0 )
  155. {
  156. matches.push_back(parg);
  157. }
  158. }
  159. if ( matches.size() > 0 )
  160. {
  161. // Ok, we found one or more arguments that match what user specified.
  162. // Let's find the longest one.
  163. CommandLineArguments::Internal::VectorOfStrings::size_type kk;
  164. CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
  165. CommandLineArguments::Internal::String::size_type maxlen = 0;
  166. for ( kk = 0; kk < matches.size(); kk ++ )
  167. {
  168. if ( matches[kk].size() > maxlen )
  169. {
  170. maxlen = matches[kk].size();
  171. maxidx = kk;
  172. }
  173. }
  174. // So, the longest one is probably the right one. Now see if it has any
  175. // additional value
  176. const char* value = 0;
  177. CommandLineArgumentsCallbackStructure *cs
  178. = &this->Internals->Callbacks[matches[maxidx]];
  179. const CommandLineArguments::Internal::String& sarg = matches[maxidx];
  180. if ( cs->ArgumentType == NO_ARGUMENT )
  181. {
  182. // No value
  183. }
  184. else if ( cs->ArgumentType == SPACE_ARGUMENT )
  185. {
  186. if ( cc == this->Internals->Argv.size()-1 )
  187. {
  188. this->Internals->LastArgument --;
  189. return 0;
  190. }
  191. // Value is the next argument
  192. value = this->Internals->Argv[cc+1].c_str();
  193. cc ++;
  194. }
  195. else if ( cs->ArgumentType == EQUAL_ARGUMENT )
  196. {
  197. if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
  198. {
  199. this->Internals->LastArgument --;
  200. return 0;
  201. }
  202. // Value is everythng followed the '=' sign
  203. value = arg.c_str() + sarg.size()+1;
  204. }
  205. else if ( cs->ArgumentType == CONCAT_ARGUMENT )
  206. {
  207. // Value is whatever follows the argument
  208. value = arg.c_str() + sarg.size();
  209. }
  210. // Call the callback
  211. if ( cs->Callback )
  212. {
  213. if ( !cs->Callback(sarg.c_str(), value, cs->CallData) )
  214. {
  215. this->Internals->LastArgument --;
  216. return 0;
  217. }
  218. }
  219. if ( cs->Variable )
  220. {
  221. kwsys_stl::string var = "1";
  222. if ( value )
  223. {
  224. var = value;
  225. }
  226. if ( cs->VariableType == CommandLineArguments::INT_TYPE )
  227. {
  228. int* variable = static_cast<int*>(cs->Variable);
  229. char* res = 0;
  230. *variable = strtol(var.c_str(), &res, 10);
  231. //if ( res && *res )
  232. // {
  233. // Can handle non-int
  234. // }
  235. }
  236. else if ( cs->VariableType == CommandLineArguments::DOUBLE_TYPE )
  237. {
  238. double* variable = static_cast<double*>(cs->Variable);
  239. char* res = 0;
  240. *variable = strtod(var.c_str(), &res);
  241. //if ( res && *res )
  242. // {
  243. // Can handle non-int
  244. // }
  245. }
  246. else if ( cs->VariableType == CommandLineArguments::STRING_TYPE )
  247. {
  248. char** variable = static_cast<char**>(cs->Variable);
  249. if ( *variable )
  250. {
  251. delete [] *variable;
  252. *variable = 0;
  253. }
  254. *variable = new char[ strlen(var.c_str()) + 1 ];
  255. strcpy(*variable, var.c_str());
  256. }
  257. else if ( cs->VariableType == CommandLineArguments::STL_STRING_TYPE )
  258. {
  259. kwsys_stl::string* variable = static_cast<kwsys_stl::string*>(cs->Variable);
  260. *variable = var;
  261. }
  262. else if ( cs->VariableType == CommandLineArguments::BOOL_TYPE )
  263. {
  264. bool* variable = static_cast<bool*>(cs->Variable);
  265. if ( var == "1" || var == "ON" || var == "TRUE" || var == "true" || var == "on" ||
  266. var == "True" || var == "yes" || var == "Yes" || var == "YES" )
  267. {
  268. *variable = true;
  269. }
  270. else
  271. {
  272. *variable = false;
  273. }
  274. }
  275. else
  276. {
  277. kwsys_ios::cerr << "Got unknown argument type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
  278. this->Internals->LastArgument --;
  279. return 0;
  280. }
  281. }
  282. }
  283. else
  284. {
  285. // Handle unknown arguments
  286. if ( this->Internals->UnknownArgumentCallback )
  287. {
  288. if ( !this->Internals->UnknownArgumentCallback(arg.c_str(),
  289. this->Internals->ClientData) )
  290. {
  291. this->Internals->LastArgument --;
  292. return 0;
  293. }
  294. return 1;
  295. }
  296. else
  297. {
  298. kwsys_ios::cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << kwsys_ios::endl;
  299. this->Internals->LastArgument --;
  300. return 0;
  301. }
  302. }
  303. }
  304. return 1;
  305. }
  306. //----------------------------------------------------------------------------
  307. void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
  308. {
  309. CommandLineArguments::Internal::VectorOfStrings::size_type size
  310. = this->Internals->Argv.size() - this->Internals->LastArgument + 1;
  311. CommandLineArguments::Internal::VectorOfStrings::size_type cc;
  312. // Copy Argv0 as the first argument
  313. char** args = new char*[ size ];
  314. args[0] = new char[ this->Internals->Argv0.size() + 1 ];
  315. strcpy(args[0], this->Internals->Argv0.c_str());
  316. int cnt = 1;
  317. // Copy everything after the LastArgument, since that was not parsed.
  318. for ( cc = this->Internals->LastArgument+1;
  319. cc < this->Internals->Argv.size(); cc ++ )
  320. {
  321. args[cnt] = new char[ this->Internals->Argv[cc].size() + 1];
  322. strcpy(args[cnt], this->Internals->Argv[cc].c_str());
  323. cnt ++;
  324. }
  325. *argc = cnt;
  326. *argv = args;
  327. }
  328. //----------------------------------------------------------------------------
  329. void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv)
  330. {
  331. int cc;
  332. for ( cc = 0; cc < argc; ++ cc )
  333. {
  334. delete [] *argv[cc];
  335. }
  336. delete [] *argv;
  337. }
  338. //----------------------------------------------------------------------------
  339. void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type,
  340. CallbackType callback, void* call_data, const char* help)
  341. {
  342. CommandLineArgumentsCallbackStructure s;
  343. s.Argument = argument;
  344. s.ArgumentType = type;
  345. s.Callback = callback;
  346. s.CallData = call_data;
  347. s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
  348. s.Variable = 0;
  349. s.Help = help;
  350. this->Internals->Callbacks[argument] = s;
  351. this->GenerateHelp();
  352. }
  353. //----------------------------------------------------------------------------
  354. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  355. VariableTypeEnum vtype, void* variable, const char* help)
  356. {
  357. CommandLineArgumentsCallbackStructure s;
  358. s.Argument = argument;
  359. s.ArgumentType = type;
  360. s.Callback = 0;
  361. s.CallData = 0;
  362. s.VariableType = vtype;
  363. s.Variable = variable;
  364. s.Help = help;
  365. this->Internals->Callbacks[argument] = s;
  366. this->GenerateHelp();
  367. }
  368. //----------------------------------------------------------------------------
  369. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  370. int* variable, const char* help)
  371. {
  372. this->AddArgument(argument, type, CommandLineArguments::INT_TYPE, variable, help);
  373. }
  374. //----------------------------------------------------------------------------
  375. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  376. double* variable, const char* help)
  377. {
  378. this->AddArgument(argument, type, CommandLineArguments::DOUBLE_TYPE, variable, help);
  379. }
  380. //----------------------------------------------------------------------------
  381. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  382. char** variable, const char* help)
  383. {
  384. this->AddArgument(argument, type, CommandLineArguments::STRING_TYPE, variable, help);
  385. }
  386. //----------------------------------------------------------------------------
  387. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  388. kwsys_stl::string* variable, const char* help)
  389. {
  390. this->AddArgument(argument, type, CommandLineArguments::STL_STRING_TYPE, variable, help);
  391. }
  392. //----------------------------------------------------------------------------
  393. void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
  394. bool* variable, const char* help)
  395. {
  396. this->AddArgument(argument, type, CommandLineArguments::BOOL_TYPE, variable, help);
  397. }
  398. //----------------------------------------------------------------------------
  399. void CommandLineArguments::AddBooleanArgument(const char* argument, bool*
  400. variable, const char* help)
  401. {
  402. this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
  403. CommandLineArguments::BOOL_TYPE, variable, help);
  404. }
  405. //----------------------------------------------------------------------------
  406. void CommandLineArguments::AddBooleanArgument(const char* argument, int*
  407. variable, const char* help)
  408. {
  409. this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
  410. CommandLineArguments::INT_TYPE, variable, help);
  411. }
  412. //----------------------------------------------------------------------------
  413. void CommandLineArguments::SetClientData(void* client_data)
  414. {
  415. this->Internals->ClientData = client_data;
  416. }
  417. //----------------------------------------------------------------------------
  418. void CommandLineArguments::SetUnknownArgumentCallback(
  419. CommandLineArguments::ErrorCallbackType callback)
  420. {
  421. this->Internals->UnknownArgumentCallback = callback;
  422. }
  423. //----------------------------------------------------------------------------
  424. const char* CommandLineArguments::GetHelp(const char* arg)
  425. {
  426. CommandLineArguments::Internal::CallbacksMap::iterator it
  427. = this->Internals->Callbacks.find(arg);
  428. if ( it == this->Internals->Callbacks.end() )
  429. {
  430. return 0;
  431. }
  432. // Since several arguments may point to the same argument, find the one this
  433. // one point to if this one is pointing to another argument.
  434. CommandLineArgumentsCallbackStructure *cs = &(it->second);
  435. for(;;)
  436. {
  437. CommandLineArguments::Internal::CallbacksMap::iterator hit
  438. = this->Internals->Callbacks.find(cs->Help);
  439. if ( hit == this->Internals->Callbacks.end() )
  440. {
  441. break;
  442. }
  443. cs = &(hit->second);
  444. }
  445. return cs->Help;
  446. }
  447. //----------------------------------------------------------------------------
  448. void CommandLineArguments::SetLineLength(unsigned int ll)
  449. {
  450. if ( ll < 9 || ll > 1000 )
  451. {
  452. return;
  453. }
  454. this->LineLength = ll;
  455. this->GenerateHelp();
  456. }
  457. //----------------------------------------------------------------------------
  458. const char* CommandLineArguments::GetArgv0()
  459. {
  460. return this->Internals->Argv0.c_str();
  461. }
  462. //----------------------------------------------------------------------------
  463. unsigned int CommandLineArguments::GetLastArgument()
  464. {
  465. return this->Internals->LastArgument + 1;
  466. }
  467. //----------------------------------------------------------------------------
  468. void CommandLineArguments::GenerateHelp()
  469. {
  470. kwsys_ios::ostringstream str;
  471. // Collapse all arguments into the map of vectors of all arguments that do
  472. // the same thing.
  473. CommandLineArguments::Internal::CallbacksMap::iterator it;
  474. typedef kwsys_stl::map<CommandLineArguments::Internal::String,
  475. CommandLineArguments::Internal::SetOfStrings > MapArgs;
  476. MapArgs mp;
  477. MapArgs::iterator mpit, smpit;
  478. for ( it = this->Internals->Callbacks.begin();
  479. it != this->Internals->Callbacks.end();
  480. it ++ )
  481. {
  482. CommandLineArgumentsCallbackStructure *cs = &(it->second);
  483. mpit = mp.find(cs->Help);
  484. if ( mpit != mp.end() )
  485. {
  486. mpit->second.insert(it->first);
  487. mp[it->first].insert(it->first);
  488. }
  489. else
  490. {
  491. mp[it->first].insert(it->first);
  492. }
  493. }
  494. for ( it = this->Internals->Callbacks.begin();
  495. it != this->Internals->Callbacks.end();
  496. it ++ )
  497. {
  498. CommandLineArgumentsCallbackStructure *cs = &(it->second);
  499. mpit = mp.find(cs->Help);
  500. if ( mpit != mp.end() )
  501. {
  502. mpit->second.insert(it->first);
  503. smpit = mp.find(it->first);
  504. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  505. for ( sit = smpit->second.begin(); sit != smpit->second.end(); sit++ )
  506. {
  507. mpit->second.insert(*sit);
  508. }
  509. mp.erase(smpit);
  510. }
  511. else
  512. {
  513. mp[it->first].insert(it->first);
  514. }
  515. }
  516. // Find the length of the longest string
  517. CommandLineArguments::Internal::String::size_type maxlen = 0;
  518. for ( mpit = mp.begin();
  519. mpit != mp.end();
  520. mpit ++ )
  521. {
  522. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  523. for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
  524. {
  525. CommandLineArguments::Internal::String::size_type clen = sit->size();
  526. switch ( this->Internals->Callbacks[*sit].ArgumentType )
  527. {
  528. case CommandLineArguments::NO_ARGUMENT: clen += 0; break;
  529. case CommandLineArguments::CONCAT_ARGUMENT: clen += 3; break;
  530. case CommandLineArguments::SPACE_ARGUMENT: clen += 4; break;
  531. case CommandLineArguments::EQUAL_ARGUMENT: clen += 4; break;
  532. }
  533. if ( clen > maxlen )
  534. {
  535. maxlen = clen;
  536. }
  537. }
  538. }
  539. // Create format for that string
  540. char format[80];
  541. sprintf(format, " %%-%ds ", static_cast<unsigned int>(maxlen));
  542. maxlen += 4; // For the space before and after the option
  543. // Print help for each option
  544. for ( mpit = mp.begin();
  545. mpit != mp.end();
  546. mpit ++ )
  547. {
  548. CommandLineArguments::Internal::SetOfStrings::iterator sit;
  549. for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
  550. {
  551. str << kwsys_ios::endl;
  552. char argument[100];
  553. sprintf(argument, sit->c_str());
  554. switch ( this->Internals->Callbacks[*sit].ArgumentType )
  555. {
  556. case CommandLineArguments::NO_ARGUMENT: break;
  557. case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break;
  558. case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break;
  559. case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break;
  560. }
  561. char buffer[80];
  562. sprintf(buffer, format, argument);
  563. str << buffer;
  564. }
  565. const char* ptr = this->Internals->Callbacks[mpit->first].Help;
  566. int len = strlen(ptr);
  567. int cnt = 0;
  568. while ( len > 0)
  569. {
  570. // If argument with help is longer than line length, split it on previous
  571. // space (or tab) and continue on the next line
  572. CommandLineArguments::Internal::String::size_type cc;
  573. for ( cc = 0; ptr[cc]; cc ++ )
  574. {
  575. if ( *ptr == ' ' || *ptr == '\t' )
  576. {
  577. ptr ++;
  578. len --;
  579. }
  580. }
  581. if ( cnt > 0 )
  582. {
  583. for ( cc = 0; cc < maxlen; cc ++ )
  584. {
  585. str << " ";
  586. }
  587. }
  588. CommandLineArguments::Internal::String::size_type skip = len;
  589. if ( skip > this->LineLength - maxlen )
  590. {
  591. skip = this->LineLength - maxlen;
  592. for ( cc = skip-1; cc > 0; cc -- )
  593. {
  594. if ( ptr[cc] == ' ' || ptr[cc] == '\t' )
  595. {
  596. break;
  597. }
  598. }
  599. if ( cc != 0 )
  600. {
  601. skip = cc;
  602. }
  603. }
  604. str.write(ptr, skip);
  605. str << kwsys_ios::endl;
  606. ptr += skip;
  607. len -= skip;
  608. cnt ++;
  609. }
  610. }
  611. /*
  612. // This can help debugging help string
  613. str << endl;
  614. unsigned int cc;
  615. for ( cc = 0; cc < this->LineLength; cc ++ )
  616. {
  617. str << cc % 10;
  618. }
  619. str << endl;
  620. */
  621. this->Help = str.str();
  622. }
  623. } // namespace KWSYS_NAMESPACE