nexmon – Rev 1

Subversion Repositories:
Rev:
/* snprinterr.c */
/* Copyright Gerhard Rieger */

/* a function similar to vsnprintf() but it just handles %m */

#include "config.h"

#include <stddef.h>     /* ptrdiff_t */
#include <ctype.h>      /* isdigit() */
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#if HAVE_SYSLOG_H
#include <syslog.h>
#endif
#include <sys/utsname.h>
#include <time.h>       /* time_t, strftime() */
#include <sys/time.h>   /* gettimeofday() */
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "snprinterr.h"

#define HAVE_STRERROR_R 0
/* replace %m in format with actual strerror() message, write result to *str.
   keep other % formats unchanged!
   writes at most size chars including the terminating \0 to *str
   returns the number of bytes in the output without terminating \0
   result is always \0 terminated except when size==0
 */
int snprinterr(char *str, size_t size, const char *format) {
   char c;
   int full = 0;        /* 1 means: there is no space left in * str for more data or \0 */
   int count = 0;
   if (size == 0)  return 0;
   if (count >= size)  full = 1;
   while (c = *format++) {
      if (c == '%') {
         c = *format++;
         switch (c) {
         case '\0':
            ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
            break;
         default:
            ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
            ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
            break;
         case 'm':
            {
#if HAVE_STRERROR_R
#              define BUFLEN 64
               char buf[BUFLEN] = "";
#endif /* HAVE_STRERROR_R */
               char *bufp;
#if !HAVE_STRERROR_R
               bufp = strerror(errno);
#else
               /* there are two versions floating around... */
#  if 1 /* GNU version */
               bufp = strerror_r(errno, buf, BUFLEN);
#  else /* standard version */
               strerror_r(errno, buf, BUFLEN);
               bufp = buf;
#  endif
#endif /* HAVE_STRERROR_R */
               while ((c = *bufp++) != '\0') {
                  ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
               }
            }
            c = ' ';    /* not \0 ! */
            break;
         }
         if (c == '\0')  break;
      } else {
         ++count; if (!full) { (*str++ = c); if (count+1 >= size)  full = 1; }
      }
   }
   *str++ = '\0';       /* always write terminating \0 */
   return count;
#undef BUFLEN
}