GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
parser_md_cli.c
Go to the documentation of this file.
1
/*!
2
\file lib/gis/parser_md_cli.c
3
4
\brief GIS Library - Argument parsing functions (Markdown output - CLI)
5
6
(C) 2025 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 Vaclav Petras
12
*/
13
#include <stdio.h>
14
#include <string.h>
15
16
#include <grass/gis.h>
17
#include <grass/glocale.h>
18
19
#include "parser_local_proto.h"
20
21
static
void
print_cli_flag(FILE *
file
,
const
char
*key,
const
char
*label,
22
const
char
*description,
const
char
*indent);
23
static
void
print_cli_option(FILE *
file
,
const
struct
Option *opt,
24
const
char
*indent);
25
static
void
print_cli_example(FILE *
file
,
const
char
*indent);
26
27
void
print_cli_flag(FILE *
file
,
const
char
*key,
const
char
*label,
28
const
char
*description,
const
char
*indent)
29
{
30
fprintf(
file
,
"%s**"
, indent);
31
if
(strlen(key) > 1)
32
fprintf(
file
,
"-"
);
33
fprintf(
file
,
"-%s**"
, key);
34
fprintf(
file
, MD_NEWLINE);
35
fprintf(
file
,
"\n"
);
36
if
(label !=
NULL
) {
37
fprintf(
file
,
"%s"
, indent);
38
G__md_print_escaped
(
file
,
"\t"
, indent);
39
G__md_print_escaped
(
file
, label, indent);
40
fprintf(
file
, MD_NEWLINE);
41
fprintf(
file
,
"\n"
);
42
}
43
if
(description !=
NULL
) {
44
fprintf(
file
,
"%s"
, indent);
45
G__md_print_escaped
(
file
,
"\t"
, indent);
46
G__md_print_escaped
(
file
, description, indent);
47
}
48
}
49
50
void
print_cli_option(FILE *
file
,
const
struct
Option *opt,
const
char
*indent)
51
{
52
const
char
*type;
53
54
if
(opt->key_desc !=
NULL
)
55
type = opt->key_desc;
56
else
57
switch
(opt->type) {
58
case
TYPE_INTEGER:
59
type =
"integer"
;
60
break
;
61
case
TYPE_DOUBLE:
62
type =
"float"
;
63
break
;
64
case
TYPE_STRING:
65
type =
"string"
;
66
break
;
67
default
:
68
type =
"string"
;
69
break
;
70
}
71
fprintf(
file
,
"%s**%s**="
, indent, opt->key);
72
fprintf(
file
,
"*%s*"
, type);
73
if
(opt->multiple) {
74
fprintf(
file
,
" [,"
);
75
fprintf(
file
,
"*%s*,...]"
, type);
76
}
77
/* fprintf(file, "*"); */
78
if
(opt->required) {
79
fprintf(
file
,
" **[required]**"
);
80
}
81
fprintf(
file
, MD_NEWLINE);
82
fprintf(
file
,
"\n"
);
83
if
(opt->label) {
84
fprintf(
file
,
"%s"
, indent);
85
G__md_print_escaped
(
file
,
"\t"
, indent);
86
G__md_print_escaped
(
file
, opt->label, indent);
87
}
88
if
(opt->description) {
89
if
(opt->label) {
90
fprintf(
file
, MD_NEWLINE);
91
fprintf(
file
,
"\n"
);
92
}
93
fprintf(
file
,
"%s"
, indent);
94
G__md_print_escaped
(
file
,
"\t"
, indent);
95
G__md_print_escaped
(
file
, opt->description, indent);
96
}
97
98
if
(opt->options) {
99
fprintf(
file
, MD_NEWLINE);
100
fprintf(
file
,
"\n"
);
101
fprintf(
file
,
"%s"
, indent);
102
G__md_print_escaped
(
file
,
"\t"
, indent);
103
fprintf(
file
,
"%s: *"
, _(
"Allowed values"
));
104
G__md_print_escaped_for_options
(
file
, opt->options);
105
fprintf(
file
,
"*"
);
106
}
107
108
if
(opt->def && opt->def[0] !=
'\0'
) {
109
fprintf(
file
, MD_NEWLINE);
110
fprintf(
file
,
"\n"
);
111
fprintf(
file
,
"%s"
, indent);
112
G__md_print_escaped
(
file
,
"\t"
, indent);
113
fprintf(
file
,
"%s:"
, _(
"Default"
));
114
fprintf(
file
,
" *"
);
115
G__md_print_escaped
(
file
, opt->def, indent);
116
fprintf(
file
,
"*"
);
117
}
118
119
if
(opt->descs) {
120
int
i = 0;
121
122
while
(opt->opts[i]) {
123
if
(opt->descs[i]) {
124
fprintf(
file
, MD_NEWLINE);
125
fprintf(
file
,
"\n"
);
126
fprintf(
file
,
"%s"
, indent);
127
char
*thumbnails =
NULL
;
128
if
(opt->gisprompt) {
129
if
(strcmp(opt->gisprompt,
"old,colortable,colortable"
) ==
130
0)
131
thumbnails =
"colortables"
;
132
else
if
(strcmp(opt->gisprompt,
"old,barscale,barscale"
) ==
133
0)
134
thumbnails =
"barscales"
;
135
else
if
(strcmp(opt->gisprompt,
136
"old,northarrow,northarrow"
) == 0)
137
thumbnails =
"northarrows"
;
138
139
if
(thumbnails) {
140
G__md_print_escaped
(
file
,
"\t\t"
, indent);
141
fprintf(
file
,
" "
, opt->opts[i],
142
thumbnails, opt->opts[i]);
143
}
144
else
{
145
G__md_print_escaped
(
file
,
"\t\t"
, indent);
146
}
147
}
148
G__md_print_escaped
(
file
,
"\t"
, indent);
149
fprintf(
file
,
"**"
);
150
G__md_print_escaped
(
file
, opt->opts[i], indent);
151
fprintf(
file
,
"**: "
);
152
G__md_print_escaped
(
file
, opt->descs[i], indent);
153
}
154
i++;
155
}
156
}
157
}
158
159
void
print_cli_example(FILE *
file
,
const
char
*indent)
160
{
161
fprintf(
file
,
"\n%sExample:\n"
, indent);
162
163
fprintf(
file
,
"\n%s```sh\n"
, indent);
164
fprintf(
file
,
"%s%s"
, indent, st->pgm_name);
165
166
const
struct
Option *first_required_rule_option =
167
G__first_required_option_from_rules
();
168
const
struct
Option *opt =
NULL
;
169
const
char
*type;
170
171
if
(st->n_opts) {
172
opt = &st->first_option;
173
174
while
(opt !=
NULL
) {
175
if
(opt->key_desc !=
NULL
)
176
type = opt->key_desc;
177
else
178
switch
(opt->type) {
179
case
TYPE_INTEGER:
180
type =
"integer"
;
181
break
;
182
case
TYPE_DOUBLE:
183
type =
"float"
;
184
break
;
185
case
TYPE_STRING:
186
type =
"string"
;
187
break
;
188
default
:
189
type =
"string"
;
190
break
;
191
}
192
if
(opt->required || first_required_rule_option == opt) {
193
fprintf(
file
,
" "
);
194
fprintf(
file
,
"%s="
, opt->key);
195
196
char
*value =
NULL
;
197
if
(opt->answer) {
198
value =
G_store
(opt->answer);
199
}
200
else
if
(opt->options && opt->type == TYPE_STRING) {
201
// Get example value from allowed values, but only for
202
// strings because numbers may have ranges and we don't
203
// want to print a range.
204
// Get allowed values as tokens.
205
char
**tokens;
206
char
delm[2];
207
delm[0] =
','
;
208
delm[1] =
'\0'
;
209
tokens =
G_tokenize
(opt->options, delm);
210
// We are interested in the first allowed value.
211
if
(tokens[0]) {
212
G_chop
(tokens[0]);
213
value =
G_store
(tokens[0]);
214
}
215
G_free_tokens
(tokens);
216
}
217
218
if
(value) {
219
fprintf(
file
,
"%s"
, value);
220
}
221
else
{
222
if
(opt->type == TYPE_INTEGER) {
223
fprintf(
file
,
"0"
);
224
}
225
else
if
(opt->type == TYPE_DOUBLE) {
226
fprintf(
file
,
"0.0"
);
227
}
228
else
{
229
fprintf(
file
,
"%s"
, type);
230
}
231
}
232
G_free
(value);
233
}
234
opt = opt->next_opt;
235
}
236
}
237
fprintf(
file
,
"\n%s```\n"
, indent);
238
}
239
240
void
G__md_print_cli_short_version
(FILE *
file
,
const
char
*indent)
241
{
242
struct
Option *opt;
243
struct
Flag *flag;
244
const
char
*type;
245
int
new_prompt = 0;
246
247
new_prompt =
G__uses_new_gisprompt
();
248
249
fprintf(
file
,
"%s**%s**"
, indent, st->pgm_name);
250
fprintf(
file
,
"\n"
);
251
252
/* print short version first */
253
if
(st->n_flags) {
254
flag = &st->first_flag;
255
fprintf(
file
,
"%s[**-"
, indent);
256
while
(flag !=
NULL
) {
257
fprintf(
file
,
"%c"
, flag->key);
258
flag = flag->next_flag;
259
}
260
fprintf(
file
,
"**]"
);
261
fprintf(
file
,
"\n"
);
262
}
263
264
if
(st->n_opts) {
265
opt = &st->first_option;
266
267
while
(opt !=
NULL
) {
268
if
(opt->key_desc !=
NULL
)
269
type = opt->key_desc;
270
else
271
switch
(opt->type) {
272
case
TYPE_INTEGER:
273
type =
"integer"
;
274
break
;
275
case
TYPE_DOUBLE:
276
type =
"float"
;
277
break
;
278
case
TYPE_STRING:
279
type =
"string"
;
280
break
;
281
default
:
282
type =
"string"
;
283
break
;
284
}
285
fprintf(
file
,
"%s"
, indent);
286
if
(!opt->required)
287
fprintf(
file
,
"["
);
288
fprintf(
file
,
"**%s**="
, opt->key);
289
fprintf(
file
,
"*%s*"
, type);
290
if
(opt->multiple) {
291
fprintf(
file
,
" [,"
);
292
fprintf(
file
,
"*%s*,...]"
, type);
293
}
294
if
(!opt->required)
295
fprintf(
file
,
"]"
);
296
fprintf(
file
,
"\n"
);
297
298
opt = opt->next_opt;
299
}
300
}
301
if
(new_prompt)
302
fprintf(
file
,
"%s[**--overwrite**]\n"
, indent);
303
304
fprintf(
file
,
"%s[**--verbose**]\n"
, indent);
305
fprintf(
file
,
"%s[**--quiet**]\n"
, indent);
306
fprintf(
file
,
"%s[**--qq**]\n"
, indent);
307
fprintf(
file
,
"%s[**--ui**]\n"
, indent);
308
309
print_cli_example(
file
, indent);
310
}
311
312
void
G__md_print_cli_long_version
(FILE *
file
,
const
char
*indent)
313
{
314
struct
Option *opt;
315
struct
Flag *flag;
316
int
new_prompt = 0;
317
318
new_prompt =
G__uses_new_gisprompt
();
319
320
// Options (key-value parameters)
321
if
(st->n_opts) {
322
opt = &st->first_option;
323
while
(opt !=
NULL
) {
324
print_cli_option(
file
, opt, indent);
325
opt = opt->next_opt;
326
fprintf(
file
, MD_NEWLINE);
327
fprintf(
file
,
"\n"
);
328
}
329
}
330
331
// Short (one-letter) flags and tool-specific long flags
332
if
(st->n_flags || new_prompt) {
333
flag = &st->first_flag;
334
while
(st->n_flags && flag !=
NULL
) {
335
print_cli_flag(
file
, &flag->key, flag->label, flag->description,
336
indent);
337
fprintf(
file
, MD_NEWLINE);
338
fprintf(
file
,
"\n"
);
339
flag = flag->next_flag;
340
}
341
if
(new_prompt) {
342
print_cli_flag(
file
,
"overwrite"
,
NULL
,
343
_(
"Allow output files to overwrite existing files"
),
344
indent);
345
fprintf(
file
, MD_NEWLINE);
346
fprintf(
file
,
"\n"
);
347
}
348
}
349
// Pre-defined long flags
350
print_cli_flag(
file
,
"help"
,
NULL
, _(
"Print usage summary"
), indent);
351
fprintf(
file
, MD_NEWLINE);
352
fprintf(
file
,
"\n"
);
353
print_cli_flag(
file
,
"verbose"
,
NULL
, _(
"Verbose module output"
), indent);
354
fprintf(
file
, MD_NEWLINE);
355
fprintf(
file
,
"\n"
);
356
print_cli_flag(
file
,
"quiet"
,
NULL
, _(
"Quiet module output"
), indent);
357
fprintf(
file
, MD_NEWLINE);
358
fprintf(
file
,
"\n"
);
359
print_cli_flag(
file
,
"qq"
,
NULL
, _(
"Very quiet module output"
), indent);
360
fprintf(
file
, MD_NEWLINE);
361
fprintf(
file
,
"\n"
);
362
print_cli_flag(
file
,
"ui"
,
NULL
, _(
"Force launching GUI dialog"
), indent);
363
fprintf(
file
,
"\n"
);
364
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
NULL
#define NULL
Definition
ccmath.h:32
file
#define file
G__uses_new_gisprompt
int G__uses_new_gisprompt(void)
Definition
parser.c:892
G__first_required_option_from_rules
const struct Option * G__first_required_option_from_rules(void)
Definition
parser_dependencies.c:494
G__md_print_cli_long_version
void G__md_print_cli_long_version(FILE *file, const char *indent)
Definition
parser_md_cli.c:312
G__md_print_cli_short_version
void G__md_print_cli_short_version(FILE *file, const char *indent)
Definition
parser_md_cli.c:240
G__md_print_escaped
void G__md_print_escaped(FILE *f, const char *str, const char *indent)
Definition
parser_md_common.c:29
G__md_print_escaped_for_options
void G__md_print_escaped_for_options(FILE *f, const char *str)
Definition
parser_md_common.c:56
G_chop
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition
strings.c:332
G_store
char * G_store(const char *s)
Copy string to allocated memory.
Definition
strings.c:87
G_free_tokens
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
Definition
token.c:197
G_tokenize
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
Definition
token.c:47
gis
parser_md_cli.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0