2363 |
instring = word_has_equals = seen_nonequals = last_argument_was_empty = 0; |
instring = word_has_equals = seen_nonequals = last_argument_was_empty = 0; |
2364 |
for (p = line; *p != '\0'; ++p) |
for (p = line; *p != '\0'; ++p) |
2365 |
{ |
{ |
2366 |
if (ap > end) |
assert (ap <= end); |
|
abort (); |
|
2367 |
|
|
2368 |
if (instring) |
if (instring) |
2369 |
{ |
{ |
|
string_char: |
|
2370 |
/* Inside a string, just copy any char except a closing quote |
/* Inside a string, just copy any char except a closing quote |
2371 |
or a backslash-newline combination. */ |
or a backslash-newline combination. */ |
2372 |
if (*p == instring) |
if (*p == instring) |
2376 |
last_argument_was_empty = 1; |
last_argument_was_empty = 1; |
2377 |
} |
} |
2378 |
else if (*p == '\\' && p[1] == '\n') |
else if (*p == '\\' && p[1] == '\n') |
2379 |
goto swallow_escaped_newline; |
{ |
2380 |
|
/* Backslash-newline is handled differently depending on what |
2381 |
|
kind of string we're in: inside single-quoted strings you |
2382 |
|
keep them; in double-quoted strings they disappear. */ |
2383 |
|
if (instring == '"') |
2384 |
|
++p; |
2385 |
|
else |
2386 |
|
{ |
2387 |
|
*(ap++) = *(p++); |
2388 |
|
*(ap++) = *p; |
2389 |
|
} |
2390 |
|
/* If there's a TAB here, skip it. */ |
2391 |
|
if (p[1] == '\t') |
2392 |
|
++p; |
2393 |
|
} |
2394 |
else if (*p == '\n' && restp != NULL) |
else if (*p == '\n' && restp != NULL) |
2395 |
{ |
{ |
2396 |
/* End of the command line. */ |
/* End of the command line. */ |
2430 |
break; |
break; |
2431 |
|
|
2432 |
case '\\': |
case '\\': |
2433 |
/* Backslash-newline combinations are eaten. */ |
/* Backslash-newline has special case handling, ref POSIX. |
2434 |
|
We're in the fastpath, so emulate what the shell would do. */ |
2435 |
if (p[1] == '\n') |
if (p[1] == '\n') |
2436 |
{ |
{ |
2437 |
swallow_escaped_newline: |
/* Throw out the backslash and newline. */ |
2438 |
|
++p; |
2439 |
|
|
2440 |
/* Eat the backslash, the newline, and following whitespace, |
/* If there is a tab after a backslash-newline, remove it. */ |
2441 |
replacing it all with a single space. */ |
if (p[1] == '\t') |
2442 |
p += 2; |
++p; |
2443 |
|
|
2444 |
/* If there is a tab after a backslash-newline, |
/* If there's nothing in this argument yet, skip any |
2445 |
remove it from the source line which will be echoed, |
whitespace before the start of the next word. */ |
2446 |
since it was most likely used to line |
if (ap == new_argv[i]) |
2447 |
up the continued line with the previous one. */ |
p = next_token (p + 1) - 1; |
|
if (*p == '\t') |
|
|
/* Note these overlap and strcpy() is undefined for |
|
|
overlapping objects in ANSI C. The strlen() _IS_ right, |
|
|
since we need to copy the nul byte too. */ |
|
|
bcopy (p + 1, p, strlen (p)); |
|
|
|
|
|
if (instring) |
|
|
goto string_char; |
|
|
else |
|
|
{ |
|
|
if (ap != new_argv[i]) |
|
|
/* Treat this as a space, ending the arg. |
|
|
But if it's at the beginning of the arg, it should |
|
|
just get eaten, rather than becoming an empty arg. */ |
|
|
goto end_of_arg; |
|
|
else |
|
|
p = next_token (p) - 1; |
|
|
} |
|
2448 |
} |
} |
2449 |
else if (p[1] != '\0') |
else if (p[1] != '\0') |
2450 |
{ |
{ |
2498 |
|
|
2499 |
case ' ': |
case ' ': |
2500 |
case '\t': |
case '\t': |
|
end_of_arg: |
|
2501 |
/* We have the end of an argument. |
/* We have the end of an argument. |
2502 |
Terminate the text of the argument. */ |
Terminate the text of the argument. */ |
2503 |
*ap++ = '\0'; |
*ap++ = '\0'; |
2533 |
} |
} |
2534 |
|
|
2535 |
/* Ignore multiple whitespace chars. */ |
/* Ignore multiple whitespace chars. */ |
2536 |
p = next_token (p); |
p = next_token (p) - 1; |
|
/* Next iteration should examine the first nonwhite char. */ |
|
|
--p; |
|
2537 |
break; |
break; |
2538 |
|
|
2539 |
default: |
default: |
2665 |
} |
} |
2666 |
else if (*p == '\\' && p[1] == '\n') |
else if (*p == '\\' && p[1] == '\n') |
2667 |
{ |
{ |
2668 |
/* Eat the backslash, the newline, and following whitespace, |
/* POSIX says we keep the backslash-newline, but throw out the |
2669 |
replacing it all with a single space (which is escaped |
next char if it's a TAB. */ |
2670 |
from the shell). */ |
*(ap++) = '\\'; |
2671 |
p += 2; |
*(ap++) = *(p++); |
2672 |
|
*(ap++) = *p; |
2673 |
/* If there is a tab after a backslash-newline, |
|
2674 |
remove it from the source line which will be echoed, |
if (p[1] == '\t') |
2675 |
since it was most likely used to line |
++p; |
2676 |
up the continued line with the previous one. */ |
|
|
if (*p == '\t') |
|
|
bcopy (p + 1, p, strlen (p)); |
|
|
|
|
|
p = next_token (p); |
|
|
--p; |
|
|
if (unixy_shell && !batch_mode_shell) |
|
|
*ap++ = '\\'; |
|
|
*ap++ = ' '; |
|
2677 |
continue; |
continue; |
2678 |
} |
} |
2679 |
|
|