parser_interface.c 7.1 KB

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