Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/snprintf.c
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-10-11 15:34:15 +0200
committerArthur de Jong <arthur@arthurdejong.org>2006-10-11 15:34:15 +0200
commit6f17403298cf33747a45fb5ecbe78bf7632531f9 (patch)
treea5fc4cfdc3b091a0ee86f3c5c8d5e0ea8fc2c564 /snprintf.c
import release 251 of nss-ldap
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss_ldap-251@1 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'snprintf.c')
-rw-r--r--snprintf.c374
1 files changed, 374 insertions, 0 deletions
diff --git a/snprintf.c b/snprintf.c
new file mode 100644
index 0000000..d57e90f
--- /dev/null
+++ b/snprintf.c
@@ -0,0 +1,374 @@
+static char rcsId[] = "$Id: snprintf.c,v 2.9 2001/08/17 05:30:14 lukeh Exp $";
+
+#include "config.h"
+
+#ifndef HAVE_SNPRINTF
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh. This sort of thing is always nasty do deal with. Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length. This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ **************************************************************/
+
+static void dopr ();
+static char *end;
+
+#include "snprintf.h"
+#include <string.h>
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+/* varargs declarations: */
+
+#if defined(HAVE_STDARG_H)
+#include <stdarg.h>
+#define HAVE_STDARGS /* let's hope that works everywhere (mj) */
+#define VA_LOCAL_DECL va_list ap;
+#define VA_START(f) va_start(ap, f)
+#define VA_SHIFT(v,t) ; /* no-op for ANSI */
+#define VA_END va_end(ap)
+#else
+#if defined(HAVE_VARARGS_H)
+#include <varargs.h>
+#undef HAVE_STDARGS
+#define VA_LOCAL_DECL va_list ap;
+#define VA_START(f) va_start(ap) /* f is ignored! */
+#define VA_SHIFT(v,t) v = va_arg(ap,t)
+#define VA_END va_end(ap)
+#else
+XX **NO VARARGS ** XX
+#endif
+#endif
+#ifdef HAVE_STDARGS
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#else
+int snprintf ();
+int vsnprintf ();
+#endif
+
+int
+vsnprintf (str, count, fmt, args)
+ char *str;
+ size_t count;
+ const char *fmt;
+ va_list args;
+{
+ str[0] = 0;
+ end = str + count - 1;
+ dopr (str, fmt, args);
+ if (count > 0)
+ {
+ end[0] = 0;
+ }
+ return (strlen (str));
+}
+
+/* VARARGS3 */
+#ifdef HAVE_STDARGS
+int
+snprintf (char *str, size_t count, const char *fmt, ...)
+#else
+int
+snprintf (va_alist)
+ va_dcl
+#endif
+{
+#ifndef HAVE_STDARGS
+ char *str;
+ size_t count;
+ char *fmt;
+#endif
+ VA_LOCAL_DECL VA_START (fmt);
+ VA_SHIFT (str, char *);
+ VA_SHIFT (count, size_t);
+ VA_SHIFT (fmt, char *);
+ (void) vsnprintf (str, count, fmt, ap);
+ VA_END;
+ return (strlen (str));
+}
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+static void fmtstr (char *value, int ljust, int len, int zpad);
+static void fmtnum (long value, int base, int dosign,
+ int ljust, int len, int zpad);
+static void dostr (char *);
+static char *output;
+static void dopr_outch (int c);
+
+static void
+dopr (buffer, format, args)
+ char *buffer;
+ char *format;
+ va_list args;
+{
+ int ch;
+ long value;
+ int longflag = 0;
+ char *strvalue;
+ int ljust;
+ int len;
+ int zpad;
+
+ output = buffer;
+ while ((ch = *format++))
+ {
+ switch (ch)
+ {
+ case '%':
+ ljust = len = zpad = 0;
+ nextch:
+ ch = *format++;
+ switch (ch)
+ {
+ case 0:
+ dostr ("**end of format**");
+ return;
+ case '-':
+ ljust = 1;
+ goto nextch;
+ case '0': /* set zero padding if len not set */
+ if (len == 0)
+ zpad = '0';
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ len = len * 10 + ch - '0';
+ goto nextch;
+ case 'l':
+ longflag = 1;
+ goto nextch;
+ case 'u':
+ case 'U':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if (longflag)
+ {
+ value = va_arg (args, long);
+ }
+ else
+ {
+ value = va_arg (args, int);
+ }
+ fmtnum (value, 10, 0, ljust, len, zpad);
+ break;
+ case 'o':
+ case 'O':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if (longflag)
+ {
+ value = va_arg (args, long);
+ }
+ else
+ {
+ value = va_arg (args, int);
+ }
+ fmtnum (value, 8, 0, ljust, len, zpad);
+ break;
+ case 'd':
+ case 'D':
+ if (longflag)
+ {
+ value = va_arg (args, long);
+ }
+ else
+ {
+ value = va_arg (args, int);
+ }
+ fmtnum (value, 10, 1, ljust, len, zpad);
+ break;
+ case 'x':
+ if (longflag)
+ {
+ value = va_arg (args, long);
+ }
+ else
+ {
+ value = va_arg (args, int);
+ }
+ fmtnum (value, 16, 0, ljust, len, zpad);
+ break;
+ case 'X':
+ if (longflag)
+ {
+ value = va_arg (args, long);
+ }
+ else
+ {
+ value = va_arg (args, int);
+ }
+ fmtnum (value, -16, 0, ljust, len, zpad);
+ break;
+ case 's':
+ strvalue = va_arg (args, char *);
+ fmtstr (strvalue, ljust, len, zpad);
+ break;
+ case 'c':
+ ch = va_arg (args, int);
+ dopr_outch (ch);
+ break;
+ case '%':
+ dopr_outch (ch);
+ continue;
+ default:
+ dostr ("???????");
+ }
+ longflag = 0;
+ break;
+ default:
+ dopr_outch (ch);
+ break;
+ }
+ }
+ *output = 0;
+}
+
+static void
+fmtstr (value, ljust, len, zpad)
+ char *value;
+ int ljust, len, zpad;
+{
+ int padlen, strlen; /* amount to pad */
+
+ if (value == 0)
+ {
+ value = "<NULL>";
+ }
+ for (strlen = 0; value[strlen]; ++strlen); /* strlen */
+ padlen = len - strlen;
+ if (padlen < 0)
+ padlen = 0;
+ if (ljust)
+ padlen = -padlen;
+ while (padlen > 0)
+ {
+ dopr_outch (' ');
+ --padlen;
+ }
+ dostr (value);
+ while (padlen < 0)
+ {
+ dopr_outch (' ');
+ ++padlen;
+ }
+}
+
+static void
+fmtnum (value, base, dosign, ljust, len, zpad)
+ long value;
+ int base, dosign, ljust, len, zpad;
+{
+ int signvalue = 0;
+ unsigned long uvalue;
+ char convert[20];
+ int place = 0;
+ int padlen = 0; /* amount to pad */
+ int caps = 0;
+
+ /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
+ value, base, dosign, ljust, len, zpad )); */
+ uvalue = value;
+ if (dosign)
+ {
+ if (value < 0)
+ {
+ signvalue = '-';
+ uvalue = -value;
+ }
+ }
+ if (base < 0)
+ {
+ caps = 1;
+ base = -base;
+ }
+ do
+ {
+ convert[place++] =
+ (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+ [uvalue % (unsigned) base];
+ uvalue = (uvalue / (unsigned) base);
+ }
+ while (uvalue);
+ convert[place] = 0;
+ padlen = len - place;
+ if (padlen < 0)
+ padlen = 0;
+ if (ljust)
+ padlen = -padlen;
+ /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
+ convert,place,signvalue,padlen)); */
+ if (zpad && padlen > 0)
+ {
+ if (signvalue)
+ {
+ dopr_outch (signvalue);
+ --padlen;
+ signvalue = 0;
+ }
+ while (padlen > 0)
+ {
+ dopr_outch (zpad);
+ --padlen;
+ }
+ }
+ while (padlen > 0)
+ {
+ dopr_outch (' ');
+ --padlen;
+ }
+ if (signvalue)
+ dopr_outch (signvalue);
+ while (place > 0)
+ dopr_outch (convert[--place]);
+ while (padlen < 0)
+ {
+ dopr_outch (' ');
+ ++padlen;
+ }
+}
+
+static void
+dostr (str)
+ char *str;
+{
+ while (*str)
+ dopr_outch (*str++);
+}
+
+static void
+dopr_outch (c)
+ int c;
+{
+ if (iscntrl (c) && c != '\n' && c != '\t')
+ {
+ c = '@' + (c & 0x1F);
+ if (end == 0 || output < end)
+ {
+ *output++ = '^';
+ }
+ }
+ if (end == 0 || output < end)
+ {
+ *output++ = c;
+ }
+}
+
+#endif /* !HAVE_SNPRINTF */