parser_help.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*!
  2. \file lib/gis/parser_help.c
  3. \brief GIS Library - Argument parsing functions (help)
  4. (C) 2001-2009, 2011 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. \author Soeren Gebbert added Dec. 2009 WPS process_description document
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <grass/gis.h>
  14. #include <grass/glocale.h>
  15. #include "parser_local_proto.h"
  16. static void usage(FILE *fp, int markers);
  17. static void show_options(FILE *fp, int maxlen, const char *str);
  18. static int show(FILE *fp, const char *item, int len);
  19. /*!
  20. \brief Command line help/usage message.
  21. Calls to G_usage() allow the programmer to print the usage
  22. message at any time. This will explain the allowed and required
  23. command line input to the user. This description is given according
  24. to the programmer's definitions for options and flags. This function
  25. becomes useful when the user enters options and/or flags on the
  26. command line that are syntactically valid to the parser, but
  27. functionally invalid for the command (e.g. an invalid file name.)
  28. For example, the parser logic doesn't directly support grouping
  29. options. If two options be specified together or not at all, the
  30. parser must be told that these options are not required and the
  31. programmer must check that if one is specified the other must be as
  32. well. If this additional check fails, then G_parser() will succeed,
  33. but the programmer can then call G_usage() to print the standard
  34. usage message and print additional information about how the two
  35. options work together.
  36. */
  37. void G_usage(void)
  38. {
  39. usage(stderr, 0);
  40. }
  41. void G__usage_text(void)
  42. {
  43. usage(stdout, 1);
  44. }
  45. static void usage(FILE *fp, int markers)
  46. {
  47. struct Option *opt;
  48. struct Flag *flag;
  49. char item[256];
  50. const char *key_desc;
  51. int maxlen;
  52. int len, n;
  53. int new_prompt = 0;
  54. int extensive = 0; /* include also less important parts */
  55. int standard = 0; /* include also standard flags */
  56. int detailed = 0; /* details for each flag and option */
  57. new_prompt = G__uses_new_gisprompt();
  58. if (!st->pgm_name) /* v.dave && r.michael */
  59. st->pgm_name = G_program_name();
  60. if (!st->pgm_name)
  61. st->pgm_name = "??";
  62. if (st->module_info.label || st->module_info.description) {
  63. if (extensive)
  64. fprintf(fp, "\n");
  65. if (markers)
  66. fprintf(fp, "{{{DESCRIPTION}}}\n");
  67. if (extensive) {
  68. fprintf(fp, "%s\n", _("Description:"));
  69. if (st->module_info.label)
  70. fprintf(fp, " %s\n", st->module_info.label);
  71. if (st->module_info.description)
  72. fprintf(fp, " %s\n", st->module_info.description);
  73. }
  74. else {
  75. /* print label, if no label, try description */
  76. /* no leading space without heading */
  77. if (st->module_info.label)
  78. fprintf(fp, "%s\n", st->module_info.label);
  79. else if (st->module_info.description)
  80. fprintf(fp, "%s\n", st->module_info.description);
  81. }
  82. }
  83. if (extensive &&& st->module_info.keywords) {
  84. fprintf(fp, "\n");
  85. if (markers)
  86. fprintf(fp, "{{{KEYWORDS}}}\n");
  87. fprintf(fp, "%s\n ", _("Keywords:"));
  88. G__print_keywords(fp, NULL);
  89. fprintf(fp, "\n");
  90. }
  91. fprintf(fp, "\n");
  92. if (markers)
  93. fprintf(fp, "{{{USAGE}}}\n");
  94. fprintf(fp, "%s\n ", _("Usage:"));
  95. len = show(fp, st->pgm_name, 1);
  96. /* Print flags */
  97. if (st->n_flags) {
  98. item[0] = ' ';
  99. item[1] = '[';
  100. item[2] = '-';
  101. flag = &st->first_flag;
  102. for (n = 3; flag != NULL; n++, flag = flag->next_flag)
  103. item[n] = flag->key;
  104. item[n++] = ']';
  105. item[n] = 0;
  106. len = show(fp, item, len);
  107. }
  108. maxlen = 0;
  109. if (st->n_opts) {
  110. opt = &st->first_option;
  111. while (opt != NULL) {
  112. if (opt->key_desc != NULL)
  113. key_desc = opt->key_desc;
  114. else if (opt->type == TYPE_STRING)
  115. key_desc = "string";
  116. else
  117. key_desc = "value";
  118. if (!opt->key) {
  119. fprintf(stderr, "\n%s\n", _("ERROR: Option key not defined"));
  120. exit(EXIT_FAILURE);
  121. }
  122. n = strlen(opt->key);
  123. if (n > maxlen)
  124. maxlen = n;
  125. strcpy(item, " ");
  126. if (!opt->required)
  127. strcat(item, "[");
  128. strcat(item, opt->key);
  129. strcat(item, "=");
  130. strcat(item, key_desc);
  131. if (opt->multiple) {
  132. strcat(item, "[,");
  133. strcat(item, key_desc);
  134. strcat(item, ",...]");
  135. }
  136. if (!opt->required)
  137. strcat(item, "]");
  138. len = show(fp, item, len);
  139. opt = opt->next_opt;
  140. }
  141. }
  142. if (new_prompt) {
  143. strcpy(item, " [--overwrite]");
  144. len = show(fp, item, len);
  145. }
  146. strcpy(item, " [--help]");
  147. len = show(fp, item, len);
  148. strcpy(item, " [--verbose]");
  149. len = show(fp, item, len);
  150. strcpy(item, " [--quiet]");
  151. len = show(fp, item, len);
  152. strcpy(item, " [--ui]");
  153. len = show(fp, item, len);
  154. fprintf(fp, "\n");
  155. /* Print help info for flags */
  156. fprintf(fp, "\n");
  157. if (markers)
  158. fprintf(fp, "{{{FLAGS}}}\n");
  159. fprintf(fp, "%s\n", _("Flags:"));
  160. if (st->n_flags) {
  161. flag = &st->first_flag;
  162. while (flag != NULL) {
  163. fprintf(fp, " -%c ", flag->key);
  164. if (flag->label) {
  165. fprintf(fp, "%s\n", flag->label);
  166. if (detailed && flag->description)
  167. fprintf(fp, " %s\n", flag->description);
  168. }
  169. else if (flag->description) {
  170. fprintf(fp, "%s\n", flag->description);
  171. }
  172. flag = flag->next_flag;
  173. }
  174. }
  175. if (standard) {
  176. if (new_prompt)
  177. fprintf(fp, " --o %s\n",
  178. _("Allow output files to overwrite existing files"));
  179. fprintf(fp, " --h %s\n", _("Print usage summary"));
  180. fprintf(fp, " --v %s\n", _("Verbose module output"));
  181. fprintf(fp, " --q %s\n", _("Quiet module output"));
  182. fprintf(fp, " --qq %s\n", _("Super quiet module output"));
  183. fprintf(fp, " --ui %s\n", _("Force launching GUI dialog"));
  184. }
  185. /* Print help info for options */
  186. if (st->n_opts) {
  187. fprintf(fp, "\n");
  188. if (markers)
  189. fprintf(fp, "{{{PARAMETERS}}}\n");
  190. fprintf(fp, "%s\n", _("Parameters:"));
  191. opt = &st->first_option;
  192. while (opt != NULL) {
  193. fprintf(fp, " %*s ", maxlen, opt->key);
  194. if (opt->label) {
  195. fprintf(fp, "%s\n", opt->label);
  196. if (detailed && opt->description) {
  197. fprintf(fp, " %*s %s\n",
  198. maxlen, " ", opt->description);
  199. }
  200. }
  201. else if (opt->description) {
  202. fprintf(fp, "%s\n", opt->description);
  203. }
  204. if (opt->options)
  205. show_options(fp, maxlen, opt->options);
  206. /*
  207. fprintf (fp, " %*s options: %s\n", maxlen, " ",
  208. _(opt->options)) ;
  209. */
  210. if (opt->def)
  211. fprintf(fp, _(" %*s default: %s\n"), maxlen, " ",
  212. opt->def);
  213. if (detailed && opt->descs) {
  214. int i = 0;
  215. while (opt->opts[i]) {
  216. if (opt->descs[i])
  217. fprintf(fp, " %*s %s: %s\n",
  218. maxlen, " ", opt->opts[i], opt->descs[i]);
  219. i++;
  220. }
  221. }
  222. opt = opt->next_opt;
  223. }
  224. }
  225. }
  226. static void show_options(FILE *fp, int maxlen, const char *str)
  227. {
  228. char *buff = G_store(str);
  229. char *p1, *p2;
  230. int totlen, len;
  231. fprintf(fp, _(" %*s options: "), maxlen, " ");
  232. totlen = maxlen + 13;
  233. p1 = buff;
  234. while ((p2 = strchr(p1, ','))) {
  235. *p2 = '\0';
  236. len = strlen(p1) + 1;
  237. if ((len + totlen) > 76) {
  238. totlen = maxlen + 13;
  239. fprintf(fp, "\n %*s", maxlen + 13, " ");
  240. }
  241. fprintf(fp, "%s,", p1);
  242. totlen += len;
  243. p1 = p2 + 1;
  244. }
  245. len = strlen(p1);
  246. if ((len + totlen) > 76)
  247. fprintf(fp, "\n %*s", maxlen + 13, " ");
  248. fprintf(fp, "%s\n", p1);
  249. G_free(buff);
  250. }
  251. static int show(FILE *fp, const char *item, int len)
  252. {
  253. int n;
  254. n = strlen(item) + (len > 0);
  255. if (n + len > 76) {
  256. if (len)
  257. fprintf(fp, "\n ");
  258. len = 0;
  259. }
  260. fprintf(fp, "%s", item);
  261. return n + len;
  262. }