From d2fa23b5a1406a131a133ae46fc163635008dda1 Mon Sep 17 00:00:00 2001 From: Sami Kerola <kerolasa@xxxxxx> Date: Sun, 4 Oct 2009 22:21:06 +0200 Subject: [PATCH] column: getopts, new help and cleaning Cc: kerolasa@xxxxxx As a minor change this patch does include new error messages. Signed-off-by: Sami Kerola <kerolasa@xxxxxx> --- text-utils/column.c | 120 ++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 91 insertions(+), 29 deletions(-) diff --git a/text-utils/column.c b/text-utils/column.c index f5d41a2..b14583d 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1989, 1993, 1994 + * Copyright (c) 1989, 1993, 1994, 2009 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,11 +36,12 @@ * added Native Language Support * 1999-09-19 Bruno Haible <haible@xxxxxxxxxxxxxx> * modified to work correctly in multi-byte locales + * 2009-10-04 Sami Kerola <kerolasa@xxxxxx> + * long options and new help output */ #include <sys/types.h> #include <sys/ioctl.h> - #include <ctype.h> #include <limits.h> #include <stdio.h> @@ -48,8 +49,10 @@ #include <stdlib.h> #include <string.h> #include <err.h> -#include "nls.h" +#include <errno.h> +#include <getopt.h> +#include "nls.h" #include "widechar.h" #ifdef HAVE_WIDECHAR @@ -68,10 +71,30 @@ static void input __P((FILE *)); static void maketbl __P((void)); static void print __P((void)); static void r_columnate __P((void)); -static void usage __P((void)); +static void usage __P((int)); +signed int xstrtoi(const char *optarg); +static void xerr(int rc, char *s); -int termwidth = 80; /* default terminal width */ +#define DEFCOLS 25 +#define TAB 8 +#define DEFNUM 1000 +#define MAXLINELEN (LINE_MAX + 1) +typedef struct _tbl { + wchar_t **list; + int cols, *len; +} TBL; + +struct option longopts[] = +{ + { "wide", required_argument, 0, 'c' }, + { "help", no_argument, 0, 'h' }, + { "separator", required_argument, 0, 's' }, + { "table", no_argument, 0, 't' }, + { NULL, 0, 0, 0 }, +}; + +int termwidth = 80; /* default terminal width */ int entries; /* number of records */ int eval; /* exit value */ int maxlength; /* longest record */ @@ -87,6 +110,7 @@ main(int argc, char **argv) int ch, tflag, xflag; char *p; + eval = EXIT_SUCCESS; extern char *__progname; __progname = argv[0]; @@ -96,15 +120,15 @@ main(int argc, char **argv) if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) { if ((p = getenv("COLUMNS")) != NULL) - termwidth = atoi(p); + termwidth = xstrtoi(p); } else termwidth = win.ws_col; tflag = xflag = 0; - while ((ch = getopt(argc, argv, "c:s:tx")) != -1) + while ((ch = getopt_long(argc, argv, "c:hs:tx", longopts, NULL)) != -1) switch(ch) { case 'c': - termwidth = atoi(optarg); + termwidth = xstrtoi(optarg); break; case 's': separator = mbs_to_wcs(optarg); @@ -115,9 +139,12 @@ main(int argc, char **argv) case 'x': xflag = 1; break; + case 'h': + usage(EXIT_SUCCESS); + break; case '?': default: - usage(); + usage(EXIT_FAILURE); } argc -= optind; argv += optind; @@ -130,7 +157,7 @@ main(int argc, char **argv) (void)fclose(fp); } else { warn("%s", *argv); - eval = 1; + eval = EXIT_FAILURE; } if (!entries) @@ -145,11 +172,10 @@ main(int argc, char **argv) else r_columnate(); if (ferror(stdout) || fclose(stdout)) - eval = 1; + eval = EXIT_FAILURE; exit(eval); } -#define TAB 8 static void c_columnate() { @@ -222,12 +248,6 @@ print() } } -typedef struct _tbl { - wchar_t **list; - int cols, *len; -} TBL; -#define DEFCOLS 25 - static void maketbl() { @@ -251,7 +271,7 @@ maketbl() * sizeof(wchar_t *))) || !(lens = realloc(lens, ((u_int)maxcols + DEFCOLS) * sizeof(int)))) - err(1, NULL); + err(EXIT_FAILURE, NULL); memset((char *)lens + maxcols * sizeof(int), 0, DEFCOLS * sizeof(int)); maxcols += DEFCOLS; @@ -276,9 +296,6 @@ maketbl() } } -#define DEFNUM 1000 -#define MAXLINELEN (LINE_MAX + 1) - static void input(fp) FILE *fp; @@ -295,7 +312,7 @@ input(fp) continue; if (!(p = wcschr(p, '\n'))) { warnx(_("line too long")); - eval = 1; + eval = EXIT_FAILURE; continue; } *p = '\0'; @@ -306,7 +323,7 @@ input(fp) maxentry += DEFNUM; if (!(list = realloc(list, (u_int)maxentry * sizeof(wchar_t *)))) - err(1, NULL); + err(EXIT_FAILURE, _("remalloc")); } list[entries++] = wcsdup(buf); } @@ -361,16 +378,61 @@ emalloc(size) char *p; if (!(p = malloc(size))) - err(1, NULL); + err(EXIT_FAILURE, _("malloc")); memset(p, 0, size); return (p); } static void -usage() +usage(int rc) +{ + extern char *program_invocation_short_name; + const char *p = program_invocation_short_name; + if (!*p) { + p = "column"; + } + + printf(_("\nUsage: %s [options] [file ...]\n"), p); + printf(_("\nOptions:\n")); + + printf(_( + " -c, --width=SIZE output is formatted for a display of SIZE wide\n" + " -s, --separator=SEP character to be used to delimit columns\n" + " -t, --table create a table\n" + " -x fill columns before filling rows\n" + " -h, --help display this help text\n")); + + printf(_("\nFor more information see column(1).\n")); + exit(rc); +} + +signed int +xstrtoi(const char *optarg) { + signed long val; + char *endp; + + errno = 0; + val = strtol(optarg, &endp, 10); + if ((errno == ERANGE || (val < 0) || (INT_MAX < val)) || + (errno != 0 && val == 0)) { + xerr(EXIT_FAILURE, _("width argument out of range")); + } + if (optarg == endp) { + xerr(EXIT_FAILURE, _("digit missing from width argument")); + } - (void)fprintf(stderr, - _("usage: column [-tx] [-c columns] [file ...]\n")); - exit(1); + return (signed int) val; +} + +static void +xerr(int rc, char *s) +{ + extern char *program_invocation_short_name; + const char *p = program_invocation_short_name; + if (!*p) { + p = "column"; + } + fprintf(stderr, "%s: %s\n", p, s); + exit(rc); } -- 1.6.4.4