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