Add substitutes for snprintf() and vsnprintf()
authorH. Peter Anvin <hpa@zytor.com>
Fri, 28 Sep 2007 17:50:20 +0000 (10:50 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 28 Sep 2007 17:50:20 +0000 (10:50 -0700)
To deal with fools^Wpeople trying to keep really old systems alive,
create a proper framework for substitution functions, and make it
possible to deal with the lack of snprintf/vsnprintf in particular.

Makefile.in
Mkfiles/msvc.mak
Mkfiles/openwcom.mak
Mkfiles/owlinux.mak
compiler.h
configure.in
lib/snprintf.c [new file with mode: 0644]
lib/vsnprintf.c [new file with mode: 0644]
nasmlib.c

index d41d455..dd21a10 100644 (file)
@@ -23,6 +23,8 @@ LDFLAGS               = @LDFLAGS@
 LIBS           = @LIBS@
 PERL           = perl -I$(srcdir)/perllib
 
+XOBJS          = @XOBJS@
+
 INSTALL                = @INSTALL@
 INSTALL_PROGRAM        = @INSTALL_PROGRAM@
 INSTALL_DATA   = @INSTALL_DATA@
@@ -70,11 +72,11 @@ NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) insnsd.$(O)
 all: nasm$(X) ndisasm$(X) nasm.man ndisasm.man
        cd rdoff && $(MAKE) all
 
-nasm$(X): $(NASM)
-       $(CC) $(LDFLAGS) -o nasm$(X) $(NASM) $(LIBS)
+nasm$(X): $(NASM) $(XOBJS)
+       $(CC) $(LDFLAGS) -o nasm$(X) $(NASM) $(XOBJS) $(LIBS)
 
-ndisasm$(X): $(NDISASM)
-       $(CC) $(LDFLAGS) -o ndisasm$(X) $(NDISASM) $(LIBS)
+ndisasm$(X): $(NDISASM) $(XOBJS)
+       $(CC) $(LDFLAGS) -o ndisasm$(X) $(NDISASM) $(XOBJS) $(LIBS)
 
 # These source files are automagically generated from a single
 # instruction-table file by a Perl script. They're distributed,
@@ -214,7 +216,7 @@ splint:
 #
 alldeps: perlreq
        $(PERL) mkdep.pl -M Makefile.in Mkfiles/*.mak -- \
-               . output
+               . output lib
        ./config.status
 
 #-- Magic hints to mkdep.pl --#
@@ -242,6 +244,8 @@ insnsd.$(O): insnsd.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
 insnsn.$(O): insnsn.c
 labels.$(O): labels.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
  nasmlib.h regs.h version.h
+lib/snprintf.$(O): lib/snprintf.c compiler.h config.h nasmlib.h
+lib/vsnprintf.$(O): lib/vsnprintf.c compiler.h config.h nasmlib.h
 listing.$(O): listing.c compiler.h config.h insnsi.h listing.h nasm.h \
  nasmlib.h regs.h version.h
 macros.$(O): macros.c
index d0ab870..66cd981 100644 (file)
@@ -192,6 +192,8 @@ insnsd.$(O): insnsd.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h \
 insnsn.$(O): insnsn.c
 labels.$(O): labels.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h regs.h \
  version.h
+lib/snprintf.$(O): lib/snprintf.c compiler.h nasmlib.h
+lib/vsnprintf.$(O): lib/vsnprintf.c compiler.h nasmlib.h
 listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h \
  regs.h version.h
 macros.$(O): macros.c
index 382dc05..955f4f4 100644 (file)
@@ -16,7 +16,7 @@ mandir                = $(prefix)\man
 CC             = wcl386
 CFLAGS         = -3 -bcl=$(TARGET) -ox -wx -ze -fpi
 BUILD_CFLAGS   = $(CFLAGS) # -I$(srcdir)/inttypes
-INTERNAL_CFLAGS = -I$(srcdir) -I.
+INTERNAL_CFLAGS = -I$(srcdir) -I. -DHAVE_SNPRINTF -DHAVE_VSNPRINTF
 ALL_CFLAGS     = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
 LD             = $(CC)
 LDFLAGS                = $(ALL_CFLAGS)
@@ -217,6 +217,8 @@ insnsd.$(O): insnsd.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h &
 insnsn.$(O): insnsn.c
 labels.$(O): labels.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h regs.h &
  version.h
+lib\snprintf.$(O): lib\snprintf.c compiler.h nasmlib.h
+lib\vsnprintf.$(O): lib\vsnprintf.c compiler.h nasmlib.h
 listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h &
  regs.h version.h
 macros.$(O): macros.c
index 6745eb6..f25e039 100644 (file)
@@ -14,7 +14,7 @@ mandir                = $(prefix)/man
 CC             = wcl386
 CFLAGS         = -3 -bcl=$(TARGET) -ox -wx -ze -fpi
 BUILD_CFLAGS   = $(CFLAGS) # -I$(srcdir)/inttypes
-INTERNAL_CFLAGS = -I$(srcdir) -I.
+INTERNAL_CFLAGS = -I$(srcdir) -I. -DHAVE_SNPRINTF -DHAVE_VSNPRINTF
 ALL_CFLAGS     = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
 LD             = $(CC)
 LDFLAGS                = $(ALL_CFLAGS)
@@ -210,6 +210,8 @@ insnsd.$(O): insnsd.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h \
 insnsn.$(O): insnsn.c
 labels.$(O): labels.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h regs.h \
  version.h
+lib/snprintf.$(O): lib/snprintf.c compiler.h nasmlib.h
+lib/vsnprintf.$(O): lib/vsnprintf.c compiler.h nasmlib.h
 listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h \
  regs.h version.h
 macros.$(O): macros.c
index 8ceb9ee..798466f 100644 (file)
 #endif
 
 /* Some versions of MSVC have these only with underscores in front */
