From 12bef81286755cafa14cfd59a9a707199e576c0f Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:08:08 +0200 Subject: column.c: replace emalloc with xcalloc Signed-off-by: Sami Kerola --- text-utils/column.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index ffc91df65..d8c715db2 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -71,7 +71,6 @@ static char *mtsafe_strtok(char *, const char *, char **); #define MAXLINELEN (LINE_MAX + 1) static void c_columnate __P((void)); -static void *emalloc __P((int)); static void input __P((FILE *)); static void maketbl __P((void)); static void print __P((void)); @@ -270,14 +269,14 @@ maketbl() TBL *t; int coloff, cnt, i; wchar_t *p, **lp; - int *lens, maxcols; + int *lens, maxcols = DEFCOLS; TBL *tbl; wchar_t **cols; wchar_t *wcstok_state; - t = tbl = emalloc(entries * sizeof(TBL)); - cols = emalloc((maxcols = DEFCOLS) * sizeof(wchar_t *)); - lens = emalloc(maxcols * sizeof(int)); + t = tbl = xcalloc(entries, sizeof(TBL)); + cols = xcalloc(maxcols, sizeof(wchar_t *)); + lens = xcalloc(maxcols, sizeof(int)); for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { for (coloff = 0, p = *lp; (cols[coloff] = wcstok(p, separator, &wcstok_state)) != NULL; @@ -292,8 +291,8 @@ maketbl() maxcols += DEFCOLS; } } - t->list = emalloc(coloff * sizeof(wchar_t *)); - t->len = emalloc(coloff * sizeof(int)); + t->list = xcalloc(coloff, sizeof(wchar_t *)); + t->len = xcalloc(coloff, sizeof(int)); for (t->cols = coloff; --coloff >= 0;) { t->list[coloff] = cols[coloff]; t->len[coloff] = wcs_width(cols[coloff]); @@ -318,12 +317,12 @@ static void input(fp) FILE *fp; { - static int maxentry; + static int maxentry = DEFNUM; int len, lineno = 1, reportedline = 0; wchar_t *p, buf[MAXLINELEN]; if (!list) - list = emalloc((maxentry = DEFNUM) * sizeof(wchar_t *)); + list = xcalloc(maxentry, sizeof(wchar_t *)); while (fgetws(buf, MAXLINELEN, fp)) { for (p = buf; *p && iswspace(*p); ++p); if (!*p) @@ -393,14 +392,3 @@ static char *mtsafe_strtok(char *str, const char *delim, char **ptr) } } #endif - -static void * -emalloc(size) - int size; -{ - char *p; - - p = xmalloc(size); - memset(p, 0, size); - return (p); -} -- cgit v1.2.3-55-g7522 From 4ef21375ecdc47244052f1294faa01aa29666066 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:09:54 +0200 Subject: column.c: add version printing The patch makes return value to be non-zero when command line short option is unknown. Signed-off-by: Sami Kerola --- text-utils/column.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index d8c715db2..03679a87f 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -93,6 +93,7 @@ wchar_t *separator = default_separator; /* field separator for table option */ static const struct option longopts[] = { { "help", 0, 0, 'h' }, + { "version", 0, 0, 'V' }, { "columns", 0, 0, 'c' }, { "table", 0, 0, 't' }, { "separator", 0, 0, 's' }, @@ -110,6 +111,7 @@ static void __attribute__((__noreturn__)) usage(int rc) fprintf(out, _( " -h, --help displays this help text\n" + " -V, --version output version information and exit\n" " -c, --columns width of output in number of characters\n" " -t, --table create a table\n" " -s, --separator table delimeter\n" @@ -137,12 +139,15 @@ main(int argc, char **argv) termwidth = win.ws_col; tflag = xflag = 0; - while ((ch = getopt_long(argc, argv, "h?c:s:tx", longopts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "hVc:s:tx", longopts, NULL)) != -1) switch(ch) { case 'h': - case '?': usage(EXIT_SUCCESS); break; + case 'V': + printf(_("%s from %s\n"), program_invocation_short_name, + PACKAGE_STRING); + return(EXIT_SUCCESS); case 'c': termwidth = atoi(optarg); break; -- cgit v1.2.3-55-g7522 From 1df29104d02581880a96ffd5ee735138bfefd02a Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:15:21 +0200 Subject: column.c: coding style fixes Signed-off-by: Sami Kerola --- text-utils/column.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index 03679a87f..77dabd2d5 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -70,11 +70,11 @@ static char *mtsafe_strtok(char *, const char *, char **); #define DEFNUM 1000 #define MAXLINELEN (LINE_MAX + 1) -static void c_columnate __P((void)); -static void input __P((FILE *)); -static void maketbl __P((void)); -static void print __P((void)); -static void r_columnate __P((void)); +static void c_columnate(void); +static void input(FILE *); +static void maketbl(void); +static void print(void); +static void r_columnate(void); typedef struct _tbl { wchar_t **list; @@ -120,8 +120,8 @@ static void __attribute__((__noreturn__)) usage(int rc) fprintf(out, _("\nFor more information see column(1).\n")); exit(rc); } -int -main(int argc, char **argv) + +int main(int argc, char **argv) { struct winsize win; FILE *fp; @@ -132,7 +132,7 @@ main(int argc, char **argv) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) { + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1 || !win.ws_col) { if ((p = getenv("COLUMNS")) != NULL) termwidth = atoi(p); } else @@ -162,13 +162,13 @@ main(int argc, char **argv) break; default: usage(EXIT_FAILURE); - } + } argc -= optind; argv += optind; if (!*argv) input(stdin); - else { + else for (; *argv; ++argv) { if ((fp = fopen(*argv, "r")) != NULL) { input(fp); @@ -178,7 +178,6 @@ main(int argc, char **argv) eval = EXIT_FAILURE; } } - } if (!entries) exit(eval); @@ -196,8 +195,7 @@ main(int argc, char **argv) exit(eval); } -static void -c_columnate() +static void c_columnate() { int chcnt, col, cnt, endcol, numcols; wchar_t **lp; @@ -226,8 +224,7 @@ c_columnate() putwchar('\n'); } -static void -r_columnate() +static void r_columnate() { int base, chcnt, cnt, col, endcol, numcols, numrows, row; @@ -256,8 +253,7 @@ r_columnate() } } -static void -print() +static void print() { int cnt; wchar_t **lp; @@ -268,8 +264,7 @@ print() } } -static void -maketbl() +static void maketbl() { TBL *t; int coloff, cnt, i; @@ -318,9 +313,7 @@ maketbl() } } -static void -input(fp) - FILE *fp; +static void input(FILE *fp) { static int maxentry = DEFNUM; int len, lineno = 1, reportedline = 0; @@ -329,7 +322,8 @@ input(fp) if (!list) list = xcalloc(maxentry, sizeof(wchar_t *)); while (fgetws(buf, MAXLINELEN, fp)) { - for (p = buf; *p && iswspace(*p); ++p); + for (p = buf; *p && iswspace(*p); ++p) + ; if (!*p) continue; if (!(p = wcschr(p, '\n')) && !feof(fp)) { -- cgit v1.2.3-55-g7522 From 4eaeb0ef25ea00be23457a452f497307ea8291f4 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:16:29 +0200 Subject: column.c: make table function clarification Readability enchancement, and few variable type changes to be more proper. Signed-off-by: Sami Kerola --- text-utils/column.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index 77dabd2d5..984b0ef5b 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -267,29 +267,31 @@ static void print() static void maketbl() { TBL *t; - int coloff, cnt, i; + int cnt, i; wchar_t *p, **lp; - int *lens, maxcols = DEFCOLS; + ssize_t *lens; + ssize_t maxcols = DEFCOLS, coloff; TBL *tbl; wchar_t **cols; wchar_t *wcstok_state; t = tbl = xcalloc(entries, sizeof(TBL)); cols = xcalloc(maxcols, sizeof(wchar_t *)); - lens = xcalloc(maxcols, sizeof(int)); - for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { - for (coloff = 0, p = *lp; - (cols[coloff] = wcstok(p, separator, &wcstok_state)) != NULL; - p = NULL) { + lens = xcalloc(maxcols, sizeof(ssize_t)); + + for (lp = list, cnt = 0; cnt < entries; ++cnt, ++lp, ++t) { + coloff = 0; + p = *lp; + while ((cols[coloff] = wcstok(p, separator, &wcstok_state)) != NULL) { if (++coloff == maxcols) { - cols = xrealloc(cols, ((u_int)maxcols + DEFCOLS) - * sizeof(wchar_t *)); - lens = xrealloc(lens, ((u_int)maxcols + DEFCOLS) - * sizeof(int)); - memset((char *)lens + maxcols * sizeof(int), - 0, DEFCOLS * sizeof(int)); maxcols += DEFCOLS; + cols = xrealloc(cols, maxcols * sizeof(wchar_t *)); + lens = xrealloc(lens, maxcols * sizeof(ssize_t)); + /* zero fill only new memory */ + memset(lens + ((maxcols - DEFCOLS) * sizeof(ssize_t)), 0, + DEFCOLS * sizeof(int)); } + p = NULL; } t->list = xcalloc(coloff, sizeof(wchar_t *)); t->len = xcalloc(coloff, sizeof(int)); @@ -300,7 +302,8 @@ static void maketbl() lens[coloff] = t->len[coloff]; } } - for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) { + + for (t = tbl, cnt = 0; cnt < entries; ++cnt, ++t) { for (coloff = 0; coloff < t->cols - 1; ++coloff) { fputws(t->list[coloff], stdout); for (i = lens[coloff] - t->len[coloff] + 2; i > 0; i--) -- cgit v1.2.3-55-g7522 From dcbca568f72db12701519d0b060242610c12334e Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:20:25 +0200 Subject: column.c: free memory before exit Signed-off-by: Sami Kerola --- text-utils/column.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index 984b0ef5b..6b797d340 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -190,6 +190,11 @@ int main(int argc, char **argv) c_columnate(); else r_columnate(); + + for (int i = 0; i < entries; i++) + free(list[i]); + free(list); + if (ferror(stdout) || fclose(stdout)) eval = EXIT_FAILURE; exit(eval); @@ -314,6 +319,14 @@ static void maketbl() putwchar('\n'); } } + + for (cnt = 0; cnt < entries; ++cnt) { + free((tbl+cnt)->list); + free((tbl+cnt)->len); + } + free(cols); + free(lens); + free(tbl); } static void input(FILE *fp) -- cgit v1.2.3-55-g7522 From 02b77f7b2b8d8d5337ef3d8b2cb232cae27c5cfc Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:24:47 +0200 Subject: column.c: validate numeric user inputs Use strtol_or_err from strutils.h to check numeric user input is sane. Signed-off-by: Sami Kerola --- text-utils/Makefile.am | 2 ++ text-utils/column.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/Makefile.am b/text-utils/Makefile.am index 513f1c367..cc4b8b66d 100644 --- a/text-utils/Makefile.am +++ b/text-utils/Makefile.am @@ -4,6 +4,8 @@ EXTRA_DIST = README.clear README.col usrbin_exec_PROGRAMS = col colcrt colrm column hexdump rev line tailf +column_SOURCES = column.c $(top_srcdir)/lib/strutils.c + hexdump_SOURCES = hexdump.c conv.c display.c hexsyntax.c parse.c \ hexdump.h $(top_srcdir)/lib/strutils.c diff --git a/text-utils/column.c b/text-utils/column.c index 6b797d340..7604dc905 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -54,6 +54,7 @@ #include "widechar.h" #include "c.h" #include "xalloc.h" +#include "strutils.h" #ifdef HAVE_WIDECHAR #define wcs_width(s) wcswidth(s,wcslen(s)) @@ -81,7 +82,7 @@ typedef struct _tbl { int cols, *len; } TBL; -int termwidth = 80; /* default terminal width */ +long termwidth; int entries; /* number of records */ int eval; /* exit value */ @@ -134,7 +135,8 @@ int main(int argc, char **argv) if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1 || !win.ws_col) { if ((p = getenv("COLUMNS")) != NULL) - termwidth = atoi(p); + termwidth = strtol_or_err(p, + _("terminal environment COLUMNS failed")); } else termwidth = win.ws_col; @@ -149,7 +151,11 @@ int main(int argc, char **argv) PACKAGE_STRING); return(EXIT_SUCCESS); case 'c': - termwidth = atoi(optarg); + termwidth = strtol_or_err(optarg, + _("bad columns width value")); + if (termwidth < 1) + errx(EXIT_FAILURE, + _("-%c positive integer expected as an argument"), ch); break; case 's': separator = mbs_to_wcs(optarg); -- cgit v1.2.3-55-g7522 From daf093d2642f04000650fa06fdb3e1cdf80ef7c1 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 1 May 2011 19:26:49 +0200 Subject: column.c: global variables removed Variables from global scope are moved to main, and passed as function arguments where ever they are needed. Signed-off-by: Sami Kerola --- text-utils/column.c | 113 +++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 50 deletions(-) (limited to 'text-utils/column.c') diff --git a/text-utils/column.c b/text-utils/column.c index 7604dc905..bb6147cf9 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -71,37 +71,17 @@ static char *mtsafe_strtok(char *, const char *, char **); #define DEFNUM 1000 #define MAXLINELEN (LINE_MAX + 1) -static void c_columnate(void); -static void input(FILE *); -static void maketbl(void); -static void print(void); -static void r_columnate(void); +static int input(FILE *fp, int *maxlength, wchar_t ***list, int *entries); +static void c_columnate(int maxlength, long termwidth, wchar_t **list, int entries); +static void r_columnate(int maxlength, long termwidth, wchar_t **list, int entries); +static void maketbl(wchar_t **list, int entries, wchar_t *separator); +static void print(wchar_t **list, int entries); typedef struct _tbl { wchar_t **list; int cols, *len; } TBL; -long termwidth; - -int entries; /* number of records */ -int eval; /* exit value */ -int maxlength; /* longest record */ -wchar_t **list; /* array of pointers to records */ -wchar_t default_separator[] = { '\t', ' ', 0 }; -wchar_t *separator = default_separator; /* field separator for table option */ - -static const struct option longopts[] = -{ - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "columns", 0, 0, 'c' }, - { "table", 0, 0, 't' }, - { "separator", 0, 0, 's' }, - { "fillrows", 0, 0, 'x' }, - { NULL, 0, 0, 0 }, -}; - static void __attribute__((__noreturn__)) usage(int rc) { FILE *out = rc == EXIT_FAILURE ? stderr : stdout; @@ -129,6 +109,26 @@ int main(int argc, char **argv) int ch, tflag, xflag; char *p; + long termwidth; + int entries = 0; /* number of records */ + unsigned int eval = 0; /* exit value */ + int maxlength; /* longest record */ + wchar_t **list = NULL; /* array of pointers to records */ + /* field separator for table option */ + wchar_t default_separator[] = { '\t', ' ', 0 }; + wchar_t *separator = default_separator; + + static const struct option longopts[] = + { + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'V' }, + { "columns", 0, 0, 'c' }, + { "table", 0, 0, 't' }, + { "separator", 0, 0, 's' }, + { "fillrows", 0, 0, 'x' }, + { NULL, 0, 0, 0 }, + }; + setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -149,7 +149,7 @@ int main(int argc, char **argv) case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); - return(EXIT_SUCCESS); + return EXIT_SUCCESS; case 'c': termwidth = strtol_or_err(optarg, _("bad columns width value")); @@ -173,15 +173,15 @@ int main(int argc, char **argv) argv += optind; if (!*argv) - input(stdin); + eval += input(stdin, &maxlength, &list, &entries); else for (; *argv; ++argv) { if ((fp = fopen(*argv, "r")) != NULL) { - input(fp); - (void)fclose(fp); + eval += input(fp, &maxlength, &list, &entries); + fclose(fp); } else { warn("%s", *argv); - eval = EXIT_FAILURE; + eval += EXIT_FAILURE; } } @@ -189,24 +189,28 @@ int main(int argc, char **argv) exit(eval); if (tflag) - maketbl(); + maketbl(list, entries, separator); else if (maxlength >= termwidth) - print(); + print(list, entries); else if (xflag) - c_columnate(); + c_columnate(maxlength, termwidth, list, entries); else - r_columnate(); + r_columnate(maxlength, termwidth, list, entries); for (int i = 0; i < entries; i++) free(list[i]); free(list); if (ferror(stdout) || fclose(stdout)) - eval = EXIT_FAILURE; - exit(eval); + eval += EXIT_FAILURE; + + if (eval == 0) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; } -static void c_columnate() +static void c_columnate(int maxlength, long termwidth, wchar_t **list, int entries) { int chcnt, col, cnt, endcol, numcols; wchar_t **lp; @@ -235,7 +239,7 @@ static void c_columnate() putwchar('\n'); } -static void r_columnate() +static void r_columnate(int maxlength, long termwidth, wchar_t **list, int entries) { int base, chcnt, cnt, col, endcol, numcols, numrows, row; @@ -264,7 +268,7 @@ static void r_columnate() } } -static void print() +static void print(wchar_t **list, int entries) { int cnt; wchar_t **lp; @@ -275,7 +279,7 @@ static void print() } } -static void maketbl() +static void maketbl(wchar_t **list, int entries, wchar_t *separator) { TBL *t; int cnt, i; @@ -335,14 +339,17 @@ static void maketbl() free(tbl); } -static void input(FILE *fp) +static int input(FILE *fp, int *maxlength, wchar_t ***list, int *entries) { static int maxentry = DEFNUM; - int len, lineno = 1, reportedline = 0; + int len, lineno = 1, reportedline = 0, eval = 0; wchar_t *p, buf[MAXLINELEN]; + wchar_t **local_list; + int local_entries = *entries; + + if (!local_list) + local_list = xcalloc(maxentry, sizeof(wchar_t *)); - if (!list) - list = xcalloc(maxentry, sizeof(wchar_t *)); while (fgetws(buf, MAXLINELEN, fp)) { for (p = buf; *p && iswspace(*p); ++p) ; @@ -354,21 +361,27 @@ static void input(FILE *fp) lineno); reportedline = lineno; } - eval = EXIT_FAILURE; + eval = 1; continue; } lineno++; if (!feof(fp)) *p = '\0'; len = wcs_width(buf); /* len = p - buf; */ - if (maxlength < len) - maxlength = len; - if (entries == maxentry) { + if (*maxlength < len) + *maxlength = len; + if (local_entries == maxentry) { maxentry += DEFNUM; - list = xrealloc(list, (u_int)maxentry * sizeof(wchar_t *)); + local_list = xrealloc(local_list, + (u_int)maxentry * sizeof(wchar_t *)); } - list[entries++] = wcsdup(buf); + local_list[local_entries++] = wcsdup(buf); } + + *list = local_list; + *entries = local_entries; + + return eval; } #ifdef HAVE_WIDECHAR -- cgit v1.2.3-55-g7522