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:
parent
2d7d2261a0
commit
e4810f1cdb
2
README
2
README
|
@ -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
18
cols.c
|
@ -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(' ');
|
||||||
|
|
|
@ -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
7
text.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user