version 1.30, 2018/10/23 08:41:45 |
version 1.31, 2018/11/06 13:51:28 |
|
|
*/ |
*/ |
|
|
#include <err.h> |
#include <err.h> |
|
#include <errno.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> |
|
|
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) |
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) |
|
|
|
|
int needsep; /* need separator character */ |
int needsep; /* need separator character */ |
int spans = 1; /* span multiple delimiters (-t) */ |
int spans = 1; /* span multiple delimiters (-t) */ |
char *empty; /* empty field replacement string (-e) */ |
char *empty; /* empty field replacement string (-e) */ |
char *tabchar = " \t"; /* delimiter characters (-t) */ |
wchar_t tabchar[] = L" \t"; /* delimiter characters (-t) */ |
|
|
int cmp(LINE *, u_long, LINE *, u_long); |
int cmp(LINE *, u_long, LINE *, u_long); |
void fieldarg(char *); |
void fieldarg(char *); |
void joinlines(INPUT *, INPUT *); |
void joinlines(INPUT *, INPUT *); |
|
char *mbssep(char **, const wchar_t *); |
void obsolete(char **); |
void obsolete(char **); |
void outfield(LINE *, u_long, int); |
void outfield(LINE *, u_long, int); |
void outoneline(INPUT *, LINE *); |
void outoneline(INPUT *, LINE *); |
|
|
int aflag, ch, cval, vflag; |
int aflag, ch, cval, vflag; |
char *end; |
char *end; |
|
|
|
setlocale(LC_CTYPE, ""); |
|
|
if (pledge("stdio rpath", NULL) == -1) |
if (pledge("stdio rpath", NULL) == -1) |
err(1, "pledge"); |
err(1, "pledge"); |
|
|
|
|
break; |
break; |
case 't': |
case 't': |
spans = 0; |
spans = 0; |
if (strlen(tabchar = optarg) != 1) |
if (mbtowc(tabchar, optarg, MB_CUR_MAX) != |
|
strlen(optarg)) |
errx(1, "illegal tab character specification"); |
errx(1, "illegal tab character specification"); |
|
tabchar[1] = L'\0'; |
break; |
break; |
case 'v': |
case 'v': |
vflag = 1; |
vflag = 1; |
|
|
/* Split the line into fields, allocate space as necessary. */ |
/* Split the line into fields, allocate space as necessary. */ |
lp->fieldcnt = 0; |
lp->fieldcnt = 0; |
bp = lp->line; |
bp = lp->line; |
while ((fieldp = strsep(&bp, tabchar)) != NULL) { |
while ((fieldp = mbssep(&bp, tabchar)) != NULL) { |
if (spans && *fieldp == '\0') |
if (spans && *fieldp == '\0') |
continue; |
continue; |
if (lp->fieldcnt == lp->fieldalloc) { |
if (lp->fieldcnt == lp->fieldalloc) { |
|
|
free(line); |
free(line); |
} |
} |
|
|
|
char * |
|
mbssep(char **stringp, const wchar_t *wcdelim) |
|
{ |
|
char *s, *p; |
|
size_t ndelim; |
|
int i; |
|
/* tabchar is never more than 2 */ |
|
char mbdelim[2][MB_LEN_MAX + 1]; |
|
size_t mblen[2]; |
|
|
|
if ((s = *stringp) == NULL) |
|
return NULL; |
|
ndelim = wcslen(wcdelim); |
|
for (i = 0; i < ndelim; i++) { |
|
/* wcdelim generated via mbtowc */ |
|
mblen[i] = wctomb(mbdelim[i], wcdelim[i]); |
|
} |
|
for (p = s; *p != '\0'; p++) { |
|
for (i = 0; i < ndelim; i++) { |
|
if (strncmp(p, mbdelim[i], mblen[i]) == 0) { |
|
*p = '\0'; |
|
*stringp = p + mblen[i]; |
|
return s; |
|
} |
|
} |
|
} |
|
*stringp = NULL; |
|
return s; |
|
} |
|
|
int |
int |
cmp(LINE *lp1, u_long fieldno1, LINE *lp2, u_long fieldno2) |
cmp(LINE *lp1, u_long fieldno1, LINE *lp2, u_long fieldno2) |
{ |
{ |
|
|
outfield(LINE *lp, u_long fieldno, int out_empty) |
outfield(LINE *lp, u_long fieldno, int out_empty) |
{ |
{ |
if (needsep++) |
if (needsep++) |
putchar((int)*tabchar); |
putwchar(*tabchar); |
if (!ferror(stdout)) { |
if (!ferror(stdout)) { |
if (lp->fieldcnt <= fieldno || out_empty) { |
if (lp->fieldcnt <= fieldno || out_empty) { |
if (empty != NULL) |
if (empty != NULL) |