parser_help.c 6.5 KB

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