parser_interface.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*!
  2. * \file gis/parser_interface.c
  3. *
  4. * \brief GIS Library - Argument parsing functions (interface)
  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 "parser_local_proto.h"
  15. /*!
  16. * \brief Formats text for XML.
  17. *
  18. * \param[in,out] fp file to write to
  19. * \param str string to write
  20. */
  21. static void print_escaped_for_xml(FILE * fp, const char *str)
  22. {
  23. for (; *str; str++) {
  24. switch (*str) {
  25. case '&':
  26. fputs("&", fp);
  27. break;
  28. case '<':
  29. fputs("&lt;", fp);
  30. break;
  31. case '>':
  32. fputs("&gt;", fp);
  33. break;
  34. default:
  35. fputc(*str, fp);
  36. }
  37. }
  38. }
  39. /*!
  40. \brief Print module usage description in XML format.
  41. */
  42. void G__usage_xml(void)
  43. {
  44. struct Option *opt;
  45. struct Flag *flag;
  46. char *type;
  47. char *s, *top;
  48. int i;
  49. char *encoding;
  50. int new_prompt = 0;
  51. new_prompt = G__uses_new_gisprompt();
  52. /* gettext converts strings to encoding returned by nl_langinfo(CODESET) */
  53. #if defined(HAVE_LANGINFO_H)
  54. encoding = nl_langinfo(CODESET);
  55. if (!encoding || strlen(encoding) == 0) {
  56. encoding = "UTF-8";
  57. }
  58. #elif defined(__MINGW32__) && defined(USE_NLS)
  59. encoding = locale_charset();
  60. if (!encoding || strlen(encoding) == 0) {
  61. encoding = "UTF-8";
  62. }
  63. #else
  64. encoding = "UTF-8";
  65. #endif
  66. if (!st->pgm_name) /* v.dave && r.michael */
  67. st->pgm_name = G_program_name();
  68. if (!st->pgm_name)
  69. st->pgm_name = "??";
  70. fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
  71. fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
  72. fprintf(stdout, "<task name=\"%s\">\n", st->pgm_name);
  73. if (st->module_info.label) {
  74. fprintf(stdout, "\t<label>\n\t\t");
  75. print_escaped_for_xml(stdout, st->module_info.label);
  76. fprintf(stdout, "\n\t</label>\n");
  77. }
  78. if (st->module_info.description) {
  79. fprintf(stdout, "\t<description>\n\t\t");
  80. print_escaped_for_xml(stdout, st->module_info.description);
  81. fprintf(stdout, "\n\t</description>\n");
  82. }
  83. if (st->module_info.keywords) {
  84. fprintf(stdout, "\t<keywords>\n\t\t");
  85. G__print_keywords(stdout, print_escaped_for_xml);
  86. fprintf(stdout, "\n\t</keywords>\n");
  87. }
  88. /***** Don't use parameter-groups for now. We'll reimplement this later
  89. ***** when we have a concept of several mutually exclusive option
  90. ***** groups
  91. if (st->n_opts || st->n_flags)
  92. fprintf(stdout, "\t<parameter-group>\n");
  93. *****
  94. *****
  95. *****/
  96. if (st->n_opts) {
  97. opt = &st->first_option;
  98. while (opt != NULL) {
  99. /* TODO: make this a enumeration type? */
  100. switch (opt->type) {
  101. case TYPE_INTEGER:
  102. type = "integer";
  103. break;
  104. case TYPE_DOUBLE:
  105. type = "float";
  106. break;
  107. case TYPE_STRING:
  108. type = "string";
  109. break;
  110. default:
  111. type = "string";
  112. break;
  113. }
  114. fprintf(stdout, "\t<parameter "
  115. "name=\"%s\" "
  116. "type=\"%s\" "
  117. "required=\"%s\" "
  118. "multiple=\"%s\">\n",
  119. opt->key,
  120. type,
  121. opt->required == YES ? "yes" : "no",
  122. opt->multiple == YES ? "yes" : "no");
  123. if (opt->label) {
  124. fprintf(stdout, "\t\t<label>\n\t\t\t");
  125. print_escaped_for_xml(stdout, opt->label);
  126. fprintf(stdout, "\n\t\t</label>\n");
  127. }
  128. if (opt->description) {
  129. fprintf(stdout, "\t\t<description>\n\t\t\t");
  130. print_escaped_for_xml(stdout, opt->description);
  131. fprintf(stdout, "\n\t\t</description>\n");
  132. }
  133. if (opt->key_desc) {
  134. fprintf(stdout, "\t\t<keydesc>\n");
  135. top = G_calloc(strlen(opt->key_desc) + 1, 1);
  136. strcpy(top, opt->key_desc);
  137. s = strtok(top, ",");
  138. for (i = 1; s != NULL; i++) {
  139. fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
  140. print_escaped_for_xml(stdout, s);
  141. fprintf(stdout, "</item>\n");
  142. s = strtok(NULL, ",");
  143. }
  144. fprintf(stdout, "\t\t</keydesc>\n");
  145. G_free(top);
  146. }
  147. if (opt->gisprompt) {
  148. const char *atts[] = { "age", "element", "prompt", NULL };
  149. top = G_calloc(strlen(opt->gisprompt) + 1, 1);
  150. strcpy(top, opt->gisprompt);
  151. s = strtok(top, ",");
  152. fprintf(stdout, "\t\t<gisprompt ");
  153. for (i = 0; s != NULL && atts[i] != NULL; i++) {
  154. fprintf(stdout, "%s=\"%s\" ", atts[i], s);
  155. s = strtok(NULL, ",");
  156. }
  157. fprintf(stdout, "/>\n");
  158. G_free(top);
  159. }
  160. if (opt->def) {
  161. fprintf(stdout, "\t\t<default>\n\t\t\t");
  162. print_escaped_for_xml(stdout, opt->def);
  163. fprintf(stdout, "\n\t\t</default>\n");
  164. }
  165. if (opt->options) {
  166. /* TODO:
  167. * add something like
  168. * <range min="xxx" max="xxx"/>
  169. * to <values> */
  170. i = 0;
  171. fprintf(stdout, "\t\t<values>\n");
  172. while (opt->opts[i]) {
  173. fprintf(stdout, "\t\t\t<value>\n");
  174. fprintf(stdout, "\t\t\t\t<name>");
  175. print_escaped_for_xml(stdout, opt->opts[i]);
  176. fprintf(stdout, "</name>\n");
  177. if (opt->descs && opt->opts[i] && opt->descs[i]) {
  178. fprintf(stdout, "\t\t\t\t<description>");
  179. print_escaped_for_xml(stdout, opt->descs[i]);
  180. fprintf(stdout, "</description>\n");
  181. }
  182. fprintf(stdout, "\t\t\t</value>\n");
  183. i++;
  184. }
  185. fprintf(stdout, "\t\t</values>\n");
  186. }
  187. if (opt->guisection) {
  188. fprintf(stdout, "\t\t<guisection>\n\t\t\t");
  189. print_escaped_for_xml(stdout, opt->guisection);
  190. fprintf(stdout, "\n\t\t</guisection>\n");
  191. }
  192. if (opt->guidependency) {
  193. fprintf(stdout, "\t\t<guidependency>\n\t\t\t");
  194. print_escaped_for_xml(stdout, opt->guidependency);
  195. fprintf(stdout, "\n\t\t</guidependency>\n");
  196. }
  197. /* TODO:
  198. * - key_desc?
  199. * - there surely are some more. which ones?
  200. */
  201. opt = opt->next_opt;
  202. fprintf(stdout, "\t</parameter>\n");
  203. }
  204. }
  205. if (st->n_flags) {
  206. flag = &st->first_flag;
  207. while (flag != NULL) {
  208. fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
  209. if (flag->label) {
  210. fprintf(stdout, "\t\t<label>\n\t\t\t");
  211. print_escaped_for_xml(stdout, flag->label);
  212. fprintf(stdout, "\n\t\t</label>\n");
  213. }
  214. if (flag->description) {
  215. fprintf(stdout, "\t\t<description>\n\t\t\t");
  216. print_escaped_for_xml(stdout, flag->description);
  217. fprintf(stdout, "\n\t\t</description>\n");
  218. }
  219. if (flag->guisection) {
  220. fprintf(stdout, " \t\t<guisection>\n\t\t\t");
  221. print_escaped_for_xml(stdout, flag->guisection);
  222. fprintf(stdout, "\n\t\t</guisection>\n");
  223. }
  224. flag = flag->next_flag;
  225. fprintf(stdout, "\t</flag>\n");
  226. }
  227. }
  228. /***** Don't use parameter-groups for now. We'll reimplement this later
  229. ***** when we have a concept of several mutually exclusive option
  230. ***** groups
  231. if (st->n_opts || st->n_flags)
  232. fprintf(stdout, "\t</parameter-group>\n");
  233. *****
  234. *****
  235. *****/
  236. if (new_prompt) {
  237. /* overwrite */
  238. fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
  239. fprintf(stdout, "\t\t<description>\n\t\t\t");
  240. print_escaped_for_xml(stdout,
  241. "Allow output files to overwrite existing files");
  242. fprintf(stdout, "\n\t\t</description>\n");
  243. fprintf(stdout, "\t</flag>\n");
  244. }
  245. /* verbose */
  246. fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
  247. fprintf(stdout, "\t\t<description>\n\t\t\t");
  248. print_escaped_for_xml(stdout, "Verbose module output");
  249. fprintf(stdout, "\n\t\t</description>\n");
  250. fprintf(stdout, "\t</flag>\n");
  251. /* quiet */
  252. fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
  253. fprintf(stdout, "\t\t<description>\n\t\t\t");
  254. print_escaped_for_xml(stdout, "Quiet module output");
  255. fprintf(stdout, "\n\t\t</description>\n");
  256. fprintf(stdout, "\t</flag>\n");
  257. fprintf(stdout, "</task>\n");
  258. }