1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
18 #include "fc_prehdrs.h"
28 #include "fc_cmdline.h"
30 /* get 'struct cmdline_value_list' and related functions: */
31 #define SPECLIST_TAG cmdline_value
32 #define SPECLIST_TYPE char
35 #define cmdline_value_list_iterate(vallist, pvalue) \
36 TYPED_LIST_ITERATE(char *, vallist, pvalue)
37 #define cmdline_value_list_iterate_end LIST_ITERATE_END
39 static struct cmdline_value_list
*cmdline_values
= NULL
;
41 /**************************************************************************
42 Return a char* to the parameter of the option or NULL.
43 *i can be increased to get next string in the array argv[].
44 It is an error for the option to exist but be an empty string.
45 This doesn't use log_*() because it is used before logging is set up.
47 The argv strings are assumed to be in the local encoding; the returned
48 string is in the internal encoding.
49 **************************************************************************/
50 char *get_option_malloc(const char *option_name
,
51 char **argv
, int *i
, int argc
,
54 int len
= strlen(option_name
);
56 if (gc
&& cmdline_values
== NULL
) {
57 cmdline_values
= cmdline_value_list_new();
60 if (strcmp(option_name
, argv
[*i
]) == 0
61 || (strncmp(option_name
, argv
[*i
], len
) == 0 && argv
[*i
][len
] == '=')
62 || strncmp(option_name
+ 1, argv
[*i
], 2) == 0) {
63 char *opt
= argv
[*i
] + (argv
[*i
][1] != '-' ? 0 : len
);
72 if (strlen(opt
) == 0) {
73 fc_fprintf(stderr
, _("Empty argument for \"%s\".\n"), option_name
);
77 fc_fprintf(stderr
, _("Missing argument for \"%s\".\n"), option_name
);
82 ret
= local_to_internal_string_malloc(opt
);
85 cmdline_value_list_append(cmdline_values
, ret
);
94 /***************************************************************
95 Free memory allocated for commandline option values.
96 ***************************************************************/
97 void cmdline_option_values_free(void)
99 if (cmdline_values
!= NULL
) {
100 cmdline_value_list_iterate(cmdline_values
, pval
) {
102 } cmdline_value_list_iterate_end
;
104 cmdline_value_list_destroy(cmdline_values
);
108 /***************************************************************
109 Is option some form of option_name. option_name must be
110 full length long version such as "--help"
111 ***************************************************************/
112 bool is_option(const char *option_name
,char *option
)
114 return (strcmp(option_name
, option
) == 0
115 || strncmp(option_name
+ 1, option
, 2) == 0);
118 /***************************************************************
119 Like strcspn but also handles quotes, i.e. *reject chars are
120 ignored if they are inside single or double quotes.
121 ***************************************************************/
122 static size_t fc_strcspn(const char *s
, const char *reject
)
124 bool in_single_quotes
= FALSE
, in_double_quotes
= FALSE
;
125 size_t i
, len
= strlen(s
);
127 for (i
= 0; i
< len
; i
++) {
128 if (s
[i
] == '"' && !in_single_quotes
) {
129 in_double_quotes
= !in_double_quotes
;
130 } else if (s
[i
] == '\'' && !in_double_quotes
) {
131 in_single_quotes
= !in_single_quotes
;
134 if (in_single_quotes
|| in_double_quotes
) {
138 if (strchr(reject
, s
[i
])) {
146 /***************************************************************
147 Splits the string into tokens. The individual tokens are
148 returned. The delimiterset can freely be chosen.
150 i.e. "34 abc 54 87" with a delimiterset of " " will yield
151 tokens={"34", "abc", "54", "87"}
153 Part of the input string can be quoted (single or double) to embedded
154 delimiter into tokens. For example,
155 command 'a name' hard "1,2,3,4,5" 99
156 create 'Mack "The Knife"'
157 will yield 5 and 2 tokens respectively using the delimiterset " ,".
159 Tokens which aren't used aren't modified (and memory is not
160 allocated). If the string would yield more tokens only the first
161 num_tokens are extracted.
163 The user has the responsiblity to free the memory allocated by
164 **tokens using free_tokens().
165 ***************************************************************/
166 int get_tokens(const char *str
, char **tokens
, size_t num_tokens
,
167 const char *delimiterset
)
171 fc_assert_ret_val(NULL
!= str
, -1);
174 size_t len
, padlength
= 0;
176 /* skip leading delimiters */
177 str
+= strspn(str
, delimiterset
);
183 len
= fc_strcspn(str
, delimiterset
);
185 if (token
>= num_tokens
) {
189 /* strip start/end quotes if they exist */
191 if ((str
[0] == '"' && str
[len
- 1] == '"')
192 || (str
[0] == '\'' && str
[len
- 1] == '\'')) {
194 padlength
= 1; /* to set the string past the end quote */
199 tokens
[token
] = fc_malloc(len
+ 1);
200 (void) fc_strlcpy(tokens
[token
], str
, len
+ 1); /* adds the '\0' */
204 str
+= len
+ padlength
;
210 /***************************************************************
211 Frees a set of tokens created by get_tokens().
212 ***************************************************************/
213 void free_tokens(char **tokens
, size_t ntokens
)
217 for (i
= 0; i
< ntokens
; i
++) {