Subject: strerror(1) and strsignal(1)?

From: Bruce Korb <[email-masked]>
Date: Sun, 20 Feb 2011 14:43:43 -0800

Hi,

I had to go grubbing through headers to translate "11" into something
comprehensible one too many times.  If this is acceptable, I'll double
my time investment and whip up some .texi verbiage.

I believe my paperwork is in order, but I'm not convinced that this
qualifies as "significant" :-D.

Cheers - Bruce

#ifndef code_to_text
#define code_to_text strerror
#endif

#define _str(_s) #_s
#define STRINGIFY(_s) _str(_s)

static char const usage_txt[] =
  "Usage: " STRINGIFY(code_to_text) " [--help | <numeric-code> [...]]\n";

static char const xlate_func[] = STRINGIFY(code_to_text);
static char const * const code_type = xlate_func + 3;

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void
usage (char const * msg_fmt, ...)
{
  int exit_code = EXIT_SUCCESS;
  FILE * fp = stdout;

  if (msg_fmt != NULL)
    {
      va_list ap;

      fp = stderr;
      exit_code = EXIT_FAILURE;

      va_start (ap, msg_fmt);
      vfprintf (fp, msg_fmt, ap);
      va_end (ap);
    }

  fwrite (usage_txt, sizeof (usage_txt) - 1, 1, fp);
  exit (exit_code);
}

int
main (int argc, char ** argv)
{
  char const * arg1 = argv[1];

  switch (argc)
    {
    case 1: usage ("no %s codes were supplied\n", code_type);
    case 2:
      if (*arg1 != '-')
        break;
      if (strcmp (arg1 + 1, "-help") == 0)
        usage (NULL);
      if ((arg1[1] == 'h') && (arg1[2] == '\0'))
        usage (NULL);
      break;
    }

  while (--argc > 0)
    {
      static char const bad_num[] =
        "'%s' is not a valid number - error %d (%s)\n";
      char const * arg = *(++argv);
      unsigned long val;
      char * p;

      errno = 0;
      val = strtoul (arg, &p, 0);
      if (errno != 0)
        usage (bad_num, arg, errno, strerror (errno));
      if (*p != '\0')
        usage (bad_num, arg, EINVAL, strerror (EINVAL));

      printf ("%s %3d %s\n", code_type, val, code_to_text (val));
    }

  return EXIT_SUCCESS;
}
/*
 * Local Variables:
 * mode: C
 * c-file-style: "gnu"
 * indent-tabs-mode: nil
 * End:
 * end of strerror.c */