Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/rs/rs.cc
Show All 35 Lines | |||||
*/ | */ | ||||
#include <err.h> | #include <err.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | |||||
#include <vector> | #include <vector> | ||||
static long flags; | static long flags; | ||||
#define TRANSPOSE 000001 | #define TRANSPOSE 000001 | ||||
#define MTRANSPOSE 000002 | #define MTRANSPOSE 000002 | ||||
#define ONEPERLINE 000004 | #define ONEPERLINE 000004 | ||||
#define ONEISEPONLY 000010 | #define ONEISEPONLY 000010 | ||||
#define ONEOSEPONLY 000020 | #define ONEOSEPONLY 000020 | ||||
#define NOTRIMENDCOL 000040 | #define NOTRIMENDCOL 000040 | ||||
#define SQUEEZE 000100 | #define SQUEEZE 000100 | ||||
#define SHAPEONLY 000200 | #define SHAPEONLY 000200 | ||||
#define DETAILSHAPE 000400 | #define DETAILSHAPE 000400 | ||||
#define RIGHTADJUST 001000 | #define RIGHTADJUST 001000 | ||||
#define NULLPAD 002000 | #define NULLPAD 002000 | ||||
#define RECYCLE 004000 | #define RECYCLE 004000 | ||||
#define SKIPPRINT 010000 | #define SKIPPRINT 010000 | ||||
#define ICOLBOUNDS 020000 | #define ICOLBOUNDS 020000 | ||||
#define OCOLBOUNDS 040000 | #define OCOLBOUNDS 040000 | ||||
#define ONEPERCHAR 0100000 | #define ONEPERCHAR 0100000 | ||||
#define NOARGS 0200000 | #define NOARGS 0200000 | ||||
static short *colwidths; | static short *colwidths; | ||||
static short *cord; | |||||
static short *icbd; | |||||
static short *ocbd; | |||||
static std::vector<char *> elem; | static std::vector<char *> elem; | ||||
static char *curline; | static char *curline; | ||||
static size_t curlen; | static size_t curlen; | ||||
static size_t irows, icols; | static size_t irows, icols; | ||||
static size_t orows = 0, ocols = 0; | static size_t orows = 0, ocols = 0; | ||||
static size_t maxlen; | static size_t maxlen; | ||||
static int skip; | static int skip; | ||||
static int propgutter; | static int propgutter; | ||||
static char isep = ' ', osep = ' '; | static char isep = ' ', osep = ' '; | ||||
static char blank[] = ""; | static char blank[] = ""; | ||||
static int owidth = 80, gutter = 2; | static size_t owidth = 80, gutter = 2; | ||||
static void getargs(int, char *[]); | static void getargs(int, char *[]); | ||||
static void getfile(void); | static void getfile(void); | ||||
static int get_line(void); | static int get_line(void); | ||||
static char *getlist(short **, char *); | static long getnum(const char *); | ||||
static char *getnum(int *, char *, int); | |||||
static void prepfile(void); | static void prepfile(void); | ||||
static void prints(char *, int); | static void prints(char *, int); | ||||
static void putfile(void); | static void putfile(void); | ||||
static void usage(void); | static void usage(void); | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
Show All 21 Lines | getfile(void) | ||||
while (skip--) { | while (skip--) { | ||||
c = get_line(); | c = get_line(); | ||||
if (flags & SKIPPRINT) | if (flags & SKIPPRINT) | ||||
puts(curline); | puts(curline); | ||||
if (c == EOF) | if (c == EOF) | ||||
return; | return; | ||||
} | } | ||||
get_line(); | get_line(); | ||||
if (flags & NOARGS && curlen < (size_t)owidth) | if (flags & NOARGS && curlen < owidth) | ||||
flags |= ONEPERLINE; | flags |= ONEPERLINE; | ||||
if (flags & ONEPERLINE) | if (flags & ONEPERLINE) | ||||
icols = 1; | icols = 1; | ||||
else /* count cols on first line */ | else /* count cols on first line */ | ||||
for (p = curline, endp = curline + curlen; p < endp; p++) { | for (p = curline, endp = curline + curlen; p < endp; p++) { | ||||
if (*p == isep && multisep) | if (*p == isep && multisep) | ||||
continue; | continue; | ||||
icols++; | icols++; | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | prepfile(void) | ||||
colw = maxlen + gutter; | colw = maxlen + gutter; | ||||
if (flags & MTRANSPOSE) { | if (flags & MTRANSPOSE) { | ||||
orows = icols; | orows = icols; | ||||
ocols = irows; | ocols = irows; | ||||
} | } | ||||
else if (orows == 0 && ocols == 0) { /* decide rows and cols */ | else if (orows == 0 && ocols == 0) { /* decide rows and cols */ | ||||
ocols = owidth / colw; | ocols = owidth / colw; | ||||
if (ocols == 0) { | if (ocols == 0) { | ||||
warnx("display width %d is less than column width %zu", | warnx("display width %zu is less than column width %zu", | ||||
owidth, colw); | owidth, colw); | ||||
ocols = 1; | ocols = 1; | ||||
} | } | ||||
if (ocols > elem.size()) | if (ocols > elem.size()) | ||||
ocols = elem.size(); | ocols = elem.size(); | ||||
orows = elem.size() / ocols + (elem.size() % ocols ? 1 : 0); | orows = elem.size() / ocols + (elem.size() % ocols ? 1 : 0); | ||||
} | } | ||||
else if (orows == 0) /* decide on rows */ | else if (orows == 0) /* decide on rows */ | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | get_line(void) /* get line; maintain curline, curlen; manage storage */ | ||||
curlen = i; | curlen = i; | ||||
return(c); | return(c); | ||||
} | } | ||||
static void | static void | ||||
getargs(int ac, char *av[]) | getargs(int ac, char *av[]) | ||||
{ | { | ||||
long val; | long val; | ||||
char *p; | int ch; | ||||
if (ac == 1) { | if (ac == 1) { | ||||
flags |= NOARGS | TRANSPOSE; | flags |= NOARGS | TRANSPOSE; | ||||
} | } | ||||
while (--ac && **++av == '-') | |||||
for (p = *av+1; *p; p++) | while ((ch = getopt(ac, av, "C::EG:HK:S::Tc::eg:hjk:mns::tw:yz")) != -1) | ||||
switch (*p) { | switch (ch) { | ||||
case 'T': | case 'T': | ||||
flags |= MTRANSPOSE; | flags |= MTRANSPOSE; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 't': | case 't': | ||||
flags |= TRANSPOSE; | flags |= TRANSPOSE; | ||||
break; | break; | ||||
case 'c': /* input col. separator */ | case 'c': /* input col. separator */ | ||||
flags |= ONEISEPONLY; | flags |= ONEISEPONLY; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 's': /* one or more allowed */ | case 's': /* one or more allowed */ | ||||
if (p[1]) | if (optarg != NULL) | ||||
isep = *++p; | isep = *optarg; | ||||
else | else | ||||
isep = '\t'; /* default is ^I */ | isep = '\t'; /* default is ^I */ | ||||
break; | break; | ||||
case 'C': | case 'C': | ||||
flags |= ONEOSEPONLY; | flags |= ONEOSEPONLY; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 'S': | case 'S': | ||||
if (p[1]) | if (optarg != NULL) | ||||
osep = *++p; | osep = *optarg; | ||||
else | else | ||||
osep = '\t'; /* default is ^I */ | osep = '\t'; /* default is ^I */ | ||||
break; | break; | ||||
case 'w': /* window width, default 80 */ | case 'w': /* window width, default 80 */ | ||||
p = getnum(&owidth, p, 0); | val = getnum(optarg); | ||||
if (owidth <= 0) | if (val <= 0) | ||||
errx(1, "width must be a positive integer"); | errx(1, "width must be a positive integer"); | ||||
owidth = val; | |||||
break; | break; | ||||
case 'K': /* skip N lines */ | case 'K': /* skip N lines */ | ||||
flags |= SKIPPRINT; | flags |= SKIPPRINT; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 'k': /* skip, do not print */ | case 'k': /* skip, do not print */ | ||||
p = getnum(&skip, p, 0); | skip = getnum(optarg); | ||||
if (!skip) | if (skip < 1) | ||||
skip = 1; | skip = 1; | ||||
break; | break; | ||||
case 'm': | case 'm': | ||||
flags |= NOTRIMENDCOL; | flags |= NOTRIMENDCOL; | ||||
break; | break; | ||||
case 'g': /* gutter space */ | case 'g': /* gutter space */ | ||||
p = getnum(&gutter, p, 0); | gutter = getnum(optarg); | ||||
break; | break; | ||||
case 'G': | case 'G': | ||||
p = getnum(&propgutter, p, 0); | propgutter = getnum(optarg); | ||||
break; | break; | ||||
case 'e': /* each line is an entry */ | case 'e': /* each line is an entry */ | ||||
flags |= ONEPERLINE; | flags |= ONEPERLINE; | ||||
break; | break; | ||||
case 'E': | case 'E': | ||||
flags |= ONEPERCHAR; | flags |= ONEPERCHAR; | ||||
break; | break; | ||||
case 'j': /* right adjust */ | case 'j': /* right adjust */ | ||||
flags |= RIGHTADJUST; | flags |= RIGHTADJUST; | ||||
break; | break; | ||||
case 'n': /* null padding for missing values */ | case 'n': /* null padding for missing values */ | ||||
flags |= NULLPAD; | flags |= NULLPAD; | ||||
break; | break; | ||||
case 'y': | case 'y': | ||||
flags |= RECYCLE; | flags |= RECYCLE; | ||||
break; | break; | ||||
case 'H': /* print shape only */ | case 'H': /* print shape only */ | ||||
flags |= DETAILSHAPE; | flags |= DETAILSHAPE; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 'h': | case 'h': | ||||
flags |= SHAPEONLY; | flags |= SHAPEONLY; | ||||
break; | break; | ||||
case 'z': /* squeeze col width */ | case 'z': /* squeeze col width */ | ||||
flags |= SQUEEZE; | flags |= SQUEEZE; | ||||
break; | break; | ||||
/*case 'p': | /*case 'p': | ||||
ipagespace = atoi(++p); (default is 1) | ipagespace = atoi(optarg); (default is 1) | ||||
break;*/ | break;*/ | ||||
case 'o': /* col order */ | |||||
p = getlist(&cord, p); | |||||
break; | |||||
case 'b': | |||||
flags |= ICOLBOUNDS; | |||||
p = getlist(&icbd, p); | |||||
break; | |||||
case 'B': | |||||
flags |= OCOLBOUNDS; | |||||
p = getlist(&ocbd, p); | |||||
break; | |||||
brooks: It looks like these are dead code? | |||||
Done Inline ActionsYes, sorry. These options are not documented in the manpage and nothing uses the cord, icbd, or ocbd variables. jhb: Yes, sorry. These options are not documented in the manpage and nothing uses the `cord`… | |||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
av += optind; | |||||
ac -= optind; | |||||
/*if (!osep) | /*if (!osep) | ||||
osep = isep;*/ | osep = isep;*/ | ||||
switch (ac) { | switch (ac) { | ||||
#if 0 | #if 0 | ||||
case 3: | case 3: | ||||
opages = atoi(av[2]); | opages = atoi(av[2]); | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
#endif | #endif | ||||
Show All 9 Lines | case 1: | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 0: | case 0: | ||||
break; | break; | ||||
default: | default: | ||||
errx(1, "too many arguments"); | errx(1, "too many arguments"); | ||||
} | } | ||||
} | } | ||||
static char * | static long | ||||
getlist(short **list, char *p) | getnum(const char *p) | ||||
{ | { | ||||
int count = 1; | char *ep; | ||||
char *t; | long val; | ||||
for (t = p + 1; *t; t++) { | val = strtol(p, &ep, 10); | ||||
if (!isdigit((unsigned char)*t)) | if (*ep != '\0') | ||||
errx(1, | errx(1, "invalid integer %s", p); | ||||
"option %.1s requires a list of unsigned numbers separated by commas", t); | return (val); | ||||
count++; | |||||
while (*t && isdigit((unsigned char)*t)) | |||||
t++; | |||||
if (*t != ',') | |||||
break; | |||||
} | |||||
if (!(*list = (short *) malloc(count * sizeof(short)))) | |||||
errx(1, "no list space"); | |||||
count = 0; | |||||
for (t = p + 1; *t; t++) { | |||||
(*list)[count++] = atoi(t); | |||||
printf("++ %d ", (*list)[count-1]); | |||||
fflush(stdout); | |||||
while (*t && isdigit((unsigned char)*t)) | |||||
t++; | |||||
if (*t != ',') | |||||
break; | |||||
} | |||||
(*list)[count] = 0; | |||||
return(t - 1); | |||||
} | |||||
/* | |||||
* num = number p points to; if (strict) complain | |||||
* returns pointer to end of num | |||||
*/ | |||||
static char * | |||||
getnum(int *num, char *p, int strict) | |||||
{ | |||||
char *t = p; | |||||
if (!isdigit((unsigned char)*++t)) { | |||||
if (strict || *t == '-' || *t == '+') | |||||
errx(1, "option %.1s requires an unsigned integer", p); | |||||
*num = 0; | |||||
return(p); | |||||
} | |||||
*num = atoi(t); | |||||
while (*++t) | |||||
if (!isdigit((unsigned char)*t)) | |||||
break; | |||||
return(--t); | |||||
} | } |
It looks like these are dead code?