aboutsummaryrefslogtreecommitdiff
path: root/editors/awk.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-06-22 18:41:01 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2012-06-22 18:41:01 +0200
commitea664dde87d8e52df7d4003d988352a66562a945 (patch)
tree76de10da36e3d53809538f42fd1267ff90b44b83 /editors/awk.c
parent440a509849391f2dc8ec720a136577ede3306fa8 (diff)
downloadbusybox-ea664dde87d8e52df7d4003d988352a66562a945.tar.gz
awk: make -F STR interpret escape sequences. Closes 5126
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/awk.c')
-rw-r--r--editors/awk.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 71abca215..d69720d64 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -696,6 +696,10 @@ static char nextchar(char **s)
pps = *s;
if (c == '\\')
c = bb_process_escape_sequence((const char**)s);
+ /* Example awk statement:
+ * s = "abc\"def"
+ * we must treat \" as "
+ */
if (c == '\\' && *s == pps) { /* unrecognized \z? */
c = *(*s); /* yes, fetch z */
if (c)
@@ -704,6 +708,15 @@ static char nextchar(char **s)
return c;
}
+/* TODO: merge with strcpy_and_process_escape_sequences()?
+ */
+static void unescape_string_in_place(char *s1)
+{
+ char *s = s1;
+ while ((*s1 = nextchar(&s)) != '\0')
+ s1++;
+}
+
static ALWAYS_INLINE int isalnum_(int c)
{
return (isalnum(c) || c == '_');
@@ -2992,7 +3005,7 @@ static int awk_exit(int r)
* otherwise return 0 */
static int is_assignment(const char *expr)
{
- char *exprc, *val, *s, *s1;
+ char *exprc, *val;
if (!isalnum_(*expr) || (val = strchr(expr, '=')) == NULL) {
return FALSE;
@@ -3002,10 +3015,7 @@ static int is_assignment(const char *expr)
val = exprc + (val - expr);
*val++ = '\0';
- s = s1 = val;
- while ((*s1 = nextchar(&s)) != '\0')
- s1++;
-
+ unescape_string_in_place(val);
setvar_u(newvar(exprc), val);
free(exprc);
return TRUE;
@@ -3118,8 +3128,10 @@ int awk_main(int argc, char **argv)
opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL);
argv += optind;
argc -= optind;
- if (opt & 0x1)
- setvar_s(intvar[FS], opt_F); // -F
+ if (opt & 0x1) { /* -F */
+ unescape_string_in_place(opt_F);
+ setvar_s(intvar[FS], opt_F);
+ }
while (list_v) { /* -v */
if (!is_assignment(llist_pop(&list_v)))
bb_show_usage();