]> git.ipfire.org Git - thirdparty/tar.git/blame - lib/wordsplit.h
Silence gcc warnings in wordsplit
[thirdparty/tar.git] / lib / wordsplit.h
CommitLineData
7b5e8039 1/* wordsplit - a word splitter
c7b3f021 2 Copyright (C) 2009-2018 Sergey Poznyakoff
7b5e8039
SP
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3 of the License, or (at your
7 option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
c7b3f021 15 with this program. If not, see <http://www.gnu.org/licenses/>. */
7b5e8039
SP
16
17#ifndef __WORDSPLIT_H
18#define __WORDSPLIT_H
19
20#include <stddef.h>
21
55fb2fc3
PE
22#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
23# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
24#else
25# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */
26#endif
27
c7b3f021
SP
28typedef struct wordsplit wordsplit_t;
29
30/* Structure used to direct the splitting. Members marked with [Input]
31 can be defined before calling wordsplit(), those marked with [Output]
32 provide return values when the function returns. If neither mark is
33 used, the member is internal and must not be used by the caller.
34
35 In the comments below, the identifiers in parentheses indicate bits that
36 must be set (or unset, if starting with !) in ws_flags (if starting with
37 WRDSF_) or ws_options (if starting with WRDSO_) to initialize or use the
38 given member.
39
40 If not redefined explicitly, most of them are set to some reasonable
41 default value upon entry to wordsplit(). */
42struct wordsplit
7b5e8039 43{
c7b3f021
SP
44 size_t ws_wordc; /* [Output] Number of words in ws_wordv. */
45 char **ws_wordv; /* [Output] Array of parsed out words. */
46 size_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial
47 elements in ws_wordv to fill with NULLs. */
48 size_t ws_wordn; /* Number of elements ws_wordv can accomodate. */
e5474174
SP
49 unsigned ws_flags; /* [Input] Flags passed to wordsplit. */
50 unsigned ws_options; /* [Input] (WRDSF_OPTIONS)
c7b3f021
SP
51 Additional options. */
52 size_t ws_maxwords; /* [Input] (WRDSO_MAXWORDS) Return at most that
53 many words */
54 size_t ws_wordi; /* [Output] (WRDSF_INCREMENTAL) Total number of
55 words returned so far */
56
57 const char *ws_delim; /* [Input] (WRDSF_DELIM) Word delimiters. */
58 const char *ws_comment; /* [Input] (WRDSF_COMMENT) Comment characters. */
59 const char *ws_escape[2]; /* [Input] (WRDSF_ESCAPE) Characters to be escaped
60 with backslash. */
61 void (*ws_alloc_die) (wordsplit_t *wsp);
62 /* [Input] (WRDSF_ALLOC_DIE) Function called when
63 out of memory. Must not return. */
7b5e8039 64 void (*ws_error) (const char *, ...)
c7b3f021
SP
65 __attribute__ ((__format__ (__printf__, 1, 2)));
66 /* [Input] (WRDSF_ERROR) Function used for error
67 reporting */
7b5e8039 68 void (*ws_debug) (const char *, ...)
c7b3f021
SP
69 __attribute__ ((__format__ (__printf__, 1, 2)));
70 /* [Input] (WRDSF_DEBUG) Function used for debug
71 output. */
72 const char **ws_env; /* [Input] (WRDSF_ENV, !WRDSF_NOVAR) Array of
73 environment variables. */
7b5e8039 74
c7b3f021
SP
75 char **ws_envbuf;
76 size_t ws_envidx;
77 size_t ws_envsiz;
78
79 int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos);
80 /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up
81 the name VAR (LEN bytes long) in the table of
82 variables and if found returns in memory
83 location pointed to by RET the value of that
84 variable. Returns WRDSE_OK (0) on success,
85 and an error code (see WRDSE_* defines below)
86 on error. User-specific errors can be returned
87 by storing the error diagnostic string in RET
88 and returning WRDSE_USERERR.
89 Whatever is stored in RET, it must be allocated
90 using malloc(3). */
91 void *ws_closure; /* [Input] (WRDSF_CLOSURE) Passed as the CLOS
92 argument to ws_getvar and ws_command. */
93 int (*ws_command) (char **ret, const char *cmd, size_t len, char **argv,
94 void *clos);
95 /* [Input] (!WRDSF_NOCMD) Returns in the memory
96 location pointed to by RET the expansion of
97 the command CMD (LEN bytes long). If WRDSO_ARGV
98 option is set, ARGV contains CMD split out to
99 words. Otherwise ARGV is NULL.
7b5e8039 100
c7b3f021
SP
101 See ws_getvar for a discussion of possible
102 return values. */
103
104 const char *ws_input; /* Input string (the S argument to wordsplit. */
105 size_t ws_len; /* Length of ws_input. */
106 size_t ws_endp; /* Points past the last processed byte in
107 ws_input. */
108 int ws_errno; /* [Output] Error code, if an error occurred. */
109 char *ws_usererr; /* Points to textual description of
110 the error, if ws_errno is WRDSE_USERERR. Must
111 be allocated with malloc(3). */
7b5e8039 112 struct wordsplit_node *ws_head, *ws_tail;
c7b3f021
SP
113 /* Doubly-linked list of parsed out nodes. */
114 int ws_lvl; /* Invocation nesting level. */
7b5e8039
SP
115};
116
c7b3f021
SP
117/* Initial size for ws_env, if allocated automatically */
118#define WORDSPLIT_ENV_INIT 16
119
120/* Wordsplit flags. */
7b5e8039
SP
121/* Append the words found to the array resulting from a previous
122 call. */
123#define WRDSF_APPEND 0x00000001
c7b3f021 124/* Insert ws_offs initial NULLs in the array ws_wordv.
7b5e8039
SP
125 (These are not counted in the returned ws_wordc.) */
126#define WRDSF_DOOFFS 0x00000002
c7b3f021 127/* Don't do command substitution. */
7b5e8039
SP
128#define WRDSF_NOCMD 0x00000004
129/* The parameter p resulted from a previous call to
130 wordsplit(), and wordsplit_free() was not called. Reuse the
131 allocated storage. */
132#define WRDSF_REUSE 0x00000008
133/* Print errors */
134#define WRDSF_SHOWERR 0x00000010
c7b3f021 135/* Consider it an error if an undefined variable is expanded. */
7b5e8039 136#define WRDSF_UNDEF 0x00000020
7b5e8039
SP
137/* Don't do variable expansion. */
138#define WRDSF_NOVAR 0x00000040
139/* Abort on ENOMEM error */
140#define WRDSF_ENOMEMABRT 0x00000080
141/* Trim off any leading and trailind whitespace */
142#define WRDSF_WS 0x00000100
143/* Handle single quotes */
144#define WRDSF_SQUOTE 0x00000200
145/* Handle double quotes */
146#define WRDSF_DQUOTE 0x00000400
c7b3f021 147/* Handle single and double quotes */
7b5e8039
SP
148#define WRDSF_QUOTE (WRDSF_SQUOTE|WRDSF_DQUOTE)
149/* Replace each input sequence of repeated delimiters with a single
150 delimiter */
151#define WRDSF_SQUEEZE_DELIMS 0x00000800
152/* Return delimiters */
153#define WRDSF_RETURN_DELIMS 0x00001000
154/* Treat sed expressions as words */
155#define WRDSF_SED_EXPR 0x00002000
156/* ws_delim field is initialized */
157#define WRDSF_DELIM 0x00004000
158/* ws_comment field is initialized */
159#define WRDSF_COMMENT 0x00008000
160/* ws_alloc_die field is initialized */
161#define WRDSF_ALLOC_DIE 0x00010000
162/* ws_error field is initialized */
163#define WRDSF_ERROR 0x00020000
164/* ws_debug field is initialized */
165#define WRDSF_DEBUG 0x00040000
166/* ws_env field is initialized */
167#define WRDSF_ENV 0x00080000
168/* ws_getvar field is initialized */
169#define WRDSF_GETVAR 0x00100000
170/* enable debugging */
171#define WRDSF_SHOWDBG 0x00200000
172/* Don't split input into words. Useful for side effects. */
173#define WRDSF_NOSPLIT 0x00400000
174/* Keep undefined variables in place, instead of expanding them to
c7b3f021 175 empty strings. */
7b5e8039
SP
176#define WRDSF_KEEPUNDEF 0x00800000
177/* Warn about undefined variables */
178#define WRDSF_WARNUNDEF 0x01000000
179/* Handle C escapes */
180#define WRDSF_CESCAPES 0x02000000
7b5e8039
SP
181/* ws_closure is set */
182#define WRDSF_CLOSURE 0x04000000
183/* ws_env is a Key/Value environment, i.e. the value of a variable is
184 stored in the element that follows its name. */
185#define WRDSF_ENV_KV 0x08000000
7b5e8039
SP
186/* ws_escape is set */
187#define WRDSF_ESCAPE 0x10000000
7b5e8039
SP
188/* Incremental mode */
189#define WRDSF_INCREMENTAL 0x20000000
c7b3f021
SP
190/* Perform pathname and tilde expansion */
191#define WRDSF_PATHEXPAND 0x40000000
192/* ws_options is initialized */
193#define WRDSF_OPTIONS 0x80000000
7b5e8039
SP
194
195#define WRDSF_DEFFLAGS \
196 (WRDSF_NOVAR | WRDSF_NOCMD | \
197 WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_CESCAPES)
198
c7b3f021
SP
199/* Remove the word that produces empty string after path expansion */
200#define WRDSO_NULLGLOB 0x00000001
201/* Print error message if path expansion produces empty string */
202#define WRDSO_FAILGLOB 0x00000002
203/* Allow a leading period to be matched by metacharacters. */
204#define WRDSO_DOTGLOB 0x00000004
205/* ws_command needs argv parameter */
206#define WRDSO_ARGV 0x00000008
207/* Keep backslash in unrecognized escape sequences in words */
208#define WRDSO_BSKEEP_WORD 0x00000010
209/* Handle octal escapes in words */
210#define WRDSO_OESC_WORD 0x00000020
211/* Handle hex escapes in words */
212#define WRDSO_XESC_WORD 0x00000040
213
214/* ws_maxwords field is initialized */
215#define WRDSO_MAXWORDS 0x00000080
216
217/* Keep backslash in unrecognized escape sequences in quoted strings */
218#define WRDSO_BSKEEP_QUOTE 0x00000100
219/* Handle octal escapes in quoted strings */
220#define WRDSO_OESC_QUOTE 0x00000200
221/* Handle hex escapes in quoted strings */
222#define WRDSO_XESC_QUOTE 0x00000400
223
224#define WRDSO_BSKEEP WRDSO_BSKEEP_WORD
225#define WRDSO_OESC WRDSO_OESC_WORD
226#define WRDSO_XESC WRDSO_XESC_WORD
227
228/* Indices into ws_escape */
229#define WRDSX_WORD 0
230#define WRDSX_QUOTE 1
231
232/* Set escape option F in WS for words (Q==0) or quoted strings (Q==1) */
233#define WRDSO_ESC_SET(ws,q,f) ((ws)->ws_options |= ((f) << 4*(q)))
234/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */
235#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
236
237#define WRDSE_OK 0
238#define WRDSE_EOF WRDSE_OK
7b5e8039
SP
239#define WRDSE_QUOTE 1
240#define WRDSE_NOSPACE 2
c7b3f021
SP
241#define WRDSE_USAGE 3
242#define WRDSE_CBRACE 4
243#define WRDSE_UNDEF 5
244#define WRDSE_NOINPUT 6
245#define WRDSE_PAREN 7
246#define WRDSE_GLOBERR 8
247#define WRDSE_USERERR 9
248
e5474174
SP
249int wordsplit (const char *s, wordsplit_t *ws, unsigned flags);
250int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, unsigned flags);
c7b3f021
SP
251void wordsplit_free (wordsplit_t *ws);
252void wordsplit_free_words (wordsplit_t *ws);
253void wordsplit_free_envbuf (wordsplit_t *ws);
254int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv);
255
256static inline void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv)
257 __attribute__ ((deprecated));
258
259static inline void
260wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv)
261{
262 wordsplit_get_words (ws, wordc, wordv);
263}
264
265int wordsplit_append (wordsplit_t *wsp, int argc, char **argv);
7b5e8039
SP
266
267int wordsplit_c_unquote_char (int c);
268int wordsplit_c_quote_char (int c);
c7b3f021 269size_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
7b5e8039
SP
270void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
271
c7b3f021
SP
272void wordsplit_perror (wordsplit_t *ws);
273const char *wordsplit_strerror (wordsplit_t *ws);
7b5e8039 274
c7b3f021 275void wordsplit_clearerr (wordsplit_t *ws);
7b5e8039
SP
276
277#endif