GRASS 8 Programmer's Manual 8.6.0dev(2026)-ddeab64dbf
Loading...
Searching...
No Matches
parser_interface.c
Go to the documentation of this file.
1/*!
2 * \file lib/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
15#include <grass/config.h>
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <ctype.h>
21#include <unistd.h>
22#include <stdarg.h>
23#include <sys/types.h>
24
25#if defined(HAVE_LANGINFO_H)
26#include <langinfo.h>
27#endif
28#if defined(__MINGW32__) && defined(USE_NLS)
29#include <localcharset.h>
30#endif
31#ifdef HAVE_ICONV_H
32#include <iconv.h>
33#endif
34
35#include <grass/gis.h>
36#include <grass/glocale.h>
37#include <grass/spawn.h>
38
39#include "parser_local_proto.h"
40
41#ifdef HAVE_ICONV_H
42static const char *src_enc;
43#endif
44
45/*!
46 * \brief Formats text for XML.
47 *
48 * \param[in,out] fp file to write to
49 * \param str string to write
50 */
51static void print_escaped_for_xml(FILE *fp, const char *str)
52{
53#ifdef HAVE_ICONV_H
54 iconv_t conv = iconv_open("UTF-8", src_enc);
55 char *enc = NULL;
56
57 if (conv != (iconv_t)-1) {
58 char *src = (char *)str;
59 size_t srclen = strlen(src);
60 size_t dstlen = srclen * 4 + 1;
61 char *dst = G_alloca(dstlen);
62 size_t ret;
63
64 enc = dst;
65
66 ret = iconv(conv, (char **)&src, &srclen, &dst, &dstlen);
67 if (ret != (size_t)-1 && srclen == 0) {
68 str = enc;
69 *dst = '\0';
70 }
71 }
72#endif
73
74 for (; *str; str++) {
75 switch (*str) {
76 case '&':
77 fputs("&amp;", fp);
78 break;
79 case '<':
80 fputs("&lt;", fp);
81 break;
82 case '>':
83 fputs("&gt;", fp);
84 break;
85 default:
86 fputc(*str, fp);
87 }
88 }
89
90#ifdef HAVE_ICONV_H
91 if (enc) {
92 G_freea(enc);
93 }
94
95 if (conv != (iconv_t)-1)
97#endif
98}
99
100/*!
101 \brief Print module usage description in XML format.
102 */
103void G__usage_xml(void)
104{
105 struct Option *opt;
106 struct Flag *flag;
107 char *type;
108 char *s, *top;
109 int i;
110 const char *encoding = NULL;
111 int new_prompt = 0;
112
114
115 /* gettext converts strings to encoding returned by nl_langinfo(CODESET) */
116
117/* check if local_charset() comes from iconv. If so check for iconv library
118 * before using it */
119#if defined(HAVE_LANGINFO_H)
120 encoding = nl_langinfo(CODESET);
121#elif defined(_WIN32) && defined(USE_NLS)
122 encoding = locale_charset();
123#endif
124
125 if (!encoding || strlen(encoding) == 0)
126 encoding = "UTF-8";
127
128#ifdef HAVE_ICONV_H
129 src_enc = encoding;
130 encoding = "UTF-8";
131#endif
132
133 if (!st->pgm_name) /* v.dave && r.michael */
134 st->pgm_name = G_program_name();
135 if (!st->pgm_name)
136 st->pgm_name = "??";
137
138 fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
139 fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
140
141 fprintf(stdout, "<task name=\"%s\">\n", st->pgm_name);
142
143 if (st->module_info.label) {
144 fprintf(stdout, "\t<label>\n\t\t");
145 print_escaped_for_xml(stdout, st->module_info.label);
146 fprintf(stdout, "\n\t</label>\n");
147 }
148
149 if (st->module_info.description) {
150 fprintf(stdout, "\t<description>\n\t\t");
151 print_escaped_for_xml(stdout, st->module_info.description);
152 fprintf(stdout, "\n\t</description>\n");
153 }
154
155 if (st->module_info.keywords) {
156 fprintf(stdout, "\t<keywords>\n\t\t");
157 G__print_keywords(stdout, print_escaped_for_xml, FALSE);
158 fprintf(stdout, "\n\t</keywords>\n");
159 }
160
161 /***** Don't use parameter-groups for now. We'll reimplement this later
162 ***** when we have a concept of several mutually exclusive option
163 ***** groups
164 if (st->n_opts || st->n_flags)
165 fprintf(stdout, "\t<parameter-group>\n");
166 *****
167 *****
168 *****/
169
170 if (st->n_opts) {
171 opt = &st->first_option;
172 while (opt != NULL) {
173 /* TODO: make this a enumeration type? */
174 switch (opt->type) {
175 case TYPE_INTEGER:
176 type = "integer";
177 break;
178 case TYPE_DOUBLE:
179 type = "float";
180 break;
181 case TYPE_STRING:
182 type = "string";
183 break;
184 default:
185 type = "string";
186 break;
187 }
189 "\t<parameter "
190 "name=\"%s\" "
191 "type=\"%s\" "
192 "required=\"%s\" "
193 "multiple=\"%s\">\n",
194 opt->key, type, opt->required == YES ? "yes" : "no",
195 opt->multiple == YES ? "yes" : "no");
196
197 if (opt->label) {
198 fprintf(stdout, "\t\t<label>\n\t\t\t");
199 print_escaped_for_xml(stdout, opt->label);
200 fprintf(stdout, "\n\t\t</label>\n");
201 }
202
203 if (opt->description) {
204 fprintf(stdout, "\t\t<description>\n\t\t\t");
205 print_escaped_for_xml(stdout, opt->description);
206 fprintf(stdout, "\n\t\t</description>\n");
207 }
208
209 if (opt->key_desc) {
210 fprintf(stdout, "\t\t<keydesc>\n");
211 top = G_calloc(strlen(opt->key_desc) + 1, 1);
212 strcpy(top, opt->key_desc);
213 s = strtok(top, ",");
214 for (i = 1; s != NULL; i++) {
215 fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
216 print_escaped_for_xml(stdout, s);
217 fprintf(stdout, "</item>\n");
218 s = strtok(NULL, ",");
219 }
220 fprintf(stdout, "\t\t</keydesc>\n");
221 G_free(top);
222 }
223
224 if (opt->gisprompt) {
225 const char *atts[] = {"age", "element", "prompt", NULL};
226 top = G_calloc(strlen(opt->gisprompt) + 1, 1);
227 strcpy(top, opt->gisprompt);
228 s = strtok(top, ",");
229 fprintf(stdout, "\t\t<gisprompt ");
230 for (i = 0; s != NULL && atts[i] != NULL; i++) {
231 fprintf(stdout, "%s=\"%s\" ", atts[i], s);
232 s = strtok(NULL, ",");
233 }
234 fprintf(stdout, "/>\n");
235 G_free(top);
236 }
237
238 if (opt->def) {
239 fprintf(stdout, "\t\t<default>\n\t\t\t");
240 print_escaped_for_xml(stdout, opt->def);
241 fprintf(stdout, "\n\t\t</default>\n");
242 }
243
244 if (opt->options) {
245 /* TODO:
246 * add something like
247 * <range min="xxx" max="xxx"/>
248 * to <values> */
249 i = 0;
250 fprintf(stdout, "\t\t<values>\n");
251 while (opt->opts[i]) {
252 fprintf(stdout, "\t\t\t<value>\n");
253 fprintf(stdout, "\t\t\t\t<name>");
254 print_escaped_for_xml(stdout, opt->opts[i]);
255 fprintf(stdout, "</name>\n");
256 if (opt->descs && opt->opts[i] && opt->descs[i]) {
257 fprintf(stdout, "\t\t\t\t<description>");
258 print_escaped_for_xml(stdout, opt->descs[i]);
259 fprintf(stdout, "</description>\n");
260 }
261 fprintf(stdout, "\t\t\t</value>\n");
262 i++;
263 }
264 fprintf(stdout, "\t\t</values>\n");
265 }
266 if (opt->guisection) {
267 fprintf(stdout, "\t\t<guisection>\n\t\t\t");
268 print_escaped_for_xml(stdout, opt->guisection);
269 fprintf(stdout, "\n\t\t</guisection>\n");
270 }
271 if (opt->guidependency) {
272 fprintf(stdout, "\t\t<guidependency>\n\t\t\t");
273 print_escaped_for_xml(stdout, opt->guidependency);
274 fprintf(stdout, "\n\t\t</guidependency>\n");
275 }
276 /* TODO:
277 * - key_desc?
278 * - there surely are some more. which ones?
279 */
280
281 opt = opt->next_opt;
282 fprintf(stdout, "\t</parameter>\n");
283 }
284 }
285
286 if (st->n_flags) {
287 flag = &st->first_flag;
288 while (flag != NULL) {
289 fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
290
291 if (flag->label) {
292 fprintf(stdout, "\t\t<label>\n\t\t\t");
293 print_escaped_for_xml(stdout, flag->label);
294 fprintf(stdout, "\n\t\t</label>\n");
295 }
296
297 if (flag->suppress_required)
298 fprintf(stdout, "\t\t<suppress_required/>\n");
299
300 if (flag->description) {
301 fprintf(stdout, "\t\t<description>\n\t\t\t");
302 print_escaped_for_xml(stdout, flag->description);
303 fprintf(stdout, "\n\t\t</description>\n");
304 }
305 if (flag->guisection) {
306 fprintf(stdout, " \t\t<guisection>\n\t\t\t");
307 print_escaped_for_xml(stdout, flag->guisection);
308 fprintf(stdout, "\n\t\t</guisection>\n");
309 }
310 flag = flag->next_flag;
311 fprintf(stdout, "\t</flag>\n");
312 }
313 }
314
315 /***** Don't use parameter-groups for now. We'll reimplement this later
316 ***** when we have a concept of several mutually exclusive option
317 ***** groups
318 if (st->n_opts || st->n_flags)
319 fprintf(stdout, "\t</parameter-group>\n");
320 *****
321 *****
322 *****/
323
324 if (new_prompt) {
325 /* overwrite */
326 fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
327 fprintf(stdout, "\t\t<description>\n\t\t\t");
328 print_escaped_for_xml(
329 stdout, _("Allow output files to overwrite existing files"));
330 fprintf(stdout, "\n\t\t</description>\n");
331 fprintf(stdout, "\t</flag>\n");
332 }
333
334 /* help */
335 fprintf(stdout, "\t<flag name=\"%s\">\n", "help");
336 fprintf(stdout, "\t\t<description>\n\t\t\t");
337 print_escaped_for_xml(stdout, _("Print usage summary"));
338 fprintf(stdout, "\n\t\t</description>\n");
339 fprintf(stdout, "\t</flag>\n");
340
341 /* verbose */
342 fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
343 fprintf(stdout, "\t\t<description>\n\t\t\t");
344 print_escaped_for_xml(stdout, _("Verbose module output"));
345 fprintf(stdout, "\n\t\t</description>\n");
346 fprintf(stdout, "\t</flag>\n");
347
348 /* quiet */
349 fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
350 fprintf(stdout, "\t\t<description>\n\t\t\t");
351 print_escaped_for_xml(stdout, _("Quiet module output"));
352 fprintf(stdout, "\n\t\t</description>\n");
353 fprintf(stdout, "\t</flag>\n");
354
356
357 fprintf(stdout, "</task>\n");
358}
#define NULL
Definition ccmath.h:32
const char * G_program_name(void)
Return module name.
Definition progrm_nme.c:28
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_calloc(m, n)
Definition defs/gis.h:140
#define G_alloca(n)
Definition defs/gis.h:57
#define G_freea(p)
Definition defs/gis.h:58
#define TYPE_STRING
Definition gis.h:191
#define YES
Definition gis.h:192
#define TYPE_INTEGER
Definition gis.h:189
#define FALSE
Definition gis.h:82
#define TYPE_DOUBLE
Definition gis.h:190
#define _(str)
Definition glocale.h:10
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *), int newline)
Print list of keywords (internal use only)
Definition parser.c:929
int G__uses_new_gisprompt(void)
Definition parser.c:892
struct state * st
Definition parser.c:104
void G__describe_option_rules_xml(FILE *fp)
Describe option rules in XML format (internal use only)
void G__usage_xml(void)
Print module usage description in XML format.
#define strcpy
Definition parson.c:66
Structure that stores flag info.
Definition gis.h:594
Structure that stores option information.
Definition gis.h:563