[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
patch: textutils-2.1/src/join.c: support field ranges with `-o'
From: |
Toomas Rosin |
Subject: |
patch: textutils-2.1/src/join.c: support field ranges with `-o' |
Date: |
Sun Sep 15 16:56:03 2002 |
Hello!
I have a script that does, at one point, something like this:
join -a1 -a2 -e- -13 -26 \
-o 1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11 \
-o 2.1,2.2,2.3,2.4,2.5,2.6,2.7 \
file1 file2
(horrors!). The appended patch makes it possible to do the same thing
as follows:
join -a1 -a2 -e- -13 -26 -o1.1-11,2.1-7 file1 file2
. I am not very sure that my patch has no bugs, but the patched
`join' has already worked correctly for me in several situations, and
it passes "make check". It also differs from the original `join' in
that it tolerates redundant field separator characters ([, \t]).
(This could be reverted by rewriting the check for "*q == '\0'" (line
658 in the patched join.c).)
As `cut' recognizes field ranges, should `join' not?
Have a nice day,
Toomas.
--- textutils-2.1/src/join.c.orig Tue Jul 2 07:15:06 2002
+++ textutils-2.1/src/join.c Sun Sep 15 22:48:17 2002
@@ -615,63 +615,7 @@
/* Add to the end of the list so the fields are in the right order. */
outlist_end->next = o;
outlist_end = o;
-}
-
-/* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
- pair. In S, the field index string is 1-based; *FIELD_INDEX is zero-based.
- If S is valid, return zero. Otherwise, give a diagnostic, don't update
- *FILE_INDEX or *FIELD_INDEX, and return nonzero. */
-
-static int
-decode_field_spec (const char *s, int *file_index, int *field_index)
-{
- int invalid = 1;
-
- /* The first character must be 0, 1, or 2. */
- switch (s[0])
- {
- case '0':
- if (s[1] == '\0')
- {
- *file_index = 0;
- /* Give *field_index an invalid value. */
- *field_index = -1;
- invalid = 0;
- }
- else
- {
- /* `0' must be all alone -- no `.FIELD'. */
- error (0, 0, _("invalid field specifier: `%s'"), s);
- }
- break;
-
- case '1':
- case '2':
- if (s[1] == '.' && s[2] != '\0')
- {
- strtol_error s_err;
- long int tmp_long;
-
- s_err = xstrtol (s + 2, NULL, 10, &tmp_long, "");
- if (s_err != LONGINT_OK || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (0, 0, _("invalid field number: `%s'"), s + 2);
- }
- else
- {
- *file_index = s[0] - '0';
- /* Convert to a zero-based index. */
- *field_index = (int) tmp_long - 1;
- invalid = 0;
- }
- }
- break;
-
- default:
- error (0, 0, _("invalid file number in field spec: `%s'"), s);
- break;
- }
- return invalid;
+ uni_blank.nfields = max (uni_blank.nfields, field);
}
/* Add the comma or blank separated field spec(s) in STR to `outlist'.
@@ -686,23 +630,84 @@
str = (char *) alloca (strlen (c_str) + 1);
strcpy (str, c_str);
+#define FIELDSPEC_ASSERT(condition) \
+ do \
+ { \
+ if (condition) \
+ break; \
+ error (0, 0, _("invalid field specifier: `%s'"), \
+ spec_item); \
+ return 1; \
+ } \
+ while (0)
+
p = str;
do
{
- int invalid;
int file_index, field_index;
- char *spec_item = p;
-
+ char *spec_item, *q;
+ strtol_error s_err;
+ long lo, hi;
+
+ lo = hi = 0;
+ q = spec_item = p;
p = strpbrk (p, ", \t");
if (p)
*p++ = 0;
- invalid = decode_field_spec (spec_item, &file_index, &field_index);
- if (invalid)
- return 1;
- add_field (file_index, field_index);
- uni_blank.nfields = max (uni_blank.nfields, field_index);
+
+ if (*q == '\0')
+ {
+ /* Redundant separator. */
+ continue;
+ }
+
+ if (*q == '0')
+ {
+ add_field (0, -1);
+ /* `0' must be all alone -- no `.FIELD'. */
+ FIELDSPEC_ASSERT (*++q == 0);
+ continue;
+ }
+
+ FIELDSPEC_ASSERT ((*q == '1') || (*q == '2'));
+ file_index = *q - '0';
+ FIELDSPEC_ASSERT (*++q == '.');
+
+ FIELDSPEC_ASSERT (isdigit (*++q));
+ s_err = xstrtol (q, &q, 10, &lo, NULL);
+ FIELDSPEC_ASSERT ((s_err == LONGINT_OK) &&
+ (lo > 0) &&
+ (lo <= INT_MAX));
+
+ if (*q == '\0')
+ {
+ /* A single field. */
+ add_field (file_index, lo - 1);
+ continue;
+ }
+
+ FIELDSPEC_ASSERT (*q == '-');
+ FIELDSPEC_ASSERT (isdigit (*++q));
+
+ /* Field range. */
+ s_err = xstrtol (q, &q, 10, &hi, "");
+ FIELDSPEC_ASSERT ((s_err == LONGINT_OK) &&
+ (hi >= lo) &&
+ (hi <= INT_MAX) &&
+ (*q == 0));
+
+ /* Convert to a zero-based index. */
+ hi--, lo--;
+
+ for (; lo <= hi; lo ++)
+ {
+ add_field (file_index, lo);
+ }
}
while (p);
+
+#undef FIELDSPEC_ASSERT
+
return 0;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- patch: textutils-2.1/src/join.c: support field ranges with `-o',
Toomas Rosin <=