123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- /*!
- * \file lib/gis/parser_interface.c
- *
- * \brief GIS Library - Argument parsing functions (interface)
- *
- * (C) 2001-2009 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public License
- * (>=v2). Read the file COPYING that comes with GRASS for details.
- *
- * \author Original author CERL
- * \author Soeren Gebbert added Dec. 2009 WPS process_description document
- */
- #include <grass/config.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <stdarg.h>
- #include <sys/types.h>
- #if defined(HAVE_LANGINFO_H)
- #include <langinfo.h>
- #endif
- #if defined(__MINGW32__) && defined(USE_NLS)
- #include <localcharset.h>
- #endif
- #ifdef HAVE_ICONV_H
- #include <iconv.h>
- #endif
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include <grass/spawn.h>
- #include "parser_local_proto.h"
- #ifdef HAVE_ICONV_H
- static const char *src_enc;
- #endif
- /*!
- * \brief Formats text for XML.
- *
- * \param[in,out] fp file to write to
- * \param str string to write
- */
- static void print_escaped_for_xml(FILE *fp, const char *str)
- {
- #ifdef HAVE_ICONV_H
- iconv_t conv = iconv_open("UTF-8", src_enc);
- char *enc = NULL;
- if (conv != (iconv_t) -1)
- {
- char *src = (char *) str;
- size_t srclen = strlen(src);
- size_t dstlen = srclen * 4 + 1;
- char *dst = G_alloca(dstlen);
- size_t ret;
- enc = dst;
- ret = iconv(conv, (char **)&src, &srclen, &dst, &dstlen);
- if (ret != (size_t) -1 && srclen == 0) {
- str = enc;
- *dst = '\0';
- }
- }
- #endif
- for (; *str; str++) {
- switch (*str) {
- case '&':
- fputs("&", fp);
- break;
- case '<':
- fputs("<", fp);
- break;
- case '>':
- fputs(">", fp);
- break;
- default:
- fputc(*str, fp);
- }
- }
- #ifdef HAVE_ICONV_H
- if (enc)
- G_freea(enc);
- if (conv != (iconv_t) -1)
- iconv_close(conv);
- #endif
- }
- /*!
- \brief Print module usage description in XML format.
- */
- void G__usage_xml(void)
- {
- struct Option *opt;
- struct Flag *flag;
- char *type;
- char *s, *top;
- int i;
- const char *encoding;
- int new_prompt = 0;
- new_prompt = G__uses_new_gisprompt();
- /* gettext converts strings to encoding returned by nl_langinfo(CODESET) */
- #if defined(HAVE_LANGINFO_H)
- encoding = nl_langinfo(CODESET);
- #elif defined(__MINGW32__) && defined(USE_NLS)
- encoding = locale_charset();
- #endif
- if (!encoding || strlen(encoding) == 0)
- encoding = "UTF-8";
- #ifdef HAVE_ICONV_H
- src_enc = encoding;
- encoding = "UTF-8";
- #endif
- if (!st->pgm_name) /* v.dave && r.michael */
- st->pgm_name = G_program_name();
- if (!st->pgm_name)
- st->pgm_name = "??";
- fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
- fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
- fprintf(stdout, "<task name=\"%s\">\n", st->pgm_name);
- if (st->module_info.label) {
- fprintf(stdout, "\t<label>\n\t\t");
- print_escaped_for_xml(stdout, st->module_info.label);
- fprintf(stdout, "\n\t</label>\n");
- }
- if (st->module_info.description) {
- fprintf(stdout, "\t<description>\n\t\t");
- print_escaped_for_xml(stdout, st->module_info.description);
- fprintf(stdout, "\n\t</description>\n");
- }
- if (st->module_info.keywords) {
- fprintf(stdout, "\t<keywords>\n\t\t");
- G__print_keywords(stdout, print_escaped_for_xml);
- fprintf(stdout, "\n\t</keywords>\n");
- }
- /***** Don't use parameter-groups for now. We'll reimplement this later
- ***** when we have a concept of several mutually exclusive option
- ***** groups
- if (st->n_opts || st->n_flags)
- fprintf(stdout, "\t<parameter-group>\n");
- *****
- *****
- *****/
- if (st->n_opts) {
- opt = &st->first_option;
- while (opt != NULL) {
- /* TODO: make this a enumeration type? */
- switch (opt->type) {
- case TYPE_INTEGER:
- type = "integer";
- break;
- case TYPE_DOUBLE:
- type = "float";
- break;
- case TYPE_STRING:
- type = "string";
- break;
- default:
- type = "string";
- break;
- }
- fprintf(stdout, "\t<parameter "
- "name=\"%s\" "
- "type=\"%s\" "
- "required=\"%s\" "
- "multiple=\"%s\">\n",
- opt->key,
- type,
- opt->required == YES ? "yes" : "no",
- opt->multiple == YES ? "yes" : "no");
- if (opt->label) {
- fprintf(stdout, "\t\t<label>\n\t\t\t");
- print_escaped_for_xml(stdout, opt->label);
- fprintf(stdout, "\n\t\t</label>\n");
- }
- if (opt->description) {
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout, opt->description);
- fprintf(stdout, "\n\t\t</description>\n");
- }
- if (opt->key_desc) {
- fprintf(stdout, "\t\t<keydesc>\n");
- top = G_calloc(strlen(opt->key_desc) + 1, 1);
- strcpy(top, opt->key_desc);
- s = strtok(top, ",");
- for (i = 1; s != NULL; i++) {
- fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
- print_escaped_for_xml(stdout, s);
- fprintf(stdout, "</item>\n");
- s = strtok(NULL, ",");
- }
- fprintf(stdout, "\t\t</keydesc>\n");
- G_free(top);
- }
- if (opt->gisprompt) {
- const char *atts[] = { "age", "element", "prompt", NULL };
- top = G_calloc(strlen(opt->gisprompt) + 1, 1);
- strcpy(top, opt->gisprompt);
- s = strtok(top, ",");
- fprintf(stdout, "\t\t<gisprompt ");
- for (i = 0; s != NULL && atts[i] != NULL; i++) {
- fprintf(stdout, "%s=\"%s\" ", atts[i], s);
- s = strtok(NULL, ",");
- }
- fprintf(stdout, "/>\n");
- G_free(top);
- }
- if (opt->def) {
- fprintf(stdout, "\t\t<default>\n\t\t\t");
- print_escaped_for_xml(stdout, opt->def);
- fprintf(stdout, "\n\t\t</default>\n");
- }
- if (opt->options) {
- /* TODO:
- * add something like
- * <range min="xxx" max="xxx"/>
- * to <values> */
- i = 0;
- fprintf(stdout, "\t\t<values>\n");
- while (opt->opts[i]) {
- fprintf(stdout, "\t\t\t<value>\n");
- fprintf(stdout, "\t\t\t\t<name>");
- print_escaped_for_xml(stdout, opt->opts[i]);
- fprintf(stdout, "</name>\n");
- if (opt->descs && opt->opts[i] && opt->descs[i]) {
- fprintf(stdout, "\t\t\t\t<description>");
- print_escaped_for_xml(stdout, opt->descs[i]);
- fprintf(stdout, "</description>\n");
- }
- fprintf(stdout, "\t\t\t</value>\n");
- i++;
- }
- fprintf(stdout, "\t\t</values>\n");
- }
- if (opt->guisection) {
- fprintf(stdout, "\t\t<guisection>\n\t\t\t");
- print_escaped_for_xml(stdout, opt->guisection);
- fprintf(stdout, "\n\t\t</guisection>\n");
- }
- if (opt->guidependency) {
- fprintf(stdout, "\t\t<guidependency>\n\t\t\t");
- print_escaped_for_xml(stdout, opt->guidependency);
- fprintf(stdout, "\n\t\t</guidependency>\n");
- }
- /* TODO:
- * - key_desc?
- * - there surely are some more. which ones?
- */
- opt = opt->next_opt;
- fprintf(stdout, "\t</parameter>\n");
- }
- }
- if (st->n_flags) {
- flag = &st->first_flag;
- while (flag != NULL) {
- fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
- if (flag->label) {
- fprintf(stdout, "\t\t<label>\n\t\t\t");
- print_escaped_for_xml(stdout, flag->label);
- fprintf(stdout, "\n\t\t</label>\n");
- }
- if (flag->suppress_required)
- fprintf(stdout, "\t\t<suppress_required/>\n");
- if (flag->description) {
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout, flag->description);
- fprintf(stdout, "\n\t\t</description>\n");
- }
- if (flag->guisection) {
- fprintf(stdout, " \t\t<guisection>\n\t\t\t");
- print_escaped_for_xml(stdout, flag->guisection);
- fprintf(stdout, "\n\t\t</guisection>\n");
- }
- flag = flag->next_flag;
- fprintf(stdout, "\t</flag>\n");
- }
- }
- /***** Don't use parameter-groups for now. We'll reimplement this later
- ***** when we have a concept of several mutually exclusive option
- ***** groups
- if (st->n_opts || st->n_flags)
- fprintf(stdout, "\t</parameter-group>\n");
- *****
- *****
- *****/
- if (new_prompt) {
- /* overwrite */
- fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout,
- _("Allow output files to overwrite existing files"));
- fprintf(stdout, "\n\t\t</description>\n");
- fprintf(stdout, "\t</flag>\n");
- }
- /* help */
- fprintf(stdout, "\t<flag name=\"%s\">\n", "help");
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout, _("Print usage summary"));
- fprintf(stdout, "\n\t\t</description>\n");
- fprintf(stdout, "\t</flag>\n");
- /* verbose */
- fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout, _("Verbose module output"));
- fprintf(stdout, "\n\t\t</description>\n");
- fprintf(stdout, "\t</flag>\n");
- /* quiet */
- fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
- fprintf(stdout, "\t\t<description>\n\t\t\t");
- print_escaped_for_xml(stdout, _("Quiet module output"));
- fprintf(stdout, "\n\t\t</description>\n");
- fprintf(stdout, "\t</flag>\n");
- G__describe_option_rules_xml(stdout);
- fprintf(stdout, "</task>\n");
- }
|