All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sami Kerola <kerolasa@iki.fi>
To: util-linux@vger.kernel.org
Cc: kerolasa@iki.fi
Subject: [PATCH] column: make defined separator to be non-greedy
Date: Wed, 26 Sep 2012 21:45:36 +0100	[thread overview]
Message-ID: <1348692336-21301-1-git-send-email-kerolasa@iki.fi> (raw)

This patch changes interpretation of subsequent delimeter interpretation.
Earlier version merged columns that had null string as content together,
which lead to output as visualized below.

$ printf "a:b:c\n1::3\n" | column  -t -s ':'
a  b  c
1  3

The number 3 has wrong column, which this patch takes care of, and alters
the output following way.

$ printf "a:b:c\n1::3\n" | column  -t -s ':'
a  b  c
1     3

This patch does not alter the default case, e.g., subsequent white spaces
are understood as separator of the same field, and the beginning of line
white spaces are being ignored together.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 text-utils/column.c | 37 ++++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/text-utils/column.c b/text-utils/column.c
index 61668fd..7eea66a 100644
--- a/text-utils/column.c
+++ b/text-utils/column.c
@@ -75,7 +75,8 @@ static char *mtsafe_strtok(char *, const char *, char **);
 static int input(FILE *fp, int *maxlength, wchar_t ***list, int *entries);
 static void c_columnate(int maxlength, long termwidth, wchar_t **list, int entries);
 static void r_columnate(int maxlength, long termwidth, wchar_t **list, int entries);
-static void maketbl(wchar_t **list, int entries, wchar_t *separator);
+static wchar_t *local_wcstok(wchar_t *p, const wchar_t *separator, int greedy, wchar_t **wcstok_state);
+static void maketbl(wchar_t **list, int entries, wchar_t *separator, int greedy);
 static void print(wchar_t **list, int entries);
 
 typedef struct _tbl {
@@ -112,6 +113,7 @@ int main(int argc, char **argv)
 	unsigned int eval = 0;		/* exit value */
 	int maxlength = 0;		/* longest record */
 	wchar_t **list = NULL;		/* array of pointers to records */
+	int greedy = 1;
 
 	/* field separator for table option */
 	wchar_t default_separator[] = { '\t', ' ', 0 };
@@ -151,6 +153,7 @@ int main(int argc, char **argv)
 			break;
 		case 's':
 			separator = mbs_to_wcs(optarg);
+			greedy = 0;
 			break;
 		case 't':
 			tflag = 1;
@@ -183,7 +186,7 @@ int main(int argc, char **argv)
 		exit(eval);
 
 	if (tflag)
-		maketbl(list, entries, separator);
+		maketbl(list, entries, separator, greedy);
 	else if (maxlength >= termwidth)
 		print(list, entries);
 	else if (xflag)
@@ -270,7 +273,31 @@ static void print(wchar_t **list, int entries)
 	}
 }
 
-static void maketbl(wchar_t **list, int entries, wchar_t *separator)
+wchar_t *local_wcstok(wchar_t * p, const wchar_t * separator, int greedy,
+		      wchar_t ** wcstok_state)
+{
+	wchar_t *result;
+	if (greedy)
+		return wcstok(p, separator, wcstok_state);
+
+	if (p == NULL) {
+		if (*wcstok_state == NULL)
+			return NULL;
+		else
+			p = *wcstok_state;
+	}
+	result = p;
+	p = wcspbrk(result, separator);
+	if (p == NULL)
+		*wcstok_state = NULL;
+	else {
+		*p = '\0';
+		*wcstok_state = p + 1;
+	}
+	return result;
+}
+
+static void maketbl(wchar_t **list, int entries, wchar_t *separator, int greedy)
 {
 	TBL *t;
 	int cnt, i;
@@ -279,7 +306,7 @@ static void maketbl(wchar_t **list, int entries, wchar_t *separator)
 	ssize_t maxcols = DEFCOLS, coloff;
 	TBL *tbl;
 	wchar_t **cols;
-	wchar_t *wcstok_state;
+	wchar_t *wcstok_state = NULL;
 
 	t = tbl = xcalloc(entries, sizeof(TBL));
 	cols = xcalloc(maxcols, sizeof(wchar_t *));
@@ -288,7 +315,7 @@ static void maketbl(wchar_t **list, int entries, wchar_t *separator)
 	for (lp = list, cnt = 0; cnt < entries; ++cnt, ++lp, ++t) {
 		coloff = 0;
 		p = *lp;
-		while ((cols[coloff] = wcstok(p, separator, &wcstok_state)) != NULL) {
+		while ((cols[coloff] = local_wcstok(p, separator, greedy, &wcstok_state)) != NULL) {
 			if (++coloff == maxcols) {
 				maxcols += DEFCOLS;
 				cols = xrealloc(cols, maxcols * sizeof(wchar_t *));
-- 
1.7.12.1


             reply	other threads:[~2012-09-26 20:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-26 20:45 Sami Kerola [this message]
2012-09-26 21:01 ` [PATCH] column: make defined separator to be non-greedy Pádraig Brady
2012-09-29  9:21 ` [PATCH] docs: column.1 describe change of separator behavior in bugs section Sami Kerola
2012-09-29 10:23   ` Pádraig Brady
2012-09-29 12:49     ` Sami Kerola
2012-10-02  8:45     ` Karel Zak
2012-10-02  8:29 ` [PATCH] column: make defined separator to be non-greedy Karel Zak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1348692336-21301-1-git-send-email-kerolasa@iki.fi \
    --to=kerolasa@iki.fi \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.