version 1.24, 2016/08/31 20:43:57 |
version 1.25, 2016/09/04 20:33:36 |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
#include <limits.h> |
#include <limits.h> |
|
#include <locale.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <wchar.h> |
|
#include <wctype.h> |
|
|
void c_columnate(void); |
void c_columnate(void); |
void *ereallocarray(void *, size_t, size_t); |
void *ereallocarray(void *, size_t, size_t); |
|
|
int eval; /* exit value */ |
int eval; /* exit value */ |
int *maxwidths; /* longest record per column */ |
int *maxwidths; /* longest record per column */ |
struct field **table; /* one array of pointers per line */ |
struct field **table; /* one array of pointers per line */ |
char *separator = "\t "; /* field separator for table option */ |
wchar_t *separator = L"\t "; /* field separator for table option */ |
|
|
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
|
|
char *p; |
char *p; |
const char *errstr; |
const char *errstr; |
|
|
|
setlocale(LC_CTYPE, ""); |
|
|
termwidth = 0; |
termwidth = 0; |
if ((p = getenv("COLUMNS")) != NULL) |
if ((p = getenv("COLUMNS")) != NULL) |
termwidth = strtonum(p, 1, INT_MAX, NULL); |
termwidth = strtonum(p, 1, INT_MAX, NULL); |
|
|
errx(1, "%s: %s", errstr, optarg); |
errx(1, "%s: %s", errstr, optarg); |
break; |
break; |
case 's': |
case 's': |
separator = optarg; |
if ((separator = reallocarray(NULL, strlen(optarg) + 1, |
|
sizeof(*separator))) == NULL) |
|
err(1, NULL); |
|
if (mbstowcs(separator, optarg, strlen(optarg) + 1) == |
|
(size_t) -1) |
|
err(1, "sep"); |
break; |
break; |
case 't': |
case 't': |
tflag = 1; |
tflag = 1; |
|
|
} |
} |
|
|
if (!tflag) |
if (!tflag) |
separator = ""; |
separator = L""; |
argv += optind; |
argv += optind; |
|
|
if (*argv == NULL) { |
if (*argv == NULL) { |
|
|
static int maxentry = 0; |
static int maxentry = 0; |
static int maxcols = 0; |
static int maxcols = 0; |
static struct field *cols = NULL; |
static struct field *cols = NULL; |
int col, width; |
int col, width, twidth; |
size_t blen; |
size_t blen; |
ssize_t llen; |
ssize_t llen; |
char *p, *s, *buf = NULL; |
char *p, *s, *buf = NULL; |
|
wchar_t wc; |
|
int wlen; |
|
|
while ((llen = getline(&buf, &blen, fp)) > -1) { |
while ((llen = getline(&buf, &blen, fp)) > -1) { |
if (buf[llen - 1] == '\n') |
if (buf[llen - 1] == '\n') |
|
|
|
|
/* Skip lines containing nothing but whitespace. */ |
/* Skip lines containing nothing but whitespace. */ |
|
|
for (s = p; s != '\0'; s++) |
for (s = p; (wlen = mbtowc(&wc, s, MB_CUR_MAX)) > 0; |
if (!isspace((unsigned char)*s)) |
s += wlen) |
|
if (!iswspace(wc)) |
break; |
break; |
if (*s == '\0') |
if (*s == '\0') |
break; |
break; |
|
|
/* Skip leading, multiple, and trailing separators. */ |
/* Skip leading, multiple, and trailing separators. */ |
|
|
while (*p != '\0' && strchr(separator, *p) != NULL) |
while ((wlen = mbtowc(&wc, p, MB_CUR_MAX)) > 0 && |
p++; |
wcschr(separator, wc) != NULL) |
|
p += wlen; |
if (*p == '\0') |
if (*p == '\0') |
break; |
break; |
|
|
|
|
|
|
s = p; |
s = p; |
width = 0; |
width = 0; |
while (*p != '\0' && strchr(separator, *p) == NULL) { |
while (*p != '\0') { |
if (*p++ == '\t') |
if ((wlen = mbtowc(&wc, p, MB_CUR_MAX)) == -1) { |
INCR_NEXTTAB(width); |
|
else |
|
width++; |
width++; |
|
p++; |
|
continue; |
|
} |
|
if (wcschr(separator, wc) != NULL) |
|
break; |
|
if (*p == '\t') |
|
INCR_NEXTTAB(width); |
|
else { |
|
width += (twidth = wcwidth(wc)) == -1 ? |
|
1 : twidth; |
|
} |
|
p += wlen; |
} |
} |
|
|
if (col + 1 >= maxcols) { |
if (col + 1 >= maxcols) { |
|
|
cols[col].width = width; |
cols[col].width = width; |
if (maxwidths[col] < width) |
if (maxwidths[col] < width) |
maxwidths[col] = width; |
maxwidths[col] = width; |
if (*p != '\0') |
if (*p != '\0') { |
*p++ = '\0'; |
*p = '\0'; |
|
p += wlen; |
|
} |
if ((cols[col].content = strdup(s)) == NULL) |
if ((cols[col].content = strdup(s)) == NULL) |
err(1, NULL); |
err(1, NULL); |
} |
} |