diff options
Diffstat (limited to 'shell/shell_common.c')
-rw-r--r-- | shell/shell_common.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/shell/shell_common.c b/shell/shell_common.c index 94c94a147..82102778c 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -313,9 +313,44 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), | |||
313 | 313 | ||
314 | if (argv[0]) { | 314 | if (argv[0]) { |
315 | /* Remove trailing space $IFS chars */ | 315 | /* Remove trailing space $IFS chars */ |
316 | while (--bufpos >= 0 && isspace(buffer[bufpos]) && strchr(ifs, buffer[bufpos]) != NULL) | 316 | while (--bufpos >= 0 |
317 | && isspace(buffer[bufpos]) | ||
318 | && strchr(ifs, buffer[bufpos]) != NULL | ||
319 | ) { | ||
317 | continue; | 320 | continue; |
321 | } | ||
318 | buffer[bufpos + 1] = '\0'; | 322 | buffer[bufpos + 1] = '\0'; |
323 | |||
324 | /* Last variable takes the entire remainder with delimiters | ||
325 | * (sans trailing whitespace $IFS), | ||
326 | * but ***only "if there are fewer vars than fields"(c)***! | ||
327 | * The "X:Y:" case below: there are two fields, | ||
328 | * and therefore last delimiter (:) is eaten: | ||
329 | * IFS=": " | ||
330 | * echo "X:Y:Z:" | (read x y; echo "|$x|$y|") # |X|Y:Z:| | ||
331 | * echo "X:Y:Z" | (read x y; echo "|$x|$y|") # |X|Y:Z| | ||
332 | * echo "X:Y:" | (read x y; echo "|$x|$y|") # |X|Y|, not |X|Y:| | ||
333 | * echo "X:Y : " | (read x y; echo "|$x|$y|") # |X|Y| | ||
334 | */ | ||
335 | if (bufpos >= 0 | ||
336 | && strchr(ifs, buffer[bufpos]) != NULL | ||
337 | ) { | ||
338 | /* There _is_ a non-whitespace IFS char */ | ||
339 | /* Skip whitespace IFS char before it */ | ||
340 | while (--bufpos >= 0 | ||
341 | && isspace(buffer[bufpos]) | ||
342 | && strchr(ifs, buffer[bufpos]) != NULL | ||
343 | ) { | ||
344 | continue; | ||
345 | } | ||
346 | /* Are there $IFS chars? */ | ||
347 | if (strcspn(buffer, ifs) >= ++bufpos) { | ||
348 | /* No: last var takes one field, not more */ | ||
349 | /* So, drop trailing IFS delims */ | ||
350 | buffer[bufpos] = '\0'; | ||
351 | } | ||
352 | } | ||
353 | |||
319 | /* Use the remainder as a value for the next variable */ | 354 | /* Use the remainder as a value for the next variable */ |
320 | setvar(*argv, buffer); | 355 | setvar(*argv, buffer); |
321 | /* Set the rest to "" */ | 356 | /* Set the rest to "" */ |