diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 15:31:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 15:43:25 +0300 |
commit | 8652a500669059d77ce7bace6e9e9da1b30c54b0 (patch) | |
tree | 54ee082e3804c0574e67252be8fbceb48b8f156a /include | |
parent | 65f41a742e025487f8ec7f2e7ca2a3af3283fc96 (diff) | |
download | grecs-8652a500669059d77ce7bace6e9e9da1b30c54b0.tar.gz grecs-8652a500669059d77ce7bace6e9e9da1b30c54b0.tar.bz2 |
wordsplit: rewrite positional parameters implementation
This improves 3e07e3ad
* include/wordsplit.h (ws_paramv,ws_paramc)
(ws_parambuf,ws_paramidx,ws_paramsiz): New fields.
(WRDSO_PARAMV,WRDSO_PARAM_NEGIDX): New options.
(WRDSE_BADPARAM): New error code.
(wordsplit_free_parambuf): New proto.
* src/wordsplit.c (wordsplit_init): Initialize new fields.
(wsplt_assign_var): Fix double-free and memory leak.
(expvar): Expand positional parameters.
(begin_var_p): Add '#'
(wordsplit_free_envbuf): Fix condition.
(wordsplit_free_parambuf): New function.
(wordsplit_free): Call wordsplit_free_parambuf.
(_wordsplit_errstr): New error description.
* tests/wordsplit.at: Update wsp invocations.
Test positional parameters.
* tests/wsp.c: Rewrite.
Diffstat (limited to 'include')
-rw-r--r-- | include/wordsplit.h | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h index a175275..d7eb26f 100644 --- a/include/wordsplit.h +++ b/include/wordsplit.h | |||
@@ -72,12 +72,22 @@ struct wordsplit | |||
72 | moved to ws_envbuf first, and the ws_envbuf address is assigned | 72 | moved to ws_envbuf first, and the ws_envbuf address is assigned |
73 | to ws_env. From this moment on, all variable expansions are served | 73 | to ws_env. From this moment on, all variable expansions are served |
74 | from ws_envbuf. */ | 74 | from ws_envbuf. */ |
75 | char **ws_envbuf; /* Storage for variables */ | 75 | char **ws_envbuf; /* Storage for variables */ |
76 | size_t ws_envidx; /* Index of first free slot */ | 76 | size_t ws_envidx; /* Index of first free slot */ |
77 | size_t ws_envsiz; /* Size of the ws_envbuf array */ | 77 | size_t ws_envsiz; /* Size of the ws_envbuf array */ |
78 | |||
79 | char const **ws_paramv; /* [WRDSO_PARAMV] User-supplied positional | ||
80 | parameters */ | ||
81 | size_t ws_paramc; /* Number of positional parameters */ | ||
82 | |||
83 | /* Temporary storage for parameters. Works similarly to ws_enbuf. | ||
84 | */ | ||
85 | char **ws_parambuf; | ||
86 | size_t ws_paramidx; | ||
87 | size_t ws_paramsiz; | ||
78 | 88 | ||
79 | int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos); | 89 | int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos); |
80 | /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up | 90 | /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up |
81 | the name VAR (LEN bytes long) in the table of | 91 | the name VAR (LEN bytes long) in the table of |
82 | variables and if found returns in memory | 92 | variables and if found returns in memory |
83 | location pointed to by RET the value of that | 93 | location pointed to by RET the value of that |
@@ -96,13 +106,13 @@ struct wordsplit | |||
96 | location pointed to by RET the expansion of | 106 | location pointed to by RET the expansion of |
97 | the command CMD (LEN bytes long). On input, | 107 | the command CMD (LEN bytes long). On input, |
98 | ARGV contains CMD split out to words. | 108 | ARGV contains CMD split out to words. |
99 | 109 | ||
100 | See ws_getvar for a discussion of possible | 110 | See ws_getvar for a discussion of possible |
101 | return values. */ | 111 | return values. */ |
102 | 112 | ||
103 | const char *ws_input; /* Input string (the S argument to wordsplit. */ | 113 | const char *ws_input; /* Input string (the S argument to wordsplit. */ |
104 | size_t ws_len; /* Length of ws_input. */ | 114 | size_t ws_len; /* Length of ws_input. */ |
105 | size_t ws_endp; /* Points past the last processed byte in | 115 | size_t ws_endp; /* Points past the last processed byte in |
106 | ws_input. */ | 116 | ws_input. */ |
107 | int ws_errno; /* [Output] Error code, if an error occurred. */ | 117 | int ws_errno; /* [Output] Error code, if an error occurred. */ |
108 | char *ws_usererr; /* Points to textual description of | 118 | char *ws_usererr; /* Points to textual description of |
@@ -223,12 +233,18 @@ struct wordsplit | |||
223 | (e.g. ${VAR:-foo bar}) */ | 233 | (e.g. ${VAR:-foo bar}) */ |
224 | #define WRDSO_NOVARSPLIT 0x00001000 | 234 | #define WRDSO_NOVARSPLIT 0x00001000 |
225 | /* Don't split commands, even containing whitespace, e.g. | 235 | /* Don't split commands, even containing whitespace, e.g. |
226 | $(echo foo bar) */ | 236 | $(echo foo bar) */ |
227 | #define WRDSO_NOCMDSPLIT 0x00002000 | 237 | #define WRDSO_NOCMDSPLIT 0x00002000 |
228 | 238 | ||
239 | /* Enable positional parameters */ | ||
240 | #define WRDSO_PARAMV 0x00004000 | ||
241 | /* Enable negative positional indices (${-1} is the last positional | ||
242 | parameter) */ | ||
243 | #define WRDSO_PARAM_NEGIDX 0x00008000 | ||
244 | |||
229 | #define WRDSO_BSKEEP WRDSO_BSKEEP_WORD | 245 | #define WRDSO_BSKEEP WRDSO_BSKEEP_WORD |
230 | #define WRDSO_OESC WRDSO_OESC_WORD | 246 | #define WRDSO_OESC WRDSO_OESC_WORD |
231 | #define WRDSO_XESC WRDSO_XESC_WORD | 247 | #define WRDSO_XESC WRDSO_XESC_WORD |
232 | 248 | ||
233 | /* Indices into ws_escape */ | 249 | /* Indices into ws_escape */ |
234 | #define WRDSX_WORD 0 | 250 | #define WRDSX_WORD 0 |
@@ -247,18 +263,20 @@ struct wordsplit | |||
247 | #define WRDSE_CBRACE 4 | 263 | #define WRDSE_CBRACE 4 |
248 | #define WRDSE_UNDEF 5 | 264 | #define WRDSE_UNDEF 5 |
249 | #define WRDSE_NOINPUT 6 | 265 | #define WRDSE_NOINPUT 6 |
250 | #define WRDSE_PAREN 7 | 266 | #define WRDSE_PAREN 7 |
251 | #define WRDSE_GLOBERR 8 | 267 | #define WRDSE_GLOBERR 8 |
252 | #define WRDSE_USERERR 9 | 268 | #define WRDSE_USERERR 9 |
269 | #define WRDSE_BADPARAM 10 | ||
253 | 270 | ||
254 | int wordsplit (const char *s, wordsplit_t *ws, int flags); | 271 | int wordsplit (const char *s, wordsplit_t *ws, int flags); |
255 | int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, int flags); | 272 | int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, int flags); |
256 | void wordsplit_free (wordsplit_t *ws); | 273 | void wordsplit_free (wordsplit_t *ws); |
257 | void wordsplit_free_words (wordsplit_t *ws); | 274 | void wordsplit_free_words (wordsplit_t *ws); |
258 | void wordsplit_free_envbuf (wordsplit_t *ws); | 275 | void wordsplit_free_envbuf (wordsplit_t *ws); |
276 | void wordsplit_free_parambuf (struct wordsplit *ws); | ||
259 | int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv); | 277 | int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv); |
260 | 278 | ||
261 | static inline void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv) | 279 | static inline void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv) |
262 | __attribute__ ((deprecated)); | 280 | __attribute__ ((deprecated)); |
263 | 281 | ||
264 | static inline void | 282 | static inline void |