summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1995-11-28 20:07:17 +0000
committerJim Meyering <jim@meyering.net>1995-11-28 20:07:17 +0000
commitda8c36f53fee296cda3adb4c1427954c334dd415 (patch)
tree8430ec6cee788577fbdc702b6c8e61a3171039b1
parent83cf5efca97425a2854d690e0771b5e40aa36ae6 (diff)
downloadcoreutils-da8c36f53fee296cda3adb4c1427954c334dd415.tar.xz
(begfield): Replace unnecessary loop with if-else.
(limfield): Fix bug that made field specs like -k1.5 return a pointer into LINE beyond the first field. Rewrite to properly ignore trailing blanks. Replace unnecessary loop with if-else. (main): Don't decrement T2 corresponding to `x' in field specs like -ku.v,w.x.
-rw-r--r--src/sort.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/src/sort.c b/src/sort.c
index 30a5ecad9..40b668bc1 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -549,8 +549,10 @@ begfield (const struct line *line, const struct keyfield *key)
while (ptr < lim && blanks[UCHAR (*ptr)])
++ptr;
- while (ptr < lim && schar--)
- ++ptr;
+ if (ptr + schar <= lim)
+ ptr += schar;
+ else
+ ptr = lim;
return ptr;
}
@@ -563,13 +565,25 @@ limfield (const struct line *line, const struct keyfield *key)
{
register char *ptr = line->text, *lim = ptr + line->length;
register int eword = key->eword, echar = key->echar;
-
+ char *field_start;
+
+ /* Note: from the POSIX spec:
+ The leading field separator itself is included in
+ a field when -t is not used. */
+
+ /* Move PTR past EWORD fields or to one past the last byte on LINE,
+ whichever comes first. If there are more than EWORD fields, leave
+ PTR pointing at the beginning of the field having zero-based index,
+ EWORD. If a delimiter character was specified (via -t), then that
+ `beginning' is the first character following the delimiting TAB.
+ Otherwise, leave PTR pointing at the first `blank' character after
+ the preceding field. */
if (tab)
while (ptr < lim && eword--)
{
while (ptr < lim && *ptr != tab)
++ptr;
- if (ptr < lim && (eword || key->skipeblanks))
+ if (ptr < lim)
++ptr;
}
else
@@ -580,13 +594,39 @@ limfield (const struct line *line, const struct keyfield *key)
while (ptr < lim && !blanks[UCHAR (*ptr)])
++ptr;
}
+ /* Record beginning of field. */
+ field_start = ptr;
- if (key->skipeblanks)
- while (ptr < lim && blanks[UCHAR (*ptr)])
- ++ptr;
+ /* Make LIM point to the end of (one byte past) the current field. */
+ if (tab)
+ {
+ char *newlim;
+ newlim = memchr (ptr, tab, lim - ptr);
+ if (newlim)
+ lim = newlim;
+ }
+ else
+ {
+ char *newlim;
+ newlim = ptr;
+ while (newlim < lim && !blanks[UCHAR (*newlim)])
+ ++newlim;
+ lim = newlim;
+ }
+
+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */
+ if (ptr + echar <= lim)
+ ptr += echar;
+ else
+ ptr = lim;
- while (ptr < lim && echar--)
- ++ptr;
+ /* Back up over any trailing blanks, possibly back to the beginning
+ of the field. */
+ if (key->skipeblanks)
+ {
+ while (ptr > field_start && blanks[UCHAR (*(ptr - 1))])
+ --ptr;
+ }
return ptr;
}
@@ -1729,8 +1769,6 @@ main (int argc, char **argv)
{
for (++s; digits[UCHAR (*s)]; ++s)
t2 = t2 * 10 + *s - '0';
- if (t2)
- t2--;
}
else
{