-
-#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
-# define snprintf _snprintf
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#ifndef HAVE_SNPRINTF
+# ifdef HAVE__SNPRINTF
+#  define snprintf _snprintf
+# else
+int snprintf(char *, size_t, const char *, ...);
+# endif
 #endif
 
-#if !defined(HAVE_VSNPRINTF) && defined(HAVE__VSNPRINTF)
-# define vsnprintf _vsnprintf
+#ifndef HAVE_VSNPRINTF
+# ifdef HAVE__VSNPRINT
+#  define vsnprintf _vsnprintf
+# else
+int vsnprintf(char *, size_t, const char *, va_list);
+# endif
 #endif
 
 #endif /* COMPILER_H */
index a52b620..3def6cb 100644 (file)
@@ -87,6 +87,7 @@ AC_C_CONST
 AC_TYPE_SIZE_T
 
 dnl Checks for library functions.
+AC_SUBST_FILE(XOBJS)
 
 AC_CHECK_FUNCS(strcspn, ,
   AC_MSG_ERROR([NASM requires ANSI C (specifically, "strcspn")]))
@@ -95,15 +96,15 @@ AC_CHECK_FUNCS(strspn, ,
   AC_MSG_ERROR([NASM requires ANSI C (specifically, "strspn")]))
 
 missing=true
-AC_CHECK_FUNCS([snprintf _snprintf], missing=false)
+AC_CHECK_FUNCS([vsnprintf _vsnprintf], missing=false)
 if $missing; then
-  AC_MSG_ERROR([NASM requires ISO C99 (specifically, "snprintf")])
+   XOBJS="$XOBJS lib/vsnprintf.o"
 fi
 
 missing=true
-AC_CHECK_FUNCS([vsnprintf _vsnprintf], missing=false)
+AC_CHECK_FUNCS([snprintf _snprintf], missing=false)
 if $missing; then
-  AC_MSG_ERROR([NASM requires ISO C99 (specifically, "vsnprintf")])
+   XOBJS="$XOBJS lib/snprintf.o"
 fi
 
 AC_CHECK_FUNCS(getuid)
diff --git a/lib/snprintf.c b/lib/snprintf.c
new file mode 100644 (file)
index 0000000..f56a492
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * snprintf()
+ *
+ * Implement snprintf() in terms of vsnprintf()
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "nasmlib.h"
+
+int snprintf(char *str, size_t size, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vsnprintf(str, size, format, ap);
+    va_end(ap);
+
+    return rv;
+}
+
diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c
new file mode 100644 (file)
index 0000000..b2b19d9
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * vsnprintf()
+ *
+ * Poor substitute for a real vsnprintf() function for systems
+ * that don't have them...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "nasmlib.h"
+
+extern efunc nasm_malloc_error;
+
+#define BUFFER_SIZE    65536   /* Bigger than any string we might print... */
+
+static char snprintf_buffer[BUFFER_SIZE];
+
+int vsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+    int rv, bytes;
+
+    if (size > BUFFER_SIZE) {
+       nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
+                         "snprintf: size (%d) > BUFFER_SIZE (%d)",
+                         size, BUFFER_SIZE);
+       size = BUFFER_SIZE;
+    }
+
+    rv = vsprintf(snprintf_buffer, format, ap);
+    if (rv > BUFFER_SIZE) {
+       nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
+                         "snprintf buffer overflow");
+    }
+
+    if (rv < (int)size-1)
+       bytes = rv;
+    else
+       bytes = size-1;
+
+    if (size > 0) {
+       memcpy(str, snprintf_buffer, bytes);
+       str[bytes] = '\0';
+    }
+
+    return rv;
+}
index 0feb3ed..6f0e6af 100644 (file)
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -17,7 +17,7 @@
 #include "insns.h"
 
 int globalbits = 0;    /* defined in nasm.h, works better here for ASM+DISASM */
-static efunc nasm_malloc_error;
+efunc nasm_malloc_error;       /* Exported for the benefit of vsnprintf.c */
 
 #ifdef LOGALLOC
 static FILE *logfp;