aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2015-11-14 17:35:22 +0100
committerChristian Neukirchen <chneukirchen@gmail.com>2015-11-14 17:35:37 +0100
commitdc3713a954915fea898bf746f7dfb73bbc7469d2 (patch)
treea43d6c19a803c5ec498ff3e4125430afd23e2ea3
parentd84345abd9fa967809c9f8d94371d44d7989bdde (diff)
downloadarr-dc3713a954915fea898bf746f7dfb73bbc7469d2.tar.gz
arr-dc3713a954915fea898bf746f7dfb73bbc7469d2.tar.xz
arr-dc3713a954915fea898bf746f7dfb73bbc7469d2.zip
Negative numbers count from the end
-rw-r--r--arr.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/arr.c b/arr.c
index c1b9037..76a2c06 100644
--- a/arr.c
+++ b/arr.c
@@ -42,12 +42,18 @@ fmt_range(char **args, int bytewise, size_t argsnum)
}
s = end;
if (bytewise) {
- if (n <= argsnum)
+ if (n < 0)
+ n += argsnum + 1;
+ if (n < 0)
+ n = 0;
+ if (n >= 1 && n <= argsnum)
printf("%c", args[0][n-1]);
} else {
+ if (n < 0)
+ n += argsnum;
if (printed++)
printf("%c", lastsplit);
- if (n < argsnum)
+ if (n > 0 && n < argsnum)
printf("%s", args[n]);
}
break;
@@ -64,10 +70,14 @@ fmt_range(char **args, int bytewise, size_t argsnum)
fprintf(stderr, "can't parse number at '%s'.\n", s);
exit(1);
}
- if (s == end) // default to max range
- n = argsnum;
+ if (s == end) // default to -1
+ n = -1;
s = end;
if (bytewise) {
+ if (n < 0)
+ n += argsnum + 1;
+ if (n < 0)
+ n = 0;
if (n > argsnum)
n = argsnum;
if (l <= n)
@@ -77,6 +87,8 @@ fmt_range(char **args, int bytewise, size_t argsnum)
for (l--; l >= n; l--)
printf("%c", args[0][l-1]);
} else {
+ if (n < 0)
+ n += argsnum;
if (n >= argsnum)
n = argsnum-1;
if (l <= n)
@@ -127,6 +139,8 @@ fmt_inner(char **args, size_t argsnum)
if (s == end && *s == '-')
goto split;
s = end;
+ if (newfield < 0)
+ newfield += argsnum;
field = newfield;
break;
case '|':
@@ -135,14 +149,14 @@ fmt_inner(char **args, size_t argsnum)
return;
case '*':
s++;
- if (field >= 0 && field < argsnum-1)
+ if (field >= 0 && field < argsnum)
fmt_range(args+field, 1, strlen(args[field]));
else
fmt_range(args, 1, 0);
return;
case '}':
s++;
- if (field >= 1 && field < argsnum-1)
+ if (field >= 1 && field < argsnum)
printf("%s", args[field]);
return;
case '"':
@@ -158,14 +172,11 @@ fmt_inner(char **args, size_t argsnum)
goto split2;
default: { /* split at char, recurse */
split:
- /* TODO "|" */
- if (field == 0)
- abort();
lastsplit = *s;
s++;
split2:;
char *t;
- if (field >= 1 && field < argsnum-1)
+ if (field >= 1 && field < argsnum)
t = strdup(args[field]);
else
t = strdup("");
@@ -300,7 +311,7 @@ main(int argc, char *argv[]) {
}
if (eof)
break;
- fmt(argv[1], lines, argc+stdins);
+ fmt(argv[1], lines, argc-1+stdins);
printf("%c", delim);
}