Support NUL-containing lines in cols(1)

This required an architectural change in getlines() by also storing
the line length.
This commit is contained in:
FRIGN 2016-02-29 00:45:53 +01:00 committed by sin
parent 2d7d2261a0
commit e4810f1cdb
4 changed files with 24 additions and 14 deletions

2
README
View File

@ -21,7 +21,7 @@ The following tools are implemented:
0=*|x chroot . 0=*|x chroot .
0=*|o cksum . 0=*|o cksum .
0=*|o cmp . 0=*|o cmp .
#*|x cols . 0#*|x cols .
=*|o comm . =*|o comm .
0=*|o cp (-i) 0=*|o cp (-i)
0=*|x cron . 0=*|x cron .

18
cols.c
View File

@ -24,7 +24,7 @@ main(int argc, char *argv[])
FILE *fp; FILE *fp;
struct winsize w; struct winsize w;
struct linebuf b = EMPTY_LINEBUF; struct linebuf b = EMPTY_LINEBUF;
size_t chars = 65, maxlen = 0, i, j, k, len, bytes, cols, rows; size_t chars = 65, maxlen = 0, i, j, k, len, cols, rows;
int cflag = 0, ret = 0; int cflag = 0, ret = 0;
char *p; char *p;
@ -63,10 +63,11 @@ main(int argc, char *argv[])
} }
for (i = 0; i < b.nlines; i++) { for (i = 0; i < b.nlines; i++) {
len = utflen(b.lines[i]); /* TODO: fix libutf to run utflen on a memory chunk
bytes = strlen(b.lines[i]); * of given size to also handle embedded NULs */
if (len && bytes && b.lines[i][bytes - 1] == '\n') { len = utflen(b.lines[i].data);
b.lines[i][bytes - 1] = '\0'; if (len && b.lines[i].data[b.lines[i].len - 1] == '\n') {
b.lines[i].data[--(b.lines[i].len)] = '\0';
len--; len--;
} }
if (len > maxlen) if (len > maxlen)
@ -78,8 +79,11 @@ main(int argc, char *argv[])
for (i = 0; i < rows; i++) { for (i = 0; i < rows; i++) {
for (j = 0; j < cols && i + j * rows < b.nlines; j++) { for (j = 0; j < cols && i + j * rows < b.nlines; j++) {
len = utflen(b.lines[i + j * rows]); /* TODO: fix libutf to run utflen on a memory chunk
fputs(b.lines[i + j * rows], stdout); * of given size to also handle embedded NULs */
len = utflen(b.lines[i + j * rows].data);
fwrite(b.lines[i + j * rows].data, 1,
b.lines[i + j * rows].len, stdout);
if (j < cols - 1) if (j < cols - 1)
for (k = len; k < maxlen + 1; k++) for (k = len; k < maxlen + 1; k++)
putchar(' '); putchar(' ');

View File

@ -19,12 +19,13 @@ getlines(FILE *fp, struct linebuf *b)
b->lines = erealloc(b->lines, b->capacity * sizeof(*b->lines)); b->lines = erealloc(b->lines, b->capacity * sizeof(*b->lines));
} }
linelen = len; linelen = len;
b->lines[b->nlines - 1] = memcpy(emalloc(linelen + 1), line, linelen + 1); b->lines[b->nlines - 1].data = memcpy(emalloc(linelen + 1), line, linelen + 1);
b->lines[b->nlines - 1].len = linelen;
} }
free(line); free(line);
if (b->lines && b->nlines && linelen && b->lines[b->nlines - 1][linelen - 1] != '\n') { if (b->lines && b->nlines && linelen && b->lines[b->nlines - 1].data[linelen - 1] != '\n') {
b->lines[b->nlines - 1] = erealloc(b->lines[b->nlines - 1], linelen + 2); b->lines[b->nlines - 1].data = erealloc(b->lines[b->nlines - 1].data, linelen + 2);
b->lines[b->nlines - 1][linelen] = '\n'; b->lines[b->nlines - 1].data[linelen] = '\n';
b->lines[b->nlines - 1][linelen + 1] = '\0'; b->lines[b->nlines - 1].data[linelen + 1] = '\0';
} }
} }

7
text.h
View File

@ -1,7 +1,12 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
struct linebufline {
char *data;
size_t len;
};
struct linebuf { struct linebuf {
char **lines; struct linebufline *lines;
size_t nlines; size_t nlines;
size_t capacity; size_t capacity;
}; };