commandlineparserbase.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
  2. // vi:set ts=4 sts=4 sw=4 noet :
  3. //
  4. // Copyright 2010-2020 wkhtmltopdf authors
  5. //
  6. // This file is part of wkhtmltopdf.
  7. //
  8. // wkhtmltopdf is free software: you can redistribute it and/or modify
  9. // it under the terms of the GNU Lesser General Public License as published by
  10. // the Free Software Foundation, either version 3 of the License, or
  11. // (at your option) any later version.
  12. //
  13. // wkhtmltopdf is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Lesser General Public License
  19. // along with wkhtmltopdf. If not, see <http://www.gnu.org/licenses/>.
  20. #include "commandlineparserbase.hh"
  21. #include "outputter.hh"
  22. #include <qwebframe.h>
  23. bool ahsort(const ArgHandler * a, const ArgHandler * b) {
  24. QRegExp e("^(no|enable|disable|include-in|exclude-from)-");
  25. QString x=a->longName;
  26. QString y=b->longName;
  27. x.remove(e);
  28. y.remove(e);
  29. if (x == y) {
  30. QRegExp e("^no-");
  31. x=a->longName;
  32. y=b->longName;
  33. x.replace(e,"zzzz");
  34. y.replace(e,"zzzz");
  35. }
  36. return x < y;
  37. }
  38. /*!
  39. Output description of switches to an outputter
  40. \param o The outputter to output to
  41. \param extended Should we also output extended arguments
  42. \param doc Indicate to the outputter that it is writing documentation
  43. */
  44. void CommandLineParserBase::outputSwitches(Outputter * o, bool extended, bool doc) const {
  45. foreach (const QString & section, sections) {
  46. QList<const ArgHandler *> display;
  47. foreach (const ArgHandler * handler, sectionArgumentHandles[section]) {
  48. #ifndef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
  49. if (!doc && handler->qthack) continue;
  50. #else
  51. Q_UNUSED(doc);
  52. #endif
  53. if (!extended && handler->extended) continue;
  54. display.push_back(handler);
  55. }
  56. qSort(display.begin(), display.end(), ahsort);
  57. if (display.size() == 0) continue;
  58. o->beginSection(section);
  59. if (!sectionDesc[section].isEmpty()) {
  60. o->beginParagraph();
  61. o->text(sectionDesc[section]);
  62. o->endParagraph();
  63. }
  64. o->beginSwitch();
  65. foreach (const ArgHandler * handler, display)
  66. o->cswitch(handler);
  67. o->endSwitch();
  68. o->endSection();
  69. }
  70. }
  71. #define STRINGIZE_(x) #x
  72. #define STRINGIZE(x) STRINGIZE_(x)
  73. const char *CommandLineParserBase::appVersion() const {
  74. #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
  75. return STRINGIZE(FULL_VERSION) " (with patched qt)";
  76. #else
  77. return STRINGIZE(FULL_VERSION);
  78. #endif
  79. }
  80. /*!
  81. Output version information aka. --version
  82. \param fd The file to output to
  83. */
  84. void CommandLineParserBase::version(FILE * fd) const {
  85. fprintf(fd, "%s %s\n", appName().toLocal8Bit().constData(), appVersion());
  86. }
  87. /*!
  88. Output license information aka. --license
  89. \param fd The file to output to
  90. */
  91. void CommandLineParserBase::license(FILE * fd) const {
  92. Outputter * o = Outputter::text(fd,false);
  93. outputName(o);
  94. outputAuthors(o);
  95. outputLicense(o);
  96. delete o;
  97. }
  98. void CommandLineParserBase::parseArg(int sections, const int argc, const char ** argv, bool & defaultMode, int & arg, char * page) {
  99. if (argv[arg][1] == '-') { //We have a long style argument
  100. //After an -- apperas in the argument list all that follows is interpreted as default arguments
  101. if (argv[arg][2] == '0') {
  102. defaultMode=true;
  103. return;
  104. }
  105. //Try to find a handler for this long switch
  106. QHash<QString, ArgHandler*>::iterator j = longToHandler.find(argv[arg]+2);
  107. if (j == longToHandler.end()) { //Ups that argument did not exist
  108. fprintf(stderr, "Unknown long argument %s\n\n", argv[arg]);
  109. usage(stderr, false);
  110. exit(1);
  111. }
  112. if (!(j.value()->section & sections)) {
  113. fprintf(stderr, "%s specified in incorrect location\n\n", argv[arg]);
  114. usage(stderr, false);
  115. exit(1);
  116. }
  117. //Check to see if there is enough arguments to the switch
  118. if (argc-arg < j.value()->argn.size()+1) {
  119. fprintf(stderr, "Not enough arguments parsed to %s\n\n", argv[arg]);
  120. usage(stderr, false);
  121. exit(1);
  122. }
  123. if (!(*(j.value()))(argv+arg+1, *this, page)) {
  124. fprintf(stderr, "Invalid argument(s) parsed to %s\n\n", argv[arg]);
  125. usage(stderr, false);
  126. exit(1);
  127. }
  128. #ifndef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
  129. if (j.value()->qthack)
  130. fprintf(stderr, "The switch %s is not supported when using unpatched qt and will be ignored.", argv[arg]);
  131. #endif
  132. //Skip already handled switch arguments
  133. arg += j.value()->argn.size();
  134. } else {
  135. int c=arg;//Remember the current argument we are parsing
  136. for (int j=1; argv[c][j] != '\0'; ++j) {
  137. QHash<char, ArgHandler*>::iterator k = shortToHandler.find(argv[c][j]);
  138. //If the short argument is invalid print usage information and exit
  139. if (k == shortToHandler.end()) {
  140. fprintf(stderr, "Unknown switch -%c\n\n", argv[c][j]);
  141. usage(stderr, false);
  142. exit(1);
  143. }
  144. if (!(k.value()->section & sections)) {
  145. fprintf(stderr, "-%c specified in incorrect location\n\n", argv[c][j]);
  146. usage(stderr, false);
  147. exit(1);
  148. }
  149. //Check to see if there is enough arguments to the switch
  150. if (argc-arg < k.value()->argn.size()+1) {
  151. fprintf(stderr, "Not enough arguments parsed to -%c\n\n", argv[c][j]);
  152. usage(stderr, false);
  153. exit(1);
  154. }
  155. if (!(*(k.value()))(argv+arg+1, *this, page)) {
  156. fprintf(stderr, "Invalid argument(s) parsed to -%c\n\n", argv[c][j]);
  157. usage(stderr, false);
  158. exit(1);
  159. }
  160. #ifndef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
  161. if (k.value()->qthack)
  162. fprintf(stderr, "The switch -%c is not supported when using unpatched qt and will be ignored.", argv[c][j]);
  163. #endif
  164. //Skip already handled switch arguments
  165. arg += k.value()->argn.size();
  166. }
  167. }
  168. }