diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..ddbbdce0c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +cmake_minimum_required( VERSION 2.6 ) + +set( ZDOOM_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Directory where zdoom.pk3 and the executable will be created" ) +set( ZDOOM_EXE_NAME "zdoom" CACHE FILEPATH "Name of the executable to create" ) + +find_package( JPEG ) +find_package( ZLIB ) + +if( MSVC ) + # Eliminate unreferenced functions and data + # Perform identical COMDAT folding + set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt" ) + + # String pooling + # Function-level linking + # Disable run-time type information + set( ALL_C_FLAGS "/GF /Gy /GR-" ) + + # Avoid CRT DLL dependancies in release builds + set( REL_C_FLAGS "/MT" ) + + # Debug allocations in debug builds + set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC" ) + + # Disable warnings for unsecure CRT functions from VC8+ + if( MSVC_VERSION GREATER 1399 ) + set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996" ) + endif( MSVC_VERSION GREATER 1399 ) + + # The CMake configurations set /GR and /MD by default, which conflict with our settings. + string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} ) + string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} ) + string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ) + string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} ) + string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} ) + string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} ) + string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) +endif( MSVC ) + +set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" ) +set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} ${REL_LINKER_FLAGS}" ) +set( CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${REL_LINKER_FLAGS}" ) + +set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALL_C_FLAGS}" ) +set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${REL_C_FLAGS}" ) +set( CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" ) +set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" ) +set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" ) + +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALL_C_FLAGS}" ) +set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${REL_C_FLAGS}" ) +set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" ) +set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" ) +set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" ) + +if( ZLIB_FOUND ) + message( STATUS "Using system zlib" ) +else( ZLIB_FOUND ) + message( STATUS "Using internal zlib" ) + add_subdirectory( zlib ) + set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib ) + set( ZLIB_LIBRARIES z ) + set( ZLIB_LIBRARY z ) +endif( ZLIB_FOUND ) + +if( JPEG_FOUND ) + message( STATUS "Using system jpeg library" ) +else( JPEG_FOUND ) + message( STATUS "Using internal jpeg library" ) + add_subdirectory( jpeg-6b ) + set( JPEG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jpeg-6b ) + set( JPEG_LIBRARIES jpeg ) + set( JPEG_LIBRARY jpeg ) +endif( JPEG_FOUND ) + +add_subdirectory( tools ) +add_subdirectory( snes_spc ) +add_subdirectory( dumb ) +add_subdirectory( gdtoa ) +add_subdirectory( wadsrc ) +add_subdirectory( src ) diff --git a/Makefile b/Makefile deleted file mode 100644 index 2efb4386e..000000000 --- a/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 -endif - -ifeq (1,$(WIN)) -include Makefile.mgw -else -include Makefile.linux -endif diff --git a/Makefile.mgw b/Makefile.mgw deleted file mode 100644 index 672ae834f..000000000 --- a/Makefile.mgw +++ /dev/null @@ -1,58 +0,0 @@ -RELEASETARGET = zdoomgcc.exe -DEBUGTARGET = zdoomgccd.exe - -all: basetools game -debug: basetools debuggame -release: basetools game - -ifndef CONFIG - CONFIG=Release -endif - -game: basetools ccdv.exe - @$(MAKE) -f Makefile.mingw - -debuggame: basetools ccdv.exe - @$(MAKE) CONFIG=Debug -f Makefile.mingw - -$(RELEASETARGET): game -$(DEBUGTARGET): debuggame - -basetools: ccdv.exe - $(MAKE) -C tools/lemon - $(MAKE) -C tools/re2c - $(MAKE) -C zlib -f Makefile.mgw - $(MAKE) -C tools/makewad - $(MAKE) -C tools/dehsupp - $(MAKE) -C tools/fixrtext - $(MAKE) -C wadsrc -f Makefile.mgw - $(MAKE) -C jpeg-6b -f Makefile.mgw - $(MAKE) -C snes_spc - $(MAKE) -C dumb - -cleanexe: - @$(MAKE) -C . -f Makefile.mingw clean - -clean: - @$(MAKE) -C tools/lemon clean - @$(MAKE) -C tools/re2c clean - @$(MAKE) -C tools/dehsupp clean - @$(MAKE) -C tools/makewad clean - @$(MAKE) -C tools/fixrtext clean - @$(MAKE) -C wadsrc -f Makefile.mgw clean - @$(MAKE) -C . -f Makefile.mingw clean - @$(MAKE) -C zlib -f Makefile.mgw clean - @$(MAKE) -C jpeg-6b -f Makefile.mgw clean - @$(MAKE) -C snes_spc clean - @$(MAKE) -C dumb clean -ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - rm -f ccdv.exe -else - del /q /f ccdv.exe 2>nul -endif - -cleandep: - @$(MAKE) -C . -f Makefile.mingw cleandep - -ccdv.exe: ccdv-win32.c - @gcc -Os -s -nostdlib -fomit-frame-pointer -o ccdv.exe ccdv-win32.c -lkernel32 -luser32 diff --git a/Makefile.mingw b/Makefile.mingw deleted file mode 100644 index 1824ee220..000000000 --- a/Makefile.mingw +++ /dev/null @@ -1,162 +0,0 @@ -# This makefile makes zdoom(d).exe only. -# Makefile.mgw builds this plus everything else. - -# Sub-makefile autogenerated by premake -# And then tweaked by hand - -# Where did you install the FMOD API to? Change this line so that the build process can find it. -FMODDIR = "e:/program files (x86)/FMOD SoundSystem/FMOD Programmers API Win32" - -ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 -else - WINCMD=1 -endif - -CC ?= gcc -CXX ?= g++ - -CONFIG ?= Release -OPTLEVEL ?= 2 -ARCH_TYPE ?= pentium -TUNE_TYPE ?= i686 -RELEASETARGET ?= zdoomgcc.exe -DEBUGTARGET ?= zdoomgccd.exe -DEBUGOBJDIR ?= debugobj -RELEASEOBJDIR ?= releaseobj - -# Can be libdumbd.a, if you really need to debug DUMB -DUMBLIB ?= libdumb.a - -CCDV ?= @ccdv -RE2C = tools/re2c/re2c -LEMON = tools/lemon/lemon - -CPPFLAGS = -DWIN32 -D_WIN32 -D_WINDOWS -DHAVE_STRUPR -DHAVE_FILELENGTH -DI_DO_NOT_LIKE_BIG_DOWNLOADS -D__forceinline=inline -MMD -Izlib -IFLAC -Ijpeg-6b -Isrc -Isrc/win32 -Isrc/g_doom -Isrc/g_heretic -Isrc/g_hexen -Isrc/g_raven -Isrc/g_strife -Isrc/g_shared -Isrc/oplsynth -Isrc/sound -Isrc/textures -Isrc/thingdef -Isnes_spc/snes_spc -ifdef FMODDIR - CPPFLAGS += -I$(FMODDIR)/api/inc - LDFLAGS += -L$(FMODDIR)/api/lib -endif - -LDFLAGS += zlib/libz.a jpeg-6b/libjpeg.a snes_spc/libsnes_spc.a dumb/lib/$(DUMBLIB) -lfmodex -lwsock32 -lwinmm -lddraw -ldsound -ldxguid -ldinput8 -lole32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -LDFLAGS += -lsetupapi -Wl,--subsystem,windows -lws2_32 - -CFLAGS += -fno-strict-aliasing - -ifeq ($(CONFIG),Debug) - OBJDIR = $(DEBUGOBJDIR) - CFLAGS += $(CPPFLAGS) -Wall -Wno-unused -g3 - CPPFLAGS += -D_DEBUG - CXXFLAGS = $(CFLAGS) - TARGET = $(DEBUGTARGET) -endif -ifeq ($(CONFIG),Release) - OBJDIR = $(RELEASEOBJDIR) - CFLAGS += $(CPPFLAGS) -march=$(ARCH_TYPE) -mtune=$(TUNE_TYPE) -Wall -Wno-unused -O$(OPTLEVEL) -fomit-frame-pointer -pipe - CFLAGS += -ffunction-sections -fno-rtti - CPPFLAGS += -DNDEBUG - CXXFLAGS = $(CFLAGS) - LDFLAGS += -s -Wl,-Map=zdoomgcc.map -Wl,--gc-sections - TARGET = $(RELEASETARGET) -endif - -SRCDIRS = src/ $(addprefix src/,g_doom/ g_heretic/ g_hexen/ g_raven/ g_shared/ g_strife/ oplsynth/ sound/ win32/ textures/ thingdef/ timidity/) -VPATH = $(SRCDIRS) - -CPPSRCS = $(wildcard $(addsuffix *.cpp,$(SRCDIRS))) src/xlat/parse_xlat.cpp -CSRCS = $(wildcard $(addsuffix *.c,$(SRCDIRS))) -RCSRCS = $(wildcard $(addsuffix *.rc,$(SRCDIRS))) -ifdef NOASM - CFLAGS += -DNOASM -else - ASRCS = $(wildcard src/*.nas) - CFLAGS += -DUSEASM=1 -endif -SRCS = $(CSRCS) $(CPPSRCS) $(ASRCS) -CPPOBJFILES = $(notdir $(CPPSRCS:%.cpp=%.o)) -COBJFILES = $(notdir $(CSRCS:%.c=%.o)) -# win32/wrappers.nas should be built *only* for Visual C++ 2005 to enable execution on Windows 95 -AOBJFILES = $(filter-out %/wrappers.o,$(notdir $(ASRCS:%.nas=%.o))) -RCOBJFILES = $(notdir $(RCSRCS:%.rc=%.o)) - -COBJS = $(addprefix $(OBJDIR)/,$(CPPOBJFILES) $(COBJFILES) $(RCOBJFILES)) -DEPS = $(patsubst %.o,%.d,$(COBJS)) -UNORDEREDOBJS = $(addprefix $(OBJDIR)/,$(AOBJFILES)) $(COBJS) - -OBJS = $(OBJDIR)/autostart.o $(filter-out %/autostart.o %/autozend.o,$(UNORDEREDOBJS)) $(OBJDIR)/autozend.o - -all: $(TARGET) - -# This file needs special handling so that it actually gets compiled with SSE2 support. -$(OBJDIR)/nodebuild_classify_sse2.o: src/nodebuild_classify_sse2.cpp - $(CCDV) $(CXX) $(CXXFLAGS) -msse2 -mfpmath=sse -c -o $@ $< - -# This file needs special handling because GCC misoptimizes it otherwise. -$(OBJDIR)/fmopl.o: src/oplsynth/fmopl.cpp - $(CCDV) $(CXX) $(CXXFLAGS) -fno-tree-dominator-opts -fno-tree-fre -c -o $@ $< - -src/sc_man_scanner.h: src/sc_man_scanner.re - $(CCDV) $(RE2C) -s -o $@ $< - -src/xlat/xlat_parser.c: src/xlat/xlat_parser.y - $(CCDV) $(LEMON) -s src/xlat/xlat_parser.y - -# Dunno why make isn't picking this stuff up automatically for this file. -$(OBJDIR)/parse_xlat.o: src/xlat/parse_xlat.cpp src/xlat/xlat.h src/xlat/xlat_parser.c src/xlat/xlat_parser.h - $(CCDV) $(CXX) $(CXXFLAGS) -o $@ -c $< - -$(OBJDIR)/%.o : %.cpp - $(CCDV) $(CXX) $(CXXFLAGS) -o $@ -c $< - -$(OBJDIR)/%.o : %.nas - $(CCDV) nasm -o $@ -f win32 $< - @tools/fixrtext/fixrtext $@ - -$(OBJDIR)/%.o : %.rc - $(CCDV) windres --include-dir=src/win32 -o $@ -i $< - - -$(TARGET): testobjdir updaterev $(OBJS) - $(CCDV) $(CXX) -o $@ $(OBJS) $(LDFLAGS) - -ifeq (1,$(WINCMD)) -clean: - -del /q /f $(RELEASETARGET) 2>nul - -del /q /f $(DEBUGTARGET) 2>nul - -del /q /f $(DEBUGOBJDIR) 2>nul - -del /q /f $(RELEASEOBJDIR) 2>nul - -cleandep: - -del /q /f $(DEBUGOBJDIR)\*.d 2>nul - -del /q /f $(RELEASEOBJDIR)\*.d 2>nul -else -clean: - rm -f $(RELEASETARGET) - rm -f $(DEBUGTARGET) - rm -fr $(DEBUGOBJDIR) - rm -fr $(RELEASEOBJDIR) - -cleandep: - rm -f $(DEBUGOBJDIR)/*.d - rm -f $(RELEASEOBJDIR)/*.d -endif - -testobjdir: -ifeq (1,$(WINCMD)) - -@if not exist $(OBJDIR) mkdir $(OBJDIR) -else - -@if [ ! -e $(OBJDIR) ]; then mkdir $(OBJDIR); fi -endif - -updaterev: tools/updaterevision/updaterevision.exe - @tools/updaterevision/updaterevision . src/svnrevision.h - -tools/updaterevision/updaterevision.exe: - $(MAKE) -C tools/updaterevision - - -ifeq (,$(findstring $(MAKECMDGOALS),clean cleandep updaterev)) --include $(DEPS) -endif - -.PHONY: clean all updaterev testobjdir cleandep diff --git a/ccdv-posix.c b/ccdv-posix.c deleted file mode 100644 index e0842a90a..000000000 --- a/ccdv-posix.c +++ /dev/null @@ -1,459 +0,0 @@ -/* ccdv.c */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SETCOLOR_SUCCESS (gANSIEscapes ? "\033\1331;32m" : "") -#define SETCOLOR_FAILURE (gANSIEscapes ? "\033\1331;31m" : "") -#define SETCOLOR_WARNING (gANSIEscapes ? "\033\1331;33m" : "") -#define SETCOLOR_COMMAND (gANSIEscapes ? "\033\1331;35m" : "") -#define SETCOLOR_ERROROUTPUT (gANSIEscapes ? "\033\1331;31m" : "") -#define SETCOLOR_WARNINGOUTPUT (gANSIEscapes ? "\033\1331;39m" : "") -#define SETCOLOR_NORMAL (gANSIEscapes ? "\033\1330;39m" : "") - -#define TEXT_BLOCK_SIZE 8192 -#define INDENT 2 - -size_t gNBufUsed = 0, gNBufAllocated = 0; -char *gBuf = NULL; -int gCCPID; -char gAction[64] = ""; -char gTarget[64] = ""; -char gAr[32] = ""; -char gArLibraryTarget[64] = ""; -int gDumpCmdArgs = 0; -char gArgsStr[32768]; -int gColumns = 80; -int gANSIEscapes = 0; -int gExitStatus = 95; - -static void DumpFormattedOutput(void) -{ - char *cp; - char spaces[8 + 1] = " "; - char *saved; - int curcol; - int i; - - curcol = 0; - saved = NULL; - if(gDumpCmdArgs) - { - printf("%s%s%s", SETCOLOR_COMMAND, gArgsStr, SETCOLOR_NORMAL); - for(i = 0; i < gColumns; ++i) - { - putchar('='); - } - } - printf("%s%s%s", gDumpCmdArgs ? SETCOLOR_ERROROUTPUT : SETCOLOR_WARNINGOUTPUT, - gBuf + strlen(gArgsStr), SETCOLOR_NORMAL); - free(gBuf); -} /* DumpFormattedOutput */ - -/* Difftime(), only for timeval structures. */ -static void TimeValSubtract(struct timeval *tdiff, struct timeval *t1, - struct timeval *t0) -{ - tdiff->tv_sec = t1->tv_sec - t0->tv_sec; - tdiff->tv_usec = t1->tv_usec - t0->tv_usec; - if(tdiff->tv_usec < 0) - { - tdiff->tv_sec--; - tdiff->tv_usec += 1000000; - } -} /* TimeValSubtract */ - -static void Wait(void) -{ - int pid2, status; - - do - { - status = 0; - pid2 = (int) waitpid(gCCPID, &status, 0); - } - while(((pid2 >= 0) && (!WIFEXITED(status))) - || ((pid2 < 0) && (errno == EINTR))); - if(WIFEXITED(status)) - gExitStatus = WEXITSTATUS(status); -} /* Wait */ - -static int SlurpProgress(int fd) -{ - char s1[71]; - char *newbuf; - int nready; - size_t ntoread; - ssize_t nread; - struct timeval now, tnext, tleft; - fd_set ss; - fd_set ss2; - const char *trail = "/-\\|", *trailcp; - - trailcp = trail; - snprintf(s1, sizeof(s1), "%s%s%s... ", gAction, gTarget[0] ? " " : "", - gTarget); - printf("\r%-70s%-9s", s1, ""); - fflush(stdout); - - gettimeofday(&now, NULL); - tnext = now; - tnext.tv_sec++; - tleft.tv_sec = 1; - tleft.tv_usec = 0; - FD_ZERO(&ss2); - FD_SET(fd, &ss2); - for(;;) - { - if(gNBufUsed == (gNBufAllocated - 1)) - { - if((newbuf = - (char *) realloc(gBuf, - gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) - { - perror("ccdv: realloc"); - return (-1); - } - gNBufAllocated += TEXT_BLOCK_SIZE; - gBuf = newbuf; - } - for(;;) - { - ss = ss2; - nready = select(fd + 1, &ss, NULL, NULL, &tleft); - if(nready == 1) - break; - if(nready < 0) - { - if(errno != EINTR) - { - perror("ccdv: select"); - return (-1); - } - continue; - } - gettimeofday(&now, NULL); - if((now.tv_sec > tnext.tv_sec) - || ((now.tv_sec == tnext.tv_sec) - && (now.tv_usec >= tnext.tv_usec))) - { - tnext = now; - tnext.tv_sec++; - tleft.tv_sec = 1; - tleft.tv_usec = 0; - printf("\r%-71s%c%-7s", s1, *trailcp, ""); - fflush(stdout); - if(*++trailcp == '\0') - trailcp = trail; - } - else - { - TimeValSubtract(&tleft, &tnext, &now); - } - } - ntoread = (gNBufAllocated - gNBufUsed - 1); - nread = read(fd, gBuf + gNBufUsed, ntoread); - if(nread < 0) - { - if(errno == EINTR) - continue; - perror("ccdv: read"); - return (-1); - } - else if(nread == 0) - { - break; - } - gNBufUsed += nread; - gBuf[gNBufUsed] = '\0'; - } - snprintf(s1, sizeof(s1), "%s%s%s: ", gAction, gTarget[0] ? " " : "", - gTarget); - Wait(); - if(gExitStatus == 0) - { - printf("\r%-70s", s1); - printf("[%s%s%s]", - ((gNBufUsed - strlen(gArgsStr)) < - 4) ? SETCOLOR_SUCCESS : SETCOLOR_WARNING, "OK", - SETCOLOR_NORMAL); - printf("%-5s\n", " "); - } - else - { - printf("\r%-70s", s1); - printf("[%s%s%s]", SETCOLOR_FAILURE, "ERROR", SETCOLOR_NORMAL); - printf("%-2s\n", " "); - gDumpCmdArgs = 1; /* print cmd when there are errors */ - } - fflush(stdout); - return (0); -} /* SlurpProgress */ - -static int SlurpAll(int fd) -{ - char *newbuf; - size_t ntoread; - ssize_t nread; - - printf("%s%s%s.\n", gAction, gTarget[0] ? " " : "", gTarget); - fflush(stdout); - - for(;;) - { - if(gNBufUsed == (gNBufAllocated - 1)) - { - if((newbuf = - (char *) realloc(gBuf, - gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) - { - perror("ccdv: realloc"); - return (-1); - } - gNBufAllocated += TEXT_BLOCK_SIZE; - gBuf = newbuf; - } - ntoread = (gNBufAllocated - gNBufUsed - 1); - nread = read(fd, gBuf + gNBufUsed, ntoread); - if(nread < 0) - { - if(errno == EINTR) - continue; - perror("ccdv: read"); - return (-1); - } - else if(nread == 0) - { - break; - } - gNBufUsed += nread; - gBuf[gNBufUsed] = '\0'; - } - Wait(); - gDumpCmdArgs = (gExitStatus != 0); /* print cmd when there are errors */ - return (0); -} /* SlurpAll */ - -static const char *Basename(const char *path) -{ - const char *cp; - cp = strrchr(path, '/'); - if(cp == NULL) - return (path); - return (cp + 1); -} /* Basename */ - -static const char *Extension(const char *path) -{ - const char *cp = path; - cp = strrchr(path, '.'); - if(cp == NULL) - return (""); - return (cp); -} /* Extension */ - -static void Usage(void) -{ - char *sUsage = "\ -Usage: ccdv /path/to/cc CFLAGS...\n\ -\n\ -I wrote this to reduce the deluge Make output to make finding actual problems\n\ -easier. It is intended to be invoked from Makefiles, like this. Instead of:\n\ -\n\ - .c.o:\n\ - $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ -\n\ -Rewrite your rule so it looks like:\n\ -\n\ - .c.o:\n\ - @ccdv $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ - .cpp.o:\n\ - @ccdv $(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ -\n\ -ccdv 1.1.0 is Free under the GNU Public License. Enjoy!\n\ - -- Mike Gleason, NcFTP Software \n\ - -- John F Meinel Jr, \n\ - "; - fprintf(stderr, sUsage); - exit(96); -} /* Usage */ - -int main(int argc, char **argv) -{ - int pipe1[2]; - int devnull; - char emerg[256]; - int fd; - int nread; - int i; - int cc = 0; - int yy = 0; - int gcc = 0; - int lemon = 0; - const char *quote; - - if(argc < 2) - Usage(); - - snprintf(gAction, sizeof(gAction), "Running %s", Basename(argv[1])); - memset(gArgsStr, 0, sizeof(gArgsStr)); - - if(strcmp(gAction+8, "cc") == 0 || - strcmp(gAction+8, "ld") == 0 || - strcmp(gAction+8, "gcc") == 0 || - strcmp(gAction+8, "g++") == 0 || - strcmp(gAction+8, "c++") == 0) - { - gcc = 1; - } - else if(strcmp(gAction+8, "lemon") == 0) - { - lemon = 1; - } - - for(i = 1; i < argc; i++) - { - quote = (strchr(argv[i], ' ') != NULL) ? "\"" : ""; - snprintf(gArgsStr + strlen(gArgsStr), - sizeof(gArgsStr) - strlen(gArgsStr), "%s%s%s%s%s", - (i == 1) ? "" : " ", quote, argv[i], quote, - (i == (argc - 1)) ? "\n" : ""); - if(gcc && (strcmp(argv[i], "-o") == 0) && ((i + 1) < argc)) - { - if(strcasecmp(Extension(argv[i + 1]), ".o") != 0) - { - strcpy(gAction, "Linking"); - snprintf(gTarget, sizeof(gTarget), "%s", - Basename(argv[i + 1])); - } - } - else if(strchr("-+/", (int) argv[i][0]) != NULL) - { - continue; - } - else if(strncasecmp(Extension(argv[i]), ".c", 2) == 0) - { - cc++; - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); - } - else if(strncasecmp(Extension(argv[i]), ".y", 2) == 0) - { - if(lemon) - { - strcpy(gAction, "Generating"); - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); - } - yy++; - } - else if(strncasecmp(Extension(argv[i]), ".nas", 3) == 0 || - strncasecmp(Extension(argv[i]), ".asm", 3) == 0 || - strcasecmp(Extension(argv[i]), ".s") == 0) - { - strcpy(gAction, "Assembling"); - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); - } - else if((i == 1) && (strcmp(Basename(argv[i]), "ar") == 0)) - { - snprintf(gAr, sizeof(gAr), "%s", Basename(argv[i])); - } - else if((gArLibraryTarget[0] == '\0') - && (strcasecmp(Extension(argv[i]), ".a") == 0)) - { - snprintf(gArLibraryTarget, sizeof(gArLibraryTarget), "%s", - Basename(argv[i])); - } - } - if((gAr[0] != '\0') && (gArLibraryTarget[0] != '\0')) - { - strcpy(gAction, "Creating library"); - snprintf(gTarget, sizeof(gTarget), "%s", gArLibraryTarget); - } - else if(cc > 0) - { - strcpy(gAction, yy == 0 ? "Compiling" : "Generating"); - } - - if(pipe(pipe1) < 0) - { - perror("ccdv: pipe"); - exit(97); - } - - (void) close(0); - devnull = open("/dev/null", O_RDWR, 00666); - if((devnull != 0) && (dup2(devnull, 0) == 0)) - close(devnull); - - gCCPID = (int) fork(); - if(gCCPID < 0) - { - (void) close(pipe1[0]); - (void) close(pipe1[1]); - perror("ccdv: fork"); - exit(98); - } - else if(gCCPID == 0) - { - /* Child */ - (void) close(pipe1[0]); /* close read end */ - if(pipe1[1] != 1) - { /* use write end on stdout */ - (void) dup2(pipe1[1], 1); - (void) close(pipe1[1]); - } - (void) dup2(1, 2); /* use write end on stderr */ - execvp(argv[1], argv + 1); - perror(argv[1]); - exit(99); - } - - /* parent */ - (void) close(pipe1[1]); /* close write end */ - fd = pipe1[0]; /* use read end */ - - gColumns = (getenv("COLUMNS") != NULL) ? atoi(getenv("COLUMNS")) : 80; - gANSIEscapes = (getenv("TERM") != NULL) - && - (strstr - ("vt100:vt102:vt220:vt320:xterm:ansi:linux:scoterm:scoansi:dtterm:cons25:cygwin", - getenv("TERM")) != NULL); - gBuf = (char *) malloc(TEXT_BLOCK_SIZE); - if(gBuf == NULL) - goto panic; - gNBufUsed = 0; - gNBufAllocated = TEXT_BLOCK_SIZE; - if(strlen(gArgsStr) < (gNBufAllocated - 1)) - { - strcpy(gBuf, gArgsStr); - gNBufUsed = strlen(gArgsStr); - } - - if(isatty(1)) - { - if(SlurpProgress(fd) < 0) - goto panic; - } - else - { - if(SlurpAll(fd) < 0) - goto panic; - } - DumpFormattedOutput(); - exit(gExitStatus); - - panic: - gDumpCmdArgs = 1; /* print cmd when there are errors */ - DumpFormattedOutput(); - while((nread = read(fd, emerg, (size_t) sizeof(emerg))) > 0) - (void) write(2, emerg, (size_t) nread); - Wait(); - exit(gExitStatus); -} /* main */ - -/* eof ccdv.c */ diff --git a/ccdv-win32.c b/ccdv-win32.c deleted file mode 100644 index c3860452e..000000000 --- a/ccdv-win32.c +++ /dev/null @@ -1,742 +0,0 @@ -/* ccdv.c */ - -/* Ported to Win32 by Randy Heit - * Maybe I got a little carried away. This is pure Win32 code without any CRT in sight. - * - * To build this, use one of these command lines: - * - * [MinGW] gcc -Os -s -nostdlib -o ccdv.exe ccdv-win32.c -lkernel32 -luser32 - * [MSC] cl -O1 ccdv-win32.c -link -subsystem:console -opt:nowin98 kernel32.lib user32.lib - * - * Rewriting this to not use any global variables can save 512 bytes when compiled with MSC - * because it allows the .data section to be ommitted, which means the header can occupy - * 512 bytes rather than 1024. With GCC, it doesn't help the size any, since GCC still has - * the separate .idata and .rdata sections. Since MSC really doesn't need this tool, - * I'm not bothering with that size optimization. - */ - -#define WIN32_LEAN_AND_MEAN -#include - -#define COLOR_SUCCESS (FOREGROUND_GREEN|FOREGROUND_INTENSITY) /* green */ -#define COLOR_FAILURE (FOREGROUND_RED|FOREGROUND_INTENSITY) /* red */ -#define COLOR_WARNING (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY) /* yellow */ -#define COLOR_COMMAND (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY) /* cyan */ -#define COLOR_ERROROUTPUT (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY) /* magenta */ -#define COLOR_WARNINGOUTPUT (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY) /* white */ - -#define SETCOLOR_SUCCESS "\033[1;32m" /* green */ -#define SETCOLOR_FAILURE "\033[1;31m" /* red */ -#define SETCOLOR_WARNING "\033[0;33m" /* dark yellow */ -#define SETCOLOR_COMMAND "\033[1;35m" /* magenta */ -#define SETCOLOR_ERROROUTPUT "\033[1;31m" /* red */ -#define SETCOLOR_WARNINGOUTPUT "\033[1;39m" /* bold */ -#define SETCOLOR_NORMAL "\033[0;39m" /* normal */ - -#define TEXT_BLOCK_SIZE 8192 -#define INDENT 2 - -PROCESS_INFORMATION gCCP; -size_t gNBufUsed, gNBufAllocated; -char *gBuf; -char *gAction; -char *gTarget; -char *gAr; -char *gArLibraryTarget; -BOOL gDumpCmdArgs; -char *gArgsStr; -int gColumns; -BOOL gRxvt; -int gExitStatus; -HANDLE gHeap; - -HANDLE gStdOut, gStdErr; - -#ifdef __GNUC__ -#define REGPARM(x) __attribute((regparm(x))) -#else -#define REGPARM(x) -#endif - -void REGPARM(1) perror(const char *string) -{ - char *buffer; - char errcode[9]; - DWORD error = GetLastError(); - DWORD len = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, 0, (LPTSTR)&buffer, 0, NULL); - DWORD wrote; - WriteFile (gStdErr, string, lstrlen(string), &wrote, NULL); - wsprintf(errcode, "%08x", error); - WriteFile (gStdErr, ": Error 0x", 10, &wrote, NULL); - WriteFile (gStdErr, errcode, 8, &wrote, NULL); - if(len != 0) - { - WriteFile (gStdErr, "\n", 1, &wrote, NULL); - WriteFile (gStdErr, buffer, len, &wrote, NULL); - LocalFree(buffer); - } - WriteFile (gStdErr, "\n", 1, &wrote, NULL); - gColumns = 0; -} - -static int REGPARM(1) str2int(const char *string) -{ - int out = 0; - - while (*string >= '0' && *string <= '9') - { - out = out * 10 + *string++ - '0'; - } - return out; -} - -static void Writef(HANDLE hFile, const char *fmt, ...) -{ - char buf[1024]; - int buflen; - va_list arglist; - DWORD wrote; - - va_start(arglist, fmt); - buflen = wvsprintf(buf, fmt, arglist); - va_end(arglist); - WriteFile(hFile, buf, buflen, &wrote, NULL); -} - -static void DumpFormattedOutput() -{ - CONSOLE_SCREEN_BUFFER_INFO info; - DWORD out; - WORD color; - char *cp; - char spaces[8 + 1]; - char *saved; - int curcol; - int i; - - for(i = 0; i < 8; ++i) - { - spaces[i] = ' '; - } - spaces[i] = '\0'; - - if(gRxvt) - { - curcol = 0; - saved = NULL; - if(gDumpCmdArgs) - { - Writef(gStdOut, SETCOLOR_COMMAND "%s" SETCOLOR_NORMAL "\n", gArgsStr); - for(i = gColumns; i > 0; i -= 7) - { - WriteFile(gStdOut, "=======", i > 7 ? 7 : i, &out, NULL); - } - WriteFile(gStdOut, SETCOLOR_ERROROUTPUT, sizeof(SETCOLOR_ERROROUTPUT), &out, NULL); - } - else - { - WriteFile(gStdOut, SETCOLOR_WARNINGOUTPUT, sizeof(SETCOLOR_WARNINGOUTPUT), &out, NULL); - } - WriteFile(gStdOut, gBuf + lstrlen(gArgsStr), lstrlen(gBuf + lstrlen(gArgsStr)), &out, NULL); - WriteFile(gStdOut, SETCOLOR_NORMAL, sizeof(SETCOLOR_NORMAL), &out, NULL); - HeapFree(gHeap, 0, gBuf); - return; - } - - if(!GetConsoleScreenBufferInfo(gStdOut, &info)) - { - WriteFile(gStdOut, gBuf, lstrlen(gBuf), &out, NULL); - WriteFile(gStdOut, "\n", 1, &out, NULL); - HeapFree(gHeap, 0, gBuf); - return; - } - - color = info.wAttributes & ~(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY); - curcol = 0; - saved = NULL; - if(gDumpCmdArgs) - { - SetConsoleTextAttribute(gStdOut, color | COLOR_COMMAND); - WriteConsole(gStdOut, gBuf, lstrlen(gArgsStr)+1, &out, NULL); - SetConsoleTextAttribute(gStdOut, info.wAttributes); - for(i = gColumns; i > 0; i -= 7) - { - WriteConsole(gStdOut, "=======", i > 7 ? 7 : i, &out, NULL); - } - color |= COLOR_ERROROUTPUT; - } - else - { - color |= COLOR_WARNINGOUTPUT; - } - SetConsoleTextAttribute(gStdOut, color); - WriteConsole(gStdOut, gBuf + lstrlen(gArgsStr) + 1, lstrlen(gBuf + lstrlen(gArgsStr) + 1), &out, NULL); - SetConsoleTextAttribute(gStdOut, info.wAttributes); - HeapFree(gHeap, 0, gBuf); -} /* DumpFormattedOutput */ - -static void Wait(void) -{ - DWORD exitcode; - WaitForSingleObject(gCCP.hProcess, INFINITE); - GetExitCodeProcess(gCCP.hProcess, &exitcode); - gExitStatus = (int)exitcode; -} /* Wait */ - -static DWORD WINAPI SlurpThread(LPVOID foo) -{ - HANDLE fd = (HANDLE)foo; - char *newbuf; - DWORD ntoread; - DWORD nread; - - for(;;) - { - if(gNBufUsed == (gNBufAllocated - 1)) - { - if((newbuf = - (char *) HeapReAlloc(gHeap, 0, gBuf, - gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) - { - return 1; - } - gNBufAllocated += TEXT_BLOCK_SIZE; - gBuf = newbuf; - } - ntoread = (gNBufAllocated - gNBufUsed - 1); - if(!ReadFile(fd, gBuf + gNBufUsed, ntoread, &nread, NULL)) - { - return 2; - } - else if(nread > 0) - { - gNBufUsed += nread; - gBuf[gNBufUsed] = '\0'; - } - } - return 0; -} - -static void REGPARM(2) WriteAction(HANDLE hStdOut, const char *suffix) -{ - DWORD out; - - WriteFile(hStdOut, gAction, lstrlen(gAction), &out, NULL); - if(gTarget != NULL) - { - WriteFile(hStdOut, " ", 1, &out, NULL); - WriteFile(hStdOut, gTarget, lstrlen(gTarget), &out, NULL); - } - WriteFile(hStdOut, suffix, 3, &out, NULL); -} - -static int REGPARM(2) Slurp(HANDLE fd, HANDLE hStdOut) -{ - HANDLE handles[2]; - DWORD waitstate; - DWORD exitcode; - DWORD out; - DWORD threadid; - const char *trail = "/-\\|", *trailcp; - CONSOLE_SCREEN_BUFFER_INFO info; - CONSOLE_CURSOR_INFO cursorInfo; - WORD color, colors[5]; - int ncells, i; - - trailcp = trail; - if(hStdOut != NULL) - { - WriteAction(hStdOut, "..."); - } - - handles[0] = gCCP.hProcess; - handles[1] = CreateThread(NULL, 0, SlurpThread, (LPVOID)fd, 0, &threadid); - - if(handles[1] == 0) - { - perror("ccdv: CreateThread"); - return -1; - } - - if(hStdOut != NULL) - { - if(!gRxvt) - { - GetConsoleScreenBufferInfo(hStdOut, &info); - info.dwCursorPosition.X = info.dwSize.X - 9; - } - if(GetConsoleCursorInfo(hStdOut, &cursorInfo)) - { - cursorInfo.bVisible = FALSE; - SetConsoleCursorInfo(hStdOut, &cursorInfo); - } - else - { - cursorInfo.bVisible = TRUE; - } - } - - gExitStatus = 0xabadcafe; - while(gExitStatus == 0xabadcafe) - { - waitstate = WaitForMultipleObjects(2, handles, FALSE, 1000); - switch(waitstate) - { - case WAIT_TIMEOUT: - if(hStdOut != NULL) - { - if(!gRxvt) - { - SetConsoleCursorPosition(hStdOut, info.dwCursorPosition); - WriteConsoleA(hStdOut, trailcp, 1, &out, NULL); - } - else - { - Writef(hStdOut, "\033[999C\033[9D%c", *trailcp); - } - if(*++trailcp == '\0') - trailcp = trail; - } - break; - - case WAIT_FAILED: - perror("ccdv: WaitForMultipleObjects"); - CloseHandle(handles[1]); - return -1; - - case WAIT_OBJECT_0: - GetExitCodeProcess(gCCP.hProcess, &exitcode); - CloseHandle(handles[1]); - gExitStatus = (int)exitcode; - break; - - case WAIT_OBJECT_0+1: - GetExitCodeThread(handles[1], &exitcode); - CloseHandle(handles[1]); - if(exitcode == 1) - { - perror("ccdv: HeapReAlloc"); - return -1; - } - else if(exitcode == 2) - { - perror("ccdv: ReadFile"); - return -1; - } - Wait(); - break; - } - } - if(hStdOut != NULL) - { - if(!gRxvt) - { - info.dwCursorPosition.X = 0; - SetConsoleCursorPosition(hStdOut, info.dwCursorPosition); - WriteAction(hStdOut, ": "); - info.dwCursorPosition.X = info.dwSize.X - 10; - if(gExitStatus == 0) - { - SetConsoleCursorPosition(hStdOut, info.dwCursorPosition); - WriteConsoleA(hStdOut, "[OK] ", 9, &out, NULL); - color = ((gNBufUsed - lstrlen(gArgsStr)) < 4) ? COLOR_SUCCESS : COLOR_WARNING; - ncells = 2; - } - else - { - SetConsoleCursorPosition(hStdOut, info.dwCursorPosition); - WriteConsoleA(hStdOut, "[ERROR] ", 9, &out, NULL); - color = COLOR_FAILURE; - ncells = 5; - gDumpCmdArgs = 1; /* print cmd when there are errors */ - } - color |= info.wAttributes & ~(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY); - for(i = 0; i < ncells; ++i) - { - colors[i] = color; - } - info.dwCursorPosition.X++; - WriteConsoleOutputAttribute(hStdOut, colors, ncells, info.dwCursorPosition, &out); - if(!cursorInfo.bVisible) - { - cursorInfo.bVisible = TRUE; - SetConsoleCursorInfo(hStdOut, &cursorInfo); - } - WriteConsole(hStdOut, "\n", 1, &out, NULL); - } - else - { - WriteFile(hStdOut, "\033[255D", 6, &out, NULL); - WriteAction(hStdOut, ": "); - if(gExitStatus == 0) - { - Writef(hStdOut, "\033[999C\033[10D[%sOK%s]", - ((gNBufUsed - strlen(gArgsStr)) < - 4) ? SETCOLOR_SUCCESS : SETCOLOR_WARNING, SETCOLOR_NORMAL); - } - else - { - Writef(hStdOut, "\033[999C\033[10D[%sERROR%s]\n", - SETCOLOR_FAILURE, SETCOLOR_NORMAL); - gDumpCmdArgs = 1; /* print cmd when there are errors */ - } - } - } - else - { - gDumpCmdArgs = (gExitStatus != 0); /* print cmd when there are errors */ - } - return (0); -} /* SlurpProgress */ - -static const char *REGPARM(2) Basename(const char *path, int len) -{ - while(len > 0) - { - len--; - if(path[len] == '/' || path[len] == '\\') - { - return path + len + 1; - } - } - return path; -} /* Basename */ - -static const char *REGPARM(2) Extension(const char *path, int len) -{ - while(len > 0) - { - len--; - if(path[len] == '.') - { - return path + len; - } - } - return ""; -} /* Extension */ - -static void Usage(void) -{ - static const char sUsage[] = "\ -Usage: ccdv /path/to/cc CFLAGS...\n\ -\n\ -I wrote this to reduce the deluge Make output to make finding actual problems\n\ -easier. It is intended to be invoked from Makefiles, like this. Instead of:\n\ -\n\ - .c.o:\n\ - $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ -\n\ -Rewrite your rule so it looks like:\n\ -\n\ - .c.o:\n\ - @ccdv $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ - .cpp.o:\n\ - @ccdv $(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\ -\n\ -ccdv 1.1.0 is Free under the GNU Public License. Enjoy!\n\ - -- Mike Gleason, NcFTP Software \n\ - -- John F Meinel Jr, \n\ - "; - DWORD out; - WriteFile (gStdErr, sUsage, sizeof(sUsage)-1, &out, NULL); - ExitProcess(96); -} /* Usage */ - -static BOOL REGPARM(3) StepCmdLine(char **cmdline, char **arg, int *arglen) -{ - char *gArgsStr = *cmdline; - - // Skip whitespace - while(*gArgsStr == ' ' || *gArgsStr == '\t' || *gArgsStr == '\n' || *gArgsStr == '\r') - { - gArgsStr++; - } - if(*gArgsStr == 0) - { - *cmdline = gArgsStr; - return FALSE; - } - if(*gArgsStr == '\"') - { // It's a quoted string - *arg = ++gArgsStr; - while(*gArgsStr && *gArgsStr != '\"') - { - gArgsStr++; - } - *arglen = gArgsStr - *arg; - if(*gArgsStr) - { // Ends with a quote - gArgsStr++; - } - *cmdline = gArgsStr; - return TRUE; - } - // It's a whitespace-separated string - *arg = gArgsStr; - while(*gArgsStr && *gArgsStr != ' ' && *gArgsStr != '\t' && *gArgsStr != '\n' && *gArgsStr != '\r') - { - gArgsStr++; - } - *arglen = gArgsStr - *arg; - *cmdline = gArgsStr; - return TRUE; -} - -static void REGPARM(3) SetTarget(char **target, const char *arg, int arglen) -{ - const char *base; - - if (*target) HeapFree(gHeap, 0, *target); - base = Basename(arg, arglen); - arglen = arglen - (base - arg) + 1; - *target = HeapAlloc(gHeap, 0, arglen); - lstrcpyn(*target, base, arglen); -} - -void mainCRTStartup(void) -{ - const char *ext; - char *cmdline, *arg; - int arglen, extlen; - SECURITY_ATTRIBUTES security; - STARTUPINFO siStartInfo; - HANDLE pipeRd, pipeWr, pipeRdDup; - char emerg[256]; - DWORD nread; - int cc = 0; - int yy = 0; - int gcc = 0; - int lemon = 0; - CONSOLE_SCREEN_BUFFER_INFO bufferInfo; - - gExitStatus = 95; - gHeap = GetProcessHeap(); - gArgsStr = cmdline = GetCommandLine(); - gStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - gStdErr = GetStdHandle(STD_ERROR_HANDLE); - - if (!StepCmdLine(&cmdline, &arg, &arglen) || // Skip ccdv.exe - !StepCmdLine(&cmdline, &arg, &arglen)) // Read name of process to run - { - Usage(); - } - - if(GetConsoleScreenBufferInfo(gStdOut, &bufferInfo)) - { - gColumns = bufferInfo.dwSize.X; - } - else - { - char envbuf[16]; - DWORD envlen; - - // Check for MSYS by checking for an rxvt COLORTERM. - envlen = GetEnvironmentVariable("COLORTERM", envbuf, sizeof(envbuf)); - if(envlen > 0 && envlen < sizeof(envbuf) - 1) - { - if(lstrcmp(envbuf, "rxvt") == 0) - { - gRxvt = TRUE; - - // We're in an rxvt, so check the number of columns. - // Unfortunately, COLUMNS is not exported by default by MSYS. - envlen = GetEnvironmentVariable("COLUMNS", envbuf, sizeof(envbuf)); - if(envlen > 0 && envlen < sizeof(envbuf) - 1) - { - gColumns = str2int(envbuf); - } - else - { - gColumns = 80; - } - } - } - } - - // "Running *argv[1]*" - ext = Basename(arg, arglen); - extlen = arglen - (ext - arg); - gAction = HeapAlloc(gHeap, 0, 64+extlen); - lstrcpy(gAction, "Running "); - lstrcpyn(gAction+8, ext, extlen+1); - - if (extlen == 2 && lstrcmpi(gAction+8, "ar") == 0) - { - SetTarget(&gAr, arg, arglen); - } - else if((extlen == 2 && - (lstrcmpi(gAction+8, "cc") == 0 || - lstrcmpi(gAction+8, "cl") == 0 || - lstrcmpi(gAction+8, "ld") == 0)) || - (extlen == 3 && - (lstrcmpi(gAction+8, "gcc") == 0 || - lstrcmpi(gAction+8, "g++") == 0)) || - (extlen == 7 && lstrcmpi(gAction+8, "windres") == 0)) - { - gcc = 1; - } - else if(extlen == 5 && lstrcmpi(gAction+8, "lemon") == 0) - { - lemon = 1; - } - - while(StepCmdLine(&cmdline, &arg, &arglen)) - { - if(gcc && arglen == 2 && arg[0] == '-' && arg[1] == 'o') - { - if(StepCmdLine(&cmdline, &arg, &arglen)) - { - ext = Extension(arg, arglen); - if(ext[0] != '.' || (ext[1] != 'o' && ext[1] != 'O')) - { - lstrcpy(gAction, "Linking"); - SetTarget(&gTarget, arg, arglen); - } - } - continue; - } - else if(arg[0] == '-' || arg[0] == '+' || arg[0] == '/') - { - continue; - } - ext = Extension(arg, arglen); - if(ext[0] == '.' && (ext[1] == 'C' || ext[1] == 'c')) - { - cc++; - SetTarget(&gTarget, arg, arglen); - } - else if(ext[0] == '.' && ext[1] == 'y') - { - if(lemon) - { - lstrcpy(gAction, "Generating"); - SetTarget(&gTarget, arg, arglen); - gTarget[arglen-1] = 'c'; - } - yy++; - } - else if(ext[0] == '.' && ext[1] == 'r' && ext[2] == 'e') - { - yy++; - } - else if((ext[0] == '.' && ext[1] == 'n' && ext[2] == 'a' && ext[3] == 's') || - (ext[0] == '.' && ext[1] == 'a' && ext[2] == 's' && ext[3] == 'm') || - (ext[0] == '.' && ext[1] == 's')) - { - lstrcpy(gAction, "Assembling"); - SetTarget(&gTarget, arg, arglen); - } - else if(gArLibraryTarget == NULL && ext[0] == '.' && ext[1] == 'a') - { - SetTarget(&gArLibraryTarget, arg, arglen); - } - } - if((gAr != NULL) && (gArLibraryTarget != NULL)) - { - lstrcpy(gAction, "Creating library"); - if(gTarget != NULL) HeapFree(gHeap, 0, gTarget); - gTarget = gArLibraryTarget; - gArLibraryTarget = NULL; - } - else if(cc > 0) - { - lstrcpy(gAction, yy == 0 ? "Compiling" : "Generating"); - } - - /* Initialize security attributes for the pipe */ - security.nLength = sizeof security; - security.lpSecurityDescriptor = NULL; - security.bInheritHandle = TRUE; - - if(!CreatePipe(&pipeRd, &pipeWr, &security, 0)) - { - perror("ccdv: pipe"); - ExitProcess(97); - } - - if (!DuplicateHandle(GetCurrentProcess(), pipeRd, - GetCurrentProcess(), &pipeRdDup , 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - { - perror("ccdv: DuplicateHandle"); - } - CloseHandle(pipeRd); - - /* Initialize startup info for the child process */ - siStartInfo.cb = sizeof siStartInfo; - siStartInfo.lpReserved = NULL; - siStartInfo.lpDesktop = NULL; - siStartInfo.lpTitle = NULL; - siStartInfo.dwX = 0; - siStartInfo.dwY = 0; - siStartInfo.dwXSize = 0; - siStartInfo.dwYSize = 0; - siStartInfo.dwXCountChars = 0; - siStartInfo.dwYCountChars = 0; - siStartInfo.dwFillAttribute = 0; - siStartInfo.dwFlags = STARTF_USESTDHANDLES; - siStartInfo.wShowWindow = 0; - siStartInfo.cbReserved2 = 0; - siStartInfo.lpReserved2 = 0; - siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - siStartInfo.hStdOutput = pipeWr; - siStartInfo.hStdError = pipeWr; - - StepCmdLine(&gArgsStr, &arg, &arglen); // Skip "ccdv" - while(*gArgsStr == ' ' || *gArgsStr == '\t' || *gArgsStr == '\n' || *gArgsStr == '\r') - gArgsStr++; - - extlen = lstrlen(gArgsStr); - gNBufAllocated = extlen + TEXT_BLOCK_SIZE; - gBuf = (char *) HeapAlloc(gHeap, 0, gNBufAllocated); - if(gBuf == NULL) - goto panic; - gNBufUsed = extlen + 1; - lstrcpy(gBuf, gArgsStr); - gBuf[extlen] = '\n'; - gBuf[extlen+1] = 0; - - if(!CreateProcessA(NULL, - gArgsStr, /* command gArgsStr */ - NULL, /* process security attributes */ - NULL, /* primary thread security attributes */ - TRUE, /* handles are inherited */ - 0, /* creation flags */ - NULL, /* use parent's environment */ - NULL, /* use parent's current directory */ - &siStartInfo, /* STARTUPINFO pointer */ - &gCCP)) /* receives PROCESS_INFORMATION */ - { - CloseHandle(pipeRdDup); - CloseHandle(pipeWr); - perror("ccdv: CreateProcess"); - gExitStatus = 98; - goto panic; - } - CloseHandle(gCCP.hThread); - - if(!gRxvt) - { - if(Slurp(pipeRdDup, gStdOut) < 0) - goto panic; - } - else - { - if(Slurp(pipeRdDup, gStdOut) < 0) - goto panic; - } - DumpFormattedOutput(); - ExitProcess(gExitStatus); - - panic: - gDumpCmdArgs = 1; /* print cmd when there are errors */ - DumpFormattedOutput(); - while(ReadFile(pipeRdDup, emerg, sizeof emerg, &nread, NULL) && nread > 0) - WriteFile(gStdErr, emerg, nread, &nread, NULL); - Wait(); - ExitProcess(gExitStatus); -} /* main */ - -/* eof ccdv.c */ diff --git a/docs/rh-log.txt b/docs/rh-log.txt index c5685f00e..34b459e57 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,26 @@ +July 21, 2008 +- Converted most sprintf (and all wsprintf) calls to either mysnprintf or + FStrings, depending on the situation. +- Changed the strings in the wbstartstruct to be FStrings. +- Changed myvsnprintf() to output nothing if count is greater than INT_MAX. + This is so that I can use a series of mysnprintf() calls and advance the + pointer for each one. Once the pointer goes beyond the end of the buffer, + the count will go negative, but since it's an unsigned type it will be + seen as excessively huge instead. This should not be a problem, as there's + no reason for ZDoom to be using text buffers larger than 2 GB anywhere. +- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig(). +- Changed CalcMapName() to return an FString instead of a pointer to a static + buffer. +- Changed startmap in d_main.cpp into an FString. +- Changed CheckWarpTransMap() to take an FString& as the first argument. +- Changed d_mapname in g_level.cpp into an FString. +- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an + FString. +- Fixed: The MAPINFO parser wrote into the string buffer to construct a map + name when given a Hexen map number. This was fine with the old scanner + code, but only a happy coincidence prevents it from crashing with the new + code. + July 21, 2008 (Changes by Graf Zahl) - Added MF4_BOSSDEATH to the Minotaur. - Fixed: The boss brain looped to the wrong state. @@ -31,6 +54,31 @@ July 18, 2008 (Changes by Graf Zahl) - Added const char &operator[] (unsigned int index) to FString class. - Added Skulltag's Teleport_NoStop action special. +July 17, 2008 +- Added the 'B' conversion specifier to StringFormat::VWorker() for printing + binary numbers. + +July 16, 2008 +- Added CMake support for building with MinGW, MSYS, and NMake. Linux support + is probably broken until I get around to booting into Linux again. Niceties + provided over the existing Makefiles they're replacing: + * All command-line builds can use the same build system, rather than having + a separate one for MinGW and another for Linux. + * Microsoft's NMake tool is supported as a target. + * Progress meters. + * Parallel makes work from a fresh checkout without needing to be primed + first with a single-threaded make. + * Porting to other architectures should be simplified, whenever that day + comes. + +July 15, 2008 +- Replaced the makewad tool with zipdir. This handles the dependency tracking + itself instead of generating an external makefile to do it, since I couldn't + figure out how to generate a makefile with an external tool and include it + with a CMake-generated makefile. Where makewad used a master list of files + to generate the package file, zipdir just zips the entire contents of one or + more directories. + July 15, 2008 (Changes by Graf Zahl) - Fixed: Strife's EntityBoss didn't copy friendliness information to the sub-entities. @@ -56,6 +104,10 @@ July 12, 2008 (Changes by Graf Zahl) - Fixed: ACS's ActivatorSound must check if the activator is valid. - Changed stats drawing so that multi-line strings can be used. +July 9, 2008 +- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style + formatting can be entirely independant of the CRT. + July 5, 2008 - Added a check to G_DoSaveGame() to prevent saving when you're not actually in a level. diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt new file mode 100644 index 000000000..32e4c8c7d --- /dev/null +++ b/dumb/CMakeLists.txt @@ -0,0 +1,93 @@ +cmake_minimum_required( VERSION 2.6 ) +project( dumb ) + +# DUMB is much slower in a Debug build than a Release build, so we force a Release +# build here, since we're not maintaining DUMB, only using it. +# Comment out the below line to allow Debug builds. +set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) + +set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DDEBUGMODE=1" ) + +if( CMAKE_COMPILER_IS_GNUC ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-pointer-sign -Wno-uninitialized" ) +endif( CMAKE_COMPILER_IS_GNUC ) + +include_directories( include ) + +add_library( dumb + src/core/atexit.c + src/core/duhlen.c + src/core/duhtag.c + src/core/dumbfile.c + src/core/loadduh.c + src/core/makeduh.c + src/core/rawsig.c + src/core/readduh.c + src/core/register.c + src/core/rendduh.c + src/core/rendsig.c + src/core/unload.c + src/helpers/barray.c + src/helpers/clickrem.c + src/helpers/memfile.c + src/helpers/resample.c + src/helpers/riff.c + src/helpers/sampbuf.c + src/helpers/silence.c + src/helpers/stdfile.c + src/it/filter.cpp + src/it/itload.c + src/it/itload2.c + src/it/itmisc.c + src/it/itorder.c + src/it/itread.c + src/it/itread2.c + src/it/itrender.c + src/it/itunload.c + src/it/load669.c + src/it/load6692.c + src/it/loadasy.c + src/it/loadasy2.c + src/it/loadmod.c + src/it/loadmod2.c + src/it/loadmtm.c + src/it/loadmtm2.c + src/it/loadoldpsm.c + src/it/loadoldpsm2.c + src/it/loadpsm.c + src/it/loadpsm2.c + src/it/loadptm.c + src/it/loadptm2.c + src/it/loadriff.c + src/it/loadriff2.c + src/it/loads3m.c + src/it/loads3m2.c + src/it/loadstm.c + src/it/loadstm2.c + src/it/loadxm.c + src/it/loadxm2.c + src/it/ptmeffect.c + src/it/read669.c + src/it/read6692.c + src/it/readam.c + src/it/readasy.c + src/it/readdsmf.c + src/it/readmod.c + src/it/readmod2.c + src/it/readmtm.c + src/it/readoldpsm.c + src/it/readpsm.c + src/it/readptm.c + src/it/readriff.c + src/it/reads3m.c + src/it/reads3m2.c + src/it/readstm.c + src/it/readstm2.c + src/it/readxm.c + src/it/readxm2.c + src/it/xmeffect.c ) +target_link_libraries( dumb ) + +if( CMAKE_COMPILER_IS_GNUCXX ) + set_source_files_properties( src/it/filter.cpp PROPERTIES COMPILE_FLAGS -msse ) +endif( CMAKE_COMPILER_IS_GNUCXX ) diff --git a/dumb/Makefile b/dumb/Makefile deleted file mode 100644 index 8134212a6..000000000 --- a/dumb/Makefile +++ /dev/null @@ -1,197 +0,0 @@ -# Makefile for DUMB, derived from zlib/Makefile.mgw. -# Yes, I have forgone the Makefiles provided with DUMB, since they weren't kept -# up to date with kode54's changes. - -CMD=0 -ifeq (Windows_NT,$(OS)) - CMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - CMD=0 - endif -endif - -CCDV := @../ccdv - -CC := gcc -CFLAGS := $(LOC) -O3 -Wall -fomit-frame-pointer - -LD := $(CC) -LDFLAGS := $(LOC) -s - -AR := ar -ARFLAGS := rcs - -CONFIG ?= Release - -# Macro for replacing / with \ where necessary. Usage: $(call FIX,path) -FIX = $(subst /,\,$(subst /*,\\\*,$(1))) - -CORE_MODULES = \ - core/atexit.c \ - core/duhlen.c \ - core/duhtag.c \ - core/dumbfile.c \ - core/loadduh.c \ - core/makeduh.c \ - core/rawsig.c \ - core/readduh.c \ - core/register.c \ - core/rendduh.c \ - core/rendsig.c \ - core/unload.c \ - helpers/barray.c \ - helpers/clickrem.c \ - helpers/memfile.c \ - helpers/resample.c \ - helpers/riff.c \ - helpers/sampbuf.c \ - helpers/silence.c \ - helpers/stdfile.c \ - it/filter.cpp \ - it/itload.c \ - it/itload2.c \ - it/itmisc.c \ - it/itorder.c \ - it/itread.c \ - it/itread2.c \ - it/itrender.c \ - it/itunload.c \ - it/load669.c \ - it/load6692.c \ - it/loadasy.c \ - it/loadasy2.c \ - it/loadmod.c \ - it/loadmod2.c \ - it/loadmtm.c \ - it/loadmtm2.c \ - it/loadoldpsm.c \ - it/loadoldpsm2.c \ - it/loadpsm.c \ - it/loadpsm2.c \ - it/loadptm.c \ - it/loadptm2.c \ - it/loadriff.c \ - it/loadriff2.c \ - it/loads3m.c \ - it/loads3m2.c \ - it/loadstm.c \ - it/loadstm2.c \ - it/loadxm.c \ - it/loadxm2.c \ - it/ptmeffect.c \ - it/read669.c \ - it/read6692.c \ - it/readam.c \ - it/readasy.c \ - it/readdsmf.c \ - it/readmod.c \ - it/readmod2.c \ - it/readmtm.c \ - it/readoldpsm.c \ - it/readpsm.c \ - it/readptm.c \ - it/readriff.c \ - it/reads3m.c \ - it/reads3m2.c \ - it/readstm.c \ - it/readstm2.c \ - it/readxm.c \ - it/readxm2.c \ - it/xmeffect.c - -LIBDIR := lib -OBJDIR_BASE := obj - -WFLAGS := -Wall -W -Wstrict-prototypes -Wmissing-declarations -Wno-pointer-sign -Wno-uninitialized -WFLAGS_ALLEGRO := -Wno-missing-declarations -OFLAGS := -O2 -ffast-math -fomit-frame-pointer -DBGFLAGS := -DDEBUGMODE=1 -g3 - -CFLAGS_RELEASE := -Iinclude $(OFLAGS) -DNDEBUG -CFLAGS_DEBUG := -Iinclude $(DBGFLAGS) -D_DEBUG - -LDFLAGS := -s - -CORE_LIB_FILE_RELEASE := $(LIBDIR)/libdumb.a -CORE_LIB_FILE_DEBUG := $(LIBDIR)/libdumbd.a - -ifeq ($(CONFIG),Debug) - OBJDIR = $(OBJDIR_BASE)/debug - CFLAGS_BASE = $(CFLAGS_DEBUG) - CORE_LIB_FILE := $(CORE_LIB_FILE_DEBUG) -endif -ifeq ($(CONFIG),Release) - OBJDIR = $(OBJDIR_BASE)/release - CFLAGS_BASE = $(CFLAGS_RELEASE) - CORE_LIB_FILE := $(CORE_LIB_FILE_RELEASE) -endif - -CFLAGS = $(CFLAGS_BASE) $(WFLAGS) - -all: make-outdirs core - -core: $(CORE_LIB_FILE) - -make-outdirs: -ifeq (0,$(CMD)) - mkdir -p $(LIBDIR) - mkdir -p $(OBJDIR_BASE)/debug - mkdir -p $(OBJDIR_BASE)/release -else - -@if not exist $(call FIX,"$(LIBDIR)") mkdir $(call FIX,"$(LIBDIR)") - -@if not exist $(call FIX,"$(OBJDIR_BASE)/debug") mkdir $(call FIX,"$(OBJDIR_BASE)/debug") - -@if not exist $(call FIX,"$(OBJDIR_BASE)/release") mkdir $(call FIX,"$(OBJDIR_BASE)/release") -endif - -.PHONY: clean - -clean: -ifeq (0,$(CMD)) - rm -f $(CORE_LIB_FILE_RELEASE) - rm -f $(CORE_LIB_FILE_DEBUG) - rm -f $(OBJDIR_BASE)/debug/*.o - rm -f $(OBJDIR_BASE)/release/*.o - rmdir $(LIBDIR) >/dev/null - rmdir $(OBJDIR_BASE)/debug >/dev/null - rmdir $(OBJDIR_BASE)/release >/dev/null - rmdir $(OBJDIR_BASE) >/dev/null -else - -del /q /f $(call FIX,"$(CORE_LIB_FILE_RELEASE)") 2>nul - -del /q /f $(call FIX,"$(CORE_LIB_FILE_DEBUG)") 2>nul - -del /q /f $(call FIX,"$(OBJDIR_BASE)/debug/")*.o 2>nul - -del /q /f $(call FIX,"$(OBJDIR_BASE)/release/")*.o 2>nul - -rmdir /q $(call FIX,"$(LIBDIR)") 2>nul - -rmdir /q $(call FIX,"$(OBJDIR_BASE)/debug") 2>nul - -rmdir /q $(call FIX,"$(OBJDIR_BASE)/release") 2>nul - -rmdir /q $(call FIX,"$(OBJDIR_BASE)") 2>nul -endif - -CORE_OBJECTS := $(addprefix $(OBJDIR)/, $(notdir $(patsubst %.cpp, %.o, $(CORE_MODULES:%.c=%.o)))) - - -# Pass the current value of CFLAGS through to the commands. Or, more -# accurately, create a local copy of the current CFLAGS variable. This is -# necessary because Make doesn't expand variables in commands until they are -# executed. -$(CORE_LIB_FILE): CFLAGS := $(CFLAGS) - - -$(OBJDIR)/%.o: src/core/%.c include/dumb.h include/internal/dumb.h - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(OBJDIR)/%.o: src/helpers/%.c include/dumb.h - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(OBJDIR)/resample.o: src/helpers/resample.inc - -$(OBJDIR)/%.o: src/it/%.c include/dumb.h include/internal/it.h - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(OBJDIR)/%.o: src/it/%.cpp include/dumb.h include/internal/it.h - $(CCDV) $(CXX) $(CFLAGS_BASE) -msse -Wall -W -c -o $@ $< - -$(OBJDIR)/%.o: src/sigtypes/%.c include/dumb.h - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(CORE_LIB_FILE): $(CORE_OBJECTS) - $(CCDV) $(AR) $(ARFLAGS) $@ $^ diff --git a/dumb/vc6/dumb_static/dumb_static.vcproj b/dumb/vc6/dumb_static/dumb_static.vcproj index c838d8e42..128b3b9d9 100644 --- a/dumb/vc6/dumb_static/dumb_static.vcproj +++ b/dumb/vc6/dumb_static/dumb_static.vcproj @@ -1970,6 +1970,10 @@ + + diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt new file mode 100644 index 000000000..4b3c5a6ef --- /dev/null +++ b/gdtoa/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required( VERSION 2.6 ) +project( gdtoa ) + +set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) + +# Disable warnings for << operator precedence (4554) and +# unreferenced labels (4102) from VC +if( MSVC ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4554 /wd4102" ) +endif( MSVC ) + +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) +add_definitions( -DINFNAN_CHECK -DMULTIPLE_THREADS ) + +if( NOT MSVC ) + add_executable( arithchk arithchk.c ) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arith.h + COMMAND arithchk >${CMAKE_CURRENT_BINARY_DIR}/arith.h + DEPENDS arithchk ) + + add_executable( qnan qnan.c arith.h ) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h + COMMAND qnan >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h + DEPENDS qnan ) + + set( GEN_FP_FILES arith.h gd_qnan.h ) + set( GEN_FP_DEPS ${CMAKE_CURRENT_BINARY_DIR}/arith.h ${CMAKE_CURRENTY_BINARY_DIR}/gd_qnan.h ) +endif( NOT MSVC ) + +add_library( gdtoa + ${GEN_FP_FILES} + dmisc.c + dtoa.c + g_Qfmt.c + g__fmt.c + g_ddfmt.c + g_dfmt.c + g_ffmt.c + g_xLfmt.c + g_xfmt.c + gdtoa.c + gethex.c + gmisc.c + hd_init.c + hexnan.c + misc.c + smisc.c + strtoIQ.c + strtoId.c + strtoIdd.c + strtoIf.c + strtoIg.c + strtoIx.c + strtoIxL.c + strtod.c + strtodI.c + strtodg.c + strtof.c + strtopQ.c + strtopd.c + strtopdd.c + strtopf.c + strtopx.c + strtopxL.c + strtorQ.c + strtord.c + strtordd.c + strtorf.c + strtorx.c + strtorxL.c + sum.c + ulp.c) +target_link_libraries( gdtoa ) +if( GEN_FP_DEPS ) + add_dependencies( gdtoa ${GEN_FP_DEPS} ) +endif( GEN_FP_DEPS ) + diff --git a/gdtoa/README b/gdtoa/README new file mode 100644 index 000000000..cf1947aa2 --- /dev/null +++ b/gdtoa/README @@ -0,0 +1,336 @@ +This directory contains source for a library of binary -> decimal +and decimal -> binary conversion routines, for single-, double-, +and extended-precision IEEE binary floating-point arithmetic, and +other IEEE-like binary floating-point, including "double double", +as in + + T. J. Dekker, "A Floating-Point Technique for Extending the + Available Precision", Numer. Math. 18 (1971), pp. 224-242 + +and + + "Inside Macintosh: PowerPC Numerics", Addison-Wesley, 1994 + +The conversion routines use double-precision floating-point arithmetic +and, where necessary, high precision integer arithmetic. The routines +are generalizations of the strtod and dtoa routines described in + + David M. Gay, "Correctly Rounded Binary-Decimal and + Decimal-Binary Conversions", Numerical Analysis Manuscript + No. 90-10, Bell Labs, Murray Hill, 1990; + http://cm.bell-labs.com/cm/cs/what/ampl/REFS/rounding.ps.gz + +(based in part on papers by Clinger and Steele & White: see the +references in the above paper). + +The present conversion routines should be able to use any of IEEE binary, +VAX, or IBM-mainframe double-precision arithmetic internally, but I (dmg) +have so far only had a chance to test them with IEEE double precision +arithmetic. + +The core conversion routines are strtodg for decimal -> binary conversions +and gdtoa for binary -> decimal conversions. These routines operate +on arrays of unsigned 32-bit integers of type ULong, a signed 32-bit +exponent of type Long, and arithmetic characteristics described in +struct FPI; FPI, Long, and ULong are defined in gdtoa.h. File arith.h +is supposed to provide #defines that cause gdtoa.h to define its +types correctly. File arithchk.c is source for a program that +generates a suitable arith.h on all systems where I've been able to +test it. + +The core conversion routines are meant to be called by helper routines +that know details of the particular binary arithmetic of interest and +convert. The present directory provides helper routines for 5 variants +of IEEE binary floating-point arithmetic, each indicated by one or +two letters: + + f IEEE single precision + d IEEE double precision + x IEEE extended precision, as on Intel 80x87 + and software emulations of Motorola 68xxx chips + that do not pad the way the 68xxx does, but + only store 80 bits + xL IEEE extended precision, as on Motorola 68xxx chips + Q quad precision, as on Sun Sparc chips + dd double double, pairs of IEEE double numbers + whose sum is the desired value + +For decimal -> binary conversions, there are three families of +helper routines: one for round-nearest: + + strtof + strtod + strtodd + strtopd + strtopf + strtopx + strtopxL + strtopQ + +one with rounding direction specified: + + strtorf + strtord + strtordd + strtorx + strtorxL + strtorQ + +and one for computing an interval (at most one bit wide) that contains +the decimal number: + + strtoIf + strtoId + strtoIdd + strtoIx + strtoIxL + strtoIQ + +The latter call strtoIg, which makes one call on strtodg and adjusts +the result to provide the desired interval. On systems where native +arithmetic can easily make one-ulp adjustments on values in the +desired floating-point format, it might be more efficient to use the +native arithmetic. Routine strtodI is a variant of strtoId that +illustrates one way to do this for IEEE binary double-precision +arithmetic -- but whether this is more efficient remains to be seen. + +Functions strtod and strtof have "natural" return types, float and +double -- strtod is specified by the C standard, and strtof appears +in the stdlib.h of some systems, such as (at least some) Linux systems. +The other functions write their results to their final argument(s): +to the final two argument for the strtoI... (interval) functions, +and to the final argument for the others (strtop... and strtor...). +Where possible, these arguments have "natural" return types (double* +or float*), to permit at least some type checking. In reality, they +are viewed as arrays of ULong (or, for the "x" functions, UShort) +values. On systems where long double is the appropriate type, one can +pass long double* final argument(s) to these routines. The int value +that these routines return is the return value from the call they make +on strtodg; see the enum of possible return values in gdtoa.h. + +Source files g_ddfmt.c, misc.c, smisc.c, strtod.c, strtodg.c, and ulp.c +should use true IEEE double arithmetic (not, e.g., double extended), +at least for storing (and viewing the bits of) the variables declared +"double" within them. + +One detail indicated in struct FPI is whether the target binary +arithmetic departs from the IEEE standard by flushing denormalized +numbers to 0. On systems that do this, the helper routines for +conversion to double-double format (when compiled with +Sudden_Underflow #defined) penalize the bottom of the exponent +range so that they return a nonzero result only when the least +significant bit of the less significant member of the pair of +double values returned can be expressed as a normalized double +value. An alternative would be to drop to 53-bit precision near +the bottom of the exponent range. To get correct rounding, this +would (in general) require two calls on strtodg (one specifying +126-bit arithmetic, then, if necessary, one specifying 53-bit +arithmetic). + +By default, the core routine strtodg and strtod set errno to ERANGE +if the result overflows to +Infinity or underflows to 0. Compile +these routines with NO_ERRNO #defined to inhibit errno assignments. + +Routine strtod is based on netlib's "dtoa.c from fp", and +(f = strtod(s,se)) is more efficient for some conversions than, say, +strtord(s,se,1,&f). Parts of strtod require true IEEE double +arithmetic with the default rounding mode (round-to-nearest) and, on +systems with IEEE extended-precision registers, double-precision +(53-bit) rounding precision. If the machine uses (the equivalent of) +Intel 80x87 arithmetic, the call + _control87(PC_53, MCW_PC); +does this with many compilers. Whether this or another call is +appropriate depends on the compiler; for this to work, it may be +necessary to #include "float.h" or another system-dependent header +file. + +Source file strtodnrp.c gives a strtod that does not require 53-bit +rounding precision on systems (such as Intel IA32 systems) that may +suffer double rounding due to use of extended-precision registers. +For some conversions this variant of strtod is less efficient than the +one in strtod.c when the latter is run with 53-bit rounding precision. + +The values that the strto* routines return for NaNs are determined by +gd_qnan.h, which the makefile generates by running the program whose +source is qnan.c. Note that the rules for distinguishing signaling +from quiet NaNs are system-dependent. For cross-compilation, you need +to determine arith.h and gd_qnan.h suitably, e.g., using the +arithmetic of the target machine. + +C99's hexadecimal floating-point constants are recognized by the +strto* routines (but this feature has not yet been heavily tested). +Compiling with NO_HEX_FP #defined disables this feature. + +When compiled with -DINFNAN_CHECK, the strto* routines recognize C99's +NaN and Infinity syntax. Moreover, unless No_Hex_NaN is #defined, the +strto* routines also recognize C99's NaN(...) syntax: they accept +(case insensitively) strings of the form NaN(x), where x is a string +of hexadecimal digits and spaces; if there is only one string of +hexadecimal digits, it is taken for the fraction bits of the resulting +NaN; if there are two or more strings of hexadecimal digits, each +string is assigned to the next available sequence of 32-bit words of +fractions bits (starting with the most significant), right-aligned in +each sequence. + +For binary -> decimal conversions, I've provided just one family +of helper routines: + + g_ffmt + g_dfmt + g_ddfmt + g_xfmt + g_xLfmt + g_Qfmt + +which do a "%g" style conversion either to a specified number of decimal +places (if their ndig argument is positive), or to the shortest +decimal string that rounds to the given binary floating-point value +(if ndig <= 0). They write into a buffer supplied as an argument +and return either a pointer to the end of the string (a null character) +in the buffer, if the buffer was long enough, or 0. Other forms of +conversion are easily done with the help of gdtoa(), such as %e or %f +style and conversions with direction of rounding specified (so that, if +desired, the decimal value is either >= or <= the binary value). + +For an example of more general conversions based on dtoa(), see +netlib's "printf.c from ampl/solvers". + +For double-double -> decimal, g_ddfmt() assumes IEEE-like arithmetic +of precision max(126, #bits(input)) bits, where #bits(input) is the +number of mantissa bits needed to represent the sum of the two double +values in the input. + +The makefile creates a library, gdtoa.a. To use the helper +routines, a program only needs to include gdtoa.h. All the +source files for gdtoa.a include a more extensive gdtoaimp.h; +among other things, gdtoaimp.h has #defines that make "internal" +names end in _D2A. To make a "system" library, one could modify +these #defines to make the names start with __. + +Various comments about possible #defines appear in gdtoaimp.h, +but for most purposes, arith.h should set suitable #defines. + +Systems with preemptive scheduling of multiple threads require some +manual intervention. On such systems, it's necessary to compile +dmisc.c, dtoa.c gdota.c, and misc.c with MULTIPLE_THREADS #defined, +and to provide (or suitably #define) two locks, acquired by +ACQUIRE_DTOA_LOCK(n) and freed by FREE_DTOA_LOCK(n) for n = 0 or 1. +(The second lock, accessed in pow5mult, ensures lazy evaluation of +only one copy of high powers of 5; omitting this lock would introduce +a small probability of wasting memory, but would otherwise be harmless.) +Routines that call dtoa or gdtoa directly must also invoke freedtoa(s) +to free the value s returned by dtoa or gdtoa. It's OK to do so whether +or not MULTIPLE_THREADS is #defined, and the helper g_*fmt routines +listed above all do this indirectly (in gfmt_D2A(), which they all call). + +By default, there is a private pool of memory of length 2000 bytes +for intermediate quantities, and MALLOC (see gdtoaimp.h) is called only +if the private pool does not suffice. 2000 is large enough that MALLOC +is called only under very unusual circumstances (decimal -> binary +conversion of very long strings) for conversions to and from double +precision. For systems with preemptively scheduled multiple threads +or for conversions to extended or quad, it may be appropriate to +#define PRIVATE_MEM nnnn, where nnnn is a suitable value > 2000. +For extended and quad precisions, -DPRIVATE_MEM=20000 is probably +plenty even for many digits at the ends of the exponent range. +Use of the private pool avoids some overhead. + +Directory test provides some test routines. See its README. +I've also tested this stuff (except double double conversions) +with Vern Paxson's testbase program: see + + V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal + Conversion", manuscript, May 1991, + ftp://ftp.ee.lbl.gov/testbase-report.ps.Z . + +(The same ftp directory has source for testbase.) + +Some system-dependent additions to CFLAGS in the makefile: + + HU-UX: -Aa -Ae + OSF (DEC Unix): -ieee_with_no_inexact + SunOS 4.1x: -DKR_headers -DBad_float_h + +If you want to put this stuff into a shared library and your +operating system requires export lists for shared libraries, +the following would be an appropriate export list: + + dtoa + freedtoa + g_Qfmt + g_ddfmt + g_dfmt + g_ffmt + g_xLfmt + g_xfmt + gdtoa + strtoIQ + strtoId + strtoIdd + strtoIf + strtoIx + strtoIxL + strtod + strtodI + strtodg + strtof + strtopQ + strtopd + strtopdd + strtopf + strtopx + strtopxL + strtorQ + strtord + strtordd + strtorf + strtorx + strtorxL + +When time permits, I (dmg) hope to write in more detail about the +present conversion routines; for now, this README file must suffice. +Meanwhile, if you wish to write helper functions for other kinds of +IEEE-like arithmetic, some explanation of struct FPI and the bits +array may be helpful. Both gdtoa and strtodg operate on a bits array +described by FPI *fpi. The bits array is of type ULong, a 32-bit +unsigned integer type. Floating-point numbers have fpi->nbits bits, +with the least significant 32 bits in bits[0], the next 32 bits in +bits[1], etc. These numbers are regarded as integers multiplied by +2^e (i.e., 2 to the power of the exponent e), where e is the second +argument (be) to gdtoa and is stored in *exp by strtodg. The minimum +and maximum exponent values fpi->emin and fpi->emax for normalized +floating-point numbers reflect this arrangement. For example, the +P754 standard for binary IEEE arithmetic specifies doubles as having +53 bits, with normalized values of the form 1.xxxxx... times 2^(b-1023), +with 52 bits (the x's) and the biased exponent b represented explicitly; +b is an unsigned integer in the range 1 <= b <= 2046 for normalized +finite doubles, b = 0 for denormals, and b = 2047 for Infinities and NaNs. +To turn an IEEE double into the representation used by strtodg and gdtoa, +we multiply 1.xxxx... by 2^52 (to make it an integer) and reduce the +exponent e = (b-1023) by 52: + + fpi->emin = 1 - 1023 - 52 + fpi->emax = 1046 - 1023 - 52 + +In various wrappers for IEEE double, we actually write -53 + 1 rather +than -52, to emphasize that there are 53 bits including one implicit bit. +Field fpi->rounding indicates the desired rounding direction, with +possible values + FPI_Round_zero = toward 0, + FPI_Round_near = unbiased rounding -- the IEEE default, + FPI_Round_up = toward +Infinity, and + FPI_Round_down = toward -Infinity +given in gdtoa.h. + +Field fpi->sudden_underflow indicates whether strtodg should return +denormals or flush them to zero. Normal floating-point numbers have +bit fpi->nbits in the bits array on. Denormals have it off, with +exponent = fpi->emin. Strtodg provides distinct return values for normals +and denormals; see gdtoa.h. + +Compiling g__fmt.c, strtod.c, and strtodg.c with -DUSE_LOCALE causes +the decimal-point character to be taken from the current locale; otherwise +it is '.'. + +Please send comments to David M. Gay (dmg at acm dot org, with " at " +changed at "@" and " dot " changed to "."). diff --git a/gdtoa/arithchk.c b/gdtoa/arithchk.c new file mode 100644 index 000000000..3211aeda4 --- /dev/null +++ b/gdtoa/arithchk.c @@ -0,0 +1,183 @@ +/**************************************************************** +Copyright (C) 1997, 1998 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +/* Try to deduce arith.h from arithmetic properties. */ + +#include + + static int dalign; + typedef struct +Akind { + char *name; + int kind; + } Akind; + + static Akind +IEEE_8087 = { "IEEE_8087", 1 }, +IEEE_MC68k = { "IEEE_MC68k", 2 }, +IBM = { "IBM", 3 }, +VAX = { "VAX", 4 }, +CRAY = { "CRAY", 5}; + + static Akind * +Lcheck() +{ + union { + double d; + long L[2]; + } u; + struct { + double d; + long L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(long))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + + static Akind * +icheck() +{ + union { + double d; + int L[2]; + } u; + struct { + double d; + int L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(int))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + +char *emptyfmt = ""; /* avoid possible warning message with printf("") */ + + static Akind * +ccheck() +{ + union { + double d; + long L; + } u; + long Cray1; + + /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */ + Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 693716; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 115456; + u.d = 1e13; + if (u.L == Cray1) + return &CRAY; + return 0; + } + + static int +fzcheck() +{ + double a, b; + int i; + + a = 1.; + b = .1; + for(i = 155;; b *= b, i >>= 1) { + if (i & 1) { + a *= b; + if (i == 1) + break; + } + } + b = a * a; + return b == 0.; + } + + int +main() +{ + Akind *a = 0; + int Ldef = 0; + FILE *f; + +#ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */ + f = fopen("arith.h", "w"); + if (!f) { + printf("Cannot open arith.h\n"); + return 1; + } +#else + f = stdout; +#endif + + if (sizeof(double) == 2*sizeof(long)) + a = Lcheck(); + else if (sizeof(double) == 2*sizeof(int)) { + Ldef = 1; + a = icheck(); + } + else if (sizeof(double) == sizeof(long)) + a = ccheck(); + if (a) { + fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n", + a->name, a->kind); + if (Ldef) + fprintf(f, "#define Long int\n#define Intcast (int)(long)\n"); + if (dalign) + fprintf(f, "#define Double_Align\n"); + if (sizeof(char*) == 8) + fprintf(f, "#define X64_bit_pointers\n"); +#ifndef NO_LONG_LONG + if (sizeof(long long) < 8) +#endif + fprintf(f, "#define NO_LONG_LONG\n"); + if (a->kind <= 2 && fzcheck()) + fprintf(f, "#define Sudden_Underflow\n"); + return 0; + } + fprintf(f, "/* Unknown arithmetic */\n"); + return 1; + } diff --git a/gdtoa/dmisc.c b/gdtoa/dmisc.c new file mode 100644 index 000000000..72d271ca9 --- /dev/null +++ b/gdtoa/dmisc.c @@ -0,0 +1,216 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#ifndef MULTIPLE_THREADS + char *dtoa_result; +#endif + + char * +#ifdef KR_headers +rv_alloc(i) int i; +#else +rv_alloc(int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (size_t)i; + j <<= 1) + k++; + r = (int*)Balloc(k); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + char * +#ifdef KR_headers +nrv_alloc(s, rve, n) char *s, **rve; int n; +#else +nrv_alloc(char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while((*t = *s++) !=0) + t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +#ifdef KR_headers +freedtoa(s) char *s; +#else +freedtoa(char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + + int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = (ULong)(y & 0xffffffffUL); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = (ULong)(y & 0xffffffffUL); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } diff --git a/gdtoa/dtoa.c b/gdtoa/dtoa.c new file mode 100644 index 000000000..b7a0fa57d --- /dev/null +++ b/gdtoa/dtoa.c @@ -0,0 +1,754 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" +#include + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + char * +dtoa +#ifdef KR_headers + (d, mode, ndigits, decpt, sign, rve) + double d; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to INT_MAX. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + double d2, ds, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = INT_MAX; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); +#endif + return nrv_alloc("NaN", rve, 3); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (( j1 = -k )!=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (( j = b5 - m5 )!=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0) + i = 32 - i; +#else + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + ) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + trimzeros: + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } diff --git a/gdtoa/g_Qfmt.c b/gdtoa/g_Qfmt.c new file mode 100644 index 000000000..9d227d170 --- /dev/null +++ b/gdtoa/g_Qfmt.c @@ -0,0 +1,114 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + char* +#ifdef KR_headers +g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static CONST FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[4], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < (unsigned)(ndig + 10)) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[3] = L[_0] & 0xffff; + bits[2] = L[_1]; + bits[1] = L[_2]; + bits[0] = L[_3]; + b = buf; + if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1] | bits[2] | bits[3]) + b = strcp(b, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + bits[3] |= 0x10000; + } + else if (bits[0] | bits[1] | bits[2] | bits[3]) { + i = STRTOG_Denormal; + ex = 1; + } + else { +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 112; + mode = 2; + if (ndig <= 0) { + if (bufsize < 48) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/gdtoa/g__fmt.c b/gdtoa/g__fmt.c new file mode 100644 index 000000000..021ecfb57 --- /dev/null +++ b/gdtoa/g__fmt.c @@ -0,0 +1,99 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + char * +#ifdef KR_headers +g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign; +#else +g__fmt(char *b, char *s, char *se, int decpt, ULong sign) +#endif +{ + int i, j, k; + char *s0 = s; +#ifdef USE_LOCALE + char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + if (sign) + *b++ = '-'; + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = decimalpoint; + while((*b = *s++) !=0) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } + else if (decpt <= 0) { + *b++ = decimalpoint; + for(; decpt < 0; decpt++) + *b++ = '0'; + while((*b = *s++) !=0) + b++; + } + else { + while((*b = *s++) !=0) { + b++; + if (--decpt == 0 && *s) + *b++ = decimalpoint; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + freedtoa(s0); + return b; + } diff --git a/gdtoa/g_ddfmt.c b/gdtoa/g_ddfmt.c new file mode 100644 index 000000000..d96e78dbe --- /dev/null +++ b/gdtoa/g_ddfmt.c @@ -0,0 +1,154 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg@acm.org). */ + +#include "gdtoaimp.h" +#include + + char * +#ifdef KR_headers +g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize; +#else +g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) +#endif +{ + FPI fpi; + char *b, *s, *se; + ULong *L, bits0[4], *bits, *zx; + int bx, by, decpt, ex, ey, i, j, mode; + Bigint *x, *y, *z; + double ddx[2]; + + if (bufsize < 10 || bufsize < (unsigned)(ndig + 8)) + return 0; + + L = (ULong*)dd; + if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + nanret: + return strcp(buf, "NaN"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + if (L[2+_0] & 0xfffff || L[2+_1]) + goto nanret; + if ((L[_0] ^ L[2+_0]) & 0x80000000L) + goto nanret; /* Infinity - Infinity */ + } + infret: + b = buf; + if (L[_0] & 0x80000000L) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + L += 2; + if (L[_0] & 0xfffff || L[_1]) + goto nanret; + goto infret; + } + if (dd[0] + dd[1] == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & L[2+_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { + ddx[1] = dd[0]; + ddx[0] = dd[1]; + dd = ddx; + L = (ULong*)dd; + } + z = d2b(dd[0], &ex, &bx); + if (dd[1] == 0.) + goto no_y; + x = z; + y = d2b(dd[1], &ey, &by); + if ( (i = ex - ey) !=0) { + if (i > 0) { + x = lshift(x, i); + ex = ey; + } + else + y = lshift(y, -i); + } + if ((L[_0] ^ L[2+_0]) & 0x80000000L) { + z = diff(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1 - z->sign; + } + else { + z = sum(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1; + } + Bfree(x); + Bfree(y); + no_y: + bits = zx = z->x; + for(i = 0; !*zx; zx++) + i += 32; + i += lo0bits(zx); + if (i) { + rshift(z, i); + ex += i; + } + fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); + if (fpi.nbits < 106) { + fpi.nbits = 106; + if (j < 3) { + for(i = 0; i <= j; i++) + bits0[i] = bits[i]; + while(i < 4) + bits0[i++] = 0; + bits = bits0; + } + } + mode = 2; + if (ndig <= 0) { + if (bufsize < (unsigned)((int)(fpi.nbits * .301029995664) + 10)) { + Bfree(z); + return 0; + } + mode = 0; + } + fpi.emin = 1-1023-53+1; + fpi.emax = 2046-1023-106+1; + fpi.rounding = FPI_Round_near; + fpi.sudden_underflow = 0; + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + b = g__fmt(buf, s, se, decpt, z->sign); + Bfree(z); + return b; + } diff --git a/gdtoa/g_dfmt.c b/gdtoa/g_dfmt.c new file mode 100644 index 000000000..74b4ccc28 --- /dev/null +++ b/gdtoa/g_dfmt.c @@ -0,0 +1,89 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + char* +#ifdef KR_headers +g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize; +#else +g_dfmt(char *buf, double *d, int ndig, unsigned bufsize) +#endif +{ + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < (unsigned)(ndig + 10)) + return 0; + + L = (ULong*)d; + sign = L[_0] & 0x80000000L; + if ((L[_0] & 0x7ff00000) == 0x7ff00000) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[_1]; + bits[1] = L[_0] & 0xfffff; + if ( (ex = (L[_0] >> 20) & 0x7ff) !=0) + bits[1] |= 0x100000; + else + ex = 1; + ex -= 0x3ff + 52; + mode = 2; + if (ndig <= 0) { + if (bufsize < 25) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/gdtoa/g_ffmt.c b/gdtoa/g_ffmt.c new file mode 100644 index 000000000..9b2c5fea6 --- /dev/null +++ b/gdtoa/g_ffmt.c @@ -0,0 +1,88 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + char* +#ifdef KR_headers +g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize; +#else +g_ffmt(char *buf, float *f, int ndig, unsigned bufsize) +#endif +{ + static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; + char *b, *s, *se; + ULong bits[1], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < (unsigned)(ndig + 10)) + return 0; + + L = (ULong*)f; + sign = L[0] & 0x80000000L; + if ((L[0] & 0x7f800000) == 0x7f800000) { + /* Infinity or NaN */ + if (L[0] & 0x7fffff) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (*f == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[0] & 0x7fffff; + if ( (ex = (L[0] >> 23) & 0xff) !=0) + bits[0] |= 0x800000; + else + ex = 1; + ex -= 0x7f + 23; + mode = 2; + if (ndig <= 0) { + if (bufsize < 16) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/gdtoa/g_xLfmt.c b/gdtoa/g_xLfmt.c new file mode 100644 index 000000000..a2a993b59 --- /dev/null +++ b/gdtoa/g_xLfmt.c @@ -0,0 +1,108 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + char* +#ifdef KR_headers +g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < (unsigned)(ndig + 10)) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[1] = L[_1]; + bits[0] = L[_2]; + if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/gdtoa/g_xfmt.c b/gdtoa/g_xfmt.c new file mode 100644 index 000000000..c51a16dce --- /dev/null +++ b/gdtoa/g_xfmt.c @@ -0,0 +1,114 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + char* +#ifdef KR_headers +g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], sign; + UShort *L; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < (unsigned)(ndig + 10)) + return 0; + + L = (UShort *)V; + sign = L[_0] & 0x8000; + bits[1] = (L[_1] << 16) | L[_2]; + bits[0] = (L[_3] << 16) | L[_4]; + if ( (ex = L[_0] & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + ex = 1; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/gdtoa/gdtoa.c b/gdtoa/gdtoa.c new file mode 100644 index 000000000..bff00bd3e --- /dev/null +++ b/gdtoa/gdtoa.c @@ -0,0 +1,759 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" +#include + + static Bigint * +#ifdef KR_headers +bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits; +#else +bitstob(ULong *bits, int nbits, int *bbits) +#endif +{ + int i, k; + Bigint *b; + ULong *be, *x, *x0; + + i = ULbits; + k = 0; + while(i < nbits) { + i <<= 1; + k++; + } +#ifndef Pack_32 + if (!k) + k = 1; +#endif + b = Balloc(k); + be = bits + ((nbits - 1) >> kshift); + x = x0 = b->x; + do { + *x++ = *bits & ALL_ON; +#ifdef Pack_16 + *x++ = (*bits >> 16) & ALL_ON; +#endif + } while(++bits <= be); + i = (int)(x - x0); + while(!x0[--i]) + if (!i) { + b->wds = 0; + *bbits = 0; + goto ret; + } + b->wds = i + 1; + *bbits = i*ULbits + 32 - hi0bits(b->x[i]); + ret: + return b; + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +gdtoa +#ifdef KR_headers + (fpi, be, bits, kindp, mode, ndigits, decpt, rve) + FPI *fpi; int be; ULong *bits; + int *kindp, mode, ndigits, *decpt; char **rve; +#else + (CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) +#endif +{ + /* Arguments ndigits and decpt are similar to the second and third + arguments of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to INT_MAX. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex; + int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits; + int rdir, s2, s5, spec_case, try_quick; + Long L; + Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; + double d, d2, ds, eps; + char *s, *s0; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + inex = 0; + kind = *kindp &= ~STRTOG_Inexact; + switch(kind & STRTOG_Retmask) { + case STRTOG_Zero: + goto ret_zero; + case STRTOG_Normal: + case STRTOG_Denormal: + break; + case STRTOG_Infinite: + *decpt = INT_MAX; + return nrv_alloc("Infinity", rve, 8); + case STRTOG_NaN: + *decpt = INT_MAX; + return nrv_alloc("NaN", rve, 3); + default: + return 0; + } + b = bitstob(bits, nbits = fpi->nbits, &bbits); + be0 = be; + if ( (i = trailz(b)) !=0) { + rshift(b, i); + be += i; + bbits -= i; + } + if (!b->wds) { + Bfree(b); + ret_zero: + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + dval(d) = b2d(b, &i); + i = be + bbits - 1; + word0(d) &= Frac_mask1; + word0(d) |= Exp_11; +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ +#ifdef IBM + i <<= 2; + i += j; +#endif + ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + + /* correct assumption about exponent range */ + if ((j = i) < 0) + j = -j; + if ((j -= 1077) > 0) + ds += j * 7e-17; + + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; +#ifdef IBM + j = be + bbits - 1; + if ( (j1 = j & 3) !=0) + dval(d) *= 1 << j1; + word0(d) += j << Exp_shift - 2 & Exp_mask; +#else + word0(d) += (be + bbits - 1) << Exp_shift; +#endif + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = (int)(nbits * .30103) + 3; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + + if ( (rdir = fpi->rounding - 1) !=0) { + if (rdir < 0) + rdir = 2; + if (kind & STRTOG_Neg) + rdir = 3 - rdir; + } + + /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ + + if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir +#ifndef IMPRECISE_INEXACT + && k == 0 +#endif + ) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = dval(d); +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + } + else { + ds = 1.; + if ( (j1 = -k) !=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)(dval(d)/ds); + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + if (ds - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + if ( (L = (Long)(dval(d)/ds)) !=0) + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (i == ilim) { + ds *= 0.5; + if (dval(d) > ds + dval(eps)) + goto bump_up; + else if (dval(d) < ds - dval(eps)) { + while(*--s == '0'){} + s++; + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (dval(d) == 0.) + break; + if (i == ilim) { + if (rdir) { + if (rdir == 1) + goto bump_up; + inex = STRTOG_Inexlo; + goto ret1; + } + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + else + inex = STRTOG_Inexlo; + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = nbits - bbits; + if (be - i++ < fpi->emin) + /* denormal */ + i = be - fpi->emin + 1; + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ( (j = b5 - m5) !=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2) { + if (bbits == 1 && be0 > fpi->emin + 1) { + /* The special case */ + b2++; + s2++; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0) + i = 32 - i; +#else + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + inex = STRTOG_Inexlo; + goto ret; + } + one_digit: + inex = STRTOG_Inexhi; + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, 1); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { + if (dig == '9') + goto round_9_up; + if (j <= 0) { + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + } + else { + dig++; + inex = STRTOG_Inexhi; + } + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && !mode +#ifndef ROUND_BIASED + && !(bits[0] & 1) +#endif + ) { + if (rdir && (b->wds > 1 || b->x[0])) { + if (rdir == 2) { + inex = STRTOG_Inexlo; + goto accept; + } + while (cmp(S,mhi) > 0) { + *s++ = dig; + mhi1 = multadd(mhi, 10, 0); + if (mlo == mhi) + mlo = mhi1; + mhi = mhi1; + b = multadd(b, 10, 0); + dig = quorem(b,S) + '0'; + } + if (dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + goto accept; + } + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + } + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + accept: + *s++ = dig; + goto ret; + } + if (j1 > 0 && rdir != 2) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + inex = STRTOG_Inexhi; + goto roundoff; + } + inex = STRTOG_Inexhi; + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + if (rdir) { + if (rdir == 2 || b->wds <= 1 && !b->x[0]) + goto chopzeros; + goto roundoff; + } + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + chopzeros: + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + while(*--s == '0'){} + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + *kindp |= inex; + return s0; + } diff --git a/gdtoa/gdtoa.h b/gdtoa/gdtoa.h new file mode 100644 index 000000000..95132294e --- /dev/null +++ b/gdtoa/gdtoa.h @@ -0,0 +1,174 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#ifndef GDTOA_H_INCLUDED +#define GDTOA_H_INCLUDED + +#ifdef _MSC_VER +/* [RH] Generating arith.h strikes me as too cumbersome under Visual + * Studio, so here's the equivalent, given the limited number of + * architectures that MSC can target. (Itanium? Who cares about that?) + */ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Double_Align +#ifdef _M_X64 +#define X64_bit_pointers +#endif +#else +#include "arith.h" +#endif + +/* [RH] On 64-bit Unix systems, long is a 64-bit type. I do not that is + * is what is desired here, so I sacrifice compatibility with systems + * that use 16-bit ints (oh no!) and make Long an int instead. + */ +#ifndef Long +typedef int Long; +#endif +#ifndef ULong +typedef unsigned int ULong; +#endif +#ifndef UShort +typedef unsigned short UShort; +#endif + +#ifndef ANSI +#ifdef KR_headers +#define ANSI(x) () +#define Void /*nothing*/ +#else +#define ANSI(x) x +#define Void void +#endif +#endif /* ANSI */ + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif /* CONST */ + + enum { /* return values from strtodg */ + STRTOG_Zero = 0, + STRTOG_Normal = 1, + STRTOG_Denormal = 2, + STRTOG_Infinite = 3, + STRTOG_NaN = 4, + STRTOG_NaNbits = 5, + STRTOG_NoNumber = 6, + STRTOG_Retmask = 7, + + /* The following may be or-ed into one of the above values. */ + + STRTOG_Neg = 0x08, + STRTOG_Inexlo = 0x10, + STRTOG_Inexhi = 0x20, + STRTOG_Inexact = 0x30, + STRTOG_Underflow= 0x40, + STRTOG_Overflow = 0x80 + }; + + typedef struct +FPI { + int nbits; + int emin; + int emax; + int rounding; + int sudden_underflow; + } FPI; + +enum { /* FPI.rounding values: same as FLT_ROUNDS */ + FPI_Round_zero = 0, + FPI_Round_near = 1, + FPI_Round_up = 2, + FPI_Round_down = 3 + }; + +// Our strtod is not the CRT's strtod. +#include +#define strtod mystrtod + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, + int *sign, char **rve)); +extern char* gdtoa ANSI((CONST FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); +extern void freedtoa ANSI((char*)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); +extern int strtodg ANSI((CONST char*, char**, CONST FPI*, Long*, ULong*)); + +extern char* g_ddfmt ANSI((char*, double*, int, unsigned)); +extern char* g_dfmt ANSI((char*, double*, int, unsigned)); +extern char* g_ffmt ANSI((char*, float*, int, unsigned)); +extern char* g_Qfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xLfmt ANSI((char*, void*, int, unsigned)); + +extern int strtoId ANSI((CONST char*, char**, double*, double*)); +extern int strtoIdd ANSI((CONST char*, char**, double*, double*)); +extern int strtoIf ANSI((CONST char*, char**, float*, float*)); +extern int strtoIQ ANSI((CONST char*, char**, void*, void*)); +extern int strtoIx ANSI((CONST char*, char**, void*, void*)); +extern int strtoIxL ANSI((CONST char*, char**, void*, void*)); +extern int strtord ANSI((CONST char*, char**, int, double*)); +extern int strtordd ANSI((CONST char*, char**, int, double*)); +extern int strtorf ANSI((CONST char*, char**, int, float*)); +extern int strtorQ ANSI((CONST char*, char**, int, void*)); +extern int strtorx ANSI((CONST char*, char**, int, void*)); +extern int strtorxL ANSI((CONST char*, char**, int, void*)); +#if 1 +extern int strtodI ANSI((CONST char*, char**, double*)); +extern int strtopd ANSI((CONST char*, char**, double*)); +extern int strtopdd ANSI((CONST char*, char**, double*)); +extern int strtopf ANSI((CONST char*, char**, float*)); +extern int strtopQ ANSI((CONST char*, char**, void*)); +extern int strtopx ANSI((CONST char*, char**, void*)); +extern int strtopxL ANSI((CONST char*, char**, void*)); +#else +#define strtopd(s,se,x) strtord(s,se,1,x) +#define strtopdd(s,se,x) strtordd(s,se,1,x) +#define strtopf(s,se,x) strtorf(s,se,1,x) +#define strtopQ(s,se,x) strtorQ(s,se,1,x) +#define strtopx(s,se,x) strtorx(s,se,1,x) +#define strtopxL(s,se,x) strtorxL(s,se,1,x) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* GDTOA_H_INCLUDED */ diff --git a/gdtoa/gdtoa.vcproj b/gdtoa/gdtoa.vcproj new file mode 100644 index 000000000..7195c1457 --- /dev/null +++ b/gdtoa/gdtoa.vcproj @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdtoa/gdtoaimp.h b/gdtoa/gdtoaimp.h new file mode 100644 index 000000000..49dda8557 --- /dev/null +++ b/gdtoa/gdtoaimp.h @@ -0,0 +1,642 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* This is a variation on dtoa.c that converts arbitary binary + floating-point formats to and from decimal notation. It uses + double-precision arithmetic internally, so there are still + various #ifdefs that adapt the calculations to the native + double-precision arithmetic (any of IEEE, VAX D_floating, + or IBM mainframe arithmetic). + + Please send bug reports to David M. Gay (dmg at acm dot org, + with " at " changed at "@" and " dot " changed to "."). + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. When converting IEEE double precision values, the + * longest string gdtoa can return is about 751 bytes long. For + * conversions by strtod of strings of 800 digits and all gdtoa + * conversions of IEEE doubles in single-threaded executions with + * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with + * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtodg also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits (optionally + * preceded by 0x or 0X) and spaces; if there is only one string + * of hexadecimal digits, it is taken for the fraction bits of the + * resulting NaN; if there are two or more strings of hexadecimal + * digits, each string is assigned to the next available sequence + * of 32-bit words of fractions bits (starting with the most + * significant), right-aligned in each sequence. + * Unless GDTOA_NON_PEDANTIC_NANCHECK is #defined, input "NaN(...)" + * is consumed even when ... has the wrong form (in which case the + * "(...)" is consumed but ignored). + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define IMPRECISE_INEXACT if you do not care about the setting of + * the STRTOG_Inexact bits in the special case of doing IEEE double + * precision conversions (which could also be done by the strtog in + * dtoa.c). + * #define NO_HEX_FP to disable recognition of C9x's hexadecimal + * floating-point constants. + * #define -DNO_ERRNO to suppress setting errno (in strtod.c and + * strtodg.c). + * #define NO_STRING_H to use private versions of memcpy. + * On some K&R systems, it may also be necessary to + * #define DECLARE_SIZE_T in this case. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + */ + +#ifndef GDTOAIMP_H_INCLUDED +#define GDTOAIMP_H_INCLUDED +#include "gdtoa.h" + +#ifdef _MSC_VER +/* [RH] Generating gd_qnan.h strikes me as too cumbersome under Visual + * Studio, so here's the equivalent, given the limited number of + * architectures that MSC can target. (Itanium? Who cares about that?) + */ +#define f_QNAN 0xffc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0xfff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xfff80000 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xfff8 +#define ldus_QNAN4 0x0 +/* [RH] Interestingly, MinGW produces something different because + * it turns out that it has a true long double type. I thought that + * all ia32 compilers had phased out extended precision. + */ +#else +#include "gd_qnan.h" +#endif + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "stdlib.h" +#include "string.h" + +#ifdef KR_headers +#define KR_VOID char +#else +#define KR_VOID void +#endif + +#ifdef MALLOC +extern KR_VOID *MALLOC ANSI((size_t)); +#else +#define MALLOC malloc +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#include "errno.h" +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#define DBL_MAX 1.7976931348623157e+308 +#endif + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#define n_bigtens 2 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +#endif /* Bad_float_h */ + +#ifdef IEEE_Arith +#define Scale_Bit 0x10 +#define n_bigtens 5 +#endif + +#ifdef IBM +#define n_bigtens 3 +#endif + +#ifdef VAX +#define n_bigtens 2 +#endif + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +#define dval(x) x +#ifdef IEEE_8087 +#define word0(x) ((ULong *)&x)[1] +#define word1(x) ((ULong *)&x)[0] +#else +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[1] +#endif +#else /* !YES_ALIAS */ +#ifdef IEEE_8087 +#define word0(x) ((U*)&x)->L[1] +#define word1(x) ((U*)&x)->L[0] +#else +#define word0(x) ((U*)&x)->L[0] +#define word1(x) ((U*)&x)->L[1] +#endif +#define dval(x) ((U*)&x)->d +#endif /* YES_ALIAS */ + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#else /* ifndef IEEE_Arith */ +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#undef Pack_16 +#ifndef Pack_32 +#define Pack_32 +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +#define Pack_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#define ALL_ON 0xffffffff +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#define ALL_ON 0xffff +#endif + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#endif + +#define Kmax 15 + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + +#ifdef NO_STRING_H +#ifdef DECLARE_SIZE_T +typedef unsigned int size_t; +#endif +extern void memcpy_D2A ANSI((void*, const void*, size_t)); +#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#else /* !NO_STRING_H */ +#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#endif /* NO_STRING_H */ + +#define Balloc Balloc_D2A +#define Bfree Bfree_D2A +#define ULtoQ ULtoQ_D2A +#define ULtof ULtof_D2A +#define ULtod ULtod_D2A +#define ULtodd ULtodd_D2A +#define ULtox ULtox_D2A +#define ULtoxL ULtoxL_D2A +#define any_on any_on_D2A +#define b2d b2d_D2A +#define bigtens bigtens_D2A +#define cmp cmp_D2A +#define copybits copybits_D2A +#define d2b d2b_D2A +#define decrement decrement_D2A +#define diff diff_D2A +#define dtoa_result dtoa_result_D2A +#define g__fmt g__fmt_D2A +#define gethex gethex_D2A +#define hexdig hexdig_D2A +#define hexnan hexnan_D2A +#define hi0bits(x) hi0bits_D2A((ULong)(x)) +#define i2b i2b_D2A +#define increment increment_D2A +#define lo0bits lo0bits_D2A +#define lshift lshift_D2A +#define match match_D2A +#define mult mult_D2A +#define multadd multadd_D2A +#define nrv_alloc nrv_alloc_D2A +#define pow5mult pow5mult_D2A +#define quorem quorem_D2A +#define ratio ratio_D2A +#define rshift rshift_D2A +#define rv_alloc rv_alloc_D2A +#define s2b s2b_D2A +#define set_ones set_ones_D2A +#define strcp strcp_D2A +#define strtoIg strtoIg_D2A +#define sum sum_D2A +#define tens tens_D2A +#define tinytens tinytens_D2A +#define tinytens tinytens_D2A +#define trailz trailz_D2A +#define ulp ulp_D2A + + extern char *dtoa_result; + extern CONST double bigtens[], tens[], tinytens[]; + extern unsigned char hexdig[]; + + extern Bigint *Balloc ANSI((int)); + extern void Bfree ANSI((Bigint*)); + extern void ULtof ANSI((ULong*, ULong*, Long, int)); + extern void ULtod ANSI((ULong*, ULong*, Long, int)); + extern void ULtodd ANSI((ULong*, ULong*, Long, int)); + extern void ULtoQ ANSI((ULong*, ULong*, Long, int)); + extern void ULtox ANSI((UShort*, ULong*, Long, int)); + extern void ULtoxL ANSI((ULong*, ULong*, Long, int)); + extern ULong any_on ANSI((Bigint*, int)); + extern double b2d ANSI((Bigint*, int*)); + extern int cmp ANSI((Bigint*, Bigint*)); + extern void copybits ANSI((ULong*, int, Bigint*)); + extern Bigint *d2b ANSI((double, int*, int*)); + extern int decrement ANSI((Bigint*)); + extern Bigint *diff ANSI((Bigint*, Bigint*)); + extern char *dtoa ANSI((double d, int mode, int ndigits, + int *decpt, int *sign, char **rve)); + extern char *g__fmt ANSI((char*, char*, char*, int, ULong)); + extern int gethex ANSI((CONST char**, CONST FPI*, Long*, Bigint**, int)); + extern void hexdig_init_D2A(Void); + extern int hexnan ANSI((CONST char**, CONST FPI*, ULong*)); + extern int hi0bits_D2A ANSI((ULong)); + extern Bigint *i2b ANSI((int)); + extern Bigint *increment ANSI((Bigint*)); + extern int lo0bits ANSI((ULong*)); + extern Bigint *lshift ANSI((Bigint*, int)); + extern int match ANSI((CONST char**, char*)); + extern Bigint *mult ANSI((Bigint*, Bigint*)); + extern Bigint *multadd ANSI((Bigint*, int, int)); + extern char *nrv_alloc ANSI((char*, char **, int)); + extern Bigint *pow5mult ANSI((Bigint*, int)); + extern int quorem ANSI((Bigint*, Bigint*)); + extern double ratio ANSI((Bigint*, Bigint*)); + extern void rshift ANSI((Bigint*, int)); + extern char *rv_alloc ANSI((int)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *set_ones ANSI((Bigint*, int)); + extern char *strcp ANSI((char*, const char*)); + extern int strtoIg ANSI((CONST char*, char**, CONST FPI*, Long*, Bigint**, int*)); + extern double strtod ANSI((const char *s00, char **se)); + extern Bigint *sum ANSI((Bigint*, Bigint*)); + extern int trailz ANSI((Bigint*)); + extern double ulp ANSI((double)); + +#ifdef __cplusplus +} +#endif +/* + * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to + * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0, + * respectively), but now are determined by compiling and running + * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1. + * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=... + * and -DNAN_WORD1=... values if necessary. This should still work. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + */ +#ifdef IEEE_Arith +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN0 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN1 +#endif +#else +#define _0 1 +#define _1 0 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN1 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN0 +#endif +#endif +#else +#undef INFNAN_CHECK +#endif + +#undef SI +#ifdef Sudden_Underflow +#define SI 1 +#else +#define SI 0 +#endif + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/gdtoa/gethex.c b/gdtoa/gethex.c new file mode 100644 index 000000000..7273a6c3b --- /dev/null +++ b/gdtoa/gethex.c @@ -0,0 +1,250 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + int +#ifdef KR_headers +gethex(sp, fpi, exp, bp, sign) + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; +#else +gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + int esign, havedig, irv, k, n, nbits, up, zret; + ULong L, lostbits, *x; + Long e, e1; +#ifdef USE_LOCALE + unsigned char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + + if (!hexdig['0']) + hexdig_init_D2A(); + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (!hexdig[*s]) { + zret = 1; + if (*s != decimalpoint) + goto pcheck; + decpt = ++s; + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') + s++; + if (hexdig[*s]) + zret = 0; + havedig = 1; + s0 = s; + } + while(hexdig[*s]) + s++; + if (*s == decimalpoint && !decpt) { + decpt = ++s; + while(hexdig[*s]) + s++; + } + if (decpt) + e = -(((Long)(s-decpt)) << 2); + pcheck: + s1 = s; + switch(*s) { + case 'p': + case 'P': + esign = 0; + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) + e1 = 10*e1 + n - 0x10; + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + if (zret) { + if (!havedig) + *sp = s0 - 1; + return STRTOG_Zero; + } + n = (int)(s1 - s0 - 1); + for(k = 0; n > 7; n >>= 1) + k++; + b = Balloc(k); + x = b->x; + n = 0; + L = 0; + while(s1 > s0) { + if (*--s1 == decimalpoint) + continue; + if (n == 32) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = (int)(x - b->x); + n = 32*n - hi0bits(L); + nbits = fpi->nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 1 && any_on(b,k-1)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > fpi->emax) { + ovfl: + Bfree(b); + *bp = 0; + return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; + } + irv = STRTOG_Normal; + if (e < fpi->emin) { + irv = STRTOG_Denormal; + n = fpi->emin - e; + if (n >= nbits) { + switch (fpi->rounding) { + case FPI_Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) + goto one_bit; + break; + case FPI_Round_up: + if (!sign) + goto one_bit; + break; + case FPI_Round_down: + if (sign) { + one_bit: + *exp = fpi->emin; + x[0] = b->wds = 1; + *bp = b; + return STRTOG_Denormal | STRTOG_Inexhi + | STRTOG_Underflow; + } + } + Bfree(b); + *bp = 0; + return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = fpi->emin; + } + if (lostbits) { + up = 0; + switch(fpi->rounding) { + case FPI_Round_zero: + break; + case FPI_Round_near: + if (lostbits & 2 + && (lostbits & 1) | x[0] & 1) + up = 1; + break; + case FPI_Round_up: + up = 1 - sign; + break; + case FPI_Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k + || (n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n) { + rshift(b,1); + if (++e > fpi->emax) + goto ovfl; + } + irv |= STRTOG_Inexhi; + } + else + irv |= STRTOG_Inexlo; + } + *bp = b; + *exp = e; + return irv; + } diff --git a/gdtoa/gmisc.c b/gdtoa/gmisc.c new file mode 100644 index 000000000..988d3bfbb --- /dev/null +++ b/gdtoa/gmisc.c @@ -0,0 +1,86 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = ULbits - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & ALL_ON; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = (int)(x1 - b->x)) == 0) + b->x[0] = 0; + } + + int +#ifdef KR_headers +trailz(b) Bigint *b; +#else +trailz(Bigint *b) +#endif +{ + ULong L, *x, *xe; + int n = 0; + + x = b->x; + xe = x + b->wds; + for(n = 0; x < xe && !*x; x++) + n += ULbits; + if (x < xe) { + L = *x; + n += lo0bits(&L); + } + return n; + } diff --git a/gdtoa/hd_init.c b/gdtoa/hd_init.c new file mode 100644 index 000000000..fa6e18dee --- /dev/null +++ b/gdtoa/hd_init.c @@ -0,0 +1,55 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + unsigned char hexdig[256]; + + static void +#ifdef KR_headers +htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; +#else +htinit(unsigned char *h, unsigned char *s, int inc) +#endif +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + void +hexdig_init_D2A(Void) +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } diff --git a/gdtoa/hexnan.c b/gdtoa/hexnan.c new file mode 100644 index 000000000..0ee127f56 --- /dev/null +++ b/gdtoa/hexnan.c @@ -0,0 +1,150 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + static void +#ifdef KR_headers +L_shift(x, x1, i) ULong *x; ULong *x1; int i; +#else +L_shift(ULong *x, ULong *x1, int i) +#endif +{ + int j; + + i = 8 - i; + i <<= 2; + j = ULbits - i; + do { + *x |= x[1] << j; + x[1] >>= i; + } while(++x < x1); + } + + int +#ifdef KR_headers +hexnan(sp, fpi, x0) + CONST char **sp; FPI *fpi; ULong *x0; +#else +hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) +#endif +{ + ULong c, h, *x, *x1, *xe; + CONST char *s; + int havedig, hd0, i, nbits; + + if (!hexdig['0']) + hexdig_init_D2A(); + nbits = fpi->nbits; + x = x0 + (nbits >> kshift); + if (nbits & kmask) + x++; + *--x = 0; + x1 = xe = x; + havedig = hd0 = i = 0; + s = *sp; + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + while(c = *(CONST unsigned char*)++s) { + if (!(h = hexdig[c])) { + if (c <= ' ') { + if (hd0 < havedig) { + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x <= x0) { + i = 8; + continue; + } + hd0 = havedig; + *--x = 0; + x1 = x; + i = 0; + } + while(*(CONST unsigned char*)(s+1) <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + continue; + } + if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } +#ifndef GDTOA_NON_PEDANTIC_NANCHECK + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while(c = *++s); +#endif + return STRTOG_NaN; + } + havedig++; + if (++i > 8) { + if (x <= x0) + continue; + i = 1; + *--x = 0; + } + *x = (*x << 4) | h & 0xf; + } + if (!havedig) + return STRTOG_NaN; + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x > x0) { + x1 = x0; + do *x1++ = *x++; + while(x <= xe); + do *x1++ = 0; + while(x1 <= xe); + } + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); + } + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; + if (x1 == x0) { + *x1 = 1; + break; + } + } + return STRTOG_NaNbits; + } diff --git a/gdtoa/misc.c b/gdtoa/misc.c new file mode 100644 index 000000000..070e69bdc --- /dev/null +++ b/gdtoa/misc.c @@ -0,0 +1,900 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + static Bigint *freelist[Kmax+1]; +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#ifdef MULTIPLE_THREADS +static void ACQUIRE_DTOA_LOCK(int n); +static void FREE_DTOA_LOCK(int n); +#endif + + Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + if ( (rv = freelist[k]) !=0) { + freelist[k] = rv->next; + } + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + + int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; + } + + Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & 0xffffffffUL); +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; + } + + int +hi0bits_D2A +#ifdef KR_headers + (x) register ULong x; +#else + (register ULong x) +#endif +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & 0xffffffffUL); + } + while(x < xae); + *xc = (ULong)carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ( (y = *xb & 0xffff) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ( (y = *xb >> 16) !=0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ( (i = k & 3) !=0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if ((p5 = p5s) == 0) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if ((p51 = p5->next) == 0) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> kshift; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= kmask) { +#ifdef Pack_32 + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) !=0) + ++n1; +#else + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; +#endif + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = (ULong)(y & 0xffffffffUL); + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = (ULong)(y & 0xffffffffUL); + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + d1 = y << (32-Ebits) + k | w >> Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> 32 - k; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#endif + return dval(d); + } +#undef d0 +#undef d1 + + Bigint * +d2b +#ifdef KR_headers + (d, e, bits) double d; int *e, *bits; +#else + (double d, int *e, int *bits) +#endif +{ + Bigint *b; +#ifndef Sudden_Underflow + int i; +#endif + int de, k; + ULong *x, y, z; +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ( (de = (int)(d0 >> Exp_shift)) !=0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) { + x[0] = y | z << 32 - k; + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) !=0 ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 + }; +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#else +bigtens[] = { 1e16, 1e32 }; +CONST double tinytens[] = { 1e-16, 1e-32 }; +#endif +#endif + + CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + char * +#ifdef KR_headers +strcp_D2A(a, b) char *a; char *b; +#else +strcp_D2A(char *a, CONST char *b) +#endif +{ + while(*a = *b++) + a++; + return a; + } + +#ifdef NO_STRING_H + + KR_VOID * +#ifdef KR_headers +memcpy_D2A(a, b, len) char *a; char *b; size_t len; +#else +memcpy_D2A(void *a1, void *b1, size_t len) +#endif +{ + register char *a = (char*)a1, *ae = a + len; + register char *b = (char*)b1, *a0 = a; + while(a < ae) + *a++ = *b++; + return a0; + } + +#endif /* NO_STRING_H */ + + +#ifdef MULTIPLE_THREADS +#ifdef _WIN32 + +#undef Bias +#define WIN32_LEAN_AND_MEAN +#include + +static CRITICAL_SECTION dtoa_lock[2]; +static int did_init; + +void ACQUIRE_DTOA_LOCK(int n) +{ + if (!did_init) + { + did_init = 1; + InitializeCriticalSection(&dtoa_lock[0]); + InitializeCriticalSection(&dtoa_lock[1]); + } + EnterCriticalSection(&dtoa_lock[n]); +} + +void FREE_DTOA_LOCK(int n) +{ + LeaveCriticalSection(&dtoa_lock[n]); +} + +#endif +#endif diff --git a/gdtoa/qnan.c b/gdtoa/qnan.c new file mode 100644 index 000000000..118e74921 --- /dev/null +++ b/gdtoa/qnan.c @@ -0,0 +1,110 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2005 by David M. Gay +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that the copyright notice and this permission notice and warranty +disclaimer appear in supporting documentation, and that the name of +the author or any of his current or former employers not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* Program to compute quiet NaNs of various precisions (float, */ +/* double, and perhaps long double) on the current system, */ +/* provided the system uses binary IEEE (P754) arithmetic. */ +/* Note that one system's quiet NaN may be a signaling NaN on */ +/* another system. The IEEE arithmetic standards (P754, P854) */ +/* do not specify how to distinguish signaling NaNs from quiet */ +/* ones, and this detail varies across systems. The computed */ +/* NaN values are encoded in #defines for values for an */ +/* unsigned 32-bit integer type, called Ulong below, and */ +/* (for long double) perhaps as unsigned short values. Once */ +/* upon a time, there were PC compilers for Intel CPUs that */ +/* had sizeof(long double) = 10. Are such compilers still */ +/* distributed? */ + +#include +#include "arith.h" + +#ifndef Long +#define Long long +#endif + +typedef unsigned Long Ulong; + +#undef HAVE_IEEE +#ifdef IEEE_8087 +#define _0 1 +#define _1 0 +#define HAVE_IEEE +#endif +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define HAVE_IEEE +#endif + +#define UL (unsigned long) + + int +main(void) +{ +#ifdef HAVE_IEEE + typedef union { + float f; + double d; + Ulong L[4]; +#ifndef NO_LONG_LONG + unsigned short u[5]; + long double D; +#endif + } U; + U a, b, c; + int i; + + a.L[0] = b.L[0] = 0x7f800000; + c.f = a.f - b.f; + printf("#define f_QNAN 0x%lx\n", UL c.L[0]); + a.L[_0] = b.L[_0] = 0x7ff00000; + a.L[_1] = b.L[_1] = 0; + c.d = a.d - b.d; /* quiet NaN */ + printf("#define d_QNAN0 0x%lx\n", UL c.L[0]); + printf("#define d_QNAN1 0x%lx\n", UL c.L[1]); +#ifdef NO_LONG_LONG + for(i = 0; i < 4; i++) + printf("#define ld_QNAN%d 0xffffffff\n", i); + for(i = 0; i < 5; i++) + printf("#define ldus_QNAN%d 0xffff\n", i); +#else + b.D = c.D = a.d; + if (printf("") < 0) + c.D = 37; /* never executed; just defeat optimization */ + a.L[2] = a.L[3] = 0; + a.D = b.D - c.D; + for(i = 0; i < 4; i++) + printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]); + for(i = 0; i < 5; i++) + printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]); +#endif +#endif /* HAVE_IEEE */ + return 0; + } diff --git a/gdtoa/qnan.obj b/gdtoa/qnan.obj new file mode 100644 index 000000000..994af47d9 Binary files /dev/null and b/gdtoa/qnan.obj differ diff --git a/gdtoa/smisc.c b/gdtoa/smisc.c new file mode 100644 index 000000000..163011e0a --- /dev/null +++ b/gdtoa/smisc.c @@ -0,0 +1,191 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +#else + (CONST char *s, int nd0, int nd, ULong y9) +#endif +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; + } + + double +ratio +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + double da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); + k = ka - kb + ULbits*(a->wds - b->wds); +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); + } + +#ifdef INFNAN_CHECK + + int +match +#ifdef KR_headers + (sp, t) char **sp, *t; +#else + (CONST char **sp, char *t) +#endif +{ + int c, d; + CONST char *s = *sp; + + while( (d = *t++) !=0) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } +#endif /* INFNAN_CHECK */ + + void +#ifdef KR_headers +copybits(c, n, b) ULong *c; int n; Bigint *b; +#else +copybits(ULong *c, int n, Bigint *b) +#endif +{ + ULong *ce, *x, *xe; +#ifdef Pack_16 + int nw, nw1; +#endif + + ce = c + ((n-1) >> kshift) + 1; + x = b->x; +#ifdef Pack_32 + xe = x + b->wds; + while(x < xe) + *c++ = *x++; +#else + nw = b->wds; + nw1 = nw & 1; + for(xe = x + (nw - nw1); x < xe; x += 2) + Storeinc(c, x[1], x[0]); + if (nw1) + *c++ = *x; +#endif + while(c < ce) + *c++ = 0; + } + + ULong +#ifdef KR_headers +any_on(b, k) Bigint *b; int k; +#else +any_on(Bigint *b, int k) +#endif +{ + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) + n = nwds; + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) + return 1; + } + x0 = x; + x += n; + while(x > x0) + if (*--x) + return 1; + return 0; + } diff --git a/gdtoa/strtoIQ.c b/gdtoa/strtoIQ.c new file mode 100644 index 000000000..000fa3645 --- /dev/null +++ b/gdtoa/strtoIQ.c @@ -0,0 +1,63 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIQ(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static CONST FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoQ(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoQ(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + } + return k; + } diff --git a/gdtoa/strtoId.c b/gdtoa/strtoId.c new file mode 100644 index 000000000..d34a278ee --- /dev/null +++ b/gdtoa/strtoId.c @@ -0,0 +1,60 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoId(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + } + return k; + } diff --git a/gdtoa/strtoIdd.c b/gdtoa/strtoIdd.c new file mode 100644 index 000000000..921597fe7 --- /dev/null +++ b/gdtoa/strtoIdd.c @@ -0,0 +1,66 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoIdd(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ +#ifdef Sudden_Underflow + static CONST FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static CONST FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + ((ULong*)f1)[2] = ((ULong*)f0)[2]; + ((ULong*)f1)[3] = ((ULong*)f0)[3]; + } + return k; + } diff --git a/gdtoa/strtoIf.c b/gdtoa/strtoIf.c new file mode 100644 index 000000000..b937ff079 --- /dev/null +++ b/gdtoa/strtoIf.c @@ -0,0 +1,58 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1; +#else +strtoIf(CONST char *s, char **sp, float *f0, float *f1) +#endif +{ + static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(0); + B[0]->wds = 1; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else + *(ULong*)f1 = *(ULong*)f0; + return k; + } diff --git a/gdtoa/strtoIg.c b/gdtoa/strtoIg.c new file mode 100644 index 000000000..fd181fc9b --- /dev/null +++ b/gdtoa/strtoIg.c @@ -0,0 +1,133 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; +#else +strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *rvp) +#endif +{ + Bigint *b, *b1; + int i, nb, nw, nw1, rv, rv1, swap; + unsigned int nb1, nb11; + Long e1; + + b = *B; + rv = strtodg(s00, se, fpi, exp, b->x); + if (!(rv & STRTOG_Inexact)) { + B[1] = 0; + return *rvp = rv; + } + e1 = exp[0]; + rv1 = rv ^ STRTOG_Inexact; + b1 = Balloc(b->k); + Bcopy(b1, b); + nb = fpi->nbits; + nb1 = nb & 31; + nb11 = (nb1 - 1) & 31; + nw = b->wds; + nw1 = nw - 1; + if (rv & STRTOG_Inexlo) { + swap = 0; + b1 = increment(b1); + if (fpi->sudden_underflow + && (rv & STRTOG_Retmask) == STRTOG_Zero) { + b1->x[0] = 0; + b1->x[nw1] = 1L << nb11; + rv1 += STRTOG_Normal - STRTOG_Zero; + rv1 &= ~STRTOG_Underflow; + goto swapcheck; + } + if (b1->wds > nw + || nb1 && b1->x[nw1] & 1L << nb1) { + if (++e1 > fpi->emax) + rv1 = STRTOG_Infinite | STRTOG_Inexhi; + rshift(b1, 1); + } + else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + if (b1->x[nw1] & 1L << nb11) { + rv1 += STRTOG_Normal - STRTOG_Denormal; + rv1 &= ~STRTOG_Underflow; + } + } + } + else { + swap = STRTOG_Neg; + if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { + b1 = set_ones(b1, nb); + e1 = fpi->emax; + rv1 = STRTOG_Normal | STRTOG_Inexlo; + goto swapcheck; + } + decrement(b1); + if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + for(i = nw1; !b1->x[i]; --i) + if (!i) { + rv1 = STRTOG_Zero | STRTOG_Inexlo; + break; + } + goto swapcheck; + } + if (!(b1->x[nw1] & 1L << nb11)) { + if (e1 == fpi->emin) { + if (fpi->sudden_underflow) + rv1 += STRTOG_Zero - STRTOG_Normal; + else + rv1 += STRTOG_Denormal - STRTOG_Normal; + rv1 |= STRTOG_Underflow; + } + else { + b1 = lshift(b1, 1); + b1->x[0] |= 1; + --e1; + } + } + } + swapcheck: + if (swap ^ (rv & STRTOG_Neg)) { + rvp[0] = rv1; + rvp[1] = rv; + B[0] = b1; + B[1] = b; + exp[1] = exp[0]; + exp[0] = e1; + } + else { + rvp[0] = rv; + rvp[1] = rv1; + B[1] = b1; + exp[1] = e1; + } + return rv; + } diff --git a/gdtoa/strtoIx.c b/gdtoa/strtoIx.c new file mode 100644 index 000000000..8e972c976 --- /dev/null +++ b/gdtoa/strtoIx.c @@ -0,0 +1,64 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIx(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + UShort *L = (UShort *)a, *M = (UShort *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtox(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtox(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + M[4] = L[4]; + } + return k; + } diff --git a/gdtoa/strtoIxL.c b/gdtoa/strtoIxL.c new file mode 100644 index 000000000..86dbc744a --- /dev/null +++ b/gdtoa/strtoIxL.c @@ -0,0 +1,62 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIxL(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoxL(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoxL(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + } + return k; + } diff --git a/gdtoa/strtod.c b/gdtoa/strtod.c new file mode 100644 index 000000000..d6025dada --- /dev/null +++ b/gdtoa/strtod.c @@ -0,0 +1,985 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" +#if !defined(NO_FENV_H) && !defined(_MSC_VER) +#include +#endif + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef IEEE_Arith +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#undef tinytens +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.e-256 + }; +#endif +#endif + +#include + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + double +strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif + + _control87(_PC_53, _MCW_PC); + sign = nz0 = nz = decpt = 0; + dval(rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + { + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp; + ULong bits[2]; + switch(s[1]) { + case 'x': + case 'X': + { +#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) + FPI fpi1 = fpi; + switch(fegetround()) { + case FE_TOWARDZERO: fpi1.rounding = 0; break; + case FE_UPWARD: fpi1.rounding = 2; break; + case FE_DOWNWARD: fpi1.rounding = 3; + } +#else +#define fpi1 fpi +#endif + switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { + case STRTOG_NoNumber: + s = s00; + sign = 0; + case STRTOG_Zero: + break; + default: + if (bb) { + copybits(bits, fpi.nbits, bb); + Bfree(bb); + } + ULtod(((U*)&rv)->L, bits, exp, i); + }} + goto ret; + } + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + decpt = 1; + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + ULong bits[2]; + static CONST FPI fpinan = /* only 52 explicit bits */ + { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { +#ifndef No_Hex_NaN + if (*s == '(' /*)*/ + && hexnan(&s, &fpinan, bits) + == STRTOG_NaNbits) { + word0(rv) = 0x7ff00000 | bits[1]; + word1(rv) = bits[0]; + } + else { +#endif + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + } +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << j-32; + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { + undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (ULong)aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); + } + diff --git a/gdtoa/strtodI.c b/gdtoa/strtodI.c new file mode 100644 index 000000000..992702e25 --- /dev/null +++ b/gdtoa/strtodI.c @@ -0,0 +1,167 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + static double +#ifdef KR_headers +ulpdown(d) double *d; +#else +ulpdown(double *d) +#endif +{ + double u; + ULong *L = (ULong*)d; + + u = ulp(*d); + if (!(L[_1] | L[_0] & 0xfffff) + && (L[_0] & 0x7ff00000) > 0x00100000) + u *= 0.5; + return u; + } + + int +#ifdef KR_headers +strtodI(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtodI(CONST char *s, char **sp, double *dd) +#endif +{ + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2], sign; + Long exp; + int j, k; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + k = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + sign = k & STRTOG_Neg ? 0x80000000L : 0; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; +#ifdef Sudden_Underflow + if (k & STRTOG_Inexact) { + if (sign) + u->L[_0] = 0x80100000L; + else + u->L[2+_0] = 0x100000L; + } + break; +#else + goto contain; +#endif + + case STRTOG_Denormal: + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + goto contain; + + case STRTOG_Normal: + u->L[_1] = bits[0]; + u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + contain: + j = k & STRTOG_Inexact; + if (sign) { + u->L[_0] |= sign; + j = STRTOG_Inexact - j; + } + switch(j) { + case STRTOG_Inexlo: +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[2+_0] = u->L[_0] + 0x3500000; + u->L[2+_1] = u->L[_1]; + u->d[1] += ulp(u->d[1]); + u->L[2+_0] -= 0x3500000; + if (!(u->L[2+_0] & 0x7ff00000)) { + u->L[2+_0] = sign; + u->L[2+_1] = 0; + } + } + else +#endif + u->d[1] = u->d[0] + ulp(u->d[0]); + break; + case STRTOG_Inexhi: + u->d[1] = u->d[0]; +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[_0] += 0x3500000; + u->d[0] -= ulpdown(u->d); + u->L[_0] -= 0x3500000; + if (!(u->L[_0] & 0x7ff00000)) { + u->L[_0] = sign; + u->L[_1] = 0; + } + } + else +#endif + u->d[0] -= ulpdown(u->d); + break; + default: + u->d[1] = u->d[0]; + } + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = sign | 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + if (k & STRTOG_Inexact) { + if (sign) { + u->L[2+_0] = 0xffefffffL; + u->L[2+_1] = 0xffffffffL; + } + else { + u->L[_0] = 0x7fefffffL; + u->L[_1] = 0xffffffffL; + } + } + break; + + case STRTOG_NaN: + u->L[0] = u->L[2] = d_QNAN0; + u->L[1] = u->L[3] = d_QNAN1; + break; + + case STRTOG_NaNbits: + u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1]; + u->L[_1] = u->L[2+_1] = bits[0]; + } + return k; + } diff --git a/gdtoa/strtodg.c b/gdtoa/strtodg.c new file mode 100644 index 000000000..68c7533d1 --- /dev/null +++ b/gdtoa/strtodg.c @@ -0,0 +1,1010 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + static CONST int +fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, + 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, + 47, 49, 52 +#ifdef VAX + , 54, 56 +#endif + }; + + Bigint * +#ifdef KR_headers +increment(b) Bigint *b; +#else +increment(Bigint *b) +#endif +{ + ULong *x, *xe; + Bigint *b1; +#ifdef Pack_16 + ULong carry = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); +#else + do { + y = *x + carry; + carry = y >> 16; + *x++ = y & 0xffff; + if (!carry) + return b; + } while(x < xe); + if (carry) +#endif + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + + int +#ifdef KR_headers +decrement(b) Bigint *b; +#else +decrement(Bigint *b) +#endif +{ + ULong *x, *xe; +#ifdef Pack_16 + ULong borrow = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x) { + --*x; + break; + } + *x++ = 0xffffffffL; + } + while(x < xe); +#else + do { + y = *x - borrow; + borrow = (y & 0x10000) >> 16; + *x++ = y & 0xffff; + } while(borrow && x < xe); +#endif + return STRTOG_Inexlo; + } + + static int +#ifdef KR_headers +all_on(b, n) Bigint *b; int n; +#else +all_on(Bigint *b, int n) +#endif +{ + ULong *x, *xe; + + x = b->x; + xe = x + (n >> kshift); + while(x < xe) + if ((*x++ & ALL_ON) != ALL_ON) + return 0; + if (n &= kmask) + return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; + return 1; + } + + Bigint * +#ifdef KR_headers +set_ones(b, n) Bigint *b; int n; +#else +set_ones(Bigint *b, int n) +#endif +{ + int k; + ULong *x, *xe; + + k = (n + ((1 << kshift) - 1)) >> kshift; + if (b->k < k) { + Bfree(b); + b = Balloc(k); + } + k = n >> kshift; + if (n &= kmask) + k++; + b->wds = k; + x = b->x; + xe = x + k; + while(x < xe) + *x++ = ALL_ON; + if (n) + x[-1] >>= ULbits - n; + return b; + } + + static int +rvOK +#ifdef KR_headers + (d, fpi, exp, bits, exact, rd, irv) + double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; +#else + (double d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) +#endif +{ + Bigint *b; + ULong carry, inex, lostbits; + int bdif, e, j, k, k1, nb, rv; + + carry = rv = 0; + b = d2b(d, &e, &bdif); + bdif -= nb = fpi->nbits; + e += bdif; + if (bdif <= 0) { + if (exact) + goto trunc; + goto ret; + } + if (P == nb) { + if ( +#ifndef IMPRECISE_INEXACT + exact && +#endif + fpi->rounding == +#ifdef RND_PRODQUOT + FPI_Round_near +#else + Flt_Rounds +#endif + ) goto trunc; + goto ret; + } + switch(rd) { + case 1: + goto trunc; + case 2: + break; + default: /* round near */ + k = bdif - 1; + if (k < 0) + goto trunc; + if (!k) { + if (!exact) + goto ret; + if (b->x[0] & 2) + break; + goto trunc; + } + if (b->x[k>>kshift] & ((ULong)1 << (k & kmask))) + break; + goto trunc; + } + /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ + carry = 1; + trunc: + inex = lostbits = 0; + if (bdif > 0) { + if ( (lostbits = any_on(b, bdif)) !=0) + inex = STRTOG_Inexlo; + rshift(b, bdif); + if (carry) { + inex = STRTOG_Inexhi; + b = increment(b); + if ( (j = nb & kmask) !=0) + j = ULbits - j; + if (hi0bits(b->x[b->wds - 1]) != j) { + if (!lostbits) + lostbits = b->x[0] & 1; + rshift(b, 1); + e++; + } + } + } + else if (bdif < 0) + b = lshift(b, -bdif); + if (e < fpi->emin) { + k = fpi->emin - e; + e = fpi->emin; + if (k > nb || fpi->sudden_underflow) { + b->wds = inex = 0; + *irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + k1 = k - 1; + if (k1 > 0 && !lostbits) + lostbits = any_on(b, k1); + if (!lostbits && !exact) + goto ret; + lostbits |= + carry = b->x[k1>>kshift] & (1 << (k1 & kmask)); + rshift(b, k); + *irv = STRTOG_Denormal; + if (carry) { + b = increment(b); + inex = STRTOG_Inexhi | STRTOG_Underflow; + } + else if (lostbits) + inex = STRTOG_Inexlo | STRTOG_Underflow; + } + } + else if (e > fpi->emax) { + e = fpi->emax + 1; + *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + b->wds = inex = 0; + } + *exp = e; + copybits(bits, nb, b); + *irv |= inex; + rv = 1; + ret: + Bfree(b); + return rv; + } + + static int +#ifdef KR_headers +mantbits(d) double d; +#else +mantbits(double d) +#endif +{ + ULong L; +#ifdef VAX + L = word1(d) << 16 | word1(d) >> 16; + if (L) +#else + if ( (L = word1(d)) !=0) +#endif + return P - lo0bits(&L); +#ifdef VAX + L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11; +#else + L = word0(d) | Exp_msk1; +#endif + return P - 32 - lo0bits(&L); + } + + int +strtodg +#ifdef KR_headers + (s00, se, fpi, exp, bits) + CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; +#else + (CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits) +#endif +{ + int abe, abits, asub; + int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; + int dsign, e, e1, e2, emin, esign, finished, i, inex, irv; + int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; + int sudden_underflow; + CONST char *s, *s0, *s1; + double adj, adj0, rv, tol; + Long L; + ULong y, z; + Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; + + irv = STRTOG_Zero; + denorm = sign = nz0 = nz = 0; + dval(rv) = 0.; + rvb = 0; + nbits = fpi->nbits; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + sign = 0; + irv = STRTOG_NoNumber; + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + switch(s[1]) { + case 'x': + case 'X': + irv = gethex(&s, fpi, exp, &rvb, sign); + if (irv == STRTOG_NoNumber) { + s = s00; + sign = 0; + } + goto ret; + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + sudden_underflow = fpi->sudden_underflow; + s0 = s; + y = z = 0; + for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + decpt = 1; + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + irv = STRTOG_NoNumber; + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + irv = STRTOG_Infinite; + goto infnanexp; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + irv = STRTOG_NaN; + *exp = fpi->emax + 1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + irv = hexnan(&s, fpi, bits); +#endif + goto infnanexp; + } + } +#endif /* INFNAN_CHECK */ + irv = STRTOG_NoNumber; + s = s00; + } + goto ret; + } + + irv = STRTOG_Normal; + e1 = e -= nf; + rd = 0; + switch(fpi->rounding & 3) { + case FPI_Round_up: + rd = 2 - sign; + break; + case FPI_Round_zero: + rd = 1; + break; + case FPI_Round_down: + rd = 1 + sign; + } + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) + dval(rv) = tens[k - 9] * dval(rv) + z; + bd0 = 0; + if (nbits <= P && nd <= DBL_DIG) { + if (!e) { + if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + goto ret; + } + else if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + i = fivesbits[e] + mantbits(dval(rv)) <= P; + /* rv = */ rounded_product(dval(rv), tens[e]); + if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + goto ret; + e1 -= e; + goto rv_notOK; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e2 = e - i; + e1 -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + dval(adj) = dval(rv); + word0(adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(adj), tens[e2]); + if ((word0(adj) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto rv_notOK; + word0(adj) += P*Exp_msk1; + dval(rv) = dval(adj); +#else + /* rv = */ rounded_product(dval(rv), tens[e2]); +#endif + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e2; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e; + } +#endif + } + rv_notOK: + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + e2 = 0; + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + } + } +#ifdef IBM + /* e2 is a correction to the (base 2) exponent of the return + * value, reflecting adjustments above to avoid overflow in the + * native arithmetic. For native IBM (base 16) arithmetic, we + * must multiply e2 by 4 to change from base 16 to 2. + */ + e2 <<= 2; +#endif + rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rve += e2; + if ((j = rvbits - nbits) > 0) { + rshift(rvb, j); + rvbits = nbits; + rve += j; + } + bb0 = 0; /* trailing zero bits in rvb */ + e2 = rve + rvbits - nbits; + if (e2 > fpi->emax + 1) + goto huge; + rve1 = rve + rvbits - nbits; + if (e2 < (emin = fpi->emin)) { + denorm = 1; + j = rve - emin; + if (j > 0) { + rvb = lshift(rvb, j); + rvbits += j; + } + else if (j < 0) { + rvbits += j; + if (rvbits <= 0) { + if (rvbits < -1) { + ufl: + rvb->wds = 0; + rvb->x[0] = 0; + *exp = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + goto ret; + } + rvb->x[0] = rvb->wds = rvbits = 1; + } + else + rshift(rvb, -j); + } + rve = rve1 = emin; + if (sudden_underflow && e2 + 1 < emin) + goto ufl; + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = Balloc(rvb->k); + Bcopy(bb, rvb); + bbbits = rvbits - bb0; + bbe = rve + bb0; + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = nbits + 1 - bbbits; + i = bbe + bbbits - nbits; + if (i < emin) /* denormal */ + j += i - emin; + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + bb2 -= bb0; + if (bb2 > 0) + bb = lshift(bb, bb2); + else if (bb2 < 0) + rshift(bb, -bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + asub = 1; + inex = STRTOG_Inexhi; + delta = diff(bb, bd); + if (delta->wds <= 1 && !delta->x[0]) + break; + dsign = delta->sign; + delta->sign = finished = 0; + L = 0; + i = cmp(delta, bs); + if (rd && i <= 0) { + irv = STRTOG_Normal; + if ( (finished = dsign ^ (rd&1)) !=0) { + if (dsign != 0) { + irv |= STRTOG_Inexhi; + goto adj1; + } + irv |= STRTOG_Inexlo; + if (rve1 == emin) + goto adj1; + for(i = 0, j = nbits; j >= ULbits; + i++, j -= ULbits) { + if (rvb->x[i] & ALL_ON) + goto adj1; + } + if (j > 1 && lo0bits(rvb->x + i) < j - 1) + goto adj1; + rve = rve1 - 1; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; + break; + } + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + irv = dsign + ? STRTOG_Normal | STRTOG_Inexlo + : STRTOG_Normal | STRTOG_Inexhi; + if (dsign || bbbits > 1 || denorm || rve1 == emin) + break; + delta = lshift(delta,1); + if (cmp(delta, bs) > 0) { + irv = STRTOG_Normal | STRTOG_Inexlo; + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if (denorm && all_on(rvb, rvbits)) { + /*boundary case -- increment exponent*/ + rvb->wds = 1; + rvb->x[0] = 1; + rve = emin + nbits - (rvbits = 1); + irv = STRTOG_Normal | STRTOG_Inexhi; + denorm = 0; + break; + } + irv = STRTOG_Normal | STRTOG_Inexlo; + } + else if (bbbits == 1) { + irv = STRTOG_Normal; + drop_down: + /* boundary case -- decrement exponent */ + if (rve1 == emin) { + irv = STRTOG_Normal | STRTOG_Inexhi; + if (rvb->wds == 1 && rvb->x[0] == 1) + sudden_underflow = 1; + break; + } + rve -= nbits; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + else + irv = STRTOG_Normal | STRTOG_Inexhi; + if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + break; + if (dsign) { + rvb = increment(rvb); + j = kmask & (ULbits - (rvbits & kmask)); + if (hi0bits(rvb->x[rvb->wds - 1]) != j) + rvbits++; + irv = STRTOG_Normal | STRTOG_Inexhi; + } + else { + if (bbbits == 1) + goto undfl; + decrement(rvb); + irv = STRTOG_Normal | STRTOG_Inexlo; + } + break; + } + if ((dval(adj) = ratio(delta, bs)) <= 2.) { + adj1: + inex = STRTOG_Inexlo; + if (dsign) { + asub = 0; + inex = STRTOG_Inexhi; + } + else if (denorm && bbbits <= 1) { + undfl: + rvb->wds = 0; + rve = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + break; + } + adj0 = dval(adj) = 1.; + } + else { + adj0 = dval(adj) *= 0.5; + if (dsign) { + asub = 0; + inex = STRTOG_Inexlo; + } + if (dval(adj) < 2147483647.) { + L = (Long)adj0; + adj0 -= L; + switch(rd) { + case 0: + if (adj0 >= .5) + goto inc_L; + break; + case 1: + if (asub && adj0 > 0.) + goto inc_L; + break; + case 2: + if (!asub && adj0 > 0.) { + inc_L: + L++; + inex = STRTOG_Inexact - inex; + } + } + dval(adj) = L; + } + } + y = rve + rvbits; + + /* adj *= ulp(dval(rv)); */ + /* if (asub) rv -= adj; else rv += adj; */ + + if (!denorm && rvbits < nbits) { + rvb = lshift(rvb, j = nbits - rvbits); + rve -= j; + rvbits = nbits; + } + ab = d2b(dval(adj), &abe, &abits); + if (abe < 0) + rshift(ab, -abe); + else if (abe > 0) + ab = lshift(ab, abe); + rvb0 = rvb; + if (asub) { + /* rv -= adj; */ + j = hi0bits(rvb->x[rvb->wds-1]); + rvb = diff(rvb, ab); + k = rvb0->wds - 1; + if (denorm) + /* do nothing */; + else if (rvb->wds <= k + || hi0bits( rvb->x[k]) > + hi0bits(rvb0->x[k])) { + /* unlikely; can only have lost 1 high bit */ + if (rve1 == emin) { + --rvbits; + denorm = 1; + } + else { + rvb = lshift(rvb, 1); + --rve; + --rve1; + L = finished = 0; + } + } + } + else { + rvb = sum(rvb, ab); + k = rvb->wds - 1; + if (k >= rvb0->wds + || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) { + if (denorm) { + if (++rvbits == nbits) + denorm = 0; + } + else { + rshift(rvb, 1); + rve++; + rve1++; + L = 0; + } + } + } + Bfree(ab); + Bfree(rvb0); + if (finished) + break; + + z = rve + rvbits; + if (y == z && L) { + /* Can we stop now? */ + tol = dval(adj) * 5e-16; /* > max rel error */ + dval(adj) = adj0 - .5; + if (dval(adj) < -tol) { + if (adj0 > tol) { + irv |= inex; + break; + } + } + else if (dval(adj) > tol && adj0 < 1. - tol) { + irv |= inex; + break; + } + } + bb0 = denorm ? 0 : trailz(rvb); + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + if (!denorm && (j = nbits - rvbits)) { + if (j > 0) + rvb = lshift(rvb, j); + else + rshift(rvb, -j); + rve -= j; + } + *exp = rve; + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + if (rve > fpi->emax) { + huge: + rvb->wds = 0; + irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + infnanexp: + *exp = fpi->emax + 1; + } + ret: + if (denorm) { + if (sudden_underflow) { + rvb->wds = 0; + irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + irv = (irv & ~STRTOG_Retmask) | + (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); + if (irv & STRTOG_Inexact) + irv |= STRTOG_Underflow; + } + } + if (se) + *se = (char *)s; + if (sign) + irv |= STRTOG_Neg; + if (rvb) { + copybits(bits, nbits, rvb); + Bfree(rvb); + } + return irv; + } diff --git a/gdtoa/strtodnrp.c b/gdtoa/strtodnrp.c new file mode 100644 index 000000000..3d0297f52 --- /dev/null +++ b/gdtoa/strtodnrp.c @@ -0,0 +1,87 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2004 by David M. Gay. +All Rights Reserved +Based on material in the rest of /netlib/fp/gdota.tar.gz, +which is copyright (C) 1998, 2000 by Lucent Technologies. + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* This is a variant of strtod that works on Intel ia32 systems */ +/* with the default extended-precision arithmetic -- it does not */ +/* require setting the precision control to 53 bits. */ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + double +#ifdef KR_headers +strtod(s, sp) CONST char *s; char **sp; +#else +strtod(CONST char *s, char **sp) +#endif +{ + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + union { ULong L[2]; double d; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = u.L[1] = 0; + break; + + case STRTOG_Normal: + u.L[_1] = bits[0]; + u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Denormal: + u.L[_1] = bits[0]; + u.L[_0] = bits[1]; + break; + + case STRTOG_Infinite: + u.L[_0] = 0x7ff00000; + u.L[_1] = 0; + break; + + case STRTOG_NaN: + u.L[0] = d_QNAN0; + u.L[1] = d_QNAN1; + break; + + case STRTOG_NaNbits: + u.L[_0] = 0x7ff00000 | bits[1]; + u.L[_1] = bits[0]; + } + if (k & STRTOG_Neg) + u.L[_0] |= 0x80000000L; + return u.d; + } diff --git a/gdtoa/strtof.c b/gdtoa/strtof.c new file mode 100644 index 000000000..561264a1d --- /dev/null +++ b/gdtoa/strtof.c @@ -0,0 +1,73 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ + static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + u.L[0] = bits[0]; + break; + + case STRTOG_Infinite: + u.L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + u.L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x80000000L; + return u.f; + } diff --git a/gdtoa/strtopQ.c b/gdtoa/strtopQ.c new file mode 100644 index 000000000..9eefd768f --- /dev/null +++ b/gdtoa/strtopQ.c @@ -0,0 +1,101 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + int +#ifdef KR_headers +strtopQ(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopQ(CONST char *s, char **sp, void *V) +#endif +{ + static CONST FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; + ULong bits[4]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + L[3] = ld_QNAN3; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/gdtoa/strtopd.c b/gdtoa/strtopd.c new file mode 100644 index 000000000..4c8bbaf42 --- /dev/null +++ b/gdtoa/strtopd.c @@ -0,0 +1,49 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopd(s, sp, d) char *s; char **sp; double *d; +#else +strtopd(CONST char *s, char **sp, double *d) +#endif +{ + static CONST FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + + k = strtodg(s, sp, &fpi0, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/gdtoa/strtopdd.c b/gdtoa/strtopdd.c new file mode 100644 index 000000000..d2c6d9b89 --- /dev/null +++ b/gdtoa/strtopdd.c @@ -0,0 +1,178 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtopdd(CONST char *s, char **sp, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static CONST FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static CONST FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + ULong bits[4]; + Long exp; + int i, j, rv; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + rv = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + switch(rv & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Normal: + u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; + u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & 0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & 0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + u->L[2] = u->L[3] = 0; + break; + } + u->L[2+_1] = bits[0]; + u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + u->L[2] = u->L[3] = 0; + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + } + if (i == 0) { + u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_1] = bits[1]; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0]; + break; + } + j = 32 - i; + u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + break; + + case STRTOG_NaN: + u->L[0] = u->L[2] = d_QNAN0; + u->L[1] = u->L[3] = d_QNAN1; + } + if (rv & STRTOG_Neg) { + u->L[ _0] |= 0x80000000L; + u->L[2+_0] |= 0x80000000L; + } + return rv; + } diff --git a/gdtoa/strtopf.c b/gdtoa/strtopf.c new file mode 100644 index 000000000..806e14f6f --- /dev/null +++ b/gdtoa/strtopf.c @@ -0,0 +1,73 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopf(s, sp, f) CONST char *s; char **sp; float *f; +#else +strtopf(CONST char *s, char **sp, float *f) +#endif +{ + static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1], *L; + Long exp; + int k; + + k = strtodg(s, sp, &fpi, &exp, bits); + L = (ULong*)f; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + return k; + } diff --git a/gdtoa/strtopx.c b/gdtoa/strtopx.c new file mode 100644 index 000000000..ecd0b3991 --- /dev/null +++ b/gdtoa/strtopx.c @@ -0,0 +1,103 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + int +#ifdef KR_headers +strtopx(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopx(CONST char *s, char **sp, void *V) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + UShort *L = (UShort*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Denormal: + L[_0] = 0; + goto normal_bits; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_0] = exp + 0x3fff + 63; + normal_bits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[0] = ldus_QNAN0; + L[1] = ldus_QNAN1; + L[2] = ldus_QNAN2; + L[3] = ldus_QNAN3; + L[4] = ldus_QNAN4; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + return k; + } diff --git a/gdtoa/strtopxL.c b/gdtoa/strtopxL.c new file mode 100644 index 000000000..00810fa35 --- /dev/null +++ b/gdtoa/strtopxL.c @@ -0,0 +1,91 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + int +#ifdef KR_headers +strtopxL(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopxL(CONST char *s, char **sp, void *V) +#endif +{ + static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_2] = bits[0]; + L[_1] = bits[1]; + L[_0] = (exp + 0x3fff + 63) << 16; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/gdtoa/strtorQ.c b/gdtoa/strtorQ.c new file mode 100644 index 000000000..1cb157890 --- /dev/null +++ b/gdtoa/strtorQ.c @@ -0,0 +1,118 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + void +#ifdef KR_headers +ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoQ(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + L[3] = ld_QNAN3; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorQ(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static CONST FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + CONST FPI *fpi; + FPI fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoQ((ULong*)L, bits, exp, k); + return k; + } diff --git a/gdtoa/strtord.c b/gdtoa/strtord.c new file mode 100644 index 000000000..1aa7aefe3 --- /dev/null +++ b/gdtoa/strtord.c @@ -0,0 +1,94 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtod(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = 0; + break; + + case STRTOG_Denormal: + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_1] = bits[0]; + L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Infinite: + L[_0] = 0x7ff00000; + L[_1] = 0; + break; + + case STRTOG_NaN: + L[0] = d_QNAN0; + L[1] = d_QNAN1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d; +#else +strtord(CONST char *s, char **sp, int rounding, double *d) +#endif +{ + static CONST FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + CONST FPI *fpi; + FPI fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/gdtoa/strtordd.c b/gdtoa/strtordd.c new file mode 100644 index 000000000..5b505f1b8 --- /dev/null +++ b/gdtoa/strtordd.c @@ -0,0 +1,200 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtodd(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + int i, j; + + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + L[2] = L[3] = 0; + break; + } + L[2+_1] = bits[0]; + L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + L[2] = L[3] = 0; + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + } + if (i == 0) { + L[_0] = bits[2] & 0xfffff | 33 << 20; + L[_1] = bits[1]; + L[2+_0] = 0; + L[2+_1] = bits[0]; + break; + } + j = 32 - i; + L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & ((ULong)1L << j) - 1; + break; + + case STRTOG_Infinite: + L[_0] = L[2+_0] = 0x7ff00000; + L[_1] = L[2+_1] = 0; + break; + + case STRTOG_NaN: + L[0] = L[2] = d_QNAN0; + L[1] = L[3] = d_QNAN1; + break; + + case STRTOG_NaNbits: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 + | (ULong)0x7ff00000L; + L[2+_1] = bits[0]; + L[2+_0] = bits[1] | (ULong)0x7ff00000L; + } + if (k & STRTOG_Neg) { + L[_0] |= 0x80000000L; + L[2+_0] |= 0x80000000L; + } + } + + int +#ifdef KR_headers +strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd; +#else +strtordd(CONST char *s, char **sp, int rounding, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static CONST FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static CONST FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + CONST FPI *fpi; + FPI fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtodd((ULong*)dd, bits, exp, k); + return k; + } diff --git a/gdtoa/strtorf.c b/gdtoa/strtorf.c new file mode 100644 index 000000000..3892d68d6 --- /dev/null +++ b/gdtoa/strtorf.c @@ -0,0 +1,90 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtof(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + *L = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f; +#else +strtorf(CONST char *s, char **sp, int rounding, float *f) +#endif +{ + static CONST FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + CONST FPI *fpi; + FPI fpi1; + ULong bits[1]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtof((ULong*)f, bits, exp, k); + return k; + } diff --git a/gdtoa/strtorx.c b/gdtoa/strtorx.c new file mode 100644 index 000000000..cc3c0700f --- /dev/null +++ b/gdtoa/strtorx.c @@ -0,0 +1,120 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + void +#ifdef KR_headers +ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k; +#else +ULtox(UShort *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Denormal: + L[_0] = 0; + goto normal_bits; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_0] = exp + 0x3fff + 63; + normal_bits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[0] = ldus_QNAN0; + L[1] = ldus_QNAN1; + L[2] = ldus_QNAN2; + L[3] = ldus_QNAN3; + L[4] = ldus_QNAN4; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + } + + int +#ifdef KR_headers +strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorx(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static CONST FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + CONST FPI *fpi; + FPI fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtox((UShort*)L, bits, exp, k); + return k; + } diff --git a/gdtoa/strtorxL.c b/gdtoa/strtorxL.c new file mode 100644 index 000000000..ffcafa907 --- /dev/null +++ b/gdtoa/strtorxL.c @@ -0,0 +1,108 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + void +#ifdef KR_headers +ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoxL(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_0] = (exp + 0x3fff + 63) << 16; + L[_1] = bits[1]; + L[_2] = bits[0]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorxL(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static CONST FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + CONST FPI *fpi; + FPI fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoxL((ULong*)L, bits, exp, k); + return k; + } diff --git a/gdtoa/sum.c b/gdtoa/sum.c new file mode 100644 index 000000000..dc0c88bcf --- /dev/null +++ b/gdtoa/sum.c @@ -0,0 +1,98 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + Bigint * +#ifdef KR_headers +sum(a, b) Bigint *a; Bigint *b; +#else +sum(Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + ULong carry, *xc, *xa, *xb, *xe, y; +#ifdef Pack_32 + ULong z; +#endif + + if (a->wds < b->wds) { + c = b; b = a; a = c; + } + c = Balloc(a->k); + c->wds = a->wds; + carry = 0; + xa = a->x; + xb = b->x; + xc = c->x; + xe = xc + b->wds; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) + (*xb & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + (*xb++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = (*xa & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ + *xb++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = *xa++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif + if (carry) { + if (c->wds == c->maxwds) { + b = Balloc(c->k + 1); + Bcopy(b, c); + Bfree(c); + c = b; + } + c->x[c->wds++] = 1; + } + return c; + } diff --git a/gdtoa/ulp.c b/gdtoa/ulp.c new file mode 100644 index 000000000..7810a5c8e --- /dev/null +++ b/gdtoa/ulp.c @@ -0,0 +1,70 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + double +ulp +#ifdef KR_headers + (x) double x; +#else + (double x) +#endif +{ + Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif + return a; + } diff --git a/jpeg-6b/CMakeLists.txt b/jpeg-6b/CMakeLists.txt new file mode 100644 index 000000000..26bc11f7f --- /dev/null +++ b/jpeg-6b/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required( VERSION 2.6 ) +project( jpeg ) + +if( CMAKE_COMPILER_IS_GNUC ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fomit-frame-pointer" ) +endif( CMAKE_COMPILER_IS_GNUC ) + +add_library( jpeg + jcomapi.c + jdapimin.c + jdapistd.c + jdatasrc.c + jdcoefct.c + jdcolor.c + jddctmgr.c + jdhuff.c + jdinput.c + jdmainct.c + jdmarker.c + jdmaster.c + jdmerge.c + jdphuff.c + jdpostct.c + jdsample.c + jerror.c + jidctint.c + jmemmgr.c + jutils.c ) +target_link_libraries( jpeg ) diff --git a/jpeg-6b/Makefile.mgw b/jpeg-6b/Makefile.mgw deleted file mode 100644 index 64b33c6f7..000000000 --- a/jpeg-6b/Makefile.mgw +++ /dev/null @@ -1,63 +0,0 @@ -# Makefile for libjpeg, derived from zlib/Makefile.mgw. - -STATICLIB = libjpeg.a - -CCDV = @../ccdv - -CC = gcc -CFLAGS = $(LOC) -O2 -Wall -fomit-frame-pointer - -AS = $(CC) -ASFLAGS = $(LOC) -Wall - -LD = $(CC) -LDFLAGS = $(LOC) -s - -AR = ar -ARFLAGS = rcs - -OBJS = jcomapi.o jdapimin.o jdapistd.o jdatasrc.o jdcoefct.o jdcolor.o \ - jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o jdmaster.o \ - jdmerge.o jdphuff.o jdpostct.o jdsample.o jerror.o jidctint.o \ - jmemmgr.o jutils.o - -all: $(STATICLIB) - -.c.o: - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(STATICLIB): $(OBJS) - $(CCDV) $(AR) $(ARFLAGS) $@ $(OBJS) - - -.PHONY: clean - -clean: -ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - rm -f $(STATICLIB) - rm -f *.o -else - -del /q /f $(STATICLIB) 2>nul - -del /q /f *.o 2>nul -endif - -jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h -jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h -jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h -jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h -jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h -jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h -jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h -jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h diff --git a/jpeg-6b/jpeg-6b.vcproj b/jpeg-6b/jpeg-6b.vcproj index 5b60647db..c6d6ce0d5 100644 --- a/jpeg-6b/jpeg-6b.vcproj +++ b/jpeg-6b/jpeg-6b.vcproj @@ -405,6 +405,10 @@ > + + diff --git a/snes_spc/CMakeLists.txt b/snes_spc/CMakeLists.txt new file mode 100644 index 000000000..89183540a --- /dev/null +++ b/snes_spc/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required( VERSION 2.6 ) +project( snes_spc ) + +# I don't plan on debugging this, so make it a release build. +set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) + +if( CMAKE_COMPILER_IS_GNUCXX ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fomit-frame-pointer" ) +endif( CMAKE_COMPILER_IS_GNUCXX ) + +add_library( snes_spc + snes_spc/dsp.cpp + snes_spc/SNES_SPC.cpp + snes_spc/SNES_SPC_misc.cpp + snes_spc/SNES_SPC_state.cpp + snes_spc/spc.cpp + snes_spc/SPC_DSP.cpp + snes_spc/SPC_Filter.cpp ) +target_link_libraries( snes_spc ) diff --git a/snes_spc/Makefile b/snes_spc/Makefile deleted file mode 100644 index 049e1332a..000000000 --- a/snes_spc/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# Makefile for snes_spc, derived from zlib/Makefile.mgw. - -CMD=0 -ifeq (Windows_NT,$(OS)) - CMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - CMD=0 - endif -endif - -STATICLIB = libsnes_spc.a - -CCDV = @../ccdv - -CC = gcc - -# SNES_SPC::cpu_write_high() contains an intentional write outside -# the RAM array, so don't warn about it. -CFLAGS = $(LOC) -O3 -Wall -Wno-array-bounds -fomit-frame-pointer - -LD = $(CC) -LDFLAGS = $(LOC) -s - -AR = ar -ARFLAGS = rcs - -OBJS = snes_spc/dsp.o snes_spc/SNES_SPC.o snes_spc/SNES_SPC_misc.o snes_spc/SNES_SPC_state.o \ - snes_spc/spc.o snes_spc/SPC_DSP.o snes_spc/SPC_Filter.o - -all: $(STATICLIB) - -.cpp.o: - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(STATICLIB): $(OBJS) - $(CCDV) $(AR) $(ARFLAGS) $@ $(OBJS) - - -.PHONY: clean - -clean: -ifeq (0,$(CMD)) - rm -f $(STATICLIB) - rm -f snes_spc/*.o -else - -del /q /f $(STATICLIB) 2>nul - -del /q /f snes_spc\*.o 2>nul -endif - -dsp.o: snes_spc/dsp.cpp snes_spc/dsp.h snes_spc/SPC_DSP.h -SNES_SPC.o: snes_spc/SNES_SPC.cpp snes_spc/SNES_SPC.h snes_spc/SPC_DSP.h -SNES_SPC_misc.o: snes_spc/SNES_SPC_misc.cpp snes_spc/SNES_SPC.h snes_spc/SPC_DSP.h -SNES_SPC_state.o: snes_spc/SNES_SPC_state.cpp snes_spc/SNES_SPC.h snes_spc/SPC_DSP.h -spc.o: snes_spc/spc.cpp snes_spc/spc.h snes_spc/SNES_SPC.h snes_spc/SPC_DSP.h snes_spc/SPC_Filter.h -SPC_DSP.o: snes_spc/SPC_DSP.cpp snes_spc/SPC_DSP.h -SPC_Filter.o: snes_spc/SPC_Filter.cpp snes_spc/SPC_Filter.h diff --git a/snes_spc/snes_spc.vcproj b/snes_spc/snes_spc.vcproj index a02cc1d62..ea0e62bf4 100644 --- a/snes_spc/snes_spc.vcproj +++ b/snes_spc/snes_spc.vcproj @@ -80,6 +80,69 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..62c13410f --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,697 @@ +cmake_minimum_required( VERSION 2.6 ) +include( CheckFunctionExists ) + +option( NO_ASM "Disable assembly code" ) +if( CMAKE_COMPILER_IS_GNUCXX ) + option( NO_STRIP "Do not strip Release or MinSizeRel builds" ) +endif( CMAKE_COMPILER_IS_GNUCXX ) + +if( CMAKE_SIZEOF_VOID_P MATCHES "8" ) + set( X64 64 ) +endif( CMAKE_SIZEOF_VOID_P MATCHES "8" ) + +if( WIN32 ) + if( X64 ) + set( WIN_TYPE Win64 ) + set( XBITS x64 ) + else( X64 ) + set( WIN_TYPE Win32 ) + set( XBITS x86 ) + endif( X64 ) + + add_definitions( -D_WIN32 ) + + set( FMOD_SEARCH_PATHS + "C:/Program Files/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" + "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" + "E:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" ) + set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES inc ) + set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib ) + set( NASM_NAMES nasmw nasm ) + + find_path( D3D_INCLUDE_DIR d3d9.h + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Include ) + if( NOT D3D_INCLUDE_DIR ) + message( SEND_ERROR "Could not find DirectX 9 header files" ) + else( NOT D3D_INCLUDE_DIR ) + include_directories( ${D3D_INCLUDE_DIR} ) + endif( NOT D3D_INCLUDE_DIR ) + + find_library( DX_ddraw_LIBRARY ddraw + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Lib Lib/${XBITS} ) + find_library( DX_dxguid_LIBRARY dxguid + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Lib Lib/${XBITS} ) + find_library( DX_dinput8_LIBRARY dinput8 + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Lib Lib/${XBITS} ) + + set( DX_LIBS_FOUND YES ) + if( NOT DX_ddraw_LIBRARY ) + set( DX_LIBS_FOUND NO ) + endif( NOT DX_ddraw_LIBRARY ) + if( NOT DX_dxguid_LIBRARY ) + set( DX_LIBS_FOUND NO ) + endif( NOT DX_dxguid_LIBRARY ) + if( NOT DX_dinput8_LIBRARY ) + set( DX_LIBS_FOUND NO ) + endif( NOT DX_dinput8_LIBRARY ) + + if( NOT DX_LIBS_FOUND ) + message( FATAL_ERROR "Could not find DirectX 9 libraries" ) + endif( NOT DX_LIBS_FOUND ) + + set( ZDOOM_LIBS + wsock32 + winmm + "${DX_ddraw_LIBRARY}" + "${DX_dxguid_LIBRARY}" + "${DX_dinput8_LIBRARY}" + ole32 + user32 + gdi32 + comctl32 + comdlg32 + ws2_32 + setupapi ) +else( WIN32 ) + option( NO_GTK "Disable GTK+ dialogs (Not applicable to Windows)" ) + option( VALGRIND "Add special Valgrind sequences to self-modifying code" ) + + set( FMOD_SEARCH_PATHS + /usr/local/include + /usr/include + /opt/local/include + /opt/include ) + set( NASM_NAMES nasm ) + + # Non-Windows version also needs SDL + find_package( SDL ) + if( NOT SDL_FOUND ) + message( SEND_ERROR "SDL is required for building." ) + endif( NOT SDL_FOUND ) + set( ZDOOM_LIBS "${SDL_LIBRARY}" ) + include_directories( "${SDL_INCLUDE_DIR}" ) + + # Use GTK+ for the IWAD picker, if available. + if( NOT NO_GTK ) + find_package( GTK ) + if( GTK_FOUND ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} ${GTK_LIBRARIES ) + include_directories( "${GTK_LIBRARIES}" ) + else( GTK_FOUND ) + set( NO_GTK ON ) + endif( GTK_FOUND ) + endif( NOT NO_GTK ) + + if( NO_GTK ) + add_definitions( -DNO_GTK=1 ) + endif( NO_GTK ) +endif( WIN32 ) + +if( X64 ) + set( NO_ASM ON ) +endif( X64 ) + +# Decide on the name of the FMOD library we want to use. + +if( NOT FMOD_LIB_NAME AND MSVC ) + set( FMOD_LIB_NAME fmodex${X64}_vc ) +endif( NOT FMOD_LIB_NAME AND MSVC ) + +if( NOT FMOD_LIB_NAME AND BORLAND ) + set( FMOD_LIB_NAME fmodex${X64}_bc ) +endif( NOT FMOD_LIB_NAME AND BORLAND ) + +if( NOT FMOD_LIB_NAME ) + set( FMOD_LIB_NAME fmodex${X64} ) +endif( NOT FMOD_LIB_NAME ) + + +# Search for FMOD include files + +find_path( FMOD_INCLUDE_DIR fmod.h + PATHS ${FMOD_SEARCH_PATHS} + ${FMOD_INC_PATH_SUFFIXES} ) + +if( FMOD_INCLUDE_DIR ) + message( STATUS "FMOD include files found at ${FMOD_INCLUDE_DIR}" ) +else( FMOD_INCLUDE_DIR ) + message( SEND_ERROR "Could not find FMOD include files" ) +endif( FMOD_INCLUDE_DIR ) + + +# Search for FMOD library + +find_library( FMOD_LIBRARY ${FMOD_LIB_NAME} + PATHS ${FMOD_SEARCH_PATHS} + ${FMOD_LIB_PATH_SUFFIXES} ) + +if( FMOD_LIBRARY ) + message( STATUS "FMOD library found at ${FMOD_LIBRARY}" ) +else( FMOD_LIBRARY ) + message( SEND_ERROR "Could not find FMOD library" ) +endif( FMOD_LIBRARY ) + + +# Search for NASM + +if( NOT NO_ASM ) + find_program( NASM_PATH NAMES ${NASM_NAMES} ) + + if( NOT NASM_PATH ) + message( STATUS "Could not find NASM. Disabling assembly code." ) + set( NO_ASM ON ) + else( NOT NASM_PATH ) + # I think the only reason there was a version requirement was because the + # executable name for Windows changed from 0.x to 2.0, right? This is + # how to do it in case I need to do something similar later. + + # execute_process( COMMAND ${NASM_PATH} -v + # OUTPUT_VARIABLE NASM_VER_STRING ) + # string( REGEX REPLACE ".*version ([0-9]+[.][0-9]+).*" "\\1" NASM_VER "${NASM_VER_STRING}" ) + # if( NOT NASM_VER LESS 2 ) + # message( SEND_ERROR "NASM version should be 2 or later. (Installed version is ${NASM_VER}.)" ) + # endif( NOT NASM_VER LESS 2 ) + endif( NOT NASM_PATH ) +endif( NOT NO_ASM ) + +if( NOT NO_ASM ) + # Valgrind support is meaningless without assembly code. + if( VALGRIND ) + add_definitions( -DVALGRIND_AWARE=1 ) + # If you're Valgrinding, you probably want to keep symbols around. + set( NO_STRIP ON ) + endif( VALGRIND ) + + # Tell CMake how to assemble our files + if( UNIX ) + set( NASM_OUTPUT_EXTENSION .o ) + set( NASM_FLAGS -f elf -DM_TARGET_LINUX ) + else( UNIX ) + set( NASM_OUTPUT_EXTENSION .obj ) + set( NASM_FLAGS -f win32 -DWIN32 ) + endif( UNIX ) + if( WIN32 ) + set( FIXRTEXT fixrtext ) + endif( WIN32 ) + MACRO( ADD_ASM_FILE infile ) + set( ASM_OUTPUT_${infile} "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${infile}${NASM_OUTPUT_EXTENSION}" ) + if( WIN32 ) + set( FIXRTEXT_${infile} COMMAND ${FIXRTEXT} "${ASM_OUTPUT_${infile}}" ) + endif( WIN32 ) + add_custom_command( OUTPUT ${ASM_OUTPUT_${infile}} + COMMAND ${NASM_PATH} ${NASM_FLAGS} -i${CMAKE_CURRENT_SOURCE_DIR}/ -o"${ASM_OUTPUT_${infile}}" "${CMAKE_CURRENT_SOURCE_DIR}/${infile}" + ${FIXRTEXT_${infile}} + DEPENDS ${infile} ${FIXRTEXT} ) + set( ASM_SOURCES ${ASM_SOURCES} "${ASM_OUTPUT_${infile}}" ) + ENDMACRO( ADD_ASM_FILE ) +endif( NOT NO_ASM ) + +# Set up flags for GCC + +if( CMAKE_COMPILER_IS_GNUCXX ) + set( REL_CXX_FLAGS "-fno-rtti -fomit-frame-pointer" ) + set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${REL_CXX_FLAGS}" ) + set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_CXX_FLAGS}" ) + set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_CXX_FLAGS}" ) + + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused -fno-strict-aliasing" ) + + if( NOT NO_STRIP ) + set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s" ) + set (CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} -s" ) + endif( NOT NO_STRIP ) +endif( CMAKE_COMPILER_IS_GNUCXX ) + +# Check for functions that may or may not exist. + +CHECK_FUNCTION_EXISTS( filelength FILELENGTH_EXISTS ) +if( FILELENGTH_EXISTS ) + add_definitions( -DHAVE_FILELENGTH=1 ) +endif( FILELENGTH_EXISTS ) + +CHECK_FUNCTION_EXISTS( strupr STRUPR_EXISTS ) +if( NOT STRUPR_EXISTS ) + add_definitions( -DNEED_STRUPR=1 ) +endif( NOT STRUPR_EXISTS ) + +CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS ) +if( NOT STRICMP_EXISTS ) + add_definitions( -Dstricmp=strcasecmp ) +endif( NOT STRICMP_EXISTS ) + +CHECK_FUNCTION_EXISTS( strnicmp STRNICMP_EXISTS ) +if( NOT STRNICMP_EXISTS ) + add_definitions( -Dstrnicmp=strncasecmp ) +endif( NOT STRNICMP_EXISTS ) + +if( NOT MSVC ) + add_definitions( -D__forceinline=inline ) +endif( NOT MSVC ) + +# Update svnrevision.h + +add_custom_command( OUTPUT ${CMAKE_SOURCE_DIR}/src/svnrevision.h + COMMAND updaterevision . src/svnrevision.h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + DEPENDS updaterevision ) + +add_custom_target( revision_check ALL + DEPENDS ${CMAKE_SOURCE_DIR}/src/svnrevision.h ) + +# Libraries ZDoom needs + +set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${FMOD_LIBRARY}" ) +include_directories( "${ZLIB_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" ) + +# Start defining source files for ZDoom + +if( WIN32 ) + set( SYSTEM_SOURCES_DIR win32 ) + set( SYSTEM_SOURCES + win32/eaxedit.cpp + win32/fb_d3d9.cpp + win32/fb_d3d9_wipe.cpp + win32/fb_ddraw.cpp + win32/hardware.cpp + win32/helperthread.cpp + win32/i_cd.cpp + win32/i_crash.cpp + win32/i_input.cpp + win32/i_main.cpp + win32/i_movie.cpp + win32/i_system.cpp + win32/st_start.cpp + win32/win32video.cpp ) + if( CMAKE_COMPILER_IS_GNUCXX ) + # CMake is not set up to compile and link rc files with GCC. :( + add_custom_command( OUTPUT zdoom-rc.o + COMMAND windres -o zdoom-rc.o -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zdoom.rc + DEPENDS win32/zdoom.rc ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} zdoom-rc.o ) + else( CMAKE_COMPILER_IS_GNUCXX ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} win32/zdoom.rc ) + endif( CMAKE_COMPILER_IS_GNUCXX ) +else( WIN32 ) + set( SYSTEM_SOURCES_DIR sdl ) + set( SYSTEM_SOURCES + sdl/crashcatcher.c + sdl/hardware.cpp + sdl/i_input.cpp + sdl/i_main.cpp + sdl/i_movie.cpp + sdl/i_system.cpp + sdl/sdlvideo.cpp + sdl/st_start.cpp ) +endif( WIN32 ) + +if( NOT NO_ASM ) + ADD_ASM_FILE( a.nas ) + ADD_ASM_FILE( misc.nas ) + ADD_ASM_FILE( tmap.nas ) + ADD_ASM_FILE( tmap2.nas ) + ADD_ASM_FILE( tmap3.nas ) + if( WIN32 ) + if( NOT X64 ) + ADD_ASM_FILE( win32/wrappers.nas ) + endif( NOT X64 ) + endif( WIN32 ) +endif( NOT NO_ASM ) + +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y . + COMMAND lemon xlat_parser.y + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y ) + +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h + COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re + DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/sc_man_scanner.re ) + +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) + +add_executable( zdoom WIN32 + autostart.cpp + ${ASM_SOURCES} + ${SYSTEM_SOURCES} + am_map.cpp + b_bot.cpp + b_func.cpp + b_game.cpp + b_move.cpp + b_think.cpp + bbannouncer.cpp + c_bind.cpp + c_cmds.cpp + c_console.cpp + c_cvars.cpp + c_dispatch.cpp + c_expr.cpp + cmdlib.cpp + colormatcher.cpp + configfile.cpp + ct_chat.cpp + d_dehacked.cpp + d_main.cpp + d_net.cpp + d_netinfo.cpp + d_protocol.cpp + decallib.cpp + dobject.cpp + dobjgc.cpp + dobjtype.cpp + doomdef.cpp + doomstat.cpp + dsectoreffect.cpp + dthinker.cpp + f_finale.cpp + f_wipe.cpp + farchive.cpp + files.cpp + g_game.cpp + g_hub.cpp + g_level.cpp + gameconfigfile.cpp + gi.cpp + hu_scores.cpp + i_net.cpp + info.cpp + infodefaults.cpp + lumpconfigfile.cpp + m_alloc.cpp + m_argv.cpp + m_bbox.cpp + m_cheat.cpp + m_menu.cpp + m_misc.cpp + m_options.cpp + m_png.cpp + m_random.cpp + mus2midi.cpp + name.cpp + nodebuild.cpp + nodebuild_classify_nosse2.cpp + nodebuild_classify_sse2.cpp + nodebuild_events.cpp + nodebuild_extract.cpp + nodebuild_gl.cpp + nodebuild_utility.cpp + p_3dmidtex.cpp + p_acs.cpp + p_buildmap.cpp + p_ceiling.cpp + p_conversation.cpp + p_doors.cpp + p_effect.cpp + p_enemy.cpp + p_enemy_a_lookex.cpp + p_floor.cpp + p_interaction.cpp + p_lights.cpp + p_linkedsectors.cpp + p_lnspec.cpp + p_map.cpp + p_maputl.cpp + p_mobj.cpp + p_pillar.cpp + p_plats.cpp + p_pspr.cpp + p_saveg.cpp + p_sectors.cpp + p_setup.cpp + p_sight.cpp + p_slopes.cpp + p_spec.cpp + p_switch.cpp + p_teleport.cpp + p_terrain.cpp + p_things.cpp + p_tick.cpp + p_trace.cpp + p_udmf.cpp + p_user.cpp + p_writemap.cpp + p_xlat.cpp + parsecontext.cpp + po_man.cpp + r_anim.cpp + r_bsp.cpp + r_data.cpp + r_draw.cpp + r_drawt.cpp + r_interpolate.cpp + r_main.cpp + r_plane.cpp + r_polymost.cpp + r_segs.cpp + r_sky.cpp + r_things.cpp + r_translate.cpp + s_advsound.cpp + s_environment.cpp + s_playlist.cpp + s_sndseq.cpp + s_sound.cpp + sc_man.cpp + st_stuff.cpp + stats.cpp + stringtable.cpp + tables.cpp + teaminfo.cpp + tempfiles.cpp + v_collection.cpp + v_draw.cpp + v_font.cpp + v_palette.cpp + v_pfx.cpp + v_text.cpp + v_video.cpp + w_wad.cpp + wi_stuff.cpp + zstrformat.cpp + zstring.cpp + g_doom/a_arachnotron.cpp + g_doom/a_archvile.cpp + g_doom/a_bossbrain.cpp + g_doom/a_bruiser.cpp + g_doom/a_cacodemon.cpp + g_doom/a_cyberdemon.cpp + g_doom/a_demon.cpp + g_doom/a_doomimp.cpp + g_doom/a_doommisc.cpp + g_doom/a_doomweaps.cpp + g_doom/a_fatso.cpp + g_doom/a_keen.cpp + g_doom/a_lostsoul.cpp + g_doom/a_painelemental.cpp + g_doom/a_possessed.cpp + g_doom/a_revenant.cpp + g_doom/a_scriptedmarine.cpp + g_doom/a_spidermaster.cpp + g_doom/doom_sbar.cpp + g_heretic/a_chicken.cpp + g_heretic/a_dsparil.cpp + g_heretic/a_hereticartifacts.cpp + g_heretic/a_hereticimp.cpp + g_heretic/a_hereticmisc.cpp + g_heretic/a_hereticweaps.cpp + g_heretic/a_ironlich.cpp + g_heretic/a_knight.cpp + g_heretic/a_wizard.cpp + g_heretic/heretic_sbar.cpp + g_hexen/a_bats.cpp + g_hexen/a_bishop.cpp + g_hexen/a_blastradius.cpp + g_hexen/a_boostarmor.cpp + g_hexen/a_centaur.cpp + g_hexen/a_clericboss.cpp + g_hexen/a_clericflame.cpp + g_hexen/a_clericholy.cpp + g_hexen/a_clericmace.cpp + g_hexen/a_clericstaff.cpp + g_hexen/a_dragon.cpp + g_hexen/a_fighteraxe.cpp + g_hexen/a_fighterboss.cpp + g_hexen/a_fighterhammer.cpp + g_hexen/a_fighterplayer.cpp + g_hexen/a_fighterquietus.cpp + g_hexen/a_firedemon.cpp + g_hexen/a_flechette.cpp + g_hexen/a_fog.cpp + g_hexen/a_healingradius.cpp + g_hexen/a_heresiarch.cpp + g_hexen/a_hexenspecialdecs.cpp + g_hexen/a_iceguy.cpp + g_hexen/a_korax.cpp + g_hexen/a_mageboss.cpp + g_hexen/a_magecone.cpp + g_hexen/a_magelightning.cpp + g_hexen/a_magestaff.cpp + g_hexen/a_magewand.cpp + g_hexen/a_pig.cpp + g_hexen/a_serpent.cpp + g_hexen/a_spike.cpp + g_hexen/a_summon.cpp + g_hexen/a_teleportother.cpp + g_hexen/a_weaponpieces.cpp + g_hexen/a_wraith.cpp + g_hexen/hexen_sbar.cpp + g_raven/a_artitele.cpp + g_raven/a_minotaur.cpp + g_strife/a_acolyte.cpp + g_strife/a_alienspectres.cpp + g_strife/a_coin.cpp + g_strife/a_crusader.cpp + g_strife/a_entityboss.cpp + g_strife/a_inquisitor.cpp + g_strife/a_loremaster.cpp + g_strife/a_macil.cpp + g_strife/a_oracle.cpp + g_strife/a_programmer.cpp + g_strife/a_reaver.cpp + g_strife/a_rebels.cpp + g_strife/a_sentinel.cpp + g_strife/a_spectral.cpp + g_strife/a_stalker.cpp + g_strife/a_strifeitems.cpp + g_strife/a_strifestuff.cpp + g_strife/a_strifeweapons.cpp + g_strife/a_templar.cpp + g_strife/a_thingstoblowup.cpp + g_strife/strife_sbar.cpp + g_shared/a_action.cpp + g_shared/a_armor.cpp + g_shared/a_artifacts.cpp + g_shared/a_bridge.cpp + g_shared/a_camera.cpp + g_shared/a_debris.cpp + g_shared/a_decals.cpp + g_shared/a_flashfader.cpp + g_shared/a_fountain.cpp + g_shared/a_hatetarget.cpp + g_shared/a_keys.cpp + g_shared/a_lightning.cpp + g_shared/a_mapmarker.cpp + g_shared/a_morph.cpp + g_shared/a_movingcamera.cpp + g_shared/a_pickups.cpp + g_shared/a_puzzleitems.cpp + g_shared/a_quake.cpp + g_shared/a_randomspawner.cpp + g_shared/a_secrettrigger.cpp + g_shared/a_sectoraction.cpp + g_shared/a_setcolor.cpp + g_shared/a_skies.cpp + g_shared/a_soundenvironment.cpp + g_shared/a_soundsequence.cpp + g_shared/a_spark.cpp + g_shared/a_specialspot.cpp + g_shared/a_waterzone.cpp + g_shared/a_weaponpiece.cpp + g_shared/a_weapons.cpp + g_shared/hudmessages.cpp + g_shared/sbarinfo_display.cpp + g_shared/sbarinfo_parser.cpp + g_shared/sbar_mugshot.cpp + g_shared/shared_hud.cpp + g_shared/shared_sbar.cpp + oplsynth/fmopl.cpp + oplsynth/mlopl.cpp + oplsynth/mlopl_io.cpp + oplsynth/music_opldumper_mididevice.cpp + oplsynth/music_opl_mididevice.cpp + oplsynth/opl_mus_player.cpp + sound/fmodsound.cpp + sound/i_music.cpp + sound/i_sound.cpp + sound/music_cd.cpp + sound/music_dumb.cpp + sound/music_midistream.cpp + sound/music_midi_base.cpp + sound/music_midi_midiout.cpp + sound/music_midi_timidity.cpp + sound/music_mus_midiout.cpp + sound/music_mus_opl.cpp + sound/music_spc.cpp + sound/music_stream.cpp + sound/music_timidity_mididevice.cpp + sound/music_win_mididevice.cpp + textures/automaptexture.cpp + textures/bitmap.cpp + textures/buildtexture.cpp + textures/canvastexture.cpp + textures/ddstexture.cpp + textures/flattexture.cpp + textures/imgztexture.cpp + textures/jpegtexture.cpp + textures/multipatchtexture.cpp + textures/patchtexture.cpp + textures/pcxtexture.cpp + textures/pngtexture.cpp + textures/rawpagetexture.cpp + textures/texture.cpp + textures/texturemanager.cpp + textures/tgatexture.cpp + textures/warptexture.cpp + thingdef/olddecorations.cpp + thingdef/thingdef.cpp + thingdef/thingdef_codeptr.cpp + thingdef/thingdef_exp.cpp + thingdef/thingdef_main.cpp + thingdef/thingdef_properties.cpp + thingdef/thingdef_states.cpp + timidity/common.cpp + timidity/instrum.cpp + timidity/instrum_dls.cpp + timidity/instrum_font.cpp + timidity/instrum_sf2.cpp + timidity/mix.cpp + timidity/playmidi.cpp + timidity/resample.cpp + timidity/timidity.cpp + xlat/parse_xlat.cpp + autozend.cpp ) + +set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) +set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) + +target_link_libraries( zdoom ${ZDOOM_LIBS} snes_spc gdtoa dumb ) +include_directories( . + g_doom + g_heretic + g_hexen + g_raven + g_strife + g_shared + oplsynth + sound + textures + thingdef + timidity + xlat + ../snes_spc/snes_spc + ../gdtoa + ../dumb/include + ${CMAKE_BINARY_DIR}/gdtoa + ${SYSTEM_SOURCES_DIR} ) + +add_dependencies( zdoom revision_check ) + +set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) +set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) + +if( CMAKE_COMPILER_IS_GNUCXX ) + # GCC misoptimizes this file + set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" ) + + # Compile this one file with SSE2 support. + set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mfpmath=sse" ) +endif( CMAKE_COMPILER_IS_GNUCXX ) + +if( MSVC ) + # Compile this one file with SSE2 support. + set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "/arch:SSE2" ) +endif( MSVC ) diff --git a/src/a.nas b/src/a.nas index cdcbd7f0f..196e8317a 100644 --- a/src/a.nas +++ b/src/a.nas @@ -3,7 +3,7 @@ ; See the included license file "BUILDLIC.TXT" for license info. ; This file has been modified from Ken Silverman's original release -%include "src/valgrind.inc" +%include "valgrind.inc" SECTION .data diff --git a/src/am_map.cpp b/src/am_map.cpp index 8530e8fbe..50ae598d7 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -733,7 +733,7 @@ void AM_loadPics () for (i = 0; i < 10; i++) { - sprintf (namebuf, "AMMNUM%d", i); + mysnprintf (namebuf, countof(namebuf), "AMMNUM%d", i); marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); } diff --git a/src/b_game.cpp b/src/b_game.cpp index b3f8d0102..c6b6a0fef 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -327,7 +327,8 @@ bool FCajunMaster::SpawnBot (const char *name, int color) } if (TEAMINFO_IsValidTeam (thebot->lastteam)) { // Keep the bot on the same team when switching levels - sprintf (concat+strlen(concat), "\\team\\%d\n", thebot->lastteam); + mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat), + "\\team\\%d\n", thebot->lastteam); } Net_WriteString (concat); } @@ -602,7 +603,7 @@ bool FCajunMaster::LoadBots () } } appendinfo (newinfo->info, "team"); - sprintf (teamstr, "%d", teamnum); + mysnprintf (teamstr, countof(teamstr), "%d", teamnum); appendinfo (newinfo->info, teamstr); gotteam = true; break; diff --git a/src/c_bind.cpp b/src/c_bind.cpp index e7fb28388..f713257b0 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -275,7 +275,7 @@ static const char *KeyName (int key) if (KeyNames[key]) return KeyNames[key]; - sprintf (name, "#%d", key); + mysnprintf (name, countof(name), "#%d", key); return name; } diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 1a739b38e..33d10d4ae 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -247,7 +247,7 @@ CCMD (idclev) { int epsd, map; char buf[2]; - char *mapname; + FString mapname; buf[0] = argv[1][0] - '0'; buf[1] = argv[1][1] - '0'; @@ -283,9 +283,9 @@ CCMD (hxvisit) if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1]) { - char mapname[9]; + FString mapname("&wt@"); - sprintf (mapname, "&wt@%c%c", argv[1][0], argv[1][1]); + mapname << argv[1][0] << argv[1][1]; if (CheckWarpTransMap (mapname, false)) { diff --git a/src/c_console.cpp b/src/c_console.cpp index c0fe66a5c..7a92f7ee8 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1174,7 +1174,7 @@ void C_DrawConsole (bool hw2d) if (TickerLabel) { tickbegin = (int)strlen (TickerLabel) + 2; - sprintf (tickstr, "%s: ", TickerLabel); + mysnprintf (tickstr, countof(tickstr), "%s: ", TickerLabel); } if (tickend > 256 - ConFont->GetCharWidth(0x12)) tickend = 256 - ConFont->GetCharWidth(0x12); @@ -1184,7 +1184,8 @@ void C_DrawConsole (bool hw2d) tickstr[tickend + 2] = ' '; if (TickerPercent) { - sprintf (tickstr + tickend + 3, "%d%%", Scale (TickerAt, 100, TickerMax)); + mysnprintf (tickstr + tickend + 3, countof(tickstr) - tickend - 3, + "%d%%", Scale (TickerAt, 100, TickerMax)); } else { diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 91bbcbc2f..04f8e2aa8 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -268,15 +268,15 @@ char *FBaseCVar::ToString (UCVarValue value, ECVarType type) return value.String; case CVAR_Int: - sprintf (cstrbuf, "%i", value.Int); + mysnprintf (cstrbuf, countof(cstrbuf), "%i", value.Int); break; case CVAR_Float: - sprintf (cstrbuf, "%g", value.Float); + mysnprintf (cstrbuf, countof(cstrbuf), "%g", value.Float); break; case CVAR_GUID: - FormatGUID (cstrbuf, *value.pGUID); + FormatGUID (cstrbuf, countof(cstrbuf), *value.pGUID); break; default: @@ -356,7 +356,7 @@ UCVarValue FBaseCVar::FromInt (int value, ECVarType type) break; case CVAR_String: - sprintf (cstrbuf, "%i", value); + mysnprintf (cstrbuf, countof(cstrbuf), "%i", value); ret.String = cstrbuf; break; @@ -390,7 +390,7 @@ UCVarValue FBaseCVar::FromFloat (float value, ECVarType type) break; case CVAR_String: - sprintf (cstrbuf, "%g", value); + mysnprintf (cstrbuf, countof(cstrbuf), "%g", value); ret.String = cstrbuf; break; @@ -891,7 +891,7 @@ UCVarValue FColorCVar::FromInt2 (int value, ECVarType type) if (type == CVAR_String) { UCVarValue ret; - sprintf (cstrbuf, "%02x %02x %02x", + mysnprintf (cstrbuf, countof(cstrbuf), "%02x %02x %02x", RPART(value), GPART(value), BPART(value)); ret.String = cstrbuf; return ret; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 06770547f..66878b4a6 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -246,13 +246,13 @@ static int ListActionCommands (const char *pattern) for (i = 0; i < NUM_ACTIONS; ++i) { if (pattern == NULL || CheckWildcards (pattern, - (sprintf (matcher, "+%s", ActionMaps[i].Name), matcher))) + (mysnprintf (matcher, countof(matcher), "+%s", ActionMaps[i].Name), matcher))) { Printf ("+%s\n", ActionMaps[i].Name); count++; } if (pattern == NULL || CheckWildcards (pattern, - (sprintf (matcher, "-%s", ActionMaps[i].Name), matcher))) + (mysnprintf (matcher, countof(matcher), "-%s", ActionMaps[i].Name), matcher))) { Printf ("-%s\n", ActionMaps[i].Name); count++; diff --git a/src/c_expr.cpp b/src/c_expr.cpp index 82d972bd1..6fcd19c4f 100644 --- a/src/c_expr.cpp +++ b/src/c_expr.cpp @@ -351,7 +351,7 @@ static FStringProd *DoubleToString (FProduction *prod) char buf[128]; FStringProd *newprod; - sprintf (buf, "%g", static_cast(prod)->Value); + mysnprintf (buf, countof(buf), "%g", static_cast(prod)->Value); newprod = NewStringProd (buf); M_Free (prod); return newprod; diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index e4df119a0..9731874e4 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -315,9 +315,9 @@ bool CheckWildcards (const char *pattern, const char *text) // [RH] Print a GUID to a text buffer using the standard format. -void FormatGUID (char *text, const GUID &guid) +void FormatGUID (char *buffer, size_t buffsize, const GUID &guid) { - sprintf (text, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + mysnprintf (buffer, buffsize, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", (uint32)guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], @@ -375,7 +375,7 @@ void CreatePath(const char * fn) if (c!='\\' && c!='/') { - sprintf(name, "%s/", fn); + mysnprintf(name, countof(name), "%s/", fn); DoCreatePath(name); } else DoCreatePath(fn); diff --git a/src/cmdlib.h b/src/cmdlib.h index 12808a492..4916eee1f 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -48,7 +48,7 @@ void ReplaceString (char **ptr, const char *str); bool CheckWildcards (const char *pattern, const char *text); -void FormatGUID (char *text, const GUID &guid); +void FormatGUID (char *buffer, size_t buffsize, const GUID &guid); const char *myasctime (); diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 2953483d6..b223b08f3 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -55,7 +55,7 @@ static void CT_ClearChatMessage (); static void CT_AddChar (char c); static void CT_BackSpace (); static void ShoveChatStr (const char *str, BYTE who); -static bool DoSubstitution (char *out, const char *in); +static bool DoSubstitution (FString &out, const char *in); static int len; static BYTE ChatQueue[QUEUESIZE]; @@ -309,7 +309,7 @@ static void CT_ClearChatMessage () static void ShoveChatStr (const char *str, BYTE who) { - char substBuff[256]; + FString substBuff; if (str[0] == '/' && (str[1] == 'm' || str[1] == 'M') && @@ -341,20 +341,20 @@ static void ShoveChatStr (const char *str, BYTE who) // //=========================================================================== -static bool DoSubstitution (char *out, const char *in) +static bool DoSubstitution (FString &out, const char *in) { player_t *player = &players[consoleplayer]; AWeapon *weapon = player->ReadyWeapon; const char *a, *b; a = in; - while ((b = strchr (a, '$'))) + out = ""; + while ( (b = strchr(a, '$')) ) { - strncpy (out, a, b - a); - out += b - a; + out.AppendCStrPart(a, b - a); a = ++b; - while (*b && isalpha (*b)) + while (*b && isalpha(*b)) { ++b; } @@ -363,71 +363,69 @@ static bool DoSubstitution (char *out, const char *in) if (len == 6) { - if (strnicmp (a, "health", 6) == 0) + if (strnicmp(a, "health", 6) == 0) { - out += sprintf (out, "%d", player->health); + out.AppendFormat("%d", player->health); } - else if (strnicmp (a, "weapon", 6) == 0) + else if (strnicmp(a, "weapon", 6) == 0) { if (weapon == NULL) { - out += sprintf (out, "no weapon"); + out += "no weapon"; } else { - out += sprintf (out, "%s", weapon->GetClass()->TypeName.GetChars()); + out += weapon->GetClass()->TypeName; } } } else if (len == 5) { - if (strnicmp (a, "armor", 5) == 0) + if (strnicmp(a, "armor", 5) == 0) { AInventory *armor = player->mo->FindInventory(); - int armorpoints = armor != NULL ? armor->Amount : 0; - out += sprintf (out, "%d", armorpoints); + out.AppendFormat("%d", armor != NULL ? armor->Amount : 0); } } else if (len == 9) { - if (strnicmp (a, "ammocount", 9) == 0) + if (strnicmp(a, "ammocount", 9) == 0) { if (weapon == NULL) { - out += sprintf (out, "0"); + out += '0'; } else { - out += sprintf (out, "%d", weapon->Ammo1 != NULL ? weapon->Ammo1->Amount : 0); + out.AppendFormat("%d", weapon->Ammo1 != NULL ? weapon->Ammo1->Amount : 0); if (weapon->Ammo2 != NULL) { - out += sprintf (out, "/%d", weapon->Ammo2->Amount); + out.AppendFormat("/%d", weapon->Ammo2->Amount); } } } } else if (len == 4) { - if (strnicmp (a, "ammo", 4) == 0) + if (strnicmp(a, "ammo", 4) == 0) { if (weapon == NULL || weapon->Ammo1 == NULL) { - out += sprintf (out, "no ammo"); + out += "no ammo"; } else { - out += sprintf (out, "%s", weapon->Ammo1->GetClass()->TypeName.GetChars()); + out.AppendFormat("%s", weapon->Ammo1->GetClass()->TypeName.GetChars()); if (weapon->Ammo2 != NULL) { - out += sprintf (out, "/%s", weapon->Ammo2->GetClass()->TypeName.GetChars()); + out.AppendFormat("/%s", weapon->Ammo2->GetClass()->TypeName.GetChars()); } } } } else if (len == 0) { - *out++ = '$'; - *out = 0; + out += '$'; if (*b == '$') { b++; @@ -435,9 +433,8 @@ static bool DoSubstitution (char *out, const char *in) } else { - *out++ = '$'; - strncpy (out, a, len); - out += len; + out += '$'; + out.AppendCStrPart(a, len); } a = b; } @@ -448,7 +445,7 @@ static bool DoSubstitution (char *out, const char *in) return false; } - strcpy (out, a); + out += a; return true; } diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 646d7ed7d..7b3c0c065 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1755,11 +1755,11 @@ static int PatchPars (int dummy) if (moredata) { // At least 3 items on this line, must be E?M? format - sprintf (mapname, "E%cM%c", *Line2, *space); + mysnprintf (mapname, countof(mapname), "E%cM%c", *Line2, *space); par = atoi (moredata + 1); } else { // Only 2 items, must be MAP?? format - sprintf (mapname, "MAP%02d", atoi(Line2) % 100); + mysnprintf (mapname, countof(mapname), "MAP%02d", atoi(Line2) % 100); par = atoi (space); } @@ -1939,7 +1939,7 @@ static int PatchText (int oldSize) { // Music names are never >6 chars char musname[9]; level_info_t *info = LevelInfos; - sprintf (musname, "d_%s", oldStr); + mysnprintf (musname, countof(musname), "d_%s", oldStr); while (info->level_name) { @@ -2577,7 +2577,7 @@ void FinishDehPatch () // Create a new class that will serve as the actual pickup char typeNameBuilder[32]; - sprintf (typeNameBuilder, "DehackedPickup%d", touchedIndex); + mysnprintf (typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", touchedIndex); PClass *subclass = RUNTIME_CLASS(ADehackedPickup)->CreateDerivedClass (typeNameBuilder, sizeof(ADehackedPickup)); AActor *defaults2 = GetDefaultByType (subclass); diff --git a/src/d_main.cpp b/src/d_main.cpp index f275b4e86..e8cf00d07 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -187,7 +187,7 @@ bool devparm; // started game with -devparm const char *D_DrawIcon; // [RH] Patch name of icon to draw on next refresh int NoWipe; // [RH] Allow wipe? (Needs to be set each time) bool singletics = false; // debug flag to cancel adaptiveness -char startmap[8]; +FString startmap; bool autostart; bool advancedemo; FILE *debugfile; @@ -1053,7 +1053,7 @@ void D_DoAdvanceDemo (void) { BorderNeedRefresh = screen->GetPageCount (); democount++; - sprintf (demoname + 4, "%d", democount); + mysnprintf (demoname + 4, countof(demoname) - 4, "%d", democount); if (Wads.CheckNumForName (demoname) < 0) { demosequence = 0; @@ -1865,7 +1865,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf if (lookfirstinprogdir) { - sprintf (wad, "%s%s%s", progdir.GetChars(), progdir[progdir.Len() - 1] != '/' ? "/" : "", file); + mysnprintf (wad, countof(wad), "%s%s%s", progdir.GetChars(), progdir[progdir.Len() - 1] != '/' ? "/" : "", file); if (FileExists (wad)) { return wad; @@ -1874,7 +1874,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf if (FileExists (file)) { - sprintf (wad, "%s", file); + mysnprintf (wad, countof(wad), "%s", file); return wad; } @@ -1914,7 +1914,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf } if (dir != NULL) { - sprintf (wad, "%s%s%s", dir, dir[strlen (dir) - 1] != '/' ? "/" : "", file); + mysnprintf (wad, countof(wad), "%s%s%s", dir, dir[strlen (dir) - 1] != '/' ? "/" : "", file); if (FileExists (wad)) { return wad; @@ -2246,11 +2246,11 @@ void D_DoomMain (void) // get skill / episode / map from parms if (gameinfo.gametype != GAME_Hexen) { - strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1"); + startmap = (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1"; } else { - strcpy (startmap, "&wt@01"); + startmap = "&wt@01"; } autostart = false; @@ -2282,7 +2282,7 @@ void D_DoomMain (void) } } - strncpy (startmap, CalcMapName (ep, map), 8); + startmap = CalcMapName (ep, map); autostart = true; } @@ -2296,7 +2296,7 @@ void D_DoomMain (void) } else { - strncpy (startmap, Args->GetArg (p+1), 8); + startmap = Args->GetArg (p + 1); Args->GetArg (p)[0] = '-'; autostart = true; } @@ -2358,7 +2358,7 @@ void D_DoomMain (void) if (autostart) { FString temp; - temp.Format ("Warp to map %s, Skill %d ", startmap, gameskill + 1); + temp.Format ("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1); StartScreen->AppendStatusLine(temp); } diff --git a/src/d_net.cpp b/src/d_net.cpp index 83db8f21d..a7cc718fb 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1379,7 +1379,7 @@ bool DoArbitrate (void *userdata) stream = &netbuffer[4]; s = ReadString (&stream); - strncpy (startmap, s, 8); + startmap = FString(s, 8); delete[] s; rngseed = ReadLong (&stream); C_ReadCVars (&stream); @@ -1600,10 +1600,10 @@ void D_CheckNetGame (void) if (Args->CheckParm ("-debugfile")) { - char filename[20]; - sprintf (filename,"debug%i.txt",consoleplayer); - Printf ("debug output to: %s\n",filename); - debugfile = fopen (filename,"w"); + char filename[20]; + mysnprintf (filename, countof(filename), "debug%i.txt", consoleplayer); + Printf ("debug output to: %s\n", filename); + debugfile = fopen (filename, "w"); } if (netgame) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 1f9468147..af5745c58 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -411,7 +411,7 @@ void D_UserInfoChanged (FBaseCVar *cvar) if (4 + strlen(cvar->GetName()) + escaped_val.Len() > 256) I_Error ("User info descriptor too big"); - sprintf (foo, "\\%s\\%s", cvar->GetName(), escaped_val.GetChars()); + mysnprintf (foo, countof(foo), "\\%s\\%s", cvar->GetName(), escaped_val.GetChars()); Net_WriteByte (DEM_UINFCHANGED); Net_WriteString (foo); diff --git a/src/doomstat.h b/src/doomstat.h index 182bed8d8..a58aca801 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -68,7 +68,7 @@ extern GameMission_t gamemission; // Selected skill type, map etc. // -extern char startmap[8]; // [RH] Actual map name now +extern FString startmap; // [RH] Actual map name now extern bool autostart; diff --git a/src/doomtype.h b/src/doomtype.h index dac73fe12..95287d6e6 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -153,23 +153,23 @@ enum // // Fixed point, 32bit as 16.16. // -#define FRACBITS 16 -#define FRACUNIT (1<DrawTexture (TexMan(name), (320-13*8)/2, (200-8*8)/2, DTA_320x200, true, TAG_DONE); } } diff --git a/src/g_game.cpp b/src/g_game.cpp index dab6b5f4c..0de51d25b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1960,13 +1960,13 @@ static void PutSaveComment (FILE *file) // Get level name //strcpy (comment, level.level_name); - sprintf(comment, "%s - %s", level.mapname, level.level_name); + mysnprintf(comment, countof(comment), "%s - %s", level.mapname, level.level_name); len = (WORD)strlen (comment); comment[len] = '\n'; // Append elapsed time levelTime = level.time / TICRATE; - sprintf (comment+len+1, "time: %02d:%02d:%02d", + mysnprintf (comment + len + 1, countof(comment) - len - 1, "time: %02d:%02d:%02d", levelTime/3600, (levelTime%3600)/60, levelTime%60); comment[len+16] = 0; diff --git a/src/g_level.cpp b/src/g_level.cpp index 695a2ca09..e36b1a8ac 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -762,12 +762,18 @@ static void G_DoParseMapInfo (int lump) break; case MITL_MAP: // map + { + char maptemp[8]; + char *mapname; + levelflags = defaultinfo.flags; sc.MustGetString (); - if (IsNum (sc.String)) + mapname = sc.String; + if (IsNum (mapname)) { // MAPNAME is a number; assume a Hexen wad - int map = atoi (sc.String); - sprintf (sc.String, "MAP%02d", map); + int mapnum = atoi (mapname); + mysnprintf (maptemp, countof(maptemp), "MAP%02d", mapnum); + mapname = maptemp; HexenHack = true; // Hexen levels are automatically nointermission, // no auto sound sequences, falling damage, @@ -782,7 +788,7 @@ static void G_DoParseMapInfo (int lump) | LEVEL_MONSTERFALLINGDAMAGE | LEVEL_HEXENHACK; } - levelindex = FindWadLevelInfo (sc.String); + levelindex = FindWadLevelInfo (mapname); if (levelindex == -1) { levelindex = wadlevelinfos.Reserve(1); @@ -806,13 +812,13 @@ static void G_DoParseMapInfo (int lump) { levelinfo->WallHorizLight = levelinfo->WallVertLight = 0; } - uppercopy (levelinfo->mapname, sc.String); + uppercopy (levelinfo->mapname, mapname); sc.MustGetString (); if (sc.String[0] == '$') { // For consistency with other definitions allow $Stringtablename here, too. levelflags |= LEVEL_LOOKUPLEVELNAME; - ReplaceString (&levelinfo->level_name, sc.String+1); + ReplaceString (&levelinfo->level_name, sc.String + 1); } else { @@ -856,6 +862,7 @@ static void G_DoParseMapInfo (int lump) } } break; + } case MITL_CLUSTERDEF: // clusterdef sc.MustGetNumber (); @@ -981,22 +988,26 @@ static void ParseMapInfoLower (FScanner &sc, case MITYPE_MAPNAME: { EndSequence newSeq; bool useseq = false; + char maptemp[8]; + char *mapname; sc.MustGetString (); - if (IsNum (sc.String)) + mapname = sc.String; + if (IsNum (mapname)) { - int map = atoi (sc.String); + int mapnum = atoi (mapname); if (HexenHack) { - sprintf (sc.String, "&wt@%02d", map); + mysnprintf (maptemp, countof(maptemp), "&wt@%02d", mapnum); } else { - sprintf (sc.String, "MAP%02d", map); + mysnprintf (maptemp, countof(maptemp), "MAP%02d", mapnum); } + mapname = maptemp; } - if (sc.Compare ("endgame")) + if (stricmp (mapname, "endgame") == 0) { newSeq.Advanced = true; newSeq.EndType = END_Pic1; @@ -1046,7 +1057,7 @@ static void ParseMapInfoLower (FScanner &sc, } useseq = true; } - else if (strnicmp (sc.String, "EndGame", 7) == 0) + else if (strnicmp (mapname, "EndGame", 7) == 0) { int type; switch (sc.String[7]) @@ -1062,46 +1073,46 @@ static void ParseMapInfoLower (FScanner &sc, newSeq.EndType = type; useseq = true; } - else if (sc.Compare ("endpic")) + else if (stricmp (mapname, "endpic") == 0) { sc.MustGetString (); newSeq.EndType = END_Pic; newSeq.PicName = sc.String; useseq = true; } - else if (sc.Compare ("endbunny")) + else if (stricmp (mapname, "endbunny") == 0) { newSeq.EndType = END_Bunny; useseq = true; } - else if (sc.Compare ("endcast")) + else if (stricmp (mapname, "endcast") == 0) { newSeq.EndType = END_Cast; useseq = true; } - else if (sc.Compare ("enddemon")) + else if (stricmp (mapname, "enddemon") == 0) { newSeq.EndType = END_Demon; useseq = true; } - else if (sc.Compare ("endchess")) + else if (stricmp (mapname, "endchess") == 0) { newSeq.EndType = END_Chess; useseq = true; } - else if (sc.Compare ("endunderwater")) + else if (stricmp (mapname, "endunderwater") == 0) { newSeq.EndType = END_Underwater; useseq = true; } - else if (sc.Compare ("endbuystrife")) + else if (stricmp (mapname, "endbuystrife") == 0) { newSeq.EndType = END_BuyStrife; useseq = true; } else { - strncpy ((char *)(info + handler->data1), sc.String, 8); + strncpy ((char *)(info + handler->data1), mapname, 8); } if (useseq) { @@ -1532,26 +1543,22 @@ void P_RemoveDefereds (void) } } -bool CheckWarpTransMap (char mapname[9], bool substitute) +bool CheckWarpTransMap (FString &mapname, bool substitute) { - if (mapname[0] == '&' && (mapname[1]&223) == 'W' && - (mapname[2]&223) == 'T' && mapname[3] == '@') + if (mapname[0] == '&' && (mapname[1] & 0xDF) == 'W' && + (mapname[2] & 0xDF) == 'T' && mapname[3] == '@') { - level_info_t *lev = FindLevelByWarpTrans (atoi (mapname + 4)); + level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4])); if (lev != NULL) { - strncpy (mapname, lev->mapname, 8); - mapname[8] = 0; + mapname = lev->mapname; return true; } else if (substitute) { - mapname[0] = 'M'; - mapname[1] = 'A'; - mapname[2] = 'P'; - mapname[3] = mapname[4]; - mapname[4] = mapname[5]; - mapname[5] = 0; + char a = mapname[4], b = mapname[5]; + mapname = "MAP"; + mapname << a << b; } } return false; @@ -1562,12 +1569,12 @@ bool CheckWarpTransMap (char mapname[9], bool substitute) // Can be called by the startup code or the menu task, // consoleplayer, playeringame[] should be set. // -static char d_mapname[256]; +static FString d_mapname; static int d_skill=-1; void G_DeferedInitNew (const char *mapname, int newskill) { - strncpy (d_mapname, mapname, 8); + d_mapname = mapname; d_skill = newskill; CheckWarpTransMap (d_mapname, true); gameaction = ga_newgame2; @@ -1607,10 +1614,11 @@ CCMD (open) } if (argv.argc() > 1) { - sprintf(d_mapname, "file:%s", argv[1]); + d_mapname = "file:"; + d_mapname += argv[1]; if (!P_CheckMapData(d_mapname)) { - Printf ("No map %s\n", d_mapname); + Printf ("No map %s\n", d_mapname.GetChars()); } else { @@ -1661,7 +1669,10 @@ void G_DoNewGame (void) { G_NewInit (); playeringame[consoleplayer] = 1; - if (d_skill != -1) gameskill = d_skill; + if (d_skill != -1) + { + gameskill = d_skill; + } G_InitNew (d_mapname, false); gameaction = ga_nothing; } @@ -1980,34 +1991,30 @@ void G_DoCompleted (void) AM_Stop (); wminfo.finished_ep = level.cluster - 1; - strncpy (wminfo.lname0, level.info->pname, 8); - strncpy (wminfo.current, level.mapname, 8); + wminfo.lname0 = level.info->pname; + wminfo.current = level.mapname; if (deathmatch && (dmflags & DF_SAME_LEVEL) && !(level.flags & LEVEL_CHANGEMAPCHEAT)) { - strncpy (wminfo.next, level.mapname, 8); - strncpy (wminfo.lname1, level.info->pname, 8); + wminfo.next = level.mapname; + wminfo.lname1 = level.info->pname; } else { if (strncmp (nextlevel, "enDSeQ", 6) == 0) { - strncpy (wminfo.next, nextlevel, 8); - wminfo.lname1[0] = 0; + wminfo.next = FString(nextlevel, 8); + wminfo.lname1 = ""; } else { level_info_t *nextinfo = FindLevelInfo (nextlevel); - strncpy (wminfo.next, nextinfo->mapname, 8); - strncpy (wminfo.lname1, nextinfo->pname, 8); + wminfo.next = nextinfo->mapname; + wminfo.lname1 = nextinfo->pname; } } - wminfo.next[8]=0; - wminfo.lname0[8]=0; - wminfo.lname1[8]=0; - wminfo.current[8]=0; CheckWarpTransMap (wminfo.next, true); @@ -2606,21 +2613,18 @@ bool FLevelLocals::IsFreelookAllowed() const return !(dmflags & DF_NO_FREELOOK); } -char *CalcMapName (int episode, int level) +FString CalcMapName (int episode, int level) { - static char lumpname[9]; + FString lumpname; if (gameinfo.flags & GI_MAPxx) { - sprintf (lumpname, "MAP%02d", level); + lumpname.Format("MAP%02d", level); } else { - lumpname[0] = 'E'; - lumpname[1] = '0' + episode; - lumpname[2] = 'M'; - lumpname[3] = '0' + level; - lumpname[4] = 0; + lumpname = ""; + lumpname << 'E' << ('0' + episode) << 'M' << ('0' + level); } return lumpname; } @@ -2719,11 +2723,11 @@ const char *G_MaybeLookupLevelName (level_info_t *ininfo) // Strip out the header from the localized string if (info->mapname[0] == 'E' && info->mapname[2] == 'M') { - sprintf (checkstring, "%s: ", info->mapname); + mysnprintf (checkstring, countof(checkstring), "%s: ", info->mapname); } else if (info->mapname[0] == 'M' && info->mapname[1] == 'A' && info->mapname[2] == 'P') { - sprintf (checkstring, "%d: ", atoi(info->mapname + 3)); + mysnprintf (checkstring, countof(checkstring), "%d: ", atoi(info->mapname + 3)); } thename = strstr (lookedup, checkstring); if (thename == NULL) diff --git a/src/g_level.h b/src/g_level.h index 1367a660f..6da01a8f7 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -356,7 +356,7 @@ extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; extern bool savegamerestore; // mapname will be changed if it is a valid warptrans -bool CheckWarpTransMap (char mapname[9], bool substitute); +bool CheckWarpTransMap (FString &mapname, bool substitute); void G_InitNew (const char *mapname, bool bTitleLevel); @@ -391,7 +391,7 @@ level_info_t *FindLevelInfo (const char *mapname); level_info_t *FindLevelByNum (int num); level_info_t *CheckLevelRedirect (level_info_t *info); -char *CalcMapName (int episode, int level); +FString CalcMapName (int episode, int level); void G_ParseMapInfo (void); void G_UnloadMapInfo (); diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp index a04fe2731..2d52c45b8 100644 --- a/src/g_shared/a_debris.cpp +++ b/src/g_shared/a_debris.cpp @@ -41,7 +41,7 @@ void P_SpawnDirt (AActor *actor, fixed_t radius) z = actor->z + (pr_dirt()<<9) + FRACUNIT; char fmt[8]; - sprintf(fmt, "Dirt%d", 1 + pr_dirt()%6); + mysnprintf(fmt, countof(fmt), "Dirt%d", 1 + pr_dirt()%6); dtype = PClass::FindClass(fmt); if (dtype) { diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 1303f3ec9..1571ec694 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -922,7 +922,8 @@ CCMD (weaponsection) tackOn = fullSection + 4; } - sprintf (tackOn, ".%s.WeaponSlots", WeaponSection.GetChars()); + mysnprintf (tackOn, countof(fullSection) - (tackOn - fullSection), + ".%s.WeaponSlots", WeaponSection.GetChars()); if (GameConfig->SetSection (fullSection)) { LocalWeapons.RestoreSlots (*GameConfig); @@ -1032,7 +1033,7 @@ void FWeaponSlots::SaveSlots (FConfigFile &config) } if (index > 0) { - sprintf (keyname, "Slot[%d]", i); + mysnprintf (keyname, countof(keyname), "Slot[%d]", i); config.SetValueForKey (keyname, buff); } } diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index ab882dc74..680d34e06 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -179,7 +179,7 @@ static void DrawHudNumber(int color, int num, int x, int y, int trans=0xc000) { char text[15]; - sprintf(text, "%d", num); + mysnprintf(text, countof(text), "%d", num); DrawHudText(color, text, x, y, trans); } @@ -206,7 +206,7 @@ static void DrawStatus(player_t * CPlayer, int x, int y) DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); - sprintf(tempstr, "%i ", CPlayer->accuracy); + mysnprintf(tempstr, countof(tempstr), "%i ", CPlayer->accuracy); screen->DrawText(hudcolor_stats, x+space, y, tempstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); @@ -216,7 +216,7 @@ static void DrawStatus(player_t * CPlayer, int x, int y) DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); - sprintf(tempstr, "%i ", CPlayer->stamina); + mysnprintf(tempstr, countof(tempstr), "%i ", CPlayer->stamina); screen->DrawText(hudcolor_stats, x+space, y, tempstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); @@ -235,7 +235,7 @@ static void DrawStatus(player_t * CPlayer, int x, int y) DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); - sprintf(tempstr, "%i/%i ", multiplayer? CPlayer->secretcount : level.found_secrets, level.total_secrets); + mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->secretcount : level.found_secrets, level.total_secrets); screen->DrawText(hudcolor_stats, x+space, y, tempstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); @@ -248,7 +248,7 @@ static void DrawStatus(player_t * CPlayer, int x, int y) DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); - sprintf(tempstr, "%i/%i ", multiplayer? CPlayer->itemcount : level.found_items, level.total_items); + mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->itemcount : level.found_items, level.total_items); screen->DrawText(hudcolor_stats, x+space, y, tempstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); @@ -261,7 +261,7 @@ static void DrawStatus(player_t * CPlayer, int x, int y) DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); - sprintf(tempstr, "%i/%i ", multiplayer? CPlayer->killcount : level.killed_monsters, level.total_monsters); + mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->killcount : level.killed_monsters, level.total_monsters); screen->DrawText(hudcolor_stats, x+space, y, tempstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); @@ -548,7 +548,7 @@ static int DrawAmmo(player_t * CPlayer, int x, int y) int maxammo = inv->MaxAmount; int ammo = ammoitem? ammoitem->Amount : 0; - sprintf(buf,"%3d/%3d", ammo,maxammo); + mysnprintf(buf, countof(buf), "%3d/%3d", ammo, maxammo); int tex_width= clamp(ConFont->StringWidth(buf)-def_width, 0, 1000); @@ -692,7 +692,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y) { char buffer[10]; int xx; - sprintf(buffer,"%d",rover->Amount); + mysnprintf(buffer, countof(buffer), "%d", rover->Amount); if (rover->Amount>=1000) xx = 32 - IndexFont->StringWidth(buffer); else xx = 22; @@ -764,17 +764,17 @@ static void DrawCoordinates(player_t * CPlayer) int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6; int ypos = 18; - sprintf(coordstr, "X: %d", x>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "X: %d", x>>FRACBITS); screen->DrawText(hudcolor_xyco, xpos, ypos, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); - sprintf(coordstr, "Y: %d", y>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "Y: %d", y>>FRACBITS); screen->DrawText(hudcolor_xyco, xpos, ypos+h, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); - sprintf(coordstr, "Z: %d", z>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "Z: %d", z>>FRACBITS); screen->DrawText(hudcolor_xyco, xpos, ypos+2*h, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); @@ -864,15 +864,15 @@ void DrawHUD() if (am_showtotaltime) { seconds = level.totaltime / TICRATE; - sprintf(printstr, "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); + mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); DrawHudText(hudcolor_ttim, printstr, hudwidth-length, bottom, FRACUNIT); bottom -= fonth; } if (am_showtime) { - seconds= level.time /TICRATE; - sprintf(printstr, "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); + seconds = level.time /TICRATE; + mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); DrawHudText(hudcolor_time, printstr, hudwidth-length, bottom, FRACUNIT); bottom -= fonth; @@ -880,12 +880,12 @@ void DrawHUD() if (level.clusterflags&CLUSTER_HUB) { seconds= level.maptime /TICRATE; - sprintf(printstr, "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); + mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); DrawHudText(hudcolor_ltim, printstr, hudwidth-length, bottom, FRACUNIT); } } - sprintf(printstr,"%s: %s",level.mapname,level.level_name); + mysnprintf(printstr, countof(printstr), "%s: %s", level.mapname, level.level_name); screen->DrawText(hudcolor_titl, 1, hudheight-fonth-1, printstr, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 440b8d044..f25e3d4fe 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -109,10 +109,10 @@ CUSTOM_CVAR (Int, crosshair, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) num = -num; } size = (SCREENWIDTH < 640) ? 'S' : 'B'; - sprintf (name, "XHAIR%c%d", size, num); + mysnprintf (name, countof(name), "XHAIR%c%d", size, num); if ((lump = Wads.CheckNumForName (name, ns_graphics)) == -1) { - sprintf (name, "XHAIR%c1", size); + mysnprintf (name, countof(name), "XHAIR%c1", size); if ((lump = Wads.CheckNumForName (name, ns_graphics)) == -1) { strcpy (name, "XHAIRS1"); @@ -1155,7 +1155,7 @@ void DBaseStatusBar::Draw (EHudState state) value = &CPlayer->mo->z; for (i = 2, value = &CPlayer->mo->z; i >= 0; y -= height, --value, --i) { - sprintf (line, "%c: %d", labels[i], *value >> FRACBITS); + mysnprintf (line, countof(line), "%c: %d", labels[i], *value >> FRACBITS); screen->DrawText (CR_GREEN, xpos, y, line, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, @@ -1184,13 +1184,13 @@ void DBaseStatusBar::Draw (EHudState state) y = 8; if (am_showtime) { - sprintf (line, "%02d:%02d:%02d", time/3600, (time%3600)/60, time%60); // Time + mysnprintf (line, countof(line), "%02d:%02d:%02d", time/3600, (time%3600)/60, time%60); // Time screen->DrawText (CR_GREY, SCREENWIDTH - 80*CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); y+=8*CleanYfac; } if (am_showtotaltime) { - sprintf (line, "%02d:%02d:%02d", totaltime/3600, (totaltime%3600)/60, totaltime%60); // Total time + mysnprintf (line, countof(line), "%02d:%02d:%02d", totaltime/3600, (totaltime%3600)/60, totaltime%60); // Total time screen->DrawText (CR_GREY, SCREENWIDTH - 80*CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); } @@ -1233,7 +1233,7 @@ void DBaseStatusBar::Draw (EHudState state) i = 0; if (cluster == NULL || !(cluster->flags & CLUSTER_HUB)) { - i = sprintf (line, "%s: ", level.mapname); + i = mysnprintf (line, countof(line), "%s: ", level.mapname); } line[i] = TEXTCOLOR_ESCAPE; line[i+1] = CR_GREY + 'A'; @@ -1249,9 +1249,8 @@ void DBaseStatusBar::Draw (EHudState state) // Draw monster count if (am_showmonsters) { - sprintf (line, "MONSTERS:" - TEXTCOLOR_GREY " %d/%d", - level.killed_monsters, level.total_monsters); + mysnprintf (line, countof(line), "MONSTERS:" TEXTCOLOR_GREY " %d/%d", + level.killed_monsters, level.total_monsters); screen->DrawText (highlight, 8, y, line, DTA_CleanNoMove, true, TAG_DONE); y += height; @@ -1260,9 +1259,8 @@ void DBaseStatusBar::Draw (EHudState state) // Draw secret count if (am_showsecrets) { - sprintf (line, "SECRETS:" - TEXTCOLOR_GREY " %d/%d", - level.found_secrets, level.total_secrets); + mysnprintf (line, countof(line), "SECRETS:" TEXTCOLOR_GREY " %d/%d", + level.found_secrets, level.total_secrets); screen->DrawText (highlight, 8, y, line, DTA_CleanNoMove, true, TAG_DONE); y += height; @@ -1271,9 +1269,8 @@ void DBaseStatusBar::Draw (EHudState state) // Draw item count if (am_showitems) { - sprintf (line, "ITEMS:" - TEXTCOLOR_GREY " %d/%d", - level.found_items, level.total_items); + mysnprintf (line, countof(line), "ITEMS:" TEXTCOLOR_GREY " %d/%d", + level.found_items, level.total_items); screen->DrawText (highlight, 8, y, line, DTA_CleanNoMove, true, TAG_DONE); } @@ -1661,16 +1658,16 @@ void DBaseStatusBar::AddFaceToImageCollectionActual (void *skn, FImageCollection { for (j = 0; j < ST_NUMSTRAIGHTFACES; j++) { - sprintf (names[facenum++], "%sST%d%d", prefix, i, j); + mysnprintf (names[facenum++], countof(names[0]), "%sST%d%d", prefix, i, j); } - sprintf (names[facenum++], "%sTR%d0", prefix, i); // turn right - sprintf (names[facenum++], "%sTL%d0", prefix, i); // turn left - sprintf (names[facenum++], "%sOUCH%d", prefix, i); // ouch! - sprintf (names[facenum++], "%sEVL%d", prefix, i); // evil grin ;) - sprintf (names[facenum++], "%sKILL%d", prefix, i); // pissed off + mysnprintf (names[facenum++], countof(names[0]), "%sTR%d0", prefix, i); // turn right + mysnprintf (names[facenum++], countof(names[0]), "%sTL%d0", prefix, i); // turn left + mysnprintf (names[facenum++], countof(names[0]), "%sOUCH%d", prefix, i); // ouch! + mysnprintf (names[facenum++], countof(names[0]), "%sEVL%d", prefix, i); // evil grin ;) + mysnprintf (names[facenum++], countof(names[0]), "%sKILL%d", prefix, i); // pissed off } - sprintf (names[facenum++], "%sGOD0", prefix); - sprintf (names[facenum++], "%sDEAD0", prefix); + mysnprintf (names[facenum++], countof(names[0]), "%sGOD0", prefix); + mysnprintf (names[facenum++], countof(names[0]), "%sDEAD0", prefix); images->Add (nameptrs, ST_NUMFACES, namespc); } diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp index ef061909b..8a0c62874 100644 --- a/src/g_strife/a_alienspectres.cpp +++ b/src/g_strife/a_alienspectres.cpp @@ -577,7 +577,7 @@ void A_AlienSpectreDeath (AActor *self) { return; } - sprintf (voc, "svox/voc%d", log); + mysnprintf (voc, countof(voc), "svox/voc%d", log); S_Sound (CHAN_VOICE, voc, 1, ATTN_NORM); player->player->SetLogNumber (log); } diff --git a/src/g_strife/a_coin.cpp b/src/g_strife/a_coin.cpp index a1fa04998..a9f7d83a9 100644 --- a/src/g_strife/a_coin.cpp +++ b/src/g_strife/a_coin.cpp @@ -33,7 +33,7 @@ const char *ACoin::PickupMessage () { static char msg[64]; - sprintf (msg, GStrings("TXT_XGOLD"), Amount); + mysnprintf (msg, countof(msg), GStrings("TXT_XGOLD"), Amount); return msg; } } diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 588b99c1b..5776e186e 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -84,7 +84,7 @@ void A_GiveQuestItem (AActor *self) char messageid[64]; - sprintf(messageid, "TXT_QUEST_%d", questitem); + mysnprintf(messageid, countof(messageid), "TXT_QUEST_%d", questitem); const char * name = GStrings[messageid]; if (name != NULL) diff --git a/src/g_strife/strife_sbar.cpp b/src/g_strife/strife_sbar.cpp index b0a955531..e73ce1c1c 100644 --- a/src/g_strife/strife_sbar.cpp +++ b/src/g_strife/strife_sbar.cpp @@ -584,7 +584,7 @@ private: { case POP_Log: // Draw the latest log message. - sprintf (buff, "%02d:%02d:%02d", + mysnprintf (buff, countof(buff), "%02d:%02d:%02d", (level.time/TICRATE)/3600, ((level.time/TICRATE)%3600)/60, (level.time/TICRATE)%60); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 0a8914d40..1eb832b8c 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -142,100 +142,6 @@ void FGameConfigFile::MigrateOldConfig () // Set default key bindings. These will be overridden // by the bindings in the config file if it exists. C_SetDefaultBindings (); - -#if 0 // Disabled for now, maybe forever. - int i; - char *execcommand; - - i = strlen (GetPathName ()) + 8; - execcommand = new char[i]; - sprintf (execcommand, "exec \"%s\"", GetPathName ()); - execcommand[i-5] = 'c'; - execcommand[i-4] = 'f'; - execcommand[i-3] = 'g'; - cvar_defflags = CVAR_ARCHIVE; - C_DoCommand (execcommand); - cvar_defflags = 0; - delete[] execcommand; - - FBaseCVar *configver = FindCVar ("configver", NULL); - if (configver != NULL) - { - UCVarValue oldver = configver->GetGenericRep (CVAR_Float); - - if (oldver.Float < 118.f) - { - C_DoCommand ("alias idclip noclip"); - C_DoCommand ("alias idspispopd noclip"); - - if (oldver.Float < 117.2f) - { - dimamount = *dimamount * 0.25f; - if (oldver.Float <= 113.f) - { - C_DoCommand ("bind t messagemode; bind \\ +showscores;" - "bind f12 spynext; bind sysrq screenshot"); - if (C_GetBinding (KEY_F5) && !stricmp (C_GetBinding (KEY_F5), "menu_video")) - { - C_ChangeBinding ("menu_display", KEY_F5); - } - } - } - } - delete configver; - } - // Change all impulses to slot commands - for (i = 0; i < NUM_KEYS; i++) - { - char slotcmd[8] = "slot "; - char *bind, *numpart; - - bind = C_GetBinding (i); - if (bind != NULL && strnicmp (bind, "impulse ", 8) == 0) - { - numpart = strchr (bind, ' '); - if (numpart != NULL && strlen (numpart) < 4) - { - strcpy (slotcmd + 5, numpart); - C_ChangeBinding (slotcmd, i); - } - } - } - - // Migrate and delete some obsolete cvars - FBaseCVar *oldvar; - UCVarValue oldval; - - oldvar = FindCVar ("autoexec", NULL); - if (oldvar != NULL) - { - oldval = oldvar->GetGenericRep (CVAR_String); - if (oldval.String[0]) - { - SetSection ("Doom.AutoExec", true); - SetValueForKey ("Path", oldval.String, true); - } - delete oldvar; - } - - oldvar = FindCVar ("def_patch", NULL); - if (oldvar != NULL) - { - oldval = oldvar->GetGenericRep (CVAR_String); - if (oldval.String[0]) - { - SetSection ("Doom.DefaultDehacked", true); - SetValueForKey ("Path", oldval.String, true); - } - delete oldvar; - } - - oldvar = FindCVar ("vid_noptc", NULL); - if (oldvar != NULL) - { - delete oldvar; - } -#endif } void FGameConfigFile::DoGlobalSetup () @@ -334,15 +240,17 @@ void FGameConfigFile::DoGameSetup (const char *gamename) { MigrateOldConfig (); } - subsection = section + sprintf (section, "%s.", gamename); + sublen = countof(section) - 1 - mysnprintf (section, countof(section), "%s.", gamename); + subsection = section + countof(section) - sublen - 1; + section[countof(section) - 1] = '\0'; - strcpy (subsection, "UnknownConsoleVariables"); + strncpy (subsection, "UnknownConsoleVariables", sublen); if (SetSection (section)) { ReadCVars (0); } - strcpy (subsection, "ConsoleVariables"); + strncpy (subsection, "ConsoleVariables", sublen); if (SetSection (section)) { ReadCVars (0); @@ -355,19 +263,19 @@ void FGameConfigFile::DoGameSetup (const char *gamename) // The NetServerInfo section will be read when it's determined that // a netgame is being played. - strcpy (subsection, "LocalServerInfo"); + strncpy (subsection, "LocalServerInfo", sublen); if (SetSection (section)) { ReadCVars (0); } - strcpy (subsection, "Player"); + strncpy (subsection, "Player", sublen); if (SetSection (section)) { ReadCVars (0); } - strcpy (subsection, "Bindings"); + strncpy (subsection, "Bindings", sublen); if (!SetSection (section)) { // Config has no bindings for the given game if (!bMigrating) @@ -384,7 +292,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) } } - strcpy (subsection, "DoubleBindings"); + strncpy (subsection, "DoubleBindings", sublen); if (SetSection (section)) { while (NextInSection (key, value)) @@ -393,7 +301,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) } } - strcpy (subsection, "ConsoleAliases"); + strncpy (subsection, "ConsoleAliases", sublen); if (SetSection (section)) { const char *name = NULL; @@ -415,7 +323,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) // Separated from DoGameSetup because it needs all the weapons properly defined void FGameConfigFile::DoWeaponSetup (const char *gamename) { - strcpy (subsection, "WeaponSlots"); + strncpy (subsection, "WeaponSlots", sublen); if (!SetSection (section) || !LocalWeapons.RestoreSlots (*this)) { @@ -425,7 +333,7 @@ void FGameConfigFile::DoWeaponSetup (const char *gamename) void FGameConfigFile::ReadNetVars () { - strcpy (subsection, "NetServerInfo"); + strncpy (subsection, "NetServerInfo", sublen); if (SetSection (section)) { ReadCVars (0); @@ -455,19 +363,20 @@ void FGameConfigFile::ArchiveGameData (const char *gamename) { char section[32*3], *subsection; - subsection = section + sprintf (section, "%s.", gamename); + sublen = countof(section) - 1 - mysnprintf (section, countof(section), "%s.", gamename); + subsection = section + countof(section) - 1 - sublen; - strcpy (subsection, "Player"); + strncpy (subsection, "Player", sublen); SetSection (section, true); ClearCurrentSection (); C_ArchiveCVars (this, 4); - strcpy (subsection, "ConsoleVariables"); + strncpy (subsection, "ConsoleVariables", sublen); SetSection (section, true); ClearCurrentSection (); C_ArchiveCVars (this, 0); - strcpy (subsection, netgame ? "NetServerInfo" : "LocalServerInfo"); + strncpy (subsection, netgame ? "NetServerInfo" : "LocalServerInfo", sublen); if (!netgame || consoleplayer == 0) { // Do not overwrite this section if playing a netgame, and // this machine was not the initial host. @@ -476,35 +385,35 @@ void FGameConfigFile::ArchiveGameData (const char *gamename) C_ArchiveCVars (this, 5); } - strcpy (subsection, "UnknownConsoleVariables"); + strncpy (subsection, "UnknownConsoleVariables", sublen); SetSection (section, true); ClearCurrentSection (); C_ArchiveCVars (this, 2); - strcpy (subsection, "ConsoleAliases"); + strncpy (subsection, "ConsoleAliases", sublen); SetSection (section, true); ClearCurrentSection (); C_ArchiveAliases (this); - M_SaveCustomKeys (this, section, subsection); + M_SaveCustomKeys (this, section, subsection, sublen); strcpy (subsection, "Bindings"); SetSection (section, true); ClearCurrentSection (); C_ArchiveBindings (this, false); - strcpy (subsection, "DoubleBindings"); + strncpy (subsection, "DoubleBindings", sublen); SetSection (section, true); ClearCurrentSection (); C_ArchiveBindings (this, true); if (WeaponSection.IsEmpty()) { - strcpy (subsection, "WeaponSlots"); + strncpy (subsection, "WeaponSlots", sublen); } else { - sprintf (subsection, "%s.WeaponSlots", WeaponSection.GetChars()); + mysnprintf (subsection, sublen, "%s.WeaponSlots", WeaponSection.GetChars()); } SetSection (section, true); ClearCurrentSection (); @@ -535,7 +444,7 @@ FString FGameConfigFile::GetConfigPath (bool tryProg) if (pathval != NULL) return FString(pathval); -#ifndef unix +#ifdef _WIN32 path = NULL; HRESULT hr; @@ -602,7 +511,7 @@ void FGameConfigFile::AddAutoexec (DArgs *list, const char *game) const char *key; const char *value; - sprintf (section, "%s.AutoExec", game); + mysnprintf (section, countof(section), "%s.AutoExec", game); if (bMigrating) { diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index a3f7d578c..8970c87ab 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -69,6 +69,7 @@ private: char section[64]; char *subsection; + size_t sublen; }; extern FString WeaponSection; diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 1b68ef9dd..ee22e9ba5 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -213,7 +213,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER if (teams[i].players) { char score[80]; - sprintf (score, "%d", teams[i].score); + mysnprintf (score, countof(score), "%d", teams[i].score); screen->SetFont (BigFont); screen->DrawText (teams[i].GetTextColor (), scorexwidth, gamestate == GS_INTERMISSION ? y * 4 / 5 : y / 2, score, @@ -277,9 +277,9 @@ static void HU_DrawTimeRemaining (int y) seconds = timeleft / TICRATE; if (hours) - sprintf (str, "Level ends in %02d:%02d:%02d", hours, minutes, seconds); + mysnprintf (str, countof(str), "Level ends in %02d:%02d:%02d", hours, minutes, seconds); else - sprintf (str, "Level ends in %02d:%02d", minutes, seconds); + mysnprintf (str, countof(str), "Level ends in %02d:%02d", minutes, seconds); screen->DrawText (CR_GREY, SCREENWIDTH/2 - SmallFont->StringWidth (str)/2*CleanXfac, y, str, DTA_CleanNoMove, true, TAG_DONE); @@ -321,7 +321,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int x, int y, int h deathmatch ? color = sb_deathmatch_yourplayercolor : color = sb_cooperative_yourplayercolor; } - sprintf (str, "%d", deathmatch ? player->fragcount : player->killcount); + mysnprintf (str, countof(str), "%d", deathmatch ? player->fragcount : player->killcount); screen->DrawText (color, SCREENWIDTH / 4, y, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str, DTA_CleanNoMove, true, TAG_DONE); diff --git a/src/i_net.cpp b/src/i_net.cpp index 6e080df8b..905f3cdae 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -900,7 +900,7 @@ const char *neterror (void) case WSAEDISCON: return "EDISCON"; default: - sprintf (neterr, "%d", code); + mysnprintf (neterr, countof(neterr), "%d", code); return neterr; } } diff --git a/src/m_alloc.cpp b/src/m_alloc.cpp index 23d0edc65..1c14f3de0 100644 --- a/src/m_alloc.cpp +++ b/src/m_alloc.cpp @@ -32,8 +32,8 @@ ** */ -#include "i_system.h" #include +#include "i_system.h" #ifndef _MSC_VER #define _NORMAL_BLOCK 0 diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index fb61103fb..0b3a4ae3c 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -241,7 +241,7 @@ void cht_DoCheat (player_t *player, int cheat) int killcount = P_Massacre (); // killough 3/22/98: make more intelligent about plural // Ty 03/27/98 - string(s) *not* externalized - sprintf (msgbuild, "%d Monster%s Killed", killcount, killcount==1 ? "" : "s"); + mysnprintf (msgbuild, countof(msgbuild), "%d Monster%s Killed", killcount, killcount==1 ? "" : "s"); msg = msgbuild; } break; diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 736fe671e..1e8022948 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -1401,7 +1401,7 @@ void M_QuickSave () M_SaveGame (0); return; } - sprintf (tempstring, GStrings("QSPROMPT"), quickSaveSlot->Title); + mysnprintf (tempstring, countof(tempstring), GStrings("QSPROMPT"), quickSaveSlot->Title); strcpy (savegamestring, quickSaveSlot->Title); M_StartMessage (tempstring, M_QuickSaveResponse, true); } @@ -1437,7 +1437,7 @@ void M_QuickLoad () M_LoadGame (0); return; } - sprintf (tempstring, GStrings("QLPROMPT"), quickSaveSlot->Title); + mysnprintf (tempstring, countof(tempstring), GStrings("QLPROMPT"), quickSaveSlot->Title); M_StartMessage (tempstring, M_QuickLoadResponse, true); } @@ -1519,20 +1519,20 @@ void M_DrawHereticMainMenu () { int frame = (MenuTime / 5) % 7; - sprintf (name, "FBUL%c0", (frame+2)%7 + 'A'); + mysnprintf (name, countof(name), "FBUL%c0", (frame+2)%7 + 'A'); screen->DrawTexture (TexMan[name], 37, 80, DTA_Clean, true, TAG_DONE); - sprintf (name, "FBUL%c0", frame + 'A'); + mysnprintf (name, countof(name), "FBUL%c0", frame + 'A'); screen->DrawTexture (TexMan[name], 278, 80, DTA_Clean, true, TAG_DONE); } else { int frame = (MenuTime / 3) % 18; - sprintf (name, "M_SKL%.2d", 17 - frame); + mysnprintf (name, countof(name), "M_SKL%.2d", 17 - frame); screen->DrawTexture (TexMan[name], 40, 10, DTA_Clean, true, TAG_DONE); - sprintf (name, "M_SKL%.2d", frame); + mysnprintf (name, countof(name), "M_SKL%.2d", frame); screen->DrawTexture (TexMan[name], 232, 10, DTA_Clean, true, TAG_DONE); } } @@ -1666,7 +1666,7 @@ static void DrawClassMenu(void) } screen->DrawTexture (TexMan[boxLumpName[classnum]], 174, 8, DTA_Clean, true, TAG_DONE); - sprintf (name, walkLumpName[classnum], ((MenuTime >> 3) & 3) + 1); + mysnprintf (name, countof(name), walkLumpName[classnum], ((MenuTime >> 3) & 3) + 1); screen->DrawTexture (TexMan[name], 174+24, 8+12, DTA_Clean, true, TAG_DONE); } @@ -2609,9 +2609,8 @@ static void SendNewColor (int red, int green, int blue) { char command[24]; - sprintf (command, "color \"%02x %02x %02x\"", red, green, blue); + mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue); C_DoCommand (command); - R_GetPlayerTranslation (MAKERGB (red, green, blue), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } @@ -2967,7 +2966,7 @@ bool M_SaveLoadResponder (event_t *ev) case GK_F1: if (!SelSaveGame->Filename.IsEmpty()) { - sprintf (workbuf, "File on disk:\n%s", SelSaveGame->Filename.GetChars()); + mysnprintf (workbuf, countof(workbuf), "File on disk:\n%s", SelSaveGame->Filename.GetChars()); if (SaveComment != NULL) { V_FreeBrokenLines (SaveComment); diff --git a/src/m_misc.h b/src/m_misc.h index 9802ead71..2ced7e74d 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -41,7 +41,7 @@ void M_ScreenShot (const char *filename); void M_LoadDefaults (); bool M_SaveDefaults (const char *filename); -void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection); +void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen); FString GetUserFile (const char *path, bool nodir=false); diff --git a/src/m_options.cpp b/src/m_options.cpp index 42d859eff..f37fb8e9e 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1417,7 +1417,7 @@ void M_InitVideoModesMenu () { /* Depths[currval].value = currval; - sprintf (name, "%d bit", i); + mysnprintf (name, countof(name), "%d bit", i); Depths[currval].name = copystring (name); */ BitTranslate[currval++] = i; @@ -1761,7 +1761,7 @@ void M_OptDrawer () { char tbuf[16]; - sprintf (tbuf, "%d.", item->b.position); + mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position); x = CurrentMenu->indent - SmallFont->StringWidth (tbuf); screen->DrawText (CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE); } @@ -2054,10 +2054,10 @@ void M_OptDrawer () { if (printed) { - fillptr += sprintf (fillptr, " "); + fillptr += mysnprintf (fillptr, countof(flagsblah) - (fillptr - flagsblah), " "); } printed = true; - fillptr += sprintf (fillptr, "%s = %d", vars[i]->GetName (), **vars[i]); + fillptr += mysnprintf (fillptr, countof(flagsblah) - (fillptr - flagsblah), "%s = %d", vars[i]->GetName (), **vars[i]); } } screen->DrawText (ValueColor, @@ -3182,7 +3182,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) if (/* hi_bits == showbits && */ width == hiwidth && height == hiheight) ModesItems[i].e.highlight = ModesItems[i].a.selmode = c; - sprintf (strtemp, "%dx%d%s", width, height, letterbox?TEXTCOLOR_BROWN" LB":""); + mysnprintf (strtemp, countof(strtemp), "%dx%d%s", width, height, letterbox?TEXTCOLOR_BROWN" LB":""); ReplaceString (str, strtemp); } else @@ -3279,7 +3279,7 @@ static void SetModesMenu (int w, int h, int bits) { char strtemp[64]; - sprintf (strtemp, "TESTING %dx%dx%d", w, h, bits); + mysnprintf (strtemp, countof(strtemp), "TESTING %dx%dx%d", w, h, bits); ModesItems[VM_ENTERLINE].label = copystring (strtemp); ModesItems[VM_TESTLINE].label = "Please wait 5 seconds..."; } @@ -3334,7 +3334,7 @@ void M_LoadKeys (const char *modname, bool dbl) if (GameNames[gameinfo.gametype] == NULL) return; - sprintf (section, "%s.%s%sBindings", GameNames[gameinfo.gametype], modname, + mysnprintf (section, countof(section), "%s.%s%sBindings", GameNames[gameinfo.gametype], modname, dbl ? ".Double" : "."); if (GameConfig->SetSection (section)) { @@ -3365,7 +3365,7 @@ int M_DoSaveKeys (FConfigFile *config, char *section, int i, bool dbl) return i; } -void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection) +void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen) { if (ControlsMenu.items == ControlsItems) return; @@ -3381,9 +3381,9 @@ void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection) if (item->type == whitetext) { assert (item->e.command != NULL); - sprintf (subsection, "%s.Bindings", item->e.command); + mysnprintf (subsection, sublen, "%s.Bindings", item->e.command); M_DoSaveKeys (config, section, (int)i, false); - sprintf (subsection, "%s.DoubleBindings", item->e.command); + mysnprintf (subsection, sublen, "%s.DoubleBindings", item->e.command); i = M_DoSaveKeys (config, section, (int)i, true); } else diff --git a/src/oplsynth/music_opl_mididevice.cpp b/src/oplsynth/music_opl_mididevice.cpp index d08c97a1d..d1f71cbe5 100644 --- a/src/oplsynth/music_opl_mididevice.cpp +++ b/src/oplsynth/music_opl_mididevice.cpp @@ -45,9 +45,9 @@ // MACROS ------------------------------------------------------------------ -#if defined(_DEBUG) && defined(_WIN32) +#if defined(_DEBUG) && defined(_WIN32) && defined(_MSC_VER) #define DEBUGOUT(m,c,s,t) \ - { char foo[128]; sprintf(foo, m, c, s, t); OutputDebugString(foo); } + { char foo[128]; mysnprintf(foo, countof(foo), m, c, s, t); OutputDebugString(foo); } #else #define DEBUGOUT(m,c,s,t) #endif diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 706da768a..db3e9889b 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -373,7 +373,7 @@ static void LoadSectors (sectortype *bsec) sec->floorplane.d = -sec->floortexz; sec->floorplane.c = FRACUNIT; sec->floorplane.ic = FRACUNIT; - sprintf (tnam, "BTIL%04d", LittleShort(bsec->floorpicnum)); + mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->floorpicnum)); sec->floorpic = TexMan.GetTexture (tnam, FTexture::TEX_Build); sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT); sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT); @@ -386,7 +386,7 @@ static void LoadSectors (sectortype *bsec) sec->ceilingplane.d = sec->ceilingtexz; sec->ceilingplane.c = -FRACUNIT; sec->ceilingplane.ic = -FRACUNIT; - sprintf (tnam, "BTIL%04d", LittleShort(bsec->ceilingpicnum)); + mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->ceilingpicnum)); sec->ceilingpic = TexMan.GetTexture (tnam, FTexture::TEX_Build); if (bsec->ceilingstat & 1) { @@ -480,9 +480,9 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) char tnam[9]; FTextureID overpic, pic; - sprintf (tnam, "BTIL%04d", LittleShort(walls[i].picnum)); + mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].picnum)); pic = TexMan.GetTexture (tnam, FTexture::TEX_Build); - sprintf (tnam, "BTIL%04d", LittleShort(walls[i].overpicnum)); + mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].overpicnum)); overpic = TexMan.GetTexture (tnam, FTexture::TEX_Build); walls[i].x = LittleLong(walls[i].x); @@ -807,7 +807,7 @@ void ACustomSprite::BeginPlay () char name[9]; Super::BeginPlay (); - sprintf (name, "BTIL%04d", (args[0] + args[1]*256) & 0xffff); + mysnprintf (name, countof(name), "BTIL%04d", (args[0] + args[1]*256) & 0xffff); picnum = TexMan.GetTexture (name, FTexture::TEX_Build); scaleX = args[2] * (FRACUNIT/64); diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index e1b6d6c9b..8d40186a6 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -328,7 +328,7 @@ static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeaker // The speaker's voice for this node, if any. speech.Backdrop[0] = 0; //speech.Sound[8] = 0; - sprintf (fullsound, "svox/%s", speech.Sound); + mysnprintf (fullsound, countof(fullsound), "svox/%s", speech.Sound); node->SpeakerVoice = fullsound; // The speaker's name, if any. @@ -397,7 +397,7 @@ static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeaker // The speaker's voice for this node, if any. if (speech.VoiceNumber != 0) { - sprintf (fullsound, "svox/voc%u", speech.VoiceNumber); + mysnprintf (fullsound, countof(fullsound), "svox/voc%u", speech.VoiceNumber); node->SpeakerVoice = fullsound; } else @@ -491,7 +491,7 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) { char moneystr[128]; - sprintf (moneystr, "%s for %u", rsp->Reply, rsp->Count[0]); + mysnprintf (moneystr, countof(moneystr), "%s for %u", rsp->Reply, rsp->Count[0]); reply->Reply = copystring (moneystr); reply->NeedsGold = true; } @@ -759,7 +759,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang ++i; } char goodbye[25]; - sprintf(goodbye, "TXT_RANDOMGOODBYE_%d", 1+(pr_randomspeech() % NUM_RANDOM_GOODBYES)); + mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1+(pr_randomspeech() % NUM_RANDOM_GOODBYES)); item.label = (char*)GStrings[goodbye]; if (item.label == NULL) item.label = "Bye."; item.b.position = i; @@ -907,7 +907,7 @@ static void DrawConversationMenu () AInventory *coin = cp->ConversationPC->FindInventory (RUNTIME_CLASS(ACoin)); char goldstr[32]; - sprintf (goldstr, "%d", coin != NULL ? coin->Amount : 0); + mysnprintf (goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0); screen->DrawText (CR_GRAY, 21, 191, goldstr, DTA_320x200, true, DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE); screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon), diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index f6142d74f..76e5bb2ae 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -265,7 +265,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker) attacker->player->frags[attacker->player - players]++; self = attacker; gender = self->player->userinfo.gender; - sprintf (gendermessage, "OB_FRIENDLY%c", '1' + (pr_obituary() & 3)); + mysnprintf (gendermessage, countof(gendermessage), "OB_FRIENDLY%c", '1' + (pr_obituary() & 3)); message = GStrings(gendermessage); } else diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index a1d1bfbe8..67e3d1c5d 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2718,7 +2718,7 @@ FUNC(LS_SendToCommunicator) if (it != NULL && it->player != NULL && it->FindInventory(NAME_Communicator)) { char name[32]; - sprintf (name, "svox/voc%d", arg0); + mysnprintf (name, countof(name), "svox/voc%d", arg0); if (!arg3) { diff --git a/src/p_user.cpp b/src/p_user.cpp index 52cbf2372..f936f289e 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -356,7 +356,7 @@ void player_t::SetLogNumber (int num) char lumpname[16]; int lumpnum; - sprintf (lumpname, "LOG%d", num); + mysnprintf (lumpname, countof(lumpname), "LOG%d", num); lumpnum = Wads.CheckNumForName (lumpname); if (lumpnum == -1) { diff --git a/src/r_main.cpp b/src/r_main.cpp index d376d7f5b..c56e19648 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -648,7 +648,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) UCVarValue value; char temp[16]; - sprintf (temp, "%d x %d", viewwidth, viewheight); + mysnprintf (temp, countof(temp), "%d x %d", viewwidth, viewheight); value.String = temp; r_viewsize.ForceSet (value, CVAR_String); } diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp index c2a344bad..bae0bb5bb 100644 --- a/src/r_polymost.cpp +++ b/src/r_polymost.cpp @@ -665,7 +665,7 @@ void drawquad(float x0, float y0, float x1, float y1, float x2, float y2, float void printnum(int x, int y, int num) { - char foo[16]; sprintf (foo, "%d", num); + char foo[16]; mysnprintf (foo, countof(foo), "%d", num); RenderTarget->DrawText (CR_WHITE, x, y, foo); } diff --git a/src/r_things.cpp b/src/r_things.cpp index f49aca1dc..346b0d483 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -476,7 +476,7 @@ void R_InitSkins (void) { if (stricmp (skins[i].name, skins[j].name) == 0) { - sprintf (skins[i].name, "skin%d", (int)i); + mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i); Printf (PRINT_BOLD, "Skin %s duplicated as %s\n", skins[j].name, skins[i].name); break; @@ -657,7 +657,7 @@ void R_InitSkins (void) if (!remove) { if (skins[i].name[0] == 0) - sprintf (skins[i].name, "skin%d", (int)i); + mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i); // Now collect the sprite frames for this skin. If the sprite name was not // specified, use whatever immediately follows the specifier lump. diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 1a2c513fd..b834dea21 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1017,7 +1017,7 @@ static void S_AddSNDINFO (int lump) char temp[16]; sc.MustGetNumber (); - sprintf (temp, "MAP%02d", sc.Number); + mysnprintf (temp, countof(temp), "MAP%02d", sc.Number); info = FindLevelInfo (temp); sc.MustGetString (); if (info->mapname[0] && (!(info->flags & LEVEL_MUSICDEFINED))) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index a50d5c332..d47f27747 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -201,21 +201,21 @@ void S_NoiseDebug (void) else { // X coordinate - sprintf (temp, "%.0f", origin.X); + mysnprintf (temp, countof(temp), "%.0f", origin.X); screen->DrawText (color, 70, y, temp, TAG_DONE); // Y coordinate - sprintf (temp, "%.0f", origin.Z); + mysnprintf (temp, countof(temp), "%.0f", origin.Z); screen->DrawText (color, 120, y, temp, TAG_DONE); // Z coordinate - sprintf (temp, "%.0f", origin.Y); + mysnprintf (temp, countof(temp), "%.0f", origin.Y); screen->DrawText (color, 170, y, temp, TAG_DONE); // Distance if (chan->DistanceScale > 0) { - sprintf (temp, "%.0f", (origin - listener).Length()); + mysnprintf (temp, countof(temp), "%.0f", (origin - listener).Length()); screen->DrawText (color, 260, y, temp, TAG_DONE); } else @@ -225,15 +225,15 @@ void S_NoiseDebug (void) } // Volume - sprintf (temp, "%.2g", chan->Volume); + mysnprintf (temp, countof(temp), "%.2g", chan->Volume); screen->DrawText (color, 220, y, temp, TAG_DONE); // Channel - sprintf (temp, "%d", chan->EntChannel); + mysnprintf (temp, countof(temp), "%d", chan->EntChannel); screen->DrawText (color, 300, y, temp, TAG_DONE); // Flags - sprintf (temp, "%s3%sZ%sU%sM%sN%sA%sL%sE", + mysnprintf (temp, countof(temp), "%s3%sZ%sU%sM%sN%sA%sL%sE", (chan->ChanFlags & CHAN_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHAN_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHAN_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, @@ -1770,13 +1770,13 @@ bool S_ChangeCDMusic (int track, unsigned int id, bool looping) { char temp[32]; - if (id) + if (id != 0) { - sprintf (temp, ",CD,%d,%x", track, id); + mysnprintf (temp, countof(temp), ",CD,%d,%x", track, id); } else { - sprintf (temp, ",CD,%d", track); + mysnprintf (temp, countof(temp), ",CD,%d", track); } return S_ChangeMusic (temp, 0, looping); } @@ -2054,7 +2054,7 @@ CCMD (playsound) CCMD (idmus) { level_info_t *info; - char *map; + FString map; int l; if (argv.argc() > 1) @@ -2063,7 +2063,9 @@ CCMD (idmus) { l = atoi (argv[1]); if (l <= 99) + { map = CalcMapName (0, l); + } else { Printf ("%s\n", GStrings("STSTR_NOMUS")); @@ -2137,9 +2139,13 @@ CCMD (cd_play) char musname[16]; if (argv.argc() == 1) + { strcpy (musname, ",CD,"); + } else - sprintf (musname, ",CD,%d", atoi(argv[1])); + { + mysnprintf (musname, countof(musname), ",CD,%d", atoi(argv[1])); + } S_ChangeMusic (musname, 0, true); } diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 442b1ef3f..c16e5a084 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -474,7 +474,7 @@ bool TimiditySong::LaunchTimidity () FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&msgBuf, 0, NULL)) { - sprintf (hres, "%08lx", err); + mysnprintf (hres, countof(hres), "%08lx", err); msgBuf = hres; } diff --git a/src/sound/music_timidity_mididevice.cpp b/src/sound/music_timidity_mididevice.cpp index 92a0d08c7..a96b06bcc 100644 --- a/src/sound/music_timidity_mididevice.cpp +++ b/src/sound/music_timidity_mididevice.cpp @@ -468,10 +468,10 @@ int TimidityMIDIDevice::PlayTick() }; #ifdef _WIN32 char buffer[128]; - sprintf(buffer, "C%02d: %11s %3d %3d\n", (status & 15) + 1, commands[(status >> 4) & 7], parm1, parm2); + mysnprintf(buffer, countof(buffer), "C%02d: %11s %3d %3d\n", (status & 15) + 1, commands[(status >> 4) & 7], parm1, parm2); OutputDebugString(buffer); #else - fprintf(stderr, "C%02d: %11s %3d %3d\n", (status & 15) + 1, commands[(status >> 4) & 7], parm1, parm2); + //fprintf(stderr, "C%02d: %11s %3d %3d\n", (status & 15) + 1, commands[(status >> 4) & 7], parm1, parm2); #endif } } diff --git a/src/st_stuff.cpp b/src/st_stuff.cpp index 47f007c59..655391c96 100644 --- a/src/st_stuff.cpp +++ b/src/st_stuff.cpp @@ -383,8 +383,8 @@ static bool Cht_ChangeLevel (cheatseq_t *cheat) static bool Cht_ChangeStartSpot (cheatseq_t *cheat) { char cmd[64]; - - sprintf (cmd, "changemap %s %c", level.mapname, cheat->Args[0]); + + mysnprintf (cmd, countof(cmd), "changemap %s %c", level.mapname, cheat->Args[0]); C_DoCommand (cmd); return true; } diff --git a/src/stats.h b/src/stats.h index 81066b3c0..39aa7344b 100644 --- a/src/stats.h +++ b/src/stats.h @@ -43,9 +43,13 @@ extern "C" double CyclesPerSecond; #define _interlockedbittestandset64 hackfixfor #define _interlockedbittestandreset64 x64compilation +#define _interlockedbittestandset wtfnmake +#define _interlockedbittestandreset doesittoo #include #undef _interlockedbittestandset64 #undef _interlockedbittestandreset64 +#undef _interlockedbittestandset +#undef _interlockedbittestandreset typedef QWORD cycle_t; diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index d89ff8406..21e3cc41f 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -79,7 +79,7 @@ FBuildTexture::FBuildTexture (int tilenum, const BYTE *pixels, int width, int he LeftOffset = left; TopOffset = top; CalcBitSize (); - sprintf (Name, "BTIL%04d", tilenum); + mysnprintf (Name, countof(Name), "BTIL%04d", tilenum); UseType = TEX_Build; } diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 86a6df4cf..5f9079c32 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -738,8 +738,8 @@ void FinishThingdef() for(int i=0;i<31;i++) { char fmt[20]; - sprintf(fmt, "QuestItem%d", i+1); - QuestItemClasses[i]=PClass::FindClass(fmt); + mysnprintf(fmt, countof(fmt), "QuestItem%d", i+1); + QuestItemClasses[i] = PClass::FindClass(fmt); } } diff --git a/src/timidity/instrum_dls.cpp b/src/timidity/instrum_dls.cpp index 13a0528c2..5be96f716 100644 --- a/src/timidity/instrum_dls.cpp +++ b/src/timidity/instrum_dls.cpp @@ -784,7 +784,7 @@ static const char *SourceToString(USHORT usSource) case CONN_SRC_CC93: return "CC93"; default: - sprintf(unknown, "UNKNOWN (0x%04x)", usSource); + mysnprintf(unknown, countof(unknown), "UNKNOWN (0x%04x)", usSource); return unknown; } } @@ -802,7 +802,7 @@ static const char *TransformToString(USHORT usTransform) case CONN_TRN_SWITCH: return "SWITCH"; default: - sprintf(unknown, "UNKNOWN (0x%04x)", usTransform); + mysnprintf(unknown, countof(unknown), "UNKNOWN (0x%04x)", usTransform); return unknown; } } @@ -876,7 +876,7 @@ static const char *DestinationToString(USHORT usDestination) case CONN_DST_FILTER_Q: return "FILTER_Q"; default: - sprintf(unknown, "UNKNOWN (0x%04x)", usDestination); + mysnprintf(unknown, countof(unknown), "UNKNOWN (0x%04x)", usDestination); return unknown; } } diff --git a/src/tmap.nas b/src/tmap.nas index e27b7ca15..28d2ba399 100644 --- a/src/tmap.nas +++ b/src/tmap.nas @@ -33,7 +33,7 @@ BITS 32 -%include "src/valgrind.inc" +%include "valgrind.inc" ; Segment/section definition macros. diff --git a/src/tmap2.nas b/src/tmap2.nas index da95a3d85..7f6ed82da 100644 --- a/src/tmap2.nas +++ b/src/tmap2.nas @@ -37,7 +37,7 @@ BITS 32 -%include "src/valgrind.inc" +%include "valgrind.inc" %define SPACEFILLER4 (0x44444444) diff --git a/src/tmap3.nas b/src/tmap3.nas index 05b68aaeb..49444419c 100644 --- a/src/tmap3.nas +++ b/src/tmap3.nas @@ -1,4 +1,4 @@ -%include "src/valgrind.inc" +%include "valgrind.inc" %ifdef M_TARGET_WATCOM SEGMENT DATA PUBLIC ALIGN=16 CLASS=DATA USE32 diff --git a/src/v_font.cpp b/src/v_font.cpp index d4c1c6f5f..0b4288266 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -306,7 +306,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, for (i = 0; i < count; i++) { charlumps[i] = -1; - sprintf (buffer, nametemplate, i + start); + mysnprintf (buffer, countof(buffer), nametemplate, i + start); lump = Wads.CheckNumForName (buffer, ns_graphics); if (doomtemplate && lump >= 0 && i + start == 121) { // HACKHACK: Don't load STCFN121 in doom(2), because diff --git a/src/v_video.cpp b/src/v_video.cpp index fdb351f83..1835fb0ef 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -819,7 +819,7 @@ void DFrameBuffer::DrawRateStuff () int chars; int rate_x; - chars = sprintf (fpsbuff, "%2u ms (%3u fps)", howlong, LastCount); + chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount); rate_x = Width - chars * 8; Clear (rate_x, 0, Width, 8, 0, 0); SetFont (ConFont); diff --git a/src/w_wad.cpp b/src/w_wad.cpp index f2bd9543d..249e5d20a 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -465,13 +465,10 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt // Rearrange the name and extension in a part of the lump record // that I don't have any use for in order to cnstruct the fullname. rff_p->Name[8] = '\0'; - sprintf ((char *)rff_p->IDontKnow, "%s.", rff_p->Name); - rff_p->Name[0] = '\0'; + strcpy ((char *)rff_p->IDontKnow, rff_p->Name); + strcat ((char *)rff_p->IDontKnow, "."); strcat ((char *)rff_p->IDontKnow, rff_p->Extension); lump_p->fullname = copystring ((char *)rff_p->IDontKnow); - if (strstr ((char *)rff_p->IDontKnow, "TILE")) - rff_p = rff_p; - lump_p++; } Printf (" (%u files)", header.rff.NumLumps); @@ -715,7 +712,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt { char path[256]; - sprintf(path, "%s:", filename); + mysnprintf(path, countof(path), "%s:", filename); char * wadstr = path+strlen(path); for(unsigned int i = 0; i < EmbeddedWADs.Size(); i++) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index c0ffc559f..7c5b443fe 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -317,10 +317,10 @@ void WI_LoadBackground(bool isenterpic) case GAME_Doom: if (gamemode != commercial) { - char * level = isenterpic? wbs->next : wbs->current; + const char *level = isenterpic ? wbs->next : wbs->current; if (IsExMy(level)) { - sprintf(buffer, "$IN_EPI%c", level[1]); + mysnprintf(buffer, countof(buffer), "$IN_EPI%c", level[1]); lumpname = buffer; } } @@ -353,7 +353,7 @@ void WI_LoadBackground(bool isenterpic) { if (IsExMy(wbs->next)) { - sprintf(buffer, "$IN_HTC%c", wbs->next[1]); + mysnprintf(buffer, countof(buffer), "$IN_HTC%c", wbs->next[1]); lumpname = buffer; } } @@ -842,7 +842,7 @@ void WI_drawEL () // //==================================================================== -int WI_MapToIndex (char *map) +int WI_MapToIndex (const char *map) { unsigned int i; @@ -904,11 +904,11 @@ int WI_drawNum (int x, int y, int n, int digits, bool leadingzeros = true) if (leadingzeros) { - sprintf (text, "%07d", n); + mysnprintf (text, countof(text), "%07d", n); } else { - sprintf (text, "%7d", n); + mysnprintf (text, countof(text), "%7d", n); if (digits < 0) { text_p = strrchr (text, ' '); @@ -1980,7 +1980,7 @@ void WI_loadData(void) for (i = 0; i < 10; i++) { // numbers 0-9 - sprintf (name, "WINUM%d", i); + mysnprintf (name, countof(name), "WINUM%d", i); num[i] = TexMan[name]; } } @@ -2004,7 +2004,7 @@ void WI_loadData(void) for (i = 0; i < 10; i++) { - sprintf (name, "FONTB%d", 16 + i); + mysnprintf (name, countof(name), "FONTB%d", 16 + i); num[i] = TexMan[name]; } } diff --git a/src/wi_stuff.h b/src/wi_stuff.h index 28be48f06..a3a0e07e9 100644 --- a/src/wi_stuff.h +++ b/src/wi_stuff.h @@ -47,11 +47,11 @@ typedef struct wbstartstruct_s int finished_ep; int next_ep; - char current[9]; // [RH] Name of map just finished - char next[9]; // next level, [RH] actual map name + FString current; // [RH] Name of map just finished + FString next; // next level, [RH] actual map name - char lname0[9]; - char lname1[9]; + FString lname0; + FString lname1; int maxkills; int maxitems; diff --git a/src/win32/eaxedit.cpp b/src/win32/eaxedit.cpp index b94b0948d..fa73ce4bf 100644 --- a/src/win32/eaxedit.cpp +++ b/src/win32/eaxedit.cpp @@ -196,7 +196,7 @@ LRESULT AddEnvToDropDown (HWND hCtl, bool showID, const ReverbContainer *env) if (showID) { - sprintf (buff, "(%3d,%3d) %s", HIBYTE(env->ID), LOBYTE(env->ID), env->Name); + mysnprintf (buff, countof(buff), "(%3d,%3d) %s", HIBYTE(env->ID), LOBYTE(env->ID), env->Name); i = SendMessage (hCtl, CB_ADDSTRING, 0, (LPARAM)buff); } else @@ -255,9 +255,9 @@ void SetIDEdits (HWND hDlg, WORD id) { char text[4]; - sprintf (text, "%d", HIBYTE(id)); + mysnprintf (text, countof(text), "%d", HIBYTE(id)); SendMessage (GetDlgItem (hDlg, IDC_EDITID1), WM_SETTEXT, 0, (LPARAM)text); - sprintf (text, "%d", LOBYTE(id)); + mysnprintf (text, countof(text), "%d", LOBYTE(id)); SendMessage (GetDlgItem (hDlg, IDC_EDITID2), WM_SETTEXT, 0, (LPARAM)text); } @@ -406,11 +406,11 @@ LRESULT CALLBACK EditControlProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP int vali = SendMessage (env->SliderHWND, TBM_GETPOS, 0, 0); if (env->Float) { - sprintf (buff, "%d.%03d", vali/1000, abs(vali%1000)); + mysnprintf (buff, countof(buff), "%d.%03d", vali/1000, abs(vali%1000)); } else { - sprintf (buff, "%d", vali); + mysnprintf (buff, countof(buff), "%d", vali); } CallWindowProc (StdEditProc, hWnd, WM_SETTEXT, 0, (LPARAM)buff); CallWindowProc (StdEditProc, hWnd, EM_SETSEL, 0, -1); @@ -487,7 +487,7 @@ void UpdateControl (const EnvControl *control, int value, bool slider) } if (control->Float) { - sprintf (buff, "%d.%03d", value/1000, abs(value%1000)); + mysnprintf (buff, countof(buff), "%d.%03d", value/1000, abs(value%1000)); if (CurrentEnv != NULL) { CurrentEnv->Properties.*control->Float = float(value) / 1000.0; @@ -495,7 +495,7 @@ void UpdateControl (const EnvControl *control, int value, bool slider) } else { - sprintf (buff, "%d", value); + mysnprintf (buff, countof(buff), "%d", value); if (CurrentEnv != NULL) { CurrentEnv->Properties.*control->Int = value; @@ -542,10 +542,10 @@ void UpdateControls (ReverbContainer *env, HWND hDlg) } EnableWindow (GetDlgItem (hDlg, IDC_REVERT), !env->Builtin); - sprintf (buff, "%d", HIBYTE(env->ID)); + mysnprintf (buff, countof(buff), "%d", HIBYTE(env->ID)); SendMessage (GetDlgItem (hDlg, IDC_ID1), WM_SETTEXT, 0, (LPARAM)buff); - sprintf (buff, "%d", LOBYTE(env->ID)); + mysnprintf (buff, countof(buff), "%d", LOBYTE(env->ID)); SendMessage (GetDlgItem (hDlg, IDC_ID2), WM_SETTEXT, 0, (LPARAM)buff); SavedProperties = env->Properties; @@ -690,7 +690,7 @@ void SuggestNewName (const ReverbContainer *env, HWND hEdit) { len = 31 - numdigits; } - sprintf (text + len, "%d", number); + mysnprintf (text + len, countof(text) - len, "%d", number); probe = Environments; while (probe != NULL) @@ -829,7 +829,7 @@ INT_PTR CALLBACK NewEAXProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) static char foo[80]; ti.uId = 2; ti.hwnd = GetDlgItem (hDlg, IDC_EDITID2); - sprintf (foo, "This ID is already used by \"%s\".", rev->Name); + mysnprintf (foo, countof(foo), "This ID is already used by \"%s\".", rev->Name); ti.lpszText = foo; ShowErrorTip (ToolTip, ti, hDlg, "Bad ID"); } diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index 19aeeb21d..d4438ba4b 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -1164,7 +1164,7 @@ void DDrawFB::Update () } unclock (BlitCycles); - LOG1 ("cycles = %d\n", BlitCycles); + LOG1 ("cycles = %llu\n", BlitCycles); Buffer = NULL; LockCount = 0; diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index 16841194c..dec1b380f 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -53,6 +53,9 @@ #include #include #include + +#define USE_WINDOWS_DWORD +#include "doomtype.h" #include "resource.h" #include "version.h" #include "m_swap.h" @@ -637,23 +640,24 @@ HANDLE WriteTextReport () break; } } - j = sprintf (CrashSummary, "Code: %08lX", CrashPointers.ExceptionRecord->ExceptionCode); + j = mysnprintf (CrashSummary, countof(CrashSummary), "Code: %08lX", CrashPointers.ExceptionRecord->ExceptionCode); if ((size_t)i < sizeof(exceptions)/sizeof(exceptions[0])) { - j += sprintf (CrashSummary + j, " (%s", exceptions[i].Text); + j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j, " (%s", exceptions[i].Text); if (CrashPointers.ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { // Pre-NT kernels do not seem to provide this information. if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { - j += sprintf (CrashSummary + j, " - tried to %s address %08lX", + j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j, + " - tried to %s address %08lX", CrashPointers.ExceptionRecord->ExceptionInformation[0] ? "write" : "read", CrashPointers.ExceptionRecord->ExceptionInformation[1]); } } CrashSummary[j++] = ')'; } - j += sprintf (CrashSummary + j, "\r\nAddress: %p", CrashPointers.ExceptionRecord->ExceptionAddress); + j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j, "\r\nAddress: %p", CrashPointers.ExceptionRecord->ExceptionAddress); Writef (file, "%s\r\nFlags: %08X\r\n\r\n", CrashSummary, CrashPointers.ExceptionRecord->ExceptionFlags); Writef (file, "Windows %s %d.%d Build %d %s\r\n\r\n", @@ -1125,15 +1129,15 @@ static void DumpBytes (HANDLE file, BYTE *address) { if ((i & 15) == 0) { - line_p += sprintf (line_p, "\r\n%p:", address); + line_p += mysnprintf (line_p, countof(line) - (line_p - line), "\r\n%p:", address); } if (SafeReadMemory (address, &peek, 1)) { - line_p += sprintf (line_p, " %02x", *address); + line_p += mysnprintf (line_p, countof(line) - (line_p - line), " %02x", *address); } else { - line_p += sprintf (line_p, " --"); + line_p += mysnprintf (line_p, countof(line) - (line_p - line), " --"); } address++; } @@ -1918,12 +1922,13 @@ static DWORD CALLBACK StreamEditBinary (DWORD_PTR cookie, LPBYTE buffer, LONG cb BYTE buf16[16]; DWORD read, i; char *buff_p = (char *)buffer; + char *buff_end = (char *)buffer + cb; repeat: switch (info->Stage) { case 0: // Write prologue - buff_p += sprintf (buff_p, "{\\rtf1\\ansi\\deff0" + buff_p += mysnprintf (buff_p, buff_end - buff_p, "{\\rtf1\\ansi\\deff0" "{\\colortbl ;\\red0\\green0\\blue80;\\red0\\green0\\blue0;\\red80\\green0\\blue80;}" "\\viewkind4\\pard"); info->Stage++; @@ -1939,19 +1944,19 @@ repeat: goto repeat; } char *linestart = buff_p; - buff_p += sprintf (buff_p, "\\cf1 %08lx:\\cf2 ", info->Pointer); + buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf1 %08lx:\\cf2 ", info->Pointer); info->Pointer += read; for (i = 0; i < read;) { if (i <= read - 4) { - buff_p += sprintf (buff_p, " %08lx", *(DWORD *)&buf16[i]); + buff_p += mysnprintf (buff_p, buff_end - buff_p, " %08lx", *(DWORD *)&buf16[i]); i += 4; } else { - buff_p += sprintf (buff_p, " %02x", buf16[i]); + buff_p += mysnprintf (buff_p, buff_end - buff_p, " %02x", buf16[i]); i += 1; } } @@ -1959,7 +1964,7 @@ repeat: { *buff_p++ = ' '; } - buff_p += sprintf (buff_p, "\\cf3 "); + buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf3 "); for (i = 0; i < read; ++i) { BYTE code = buf16[i]; @@ -1967,17 +1972,17 @@ repeat: if (code == '\\' || code == '{' || code == '}') *buff_p++ = '\\'; *buff_p++ = code; } - buff_p += sprintf (buff_p, "\\par\r\n"); + buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\par\r\n"); } break; case 2: // Write epilogue - buff_p += sprintf (buff_p, "\\cf0 }"); + buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf0 }"); info->Stage = 4; break; case 3: // Write epilogue for truncated file - buff_p += sprintf (buff_p, "--- Rest of file truncated ---\\cf0 }"); + buff_p += mysnprintf (buff_p, buff_end - buff_p, "--- Rest of file truncated ---\\cf0 }"); info->Stage = 4; break; @@ -2015,11 +2020,11 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum) size = GetFileSize (TarFiles[filenum].File, NULL); if (size < 1024) { - sprintf (sizebuf, "(%lu bytes)", size); + mysnprintf (sizebuf, countof(sizebuf), "(%lu bytes)", size); } else { - sprintf (sizebuf, "(%lu KB)", size/1024); + mysnprintf (sizebuf, countof(sizebuf), "(%lu KB)", size/1024); } SetWindowText (sizedisplay, sizebuf); @@ -2125,7 +2130,7 @@ static void UploadFail (HWND hDlg, const char *message, int reason) { char buff[512]; - sprintf (buff, "%s: %d", message, reason); + mysnprintf (buff, countof(buff), "%s: %d", message, reason); SetWindowText (GetDlgItem (hDlg, IDC_BOINGSTATUS), buff); if (reason >= 10000 && reason <= 11999) @@ -2681,7 +2686,7 @@ static DWORD WINAPI UploadProc (LPVOID lpParam) sizeof(MultipartBinaryHeader)-1 + sizeof(MultipartHeaderGZip)-1 + fileLen + sizeof(MultipartFooter)-1; - headerLen = sprintf (xferbuf, PostHeader, contentLength); + headerLen = mysnprintf (xferbuf, countof(xferbuf), PostHeader, contentLength); bytesSent = send (sock, xferbuf, headerLen, 0); if (bytesSent != headerLen) { @@ -2710,7 +2715,7 @@ static DWORD WINAPI UploadProc (LPVOID lpParam) UploadFail (parm->hDlg, "Could not upload report", WSAGetLastError()); throw 1; } - headerLen = sprintf (xferbuf, "Windows %08lX %p %X %08lX %08lX %08lX %08lX %08lX %s", + headerLen = mysnprintf (xferbuf, countof(xferbuf), "Windows %08lX %p %X %08lX %08lX %08lX %08lX %08lX %s", CrashPointers.ExceptionRecord->ExceptionCode, CrashPointers.ExceptionRecord->ExceptionAddress, !!CrashPointers.ExceptionRecord->ExceptionInformation[0], @@ -2746,7 +2751,7 @@ static DWORD WINAPI UploadProc (LPVOID lpParam) } // Send the report file. - headerLen = sprintf (xferbuf, "%s%s", MultipartBinaryHeader, MultipartHeaderZip); + headerLen = mysnprintf (xferbuf, countof(xferbuf), "%s%s", MultipartBinaryHeader, MultipartHeaderZip); bytesSent = send (sock, xferbuf, headerLen, 0); if (bytesSent == SOCKET_ERROR) @@ -3059,7 +3064,7 @@ void DisplayCrashLog () GAMENAME" crashed but was unable to produce\n" "detailed information about the crash.\n" "\nThis is all that is available:\n\nCode=XXXXXXXX\nAddr=XXXXXXXX"; - sprintf (ohPoo + sizeof(ohPoo) - 23, "%08lX\nAddr=%p", CrashCode, CrashAddress); + mysnprintf (ohPoo + countof(ohPoo) - 23, 23, "%08lX\nAddr=%p", CrashCode, CrashAddress); MessageBox (NULL, ohPoo, GAMENAME" Very Fatal Error", MB_OK|MB_ICONSTOP); if (WinHlp32 != NULL) { diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 0314fffc0..debe7efbe 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -827,7 +827,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } #ifdef _DEBUG char foo[256]; - sprintf (foo, "Session Change: %ld %d\n", lParam, wParam); + mysnprintf (foo, countof(foo), "Session Change: %ld %d\n", lParam, wParam); OutputDebugString (foo); #endif } @@ -1064,7 +1064,7 @@ bool SetJoystickSection (bool create) if (g_pJoy != NULL && SUCCEEDED(g_pJoy->GetDeviceInfo (&inst))) { - FormatGUID (section + 9, inst.guidInstance); + FormatGUID (section + 9, countof(section) - 9, inst.guidInstance); strcpy (section + 9 + 38, ".Axes"); return GameConfig->SetSection (section, create); } diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 783e0244c..7adef0779 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -964,22 +964,23 @@ void DoMain (HINSTANCE hInstance) // //========================================================================== -void DoomSpecificInfo (char *buffer) +void DoomSpecificInfo (char *buffer, size_t bufflen) { const char *arg; + char *const buffend = buffer + bufflen - 2; // -2 for CRLF at end int i; - buffer += wsprintf (buffer, "ZDoom version " DOTVERSIONSTR " (" __DATE__ ")\r\n"); - buffer += wsprintf (buffer, "\r\nCommand line: %s\r\n", GetCommandLine()); + buffer += mysnprintf (buffer, buffend - buffer, "ZDoom version " DOTVERSIONSTR " (" __DATE__ ")\r\n"); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nCommand line: %s\r\n", GetCommandLine()); for (i = 0; (arg = Wads.GetWadName (i)) != NULL; ++i) { - buffer += wsprintf (buffer, "\r\nWad %d: %s", i, arg); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nWad %d: %s", i, arg); } if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL) { - buffer += wsprintf (buffer, "\r\n\r\nNot in a level."); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nNot in a level."); } else { @@ -987,18 +988,18 @@ void DoomSpecificInfo (char *buffer) strncpy (name, level.mapname, 8); name[8] = 0; - buffer += wsprintf (buffer, "\r\n\r\nCurrent map: %s", name); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nCurrent map: %s", name); if (!viewactive) { - buffer += wsprintf (buffer, "\r\n\r\nView not active."); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nView not active."); } else { - buffer += wsprintf (buffer, "\r\n\r\nviewx = %d", viewx); - buffer += wsprintf (buffer, "\r\nviewy = %d", viewy); - buffer += wsprintf (buffer, "\r\nviewz = %d", viewz); - buffer += wsprintf (buffer, "\r\nviewangle = %x", viewangle); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %d", viewx); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %d", viewy); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %d", viewz); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %x", viewangle); } } *buffer++ = '\r'; @@ -1093,7 +1094,7 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info) char *custominfo = (char *)HeapAlloc (GetProcessHeap(), 0, 16384); CrashPointers = *info; - DoomSpecificInfo (custominfo); + DoomSpecificInfo (custominfo, 16384); CreateCrashLog (custominfo, (DWORD)strlen(custominfo)); // If the main thread crashed, then make it clean up after itself. diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 48d219669..80745fdfa 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -515,74 +515,6 @@ void I_Quit (void) extern FILE *Logfile; bool gameisdead; -// We should use ZDoom's internal formatting routine here so that the extended -// format specifiers work here as well. - -struct snprintf_state -{ - char *buffer; - size_t maxlen; - size_t curlen; - int ideallen; -}; - -static int myvsnprintf_helper(void *data, const char *cstr, int cstr_len) -{ - snprintf_state *state = (snprintf_state *)data; - - if (INT_MAX - state->ideallen > cstr_len) - { - state->ideallen = INT_MAX; - } - else - { - state->ideallen += cstr_len; - } - if (state->curlen + cstr_len > state->maxlen) - { - cstr_len = (int)(state->maxlen - state->curlen); - } - if (cstr_len > 0) - { - memcpy(state->buffer + state->curlen, cstr, cstr_len); - state->curlen += cstr_len; - } - return cstr_len; -} - -// Unlike the MS CRT function snprintf, this one always writes a terminating -// null character to the buffer. It also returns the full length of the string -// that would have been output if the buffer had been large enough. In other -// words, it follows BSD/Linux rules and not MS rules. -int myvsnprintf(char *buffer, size_t count, const char *format, va_list argptr) -{ - size_t originalcount = count; - if (count != 0) - { - count--; - } - if (count > INT_MAX) - { - count = INT_MAX; - } - snprintf_state state = { buffer, count, 0, 0 }; - StringFormat::VWorker(myvsnprintf_helper, &state, format, argptr); - if (originalcount > 0) - { - buffer[state.curlen] = '\0'; - } - return state.ideallen; -} - -int mysnprintf(char *buffer, size_t count, const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - int len = myvsnprintf(buffer, count, format, argptr); - va_end(argptr); - return len; -} - void STACK_ARGS I_FatalError (const char *error, ...) { static BOOL alreadyThrown = false; diff --git a/src/win32/st_start.cpp b/src/win32/st_start.cpp index 10a832fc3..66c7512c4 100644 --- a/src/win32/st_start.cpp +++ b/src/win32/st_start.cpp @@ -548,7 +548,7 @@ void FBasicStartupScreen :: NetProgress(int count) { char buf[16]; - sprintf (buf, "%d/%d", NetCurPos, NetMaxPos); + mysnprintf (buf, countof(buf), "%d/%d", NetCurPos, NetMaxPos); SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, buf); SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, MIN(NetCurPos, NetMaxPos), 0); } diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index c54e4d40e..1114d5504 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -425,11 +425,11 @@ FILE *dbg; #define STARTLOG #define STOPLOG #define LOG(x) { OutputDebugString(x); } -#define LOG1(x,y) { char poo[1024]; sprintf(poo, x, y); OutputDebugString(poo); } -#define LOG2(x,y,z) { char poo[1024]; sprintf(poo, x, y, z); OutputDebugString(poo); } -#define LOG3(x,y,z,zz) { char poo[1024]; sprintf(poo, x, y, z, zz); OutputDebugString(poo); } -#define LOG4(x,y,z,a,b) { char poo[1024]; sprintf(poo, x, y, z, a, b); OutputDebugString(poo); } -#define LOG5(x,y,z,a,b,c) { char poo[1024]; sprintf(poo, x, y, z, a, b, c); OutputDebugString(poo); } +#define LOG1(x,y) { char poo[1024]; mysnprintf(poo, countof(poo), x, y); OutputDebugString(poo); } +#define LOG2(x,y,z) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z); OutputDebugString(poo); } +#define LOG3(x,y,z,zz) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, zz); OutputDebugString(poo); } +#define LOG4(x,y,z,a,b) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b); OutputDebugString(poo); } +#define LOG5(x,y,z,a,b,c) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b, c); OutputDebugString(poo); } #else #define STARTLOG #define STOPLOG diff --git a/src/zstrformat.cpp b/src/zstrformat.cpp index 567ebbd88..bcb264904 100644 --- a/src/zstrformat.cpp +++ b/src/zstrformat.cpp @@ -1,11 +1,96 @@ +/* +** zstrformat.cpp +** Routines for generic printf-style formatting. +** +**--------------------------------------------------------------------------- +** Copyright 2005-2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** Portions of this file relating to printing floating point numbers +** are covered by the following copyright: +** +**--------------------------------------------------------------------------- +** Copyright (c) 1990, 1993 +** The Regents of the University of California. All rights reserved. +** +** This code is derived from software contributed to Berkeley by +** Chris Torek. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 4. Neither the name of the University nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +**--------------------------------------------------------------------------- +** +** Even though the standard C library has a function to do printf-style +** formatting in a generic way, there is no standard interface to this +** function. So if you want to do some printf formatting that doesn't fit in +** the context of the provided functions, you need to roll your own. Why is +** that? +** +** Maybe Microsoft wants you to write a better one yourself? When used as +** part of a sprintf replacement, this function is significantly faster than +** Microsoft's offering. When used as part of a fprintf replacement, this +** function turns out to be slower, but that's probably because the CRT's +** fprintf can interact with the FILE object on a low level for better +** perfomance. If you sprintf into a buffer and then fwrite that buffer, this +** routine wins again, though the difference isn't great. +*/ + #include #include #include #include #include #include +#include #include "zstring.h" +#include "gdtoa.h" #ifndef _MSC_VER #include @@ -14,21 +99,32 @@ typedef unsigned __int64 uint64_t; typedef signed __int64 int64_t; #endif -// Even though the standard C library has a function to do printf-style formatting in a -// generic way, there is no standard interface to this function. So if you want to do -// some printf formatting that doesn't fit in the context of the provided functions, -// you need to roll your own. Why is that? -// -// Maybe Microsoft wants you to write a better one yourself? When used as part of a -// sprintf replacement, this function is significantly faster than Microsoft's -// offering. When used as part of a fprintf replacement, this function turns out to -// be slower, but that's probably because the CRT's fprintf can interact with the -// FILE object on a low level for better perfomance. If you sprintf into a buffer -// and then fwrite that buffer, this routine wins again, though the difference isn't -// great. +/* + * MAXEXPDIG is the maximum number of decimal digits needed to store a + * floating point exponent in the largest supported format. It should + * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point + * conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it + * is presently never greater than 5 in practice, we fudge it. + */ +#define MAXEXPDIG 6 +#if LDBL_MAX_EXP > 999999 +#error "floating point buffers too small" +#endif + +#define DEFPREC 6 + +static const char hexits[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; +static const char HEXits[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; +static const char spaces[16] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static const char zeroes[17] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','.'}; +static const char dotchar = '.'; namespace StringFormat { + static int writepad (OutputFunc output, void *outputData, const char *pad, int padsize, int spaceToFill); + static int printandpad (OutputFunc output, void *outputData, const char *p, const char *ep, int len, const char *with, int padsize); + static int exponent (char *p0, int exp, int fmtch); + int Worker (OutputFunc output, void *outputData, const char *fmt, ...) { va_list arglist; @@ -40,43 +136,6 @@ namespace StringFormat return len; } - static inline int writepad (OutputFunc output, void *outputData, const char *pad, int padsize, int spaceToFill) - { - int outlen = 0; - while (spaceToFill > 0) - { - int count = spaceToFill > padsize ? padsize : spaceToFill; - outlen += output (outputData, pad, count); - spaceToFill -= count; - } - return outlen; - } - - // Gasp! This is supposed to be a replacement for sprintf formatting, but - // I used sprintf for doubles anyway! Oh no! - static int fmt_fp (OutputFunc output, void *outputData, int flags, int precision, int width, double number, char type) - { - char *buff; - char format[16]; - int i; - - format[0] = '%'; - i = 1; - if (flags & F_MINUS) format[i++] = '-'; - if (flags & F_PLUS) format[i++] = '+'; - if (flags & F_ZERO) format[i++] = '0'; - if (flags & F_BLANK) format[i++] = ' '; - if (flags & F_HASH) format[i++] = '#'; - format[i++] = '*'; - format[i++] = '.'; - format[i++] = '*'; - format[i++] = type; - format[i++] = '\0'; - buff = (char *)alloca (1000 + precision); - i = sprintf (buff, format, width, precision, number); - return output (outputData, buff, i); - } - int VWorker (OutputFunc output, void *outputData, const char *fmt, va_list arglist) { const char *c; @@ -233,18 +292,13 @@ namespace StringFormat // Now that that's all out of the way, we should be pointing at the type specifier { - static const char hexits[18] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','0','x'}; - static const char HEXits[18] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','0','X'}; - static const char spaces[16] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static const char zeroes[17] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','.'}; - static const char plusprefix = '+'; - static const char minusprefix = '-'; - static const char dotchar = '.'; - const char *prefix = NULL; - int prefixlen = 0; + char prefix[3]; + int prefixlen; + char hexprefix = '\0'; + char sign = '\0'; int postprefixzeros = 0; int size = flags & 0xF000; - char buffer[32], *ibuff; + char buffer[80], *ibuff; const char *obuff = 0; char type = *c++; int bufflen = 0; @@ -253,8 +307,32 @@ namespace StringFormat uint64_t int64arg = 0; const void *voidparg; const char *charparg; + double dblarg; const char *xits = hexits; int inlen = len; + /* + * We can decompose the printed representation of floating + * point numbers into several parts, some of which may be empty: + * + * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ + * A B ---C--- D E F + * + * A: 'sign' holds this value if present; '\0' otherwise + * B: hexprefix holds the 'x' or 'X'; '\0' if not hexadecimal + * C: obuff points to the string MMMNNN. Leading and trailing + * zeros are not in the string and must be added. + * D: expchar holds this character; '\0' if no exponent, e.g. %f + * F: at least two digits for decimal, at least one digit for hex + */ + const char *decimal_point = ".";/* locale specific decimal point */ + int signflag; /* true if float is negative */ + int expt; /* integer value of exponent */ + char expchar = 'e'; /* exponent character: [eEpP\0] */ + char *dtoaend; /* pointer to end of converted digits */ + int expsize = 0; /* character count for expstr */ + int ndig = 0; /* actual number of digits returned by dtoa */ + char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ + char *dtoaresult = NULL; /* buffer allocated by dtoa */ // Using a bunch of if/else if statements is faster than a switch, because a switch generates // a jump table. A jump table means a possible data cache miss and a hefty penalty while the @@ -263,7 +341,8 @@ namespace StringFormat if (type == 'x' || type == 'X' || type == 'p' || type == 'd' || type == 'u' || type == 'i' || - type == 'o') + type == 'o' || + type == 'B') { if (type == 'X' || type == 'p') { @@ -360,6 +439,14 @@ namespace StringFormat } intarg = int(int64arg); } + else if (type == 'B') + { // Binary: Dump digits until it fits in an unsigned int + while (int64arg > UINT_MAX) + { + *--ibuff = char(int64arg & 1) + '0'; int64arg >>= 1; + } + intarg = int(int64arg); + } else { if (type != 'u') @@ -413,10 +500,19 @@ namespace StringFormat } else if (type == 'u') { // Decimal - while (intarg != 0) + int i; + + // Unsigned division is typically slower than signed division. + // Do it at most once. + if (intarg > INT_MAX) { *--ibuff = char(intarg % 10) + '0'; intarg /= 10; } + i = (int)intarg; + while (i != 0) + { + *--ibuff = char(i % 10) + '0'; i /= 10; + } } else if (type == 'o') { // Octal @@ -425,6 +521,13 @@ namespace StringFormat *--ibuff = char(intarg & 7) + '0'; intarg >>= 3; } } + else if (type == 'B') + { // Binary + while (intarg != 0) + { + *--ibuff = char(intarg & 1) + '0'; intarg >>= 1; + } + } else { // Hexadecimal while (intarg != 0) @@ -439,14 +542,16 @@ namespace StringFormat { if (bufflen >= precision) { - prefix = zeroes; - prefixlen = 1; + sign = '0'; } } else if (type == 'x' || type == 'X') { - prefix = xits + 16; - prefixlen = 2; + hexprefix = type; + } + else if (type == 'B') + { + hexprefix = '!'; } } bufflen = (int)(ptrdiff_t)(&buffer[sizeof(buffer)] - ibuff); @@ -519,59 +624,149 @@ namespace StringFormat *va_arg (arglist, int *) = inlen; } } - else if (type == 'e' || type == 'E' || - type == 'f' || type == 'F' || - type == 'g' || type == 'G') + else if (type == 'f' || type == 'F') { - // IEEE 754 floating point numbers -#ifdef _MSC_VER -#define FP_SIGN_MASK (1ui64<<63) -#define FP_EXPONENT_MASK (2047ui64<<52) -#define FP_FRACTION_MASK ((1ui64<<52)-1) -#else -#define FP_SIGN_MASK (1llu<<63) -#define FP_EXPONENT_MASK (2047llu<<52) -#define FP_FRACTION_MASK ((1llu<<52)-1) -#endif - union + expchar = '\0'; + goto fp_begin; + } + else if (type == 'g' || type == 'G') + { + expchar = type - ('g' - 'e'); + if (precision == 0) { - double d; - uint64_t i64; - } number; - number.d = va_arg (arglist, double); - - if (precision < 0) precision = 6; - - flags |= F_SIGNED; - - if ((number.i64 & FP_EXPONENT_MASK) == FP_EXPONENT_MASK) + precision = 1; + } + goto fp_begin; + } +#if 0 + // The hdtoa function provided with FreeBSD uses a hexadecimal FP constant. + // Microsoft's compiler does not support these, so I would need to hack it + // together with ints instead. It's very do-able, but until I actually have + // some reason to print hex FP numbers, I won't bother. + else if (type == 'a' || type == 'A') + { + if (type == 'A') { - if (number.i64 & FP_SIGN_MASK) - { - flags |= F_NEGATIVE; - } - if ((number.i64 & FP_FRACTION_MASK) == 0) - { - obuff = "Infinity"; - bufflen = 8; - } - else if ((number.i64 & ((FP_FRACTION_MASK+1)>>1)) == 0) - { - obuff = "NaN"; - bufflen = 3; - } - else - { - obuff = "Ind"; - } + xits = HEXits; + hexprefix = 'X'; + expchar = 'P'; } else { - // Converting a binary floating point number to an ASCII decimal - // representation is non-trivial, so I'm not going to do it myself. - // (At least for now.) - len += fmt_fp (output, outputData, flags, precision, width, number.d, type); - continue; + hexprefix = 'x'; + expchar = 'p'; + } + if (precision >= 0) + { + precision++; + } + dblarg = va_arg(arglist, double); + dtoaresult = obuff = hdtoa(dblarg, xits, precision, &expt, &signflag, &dtoaend); + if (precision < 0) + { + precision = (int)(dtoaend - obuff); + } + if (expt == INT_MAX) + { + hexprefix = '\0'; + } + goto fp_common; + } +#endif + else if (type == 'e' || type == 'E') + { + expchar = type; + if (precision < 0) // account for digit before decpt + { + precision = DEFPREC + 1; + } + else + { + precision++; + } +fp_begin: + if (precision < 0) + { + precision = DEFPREC; + } + dblarg = va_arg(arglist, double); + obuff = dtoaresult = dtoa(dblarg, expchar ? 2 : 3, precision, &expt, &signflag, &dtoaend); +//fp_common: + decimal_point = localeconv()->decimal_point; + flags |= F_SIGNED; + if (signflag) + { + flags |= F_NEGATIVE; + } + if (expt == INT_MAX) // inf or nan + { + if (*obuff == 'N') + { + obuff = (type >= 'a') ? "nan" : "NAN"; + flags &= ~F_SIGNED; + } + else + { + obuff = (type >= 'a') ? "inf" : "INF"; + } + bufflen = 3; + flags &= ~F_ZERO; + } + else + { + flags |= F_FPT; + ndig = (int)(dtoaend - obuff); + if (type == 'g' || type == 'G') + { + if (expt > -4 && expt <= precision) + { // Make %[gG] smell like %[fF]. + expchar = '\0'; + if (flags & F_HASH) + { + precision -= expt; + } + else + { + precision = ndig - expt; + } + if (precision < 0) + { + precision = 0; + } + } + else + { // Make %[gG] smell like %[eE], but trim trailing zeroes if no # flag. + if (!(flags & F_HASH)) + { + precision = ndig; + } + } + } + if (expchar) + { + expsize = exponent(expstr, expt - 1, expchar); + bufflen = expsize + precision; + if (precision > 1 || (flags & F_HASH)) + { + ++bufflen; + } + } + else + { // space for digits before decimal point + if (expt > 0) + { + bufflen = expt; + } + else // "0" + { + bufflen = 1; + } + // space for decimal pt and following digits + if (precision != 0 || (flags & F_HASH)) + { + bufflen += precision + 1; + } + } } } @@ -580,21 +775,32 @@ namespace StringFormat { if (flags & F_NEGATIVE) { - prefix = &minusprefix; - prefixlen = 1; + sign = '-'; } else if (flags & F_PLUS) { - prefix = &plusprefix; - prefixlen = 1; + sign = '+'; } else if (flags & F_BLANK) { - prefix = spaces; - prefixlen = 1; + sign = ' '; } } + // Construct complete prefix from sign and hex prefix character + prefixlen = 0; + if (sign != '\0') + { + prefix[0] = sign; + prefixlen = 1; + } + if (hexprefix != '\0') + { + prefix[prefixlen] = '0'; + prefix[prefixlen + 1] = hexprefix; + prefixlen += 2; + } + // Pad the output to the field width, if needed int fieldlen = prefixlen + postprefixzeros + bufflen; const char *pad = (flags & F_ZERO) ? zeroes : spaces; @@ -617,9 +823,55 @@ namespace StringFormat outlen += output (outputData, prefix, prefixlen); } outlen += writepad (output, outputData, zeroes, sizeof(spaces), postprefixzeros); - if (bufflen > 0) + if (!(flags & F_FPT)) { - outlen += output (outputData, obuff, bufflen); + if (bufflen > 0) + { + outlen += output (outputData, obuff, bufflen); + } + } + else + { + if (expchar == '\0') // %[fF] or sufficiently short %[gG] + { + if (expt <= 0) + { + outlen += output (outputData, zeroes, 1); + if (precision != 0 || (flags & F_HASH)) + { + outlen += output (outputData, decimal_point, 1); + } + outlen += writepad (output, outputData, zeroes, sizeof(zeroes), -expt); + // already handled initial 0's + precision += expt; + } + else + { + outlen += printandpad (output, outputData, obuff, dtoaend, expt, zeroes, sizeof(zeroes)); + obuff += expt; + if (precision || (flags & F_HASH)) + { + outlen += output (outputData, decimal_point, 1); + } + } + outlen += printandpad (output, outputData, obuff, dtoaend, precision, zeroes, sizeof(zeroes)); + } + else // %[eE] or sufficiently long %[gG] + { + if (precision > 1 || (flags & F_HASH)) + { + buffer[0] = *obuff++; + buffer[1] = *decimal_point; + outlen += output (outputData, buffer, 2); + outlen += output (outputData, obuff, ndig - 1); + outlen += writepad (output, outputData, zeroes, sizeof(zeroes), precision - ndig); + } + else // XeYY + { + outlen += output (outputData, obuff, 1); + } + outlen += output (outputData, expstr, expsize); + } } if ((flags & F_MINUS) && fieldlen < width) @@ -627,7 +879,166 @@ namespace StringFormat outlen += writepad (output, outputData, pad, sizeof(spaces), width - fieldlen); } len += outlen; + if (dtoaresult != NULL) + { + freedtoa(dtoaresult); + dtoaresult = NULL; + } } } } + + static int writepad (OutputFunc output, void *outputData, const char *pad, int padsize, int spaceToFill) + { + int outlen = 0; + while (spaceToFill > 0) + { + int count = spaceToFill > padsize ? padsize : spaceToFill; + outlen += output (outputData, pad, count); + spaceToFill -= count; + } + return outlen; + } + + static int printandpad (OutputFunc output, void *outputData, const char *p, const char *ep, int len, const char *with, int padsize) + { + int outlen = 0; + int n2 = (int)(ep - p); + if (n2 > len) + { + n2 = len; + } + if (n2 > 0) + { + outlen = output (outputData, p, n2); + } + return outlen + writepad (output, outputData, with, padsize, len - (n2 > 0 ? n2 : 0)); + } + + static int exponent (char *p0, int exp, int fmtch) + { + char *p, *t; + char expbuf[MAXEXPDIG]; + + p = p0; + *p++ = fmtch; + if (exp < 0) + { + exp = -exp; + *p++ = '-'; + } + else + { + *p++ = '+'; + } + t = expbuf + MAXEXPDIG; + if (exp > 9) + { + do + { + *--t = '0' + (exp % 10); + } + while ((exp /= 10) > 9); + *--t = '0' + exp; + for(; t < expbuf + MAXEXPDIG; *p++ = *t++) + { } + } + else + { + // Exponents for decimal floating point conversions + // (%[eEgG]) must be at least two characters long, + // whereas exponents for hexadecimal conversions can + // be only one character long. + if (fmtch == 'e' || fmtch == 'E') + { + *p++ = '0'; + } + *p++ = '0' + exp; + } + return (int)(p - p0); + } }; + +//========================================================================// +// snprintf / vsnprintf imitations + +#ifdef __GNUC__ +#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi))) +#define GCCFORMAT(stri) __attribute__((format(printf,stri,0))) +#define GCCNOWARN __attribute__((unused)) +#else +#define GCCPRINTF(a,b) +#define GCCFORMAT(a) +#define GCCNOWARN +#endif + +struct snprintf_state +{ + char *buffer; + size_t maxlen; + size_t curlen; + int ideallen; +}; + +static int myvsnprintf_helper(void *data, const char *cstr, int cstr_len) +{ + snprintf_state *state = (snprintf_state *)data; + + if (INT_MAX - cstr_len < state->ideallen) + { + state->ideallen = INT_MAX; + } + else + { + state->ideallen += cstr_len; + } + if (state->curlen + cstr_len > state->maxlen) + { + cstr_len = (int)(state->maxlen - state->curlen); + } + if (cstr_len > 0) + { + memcpy(state->buffer + state->curlen, cstr, cstr_len); + state->curlen += cstr_len; + } + return cstr_len; +} + +extern "C" +{ + +// Unlike the MS CRT function snprintf, this one always writes a terminating +// null character to the buffer. It also returns the full length of the string +// that would have been output if the buffer had been large enough. In other +// words, it follows BSD/Linux rules and not MS rules. +int myvsnprintf(char *buffer, size_t count, const char *format, va_list argptr) +{ + size_t originalcount = count; + if (count != 0) + { + count--; + } + if (count > INT_MAX) + { // This is probably an error. Output nothing. + originalcount = 0; + count = 0; + } + snprintf_state state = { buffer, count, 0, 0 }; + StringFormat::VWorker(myvsnprintf_helper, &state, format, argptr); + if (originalcount > 0) + { + buffer[state.curlen] = '\0'; + } + return state.ideallen; +} + +int mysnprintf(char *buffer, size_t count, const char *format, ...) +{ + va_list argptr; + va_start(argptr, format); + int len = myvsnprintf(buffer, count, format, argptr); + va_end(argptr); + return len; +} + +} diff --git a/src/zstring.cpp b/src/zstring.cpp index 011ef517d..9f3926438 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -3,7 +3,7 @@ ** A dynamically-allocated string class. ** **--------------------------------------------------------------------------- -** Copyright 2005-2007 Randy Heit +** Copyright 2005-2008 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without diff --git a/src/zstring.h b/src/zstring.h index ebfb357bb..ad79fb118 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -281,6 +281,7 @@ namespace StringFormat F_SIGNED = 32, F_NEGATIVE = 64, F_ZEROVALUE = 128, + F_FPT = 256, // Format specification size prefixes F_HALFHALF = 0x1000, // hh diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000..7b99c506e --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required( VERSION 2.6 ) + +add_subdirectory( lemon ) +add_subdirectory( re2c ) +if( WIN32 ) + add_subdirectory( fixrtext ) +endif( WIN32 ) +add_subdirectory( updaterevision ) +add_subdirectory( dehsupp ) +add_subdirectory( zipdir ) diff --git a/tools/dehsupp/CMakeLists.txt b/tools/dehsupp/CMakeLists.txt new file mode 100644 index 000000000..138acafe6 --- /dev/null +++ b/tools/dehsupp/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required( VERSION 2.6 ) +project( dehsupp ) + +set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) + +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/parse.h ${CMAKE_CURRENT_BINARY_DIR}/parse.c + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/parse.y ${CMAKE_CURRENT_BINARY_DIR} + COMMAND lemon parse.y + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS lemon parse.y ) + +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c + COMMAND re2c -s -o ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_SOURCE_DIR}/scanner.re + DEPENDS re2c scanner.re ) + +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) + +add_executable( dehsupp dehsupp.c parse.c scanner.c ) +add_dependencies( dehsupp ${CMAKE_CURRENT_BINARY_DIR}/parse.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ) diff --git a/tools/dehsupp/Makefile b/tools/dehsupp/Makefile deleted file mode 100644 index 35c09b5a7..000000000 --- a/tools/dehsupp/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 - endif -endif - -ifeq (1,$(WIN)) - EXE = dehsupp.exe - CFLAGS = $(LOC) -Os -Wall -fomit-frame-pointer -else - EXE = dehsupp - CFLAGS = -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -Os -Wall -fomit-frame-pointer -endif - -CCDV = @../../ccdv -CC = gcc -LDFLAGS = -s - -RE2C = ../re2c/re2c -LEMON = ../lemon/lemon -LEMONFLAGS = -RE2CFLAGS = -s - -OBJS = dehsupp.o parse.o scanner.o - -all: $(EXE) - -$(EXE): $(OBJS) - $(CCDV) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul - -del /q /f *.o 2>nul -else - rm -f $(EXE) - rm -f *.o -endif - -%.o: %.c - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -parse.h parse.c: parse.y - $(CCDV) $(LEMON) $(LEMONFLAGS) $< - -scanner.c: scanner.re - $(CCDV) $(RE2C) $(RE2CFLAGS) -o $@ $< - -parse.tab.c: parse.y - $(CCDV) $(BISON) $(BISONFLAGS) -o $@ $< diff --git a/tools/dehsupp/dehsupp.vcproj b/tools/dehsupp/dehsupp.vcproj index bdce02aa2..be391ce7a 100644 --- a/tools/dehsupp/dehsupp.vcproj +++ b/tools/dehsupp/dehsupp.vcproj @@ -342,6 +342,10 @@ + + diff --git a/tools/fixrtext/CMakeLists.txt b/tools/fixrtext/CMakeLists.txt new file mode 100644 index 000000000..c88e04a24 --- /dev/null +++ b/tools/fixrtext/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required( VERSION 2.6 ) +project( fixrtext ) + +add_executable( fixrtext fixrtext.c ) diff --git a/tools/fixrtext/Makefile b/tools/fixrtext/Makefile deleted file mode 100644 index 420aad243..000000000 --- a/tools/fixrtext/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 -endif -ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WIN=1 - WINCMD=0 -endif - -ifeq (1,$(WIN)) - EXE = fixrtext.exe - CFLAGS = $(LOC) -D_WIN32 -Os -Wall -fomit-frame-pointer -else -# This is only useful for Win32 builds. -endif - -CCDV = @../../ccdv -CC = gcc -LDFLAGS = -s - -all: $(EXE) - -$(EXE): fixrtext.c - $(CCDV) $(CC) $(LDFLAGS) -o $(EXE) fixrtext.c - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul -else - rm -f $(EXE) -endif diff --git a/tools/fixrtext/fixrtext.vcproj b/tools/fixrtext/fixrtext.vcproj index bc78575e6..cc50b605b 100644 --- a/tools/fixrtext/fixrtext.vcproj +++ b/tools/fixrtext/fixrtext.vcproj @@ -169,6 +169,10 @@ + + diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt new file mode 100644 index 000000000..213d78e86 --- /dev/null +++ b/tools/lemon/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required( VERSION 2.6 ) +project( lemon ) + +set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) + +add_executable( lemon lemon.c ) + +# Lemon wants lempar.c in its directory +add_custom_command( TARGET lemon + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/lempar.c ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/tools/lemon/Makefile b/tools/lemon/Makefile deleted file mode 100644 index bb1d88c6e..000000000 --- a/tools/lemon/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 - endif -endif - -ifeq (1,$(WIN)) - EXE = lemon.exe - CFLAGS = $(LOC) -D_WIN32 -Os -Wall -Wno-implicit -fomit-frame-pointer -else - EXE = lemon - CFLAGS = -Os -Wall -Wno-implicit -fomit-frame-pointer -endif - -CCDV = @../../ccdv -CC = gcc -LDFLAGS = -s - -OBJS = lemon.o - -all: $(EXE) - -$(EXE): $(OBJS) - $(CCDV) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) - -%.o: %.c - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul - -del /q /f *.o 2>nul -else - rm -f $(EXE) - rm -f *.o -endif - -lemon.o: lemon.c lempar.c - diff --git a/tools/lemon/lemon.vcproj b/tools/lemon/lemon.vcproj index 48f53a715..9f46d4df9 100644 --- a/tools/lemon/lemon.vcproj +++ b/tools/lemon/lemon.vcproj @@ -356,6 +356,10 @@ + + diff --git a/tools/makewad/Makefile b/tools/makewad/Makefile deleted file mode 100644 index f79212d5f..000000000 --- a/tools/makewad/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 - endif -endif - -ifeq (1,$(WIN)) - EXE = makewad.exe - CFLAGS = -Os -Wall -fomit-frame-pointer - LDFLAGS = -s -L../../zlib/ -lz - ZLIB = ../../zlib/libz.a -else - EXE = makewad - CFLAGS = -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -Os -Wall -fomit-frame-pointer - LDFLAGS = -s -lz - ZLIB = -endif - -CCDV = @../../ccdv -CC = gcc - -OBJS = makewad.o ioapi.o zip.o - -all: $(EXE) - -.c.o: - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -$(EXE): $(OBJS) $(ZLIB) - $(CCDV) $(CC) -o $(EXE) $(OBJS) $(LDFLAGS) - -ifeq (1,$(WIN)) -$(ZLIB): - make -C ../../zlib -f Makefile.mgw -endif - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul - -del /q /f *.o 2>nul -else - -rm -f $(EXE) - -rm -f *.o -endif diff --git a/tools/makewad/makewad.c b/tools/makewad/makewad.c deleted file mode 100644 index e5abc90ca..000000000 --- a/tools/makewad/makewad.c +++ /dev/null @@ -1,505 +0,0 @@ -// makewad.c -// -// Reads a wad specification from stdin. -// Produces a wad file -or- writes a Makefile to stdout. - -#include -#include -#include -#include -#include -#include -#include "zip.h" - -#define MAX_LUMPS 4096 - -typedef struct -{ - char magic[4]; - unsigned int numlumps; - int infotableofs; - -} wadinfo_t; - - -typedef struct -{ - int filepos; - unsigned int size; - char name[8]; - -} filelump_t; - -/* -// appendlump(wadfile, filename): -// -// open the file by filename, write all of its contents to the wadfile -// -// returns: 0 = success, 1 = error -*/ - -int appendlump (FILE *wadfile, char *filename) -{ - char readbuf[64*1024]; - FILE *lumpfile; - size_t readlen; - int ret = 0; - - lumpfile = fopen (filename, "rb"); - if (lumpfile == NULL) - { - fprintf (stderr, "Could not open %s: %s\n", filename, strerror(errno)); - return 1; - } - while (lumpfile != NULL) - { - // try to read a chunk of data - readlen = fread (readbuf, 1, sizeof(readbuf), lumpfile); - - // if we reached the end, or hit an error - if (readlen < sizeof(readbuf)) - { - // if it's an error, - if (ferror (lumpfile)) - { - // diagnose - fprintf (stderr, "Error reading %s: %s\n", filename, strerror(errno)); - // set return code to error - ret |= 1; - } - // in any case, close the lump file to break the loop - fclose (lumpfile); - lumpfile = NULL; - } - - // write whatever data we have in the buffer - - // if we hit an error (less bytes written than given) - if (fwrite (readbuf, 1, readlen, wadfile) < readlen) - { - // diagnose - fprintf (stderr, "Error writing to wad: %s\n", strerror(errno)); - // close the lump file to break the loop - fclose (lumpfile); - lumpfile = NULL; - // set return code to error - ret |= 1; - } - // if the lump file got closed, the loop exits - } - return ret; -} - -/* -// appendtozip(zipFile, zipname, filename): -// -// write a given lump file (filename) to the zipFile as zipname -// -// zipFile: zip object to be written to -// -// zipname: name of the file inside the zip -// filename: file to read data from -// -// returns: 0 = success, 1 = error -*/ -int appendtozip (zipFile zipfile, const char * zipname, const char *filename) -{ - char *readbuf; - FILE *lumpfile; - size_t readlen; - size_t len; - zip_fileinfo zip_inf; - - time_t currenttime; - struct tm * ltime; - - // clear zip_inf structure - memset(&zip_inf, 0, sizeof(zip_inf)); - - // try to determine local time - time(¤ttime); - ltime = localtime(¤ttime); - // if succeeded, - if (ltime != NULL) - { - // put it into the zip_inf structure - zip_inf.tmz_date.tm_sec = ltime->tm_sec; - zip_inf.tmz_date.tm_min = ltime->tm_min; - zip_inf.tmz_date.tm_hour = ltime->tm_hour; - zip_inf.tmz_date.tm_mday = ltime->tm_mday; - zip_inf.tmz_date.tm_mon = ltime->tm_mon; - zip_inf.tmz_date.tm_year = ltime->tm_year; - } - - // lumpfile = source file - lumpfile = fopen (filename, "rb"); - if (lumpfile == NULL) - { - fprintf (stderr, "Could not open %s: %s\n", filename, strerror(errno)); - return 1; - } - // len = source size - fseek (lumpfile, 0, SEEK_END); - len = ftell(lumpfile); - fseek (lumpfile, 0, SEEK_SET); - - // allocate a buffer for the whole source file - readbuf = (char*)malloc(len); - if (readbuf == NULL) - { - fclose(lumpfile); - fprintf (stderr, "Could not allocate %u bytes\n", (int)len); - return 1; - } - // read the whole source file into buffer - readlen = fread (readbuf, 1, len, lumpfile); - fclose(lumpfile); - - // if read less bytes than expected, - if (readlen != len) - { - // diagnose and return error - free (readbuf); - fprintf (stderr, "Unable to read %s\n", filename); - return 1; - } - // file loaded - - // create zip entry, giving entry name and zip_inf data, - // write data into zipfile, and close the zip entry - if (Z_OK != zipAddFileToZip(zipfile, zipname, &zip_inf, readbuf, (unsigned)len)) - { - free (readbuf); - fprintf (stderr, "Unable to write %s to zip\n", filename); - return 1; - } - // all done - free (readbuf); - return 0; -} - -/* -// buildwad(listfile, listfilename, makecmd, makefile) -// -// go through the listfile, either: -// writing dependencies (listfile + lumps with files) into a makefile, -// -or- -// writing lumps into a wad/zip file -// -// listfile: already opened source file -// listfilename: filename, if any - only for the makefile -// makecmd: given as argv[0] - only for the makefile -// makefile: output filename for makefile. determines mode: -// - if specified, we're writing deps into a makefile -// - otherwise, we're writing lumps into a wad/zip -// -*/ -int buildwad (FILE *listfile, char *listfilename, const char *makecmd, char *makefile) -{ - // destination we're writing output into - - // one of these: - zipFile zipfile = NULL; - FILE *wadfile = NULL; - - wadinfo_t header; - filelump_t directory[MAX_LUMPS]; - char str[256]; // buffer for reading listfile line by line - char *pt; - char *lumpname, *filename; - int lineno = 0; - int ret = 0; - int i; - - // prepare PWAD data - strncpy (header.magic, "PWAD", 4); - header.infotableofs = 0; - header.numlumps = 0; - memset (directory, 0, sizeof(directory)); - - // read the listfile line by line - while (fgets (str, sizeof(str), listfile)) - { - lineno++; // counting lines for diagnostic purposes - - // Strip comments - pt = strchr (str, '#'); - if (pt) *pt = 0; - - // Strip trailing whitespace - pt = str + strlen (str) - 1; - while (pt >= str && isspace(*pt)) pt--; - if (pt < str) continue; - pt[1] = 0; - - // Skip leading whitespace - pt = str; - while (isspace(*pt)) pt++; - - if (*pt == '@') - { // Rest of line is wadfile to create - if (wadfile != NULL || zipfile != NULL) - { - fprintf (stderr, "Line %d: Tried to reopen wadfile as %s.\n", lineno, pt + 1); - if (wadfile != NULL) fclose (wadfile); - if (zipfile != NULL) zipClose (zipfile, NULL); - - return 1; - } - - if (!makefile) // if it's not a makefile, - { - int ln = (int)strlen(pt+1); - - filename = pt+1; - if (ln >= 4) - { - // If the output file has an extension '.zip' or '.pk3' it will be in Zip format. - if (!stricmp(filename+ln-3, "ZIP") || !stricmp(filename+ln-3, "PK3")) - { - zipfile = zipOpen(filename, APPEND_STATUS_CREATE); - if (zipfile == NULL) - { - fprintf (stderr, "Line %d: Could not open %s: %s\n", lineno, filename, strerror(errno)); - return 1; - } - } - } - } - else filename = makefile; - - if (!zipfile) // if we didn't end up opening zip, it's a regular file - { - // open wadfile - wadfile = fopen (filename, makefile ? "w" : "wb"); - if (wadfile == NULL) - { - fprintf (stderr, "Line %d: Could not open %s: %s\n", lineno, filename, strerror(errno)); - return 1; - } - if (makefile) - { // Write out the only rule the makefile has - fprintf (wadfile, "%s: %s", pt+1, listfilename); - } - else - { - // The correct header will be written once the wad is complete - fwrite (&header, sizeof(header), 1, wadfile); - } - } - continue; - } // @ - - // Everything up to the next whitespace is the lump name - lumpname = pt; - filename = NULL; - while (*pt && !isspace(*pt)) pt++; - - // If there is more, skip whitespace and use the remainder of the line - // as the file to insert into the lump. If no filename is given, then - // a 0-length marker lump is inserted. - if (*pt) - { - *pt = 0; - filename = pt + 1; - while (*filename && isspace(*filename)) filename++; - if (*filename == 0) filename = NULL; - } - - // must have output selected - if (wadfile == NULL && zipfile == NULL) - { - fprintf (stderr, "Line %d: No wad specified before lumps.\n", lineno); - return 1; - } - - // if we're writing a makefile, - if (makefile) - { - // and the lump has a filename, - if (filename != NULL) - { - // add it as a dependency (with quotes, if needed) - if (strchr (filename, ' ')) - { - fprintf (wadfile, " \\\n\t\"%s\"", filename); - } - // ARGH! Stupid make. Too bad, but then these files can't be checked. - // Still better than something that doesn't work at all though! - else if (!strpbrk(filename, "[]^")) - { - fprintf (wadfile, " \\\n\t%s", filename); - } - } - } - else // not writing a makefile - { - if (zipfile == NULL) // must be a wadfile - { - // convert lumpname to uppercase - for (i = 0; lumpname[i]; ++i) - { - lumpname[i] = toupper(lumpname[i]); - } - // put name into directory entry - strncpy (directory[header.numlumps].name, lumpname, 8); - // put filepos into directory entry - directory[header.numlumps].filepos = ftell (wadfile); - // if filename given, - if (filename != NULL) - { - // append data to the wadfile - ret |= appendlump (wadfile, filename); - } - // put size into directory entry (how many bytes were just written) - directory[header.numlumps].size = ftell (wadfile) - directory[header.numlumps].filepos; - } - else if (filename != NULL) // writing a zip, and filename is non-null - { - // convert lumpname to lowercase - for (i = 0; lumpname[i]; ++i) - { - lumpname[i] = tolower(lumpname[i]); - } - // add lump data to the zip - ret |= appendtozip(zipfile, lumpname, filename); - } - // count all lumps - header.numlumps++; - } - - } // end of line-by-line reading - - // the finishing touches: - // - makefile: terminate the line, and write the action line - // - unzipped wad: write the directory at the end, - // and update the header with directory's position - // - zipped wad: just close it - - // if we were writing a plain file, - if (wadfile != NULL) - { - // if it's makefile, - if (makefile) - { - // terminate the dependencies line, - // and write the action command - fprintf (wadfile, "\n\t%s %s\n", makecmd, listfilename); - } - else // otherwise, it's plain wad - { - // the directory of lumps will be written at the end, - // starting at the current position - put it into the header - header.infotableofs = ftell (wadfile); - - // swap endianness, if needed -#ifdef WORDS_BIGENDIAN -#define SWAP(x) ((((x)>>24)|(((x)>>8) & 0xff00)|(((x)<<8) & 0xff0000)|((x)<<24))) - - for (i = 0; i < header.numlumps; ++i) - { - directory[i].filepos = SWAP(directory[i].filepos); - directory[i].size = SWAP(directory[i].size); - } -#endif - // write the whole directory of lumps - if (fwrite (directory, sizeof(directory[0]), header.numlumps, wadfile) != header.numlumps) - { - // failed to write the whole directory - fprintf (stderr, "Error writing to wad: %s\n", strerror(errno)); - ret |= 1; - } - else // success - seek to 0 and rewrite the header, now with offset - { - // endianness -#ifdef WORDS_BIGENDIAN - SWAP(header.infotableofs); - SWAP(header.numlumps); -#endif - // seek to 0 - fseek (wadfile, 0, SEEK_SET); - - // rewrite the header - if (fwrite (&header, sizeof(header), 1, wadfile) != 1) - { - fprintf (stderr, "Error writing to wad: %s\n", strerror(errno)); - ret |= 1; - } - } - } // plain wad - - fclose (wadfile); - } // wadfile!=NULL - wad or makefile - else if (zipfile != NULL) - { - // zip - just close it - zipClose(zipfile, NULL); - } - return ret; -} - -// If building with GCC and not MinGW, macro __cdecl to nothing. -#if defined(__GNUC__) && !defined(__MINGW32__) -#define __cdecl -#endif - -int __cdecl main (int argc, char **argv) -{ - const char *makecmd; - FILE *listfile = NULL; - char *listfilename = NULL; - char *makefile = NULL; - int ret; - int i; - - for (i = 1; i < argc; ++i) - { - if (strcmp (argv[i], "-make") == 0) - { - if (i >= argc-1) - { - goto baduse; - } - makefile = argv[++i]; - } - else if (listfile == NULL) - { - listfilename = argv[i]; - listfile = fopen (listfilename, "r"); - if (listfile == NULL) - { - fprintf (stderr, "Can't open %s: %s\n", listfilename, strerror(errno)); - return 1; - } - } - else - { - fclose (listfile); - goto baduse; - } - } - if (makefile != NULL && listfile == NULL) - { - fprintf (stderr, "You must specify a listfile if you want a makefile\n"); - return 1; - } - - // Hack for msys - if ((makecmd = getenv("OSTYPE")) != NULL && strcmp (makecmd, "msys") == 0) - { - makecmd = "../tools/makewad/makewad.exe"; - } - else - { - makecmd = argv[0]; - } - ret = buildwad (listfile ? listfile : stdin, listfilename, makecmd, makefile); - if (listfile != NULL) - { - fclose (listfile); - } - return ret; - -baduse: - fprintf (stderr, "Usage: makewad [-make makefile] [listfile]\n"); - return 1; -} diff --git a/tools/re2c/CMakeLists.txt b/tools/re2c/CMakeLists.txt new file mode 100644 index 000000000..9d8c0411d --- /dev/null +++ b/tools/re2c/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required( VERSION 2.6 ) +project( re2c ) + +add_executable( re2c + actions.cc + code.cc + dfa.cc + main.cc + mbo_getopt.cc + parser.cc + scanner.cc + substr.cc + translate.cc ) diff --git a/tools/re2c/Makefile b/tools/re2c/Makefile deleted file mode 100644 index 9261a7813..000000000 --- a/tools/re2c/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 - endif -endif - -ifeq (1,$(WIN)) - EXE = re2c.exe - CXXFLAGS = $(LOC) -D_WIN32 -DNDEBUG -Os -Wall -Wno-unused -else - EXE = re2c - CXXFLAGS = -DHAVE_CONFIG_H -DNDEBUG -Os -Wall -Wno-unused -endif - -CCDV = @../../ccdv -CXX = g++ -LDFLAGS= -s - -OBJS = actions.o code.o dfa.o main.o mbo_getopt.o parser.o scanner.o substr.o translate.o - -all: $(EXE) - -.cc.o: - $(CCDV) $(CXX) $(CXXFLAGS) -c -o $@ $< - -$(EXE): $(OBJS) - $(CCDV) $(CXX) $(LDFLAGS) -o $(EXE) $(OBJS) - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul - -del /q /f *.o 2>nul -else - rm -f $(EXE) - rm -f *.o -endif - -actions.o: actions.cc -code.o: code.cc -dfa.o: dfa.cc -main.o: main.cc -mbo_getopt.o: mbo_getopt.cc -parser.o: parser.cc -scanner.o: scanner.cc -substr.o: substr.cc -translate.o: translate.cc diff --git a/tools/re2c/re2c.vcproj b/tools/re2c/re2c.vcproj index 8bc118ea2..c10906185 100644 --- a/tools/re2c/re2c.vcproj +++ b/tools/re2c/re2c.vcproj @@ -539,12 +539,10 @@ > - - + diff --git a/tools/updaterevision/CMakeLists.txt b/tools/updaterevision/CMakeLists.txt new file mode 100644 index 000000000..627b4045e --- /dev/null +++ b/tools/updaterevision/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required( VERSION 2.6 ) +project( updaterevision ) + +if( WIN32 ) + if( CMAKE_COMPILER_IS_GNUC OR CMAKE_COMPILER_IS_GNUCXX ) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/trustinfo.o + COMMAND windres -o ${CMAKE_CURRENT_BINARY_DIR}/trustinfo.o -i ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.rc + DEPENDS trustinfo.rc ) + set( TRUSTINFO trustinfo.o ) + else( CMAKE_COMPILER_IS_GNUC OR CMAKE_COMPILER_IS_GNUCXX ) + if( MSVC_VERSION GREATER 1399 ) + # VC 8+ adds a manifest automatically to the executable. We need to + # merge ours with it. + set( MT_MERGE ON ) + else( MSVC_VERSION GREATER 1399 ) + set( TRUSTINFO trustinfo.rc ) + endif( MSVC_VERSION GREATER 1399 ) + endif( CMAKE_COMPILER_IS_GNUC OR CMAKE_COMPILER_IS_GNUCXX ) +endif( WIN32 ) + +add_executable( updaterevision updaterevision.c ${TRUSTINFO} ) + +if( MT_MERGE ) + get_target_property( UPDATEREVISION_EXE updaterevision LOCATION ) + add_custom_command(TARGET updaterevision POST_BUILD + COMMAND mt -inputresource:${UPDATEREVISION_EXE} -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:${UPDATEREVISION_EXE} -nologo + COMMENT "Embedding trustinfo into updaterevision" ) +endif( MT_MERGE ) diff --git a/tools/updaterevision/Makefile b/tools/updaterevision/Makefile deleted file mode 100644 index 0f54cb382..000000000 --- a/tools/updaterevision/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 - ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - WINCMD=0 - endif -endif - -CC = gcc -CFLAGS = -Os -Wall -fomit-frame-pointer -LDFLAGS = -s - -OBJS = updaterevision.o - -ifeq (1,$(WIN)) - EXE = updaterevision.exe - OBJS += trustinfo.o -else - EXE = updaterevision -endif - -CCDV = @../../ccdv - -all: $(EXE) - -$(EXE): $(OBJS) - $(CCDV) $(CC) -o $(EXE) $(OBJS) $(CFLAGS) $(LDFLAGS) - -%.o : %.rc - $(CCDV) windres -o $@ -i $< - -.PHONY: clean - -clean: -ifeq (1,$(WINCMD)) - -del /q /f $(EXE) 2>nul - -del /q /f *.o 2>nul -else - -rm -f $(EXE) - -rm -f *.o -endif diff --git a/tools/updaterevision/updaterevision.vcproj b/tools/updaterevision/updaterevision.vcproj index c41849593..0421cbb65 100644 --- a/tools/updaterevision/updaterevision.vcproj +++ b/tools/updaterevision/updaterevision.vcproj @@ -23,7 +23,7 @@ OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" - CharacterSet="1" + CharacterSet="2" > ... +** +** Given one or more directories, their contents are scanned recursively. +** If any files are newer than the zip file or the zip file does not exist, +** then everything in the specified directories is stored in the zip. The +** base directory names are not stored in the zip file, but subdirectories +** recursed into are stored. +*/ + +// HEADER FILES ------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zip.h" + +// MACROS ------------------------------------------------------------------ + +#ifndef _WIN32 +#define __cdecl +#endif + +// TYPES ------------------------------------------------------------------- + +typedef struct file_entry_s +{ + struct file_entry_s *next; + time_t time_write; + char path[]; +} file_entry_t; + +typedef struct dir_tree_s +{ + struct dir_tree_s *next; + file_entry_t *files; + size_t path_size; + char path[]; +} dir_tree_t; + +typedef struct file_sorted_s +{ + file_entry_t *file; + char *path_in_zip; +} file_sorted_t; + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +void print_usage(const char *cmdname); +dir_tree_t *alloc_dir_tree(const char *dir); +file_entry_t *alloc_file_entry(const char *prefix, const char *path, time_t last_written); +void free_dir_tree(dir_tree_t *tree); +void free_dir_trees(dir_tree_t *tree); +void recurse_dir(dir_tree_t *tree, const char *dirpath); +dir_tree_t *add_dir(const char *dirpath); +int count_files(dir_tree_t *trees); +int __cdecl sort_cmp(const void *a, const void *b); +file_sorted_t *sort_files(dir_tree_t *trees, int num_files); +void write_zip(const char *zipname, dir_tree_t *trees); +int append_to_zip(zipFile zipfile, const file_sorted_t *file); + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static int no_mem; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// print_usage +// +//========================================================================== + +void print_usage(const char *cmdname) +{ +#ifdef _WIN32 + const char *rchar = strrchr(cmdname, '\\'); + if (rchar != NULL) + { + cmdname = rchar+1; + } +#endif + fprintf(stderr, "Usage: %s ...\n", cmdname); +} + +//========================================================================== +// +// alloc_dir_tree +// +//========================================================================== + +dir_tree_t *alloc_dir_tree(const char *dir) +{ + dir_tree_t *tree; + size_t dirlen; + + dirlen = strlen(dir); + tree = malloc(sizeof(dir_tree_t) + dirlen + 2); + if (tree != NULL) + { + strcpy(tree->path, dir); + tree->path_size = dirlen; + if (dir[dirlen - 1] != '/') + { + tree->path_size++; + tree->path[dirlen] = '/'; + tree->path[dirlen + 1] = '\0'; + } + tree->files = NULL; + tree->next = NULL; + } + return tree; +} + +//========================================================================== +// +// alloc_file_entry +// +//========================================================================== + +file_entry_t *alloc_file_entry(const char *prefix, const char *path, time_t last_written) +{ + file_entry_t *entry; + + entry = malloc(sizeof(file_entry_t) + strlen(prefix) + strlen(path) + 1); + if (entry != NULL) + { + strcpy(entry->path, prefix); + strcat(entry->path, path); + strlwr(entry->path); + entry->next = NULL; + entry->time_write = last_written; + } + return entry; +} + +//========================================================================== +// +// free_dir_tree +// +//========================================================================== + +void free_dir_tree(dir_tree_t *tree) +{ + file_entry_t *entry, *next; + + if (tree != NULL) + { + for (entry = tree->files; entry != NULL; entry = next) + { + next = entry->next; + free(entry); + } + free(tree); + } +} + +//========================================================================== +// +// free_dir_trees +// +//========================================================================== + +void free_dir_trees(dir_tree_t *tree) +{ + dir_tree_t *next; + + for (; tree != NULL; tree = next) + { + next = tree->next; + free_dir_tree(tree); + } +} + +//========================================================================== +// +// recurse_dir +// +//========================================================================== + +void recurse_dir(dir_tree_t *tree, const char *dirpath) +{ + struct _finddata_t fileinfo; + char *dirmatch; + intptr_t handle; + + dirmatch = malloc(strlen(dirpath) + 2); + if (dirmatch == NULL) + { + no_mem = 1; + return; + } + strcpy(dirmatch, dirpath); + strcat(dirmatch, "*"); + if ((handle = _findfirst(dirmatch, &fileinfo)) == -1) + { + fprintf(stderr, "Could not scan '%s': %s\n", dirpath, strerror(errno)); + } + else + { + do + { + if (fileinfo.attrib & _A_HIDDEN) + { + // Skip hidden files and directories. (Prevents SVN bookkeeping + // info from being included.) + continue; + } + if (fileinfo.attrib & _A_SUBDIR) + { + char *newdir; + + if (fileinfo.name[0] == '.' && + (fileinfo.name[1] == '\0' || + (fileinfo.name[1] == '.' && fileinfo.name[2] == '\0'))) + { + // Do not record . and .. directories. + continue; + } + newdir = malloc(strlen(dirpath) + strlen(fileinfo.name) + 2); + strcpy(newdir, dirpath); + strcat(newdir, fileinfo.name); + strcat(newdir, "/"); + recurse_dir(tree, newdir); + } + else + { + file_entry_t *entry; + + entry = alloc_file_entry(dirpath, fileinfo.name, fileinfo.time_write); + if (entry == NULL) + { + no_mem = 1; + break; + } + entry->next = tree->files; + tree->files = entry; + } + } while (_findnext(handle, &fileinfo) == 0); + _findclose(handle); + } + free(dirmatch); +} + +//========================================================================== +// +// add_dir +// +//========================================================================== + +dir_tree_t *add_dir(const char *dirpath) +{ + dir_tree_t *tree = alloc_dir_tree(dirpath); + + if (tree != NULL) + { + recurse_dir(tree, tree->path); + } + return tree; +} + +//========================================================================== +// +// count_files +// +//========================================================================== + +int count_files(dir_tree_t *trees) +{ + dir_tree_t *tree; + file_entry_t *file; + int count; + + for (count = 0, tree = trees; tree != NULL; tree = tree->next) + { + for (file = tree->files; file != NULL; file = file->next) + { + count++; + } + } + return count; +} + +//========================================================================== +// +// sort_cmp +// +// Arbitrarily-selected sorting for the zip files: Files in the root +// directory sort after files in subdirectories. Otherwise, everything +// sorts by name. +// +//========================================================================== + +int __cdecl sort_cmp(const void *a, const void *b) +{ + const file_sorted_t *sort1 = (const file_sorted_t *)a; + const file_sorted_t *sort2 = (const file_sorted_t *)b; + int in_dir1, in_dir2; + + in_dir1 = (strchr(sort1->path_in_zip, '/') != NULL); + in_dir2 = (strchr(sort2->path_in_zip, '/') != NULL); + if (in_dir1 == 1 && in_dir2 == 0) + { + return -1; + } + if (in_dir1 == 0 && in_dir2 == 1) + { + return 1; + } + return strcmp(((const file_sorted_t *)a)->path_in_zip, + ((const file_sorted_t *)b)->path_in_zip); +} + +//========================================================================== +// +// sort_files +// +//========================================================================== + +file_sorted_t *sort_files(dir_tree_t *trees, int num_files) +{ + file_sorted_t *sorter; + dir_tree_t *tree; + file_entry_t *file; + int i; + + sorter = malloc(sizeof(*sorter) * num_files); + if (sorter != NULL) + { + for (i = 0, tree = trees; tree != NULL; tree = tree->next) + { + for (file = tree->files; file != NULL; file = file->next) + { + sorter[i].file = file; + sorter[i].path_in_zip = file->path + tree->path_size; + i++; + } + } + qsort(sorter, num_files, sizeof(*sorter), sort_cmp); + } + return sorter; +} + +//========================================================================== +// +// write_zip +// +//========================================================================== + +void write_zip(const char *zipname, dir_tree_t *trees) +{ + int i, num_files; + file_sorted_t *sorted; + zipFile zip; + + num_files = count_files(trees); + sorted = sort_files(trees, num_files); + if (sorted == NULL) + { + no_mem = 1; + return; + } + zip = zipOpen(zipname, APPEND_STATUS_CREATE); + if (zip == NULL) + { + fprintf(stderr, "Could not open %s: %s\n", zipname, strerror(errno)); + } + else + { + for (i = 0; i < num_files; ++i) + { + append_to_zip(zip, sorted + i); + } + zipClose(zip, NULL); + printf("Wrote %d/%d files to %s\n", i, num_files, zipname); + } + free(sorted); +} + +//========================================================================== +// +// append_to_zip +// +// Write a given file to the zipFile. +// +// zipfile: zip object to be written to +// file: file to read data from +// +// returns: 0 = success, 1 = error +// +//========================================================================== + +int append_to_zip(zipFile zipfile, const file_sorted_t *file) +{ + char *readbuf; + FILE *lumpfile; + size_t readlen; + size_t len; + zip_fileinfo zip_inf; + struct tm *ltime; + + // clear zip_inf structure + memset(&zip_inf, 0, sizeof(zip_inf)); + + // try to determine local time + ltime = localtime(&file->file->time_write); + // if succeeded, + if (ltime != NULL) + { + // put it into the zip_inf structure + zip_inf.tmz_date.tm_sec = ltime->tm_sec; + zip_inf.tmz_date.tm_min = ltime->tm_min; + zip_inf.tmz_date.tm_hour = ltime->tm_hour; + zip_inf.tmz_date.tm_mday = ltime->tm_mday; + zip_inf.tmz_date.tm_mon = ltime->tm_mon; + zip_inf.tmz_date.tm_year = ltime->tm_year; + } + + // lumpfile = source file + lumpfile = fopen(file->file->path, "rb"); + if (lumpfile == NULL) + { + fprintf(stderr, "Could not open %s: %s\n", file->file->path, strerror(errno)); + return 1; + } + // len = source size + fseek (lumpfile, 0, SEEK_END); + len = ftell(lumpfile); + fseek (lumpfile, 0, SEEK_SET); + + // allocate a buffer for the whole source file + readbuf = malloc(len); + if (readbuf == NULL) + { + fclose(lumpfile); + fprintf(stderr, "Could not allocate %u bytes\n", (int)len); + return 1; + } + // read the whole source file into buffer + readlen = fread(readbuf, 1, len, lumpfile); + fclose(lumpfile); + + // if read less bytes than expected, + if (readlen != len) + { + // diagnose and return error + free(readbuf); + fprintf(stderr, "Unable to read %s\n", file->file->path); + return 1; + } + // file loaded + + // create zip entry, giving entry name and zip_inf data, + // write data into zipfile, and close the zip entry + if (Z_OK != zipAddFileToZip(zipfile, file->path_in_zip, &zip_inf, readbuf, (unsigned)len)) + { + free(readbuf); + fprintf(stderr, "Unable to write %s to zip\n", file->file->path); + return 1; + } + // all done + free(readbuf); + return 0; +} + +int __cdecl main (int argc, char **argv) +{ + int i; + dir_tree_t *tree, *trees; + file_entry_t *file; + struct _stat zipstat; + int needwrite; + char *s; + + if (argc < 3) + { + print_usage(argv[0]); + return 1; + } + + trees = NULL; + for (i = 2; i < argc; ++i) + { +#ifdef _WIN32 + for (s = argv[i]; *s != '\0'; ++s) + { + if (*s == '\\') + { + *s = '/'; + } + } +#endif + tree = add_dir(argv[i]); + tree->next = trees; + trees = tree; + if(no_mem) + { + free_dir_trees(trees); + fprintf(stderr, "Out of memory.\n"); + return 1; + } + } + + needwrite = 0; + if (_stat(argv[1], &zipstat) != 0) + { + if (errno == ENOENT) + { + needwrite = 1; + } + else + { + fprintf(stderr, "Could not stat %s: %s\n", argv[1], strerror(errno)); + } + } + else + { + // Check the files in each tree. If any one of them was modified more + // recently than the zip, then it needs to be recreated. + for (tree = trees; tree != NULL; tree = tree->next) + { + for (file = tree->files; file != NULL; file = file->next) + { + if (file->time_write > zipstat.st_mtime) + { + needwrite = 1; + break; + } + } + } + } + if (needwrite) + { + write_zip(argv[1], trees); + } + free_dir_trees(trees); + if (no_mem) + { + fprintf(stderr, "Out of memory.\n"); + return 1; + } + return 0; +} diff --git a/tools/makewad/makewad.vcproj b/tools/zipdir/zipdir.vcproj similarity index 86% rename from tools/makewad/makewad.vcproj rename to tools/zipdir/zipdir.vcproj index 243101e4f..61103dfb1 100644 --- a/tools/makewad/makewad.vcproj +++ b/tools/zipdir/zipdir.vcproj @@ -2,7 +2,7 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -353,42 +353,6 @@ RelativePath=".\ioapi.h" > - - - - - - - - - - - - - - @@ -397,6 +361,10 @@ RelativePath=".\zip.h" > + + diff --git a/wadsrc/dehsupp.txt b/wadsrc/sources/dehsupp.txt similarity index 100% rename from wadsrc/dehsupp.txt rename to wadsrc/sources/dehsupp.txt diff --git a/wadsrc/strfhelp.o b/wadsrc/static/acs/strfhelp.o similarity index 100% rename from wadsrc/strfhelp.o rename to wadsrc/static/acs/strfhelp.o diff --git a/wadsrc/decorate/constants.txt b/wadsrc/static/actors/constants.txt similarity index 100% rename from wadsrc/decorate/constants.txt rename to wadsrc/static/actors/constants.txt diff --git a/wadsrc/decorate/doom/arachnotron.txt b/wadsrc/static/actors/doom/arachnotron.txt similarity index 100% rename from wadsrc/decorate/doom/arachnotron.txt rename to wadsrc/static/actors/doom/arachnotron.txt diff --git a/wadsrc/decorate/doom/archvile.txt b/wadsrc/static/actors/doom/archvile.txt similarity index 100% rename from wadsrc/decorate/doom/archvile.txt rename to wadsrc/static/actors/doom/archvile.txt diff --git a/wadsrc/decorate/doom/bossbrain.txt b/wadsrc/static/actors/doom/bossbrain.txt similarity index 100% rename from wadsrc/decorate/doom/bossbrain.txt rename to wadsrc/static/actors/doom/bossbrain.txt diff --git a/wadsrc/decorate/doom/bruiser.txt b/wadsrc/static/actors/doom/bruiser.txt similarity index 100% rename from wadsrc/decorate/doom/bruiser.txt rename to wadsrc/static/actors/doom/bruiser.txt diff --git a/wadsrc/decorate/doom/cacodemon.txt b/wadsrc/static/actors/doom/cacodemon.txt similarity index 100% rename from wadsrc/decorate/doom/cacodemon.txt rename to wadsrc/static/actors/doom/cacodemon.txt diff --git a/wadsrc/decorate/doom/cyberdemon.txt b/wadsrc/static/actors/doom/cyberdemon.txt similarity index 100% rename from wadsrc/decorate/doom/cyberdemon.txt rename to wadsrc/static/actors/doom/cyberdemon.txt diff --git a/wadsrc/decorate/doom/deadthings.txt b/wadsrc/static/actors/doom/deadthings.txt similarity index 100% rename from wadsrc/decorate/doom/deadthings.txt rename to wadsrc/static/actors/doom/deadthings.txt diff --git a/wadsrc/decorate/doom/demon.txt b/wadsrc/static/actors/doom/demon.txt similarity index 100% rename from wadsrc/decorate/doom/demon.txt rename to wadsrc/static/actors/doom/demon.txt diff --git a/wadsrc/decorate/doom/doomammo.txt b/wadsrc/static/actors/doom/doomammo.txt similarity index 100% rename from wadsrc/decorate/doom/doomammo.txt rename to wadsrc/static/actors/doom/doomammo.txt diff --git a/wadsrc/decorate/doom/doomarmor.txt b/wadsrc/static/actors/doom/doomarmor.txt similarity index 100% rename from wadsrc/decorate/doom/doomarmor.txt rename to wadsrc/static/actors/doom/doomarmor.txt diff --git a/wadsrc/decorate/doom/doomartifacts.txt b/wadsrc/static/actors/doom/doomartifacts.txt similarity index 100% rename from wadsrc/decorate/doom/doomartifacts.txt rename to wadsrc/static/actors/doom/doomartifacts.txt diff --git a/wadsrc/decorate/doom/doomdecorations.txt b/wadsrc/static/actors/doom/doomdecorations.txt similarity index 100% rename from wadsrc/decorate/doom/doomdecorations.txt rename to wadsrc/static/actors/doom/doomdecorations.txt diff --git a/wadsrc/decorate/doom/doomhealth.txt b/wadsrc/static/actors/doom/doomhealth.txt similarity index 100% rename from wadsrc/decorate/doom/doomhealth.txt rename to wadsrc/static/actors/doom/doomhealth.txt diff --git a/wadsrc/decorate/doom/doomimp.txt b/wadsrc/static/actors/doom/doomimp.txt similarity index 100% rename from wadsrc/decorate/doom/doomimp.txt rename to wadsrc/static/actors/doom/doomimp.txt diff --git a/wadsrc/decorate/doom/doomkeys.txt b/wadsrc/static/actors/doom/doomkeys.txt similarity index 100% rename from wadsrc/decorate/doom/doomkeys.txt rename to wadsrc/static/actors/doom/doomkeys.txt diff --git a/wadsrc/decorate/doom/doommisc.txt b/wadsrc/static/actors/doom/doommisc.txt similarity index 100% rename from wadsrc/decorate/doom/doommisc.txt rename to wadsrc/static/actors/doom/doommisc.txt diff --git a/wadsrc/decorate/doom/doomplayer.txt b/wadsrc/static/actors/doom/doomplayer.txt similarity index 100% rename from wadsrc/decorate/doom/doomplayer.txt rename to wadsrc/static/actors/doom/doomplayer.txt diff --git a/wadsrc/decorate/doom/doomweapons.txt b/wadsrc/static/actors/doom/doomweapons.txt similarity index 100% rename from wadsrc/decorate/doom/doomweapons.txt rename to wadsrc/static/actors/doom/doomweapons.txt diff --git a/wadsrc/decorate/doom/fatso.txt b/wadsrc/static/actors/doom/fatso.txt similarity index 100% rename from wadsrc/decorate/doom/fatso.txt rename to wadsrc/static/actors/doom/fatso.txt diff --git a/wadsrc/decorate/doom/keen.txt b/wadsrc/static/actors/doom/keen.txt similarity index 100% rename from wadsrc/decorate/doom/keen.txt rename to wadsrc/static/actors/doom/keen.txt diff --git a/wadsrc/decorate/doom/lostsoul.txt b/wadsrc/static/actors/doom/lostsoul.txt similarity index 100% rename from wadsrc/decorate/doom/lostsoul.txt rename to wadsrc/static/actors/doom/lostsoul.txt diff --git a/wadsrc/decorate/doom/painelemental.txt b/wadsrc/static/actors/doom/painelemental.txt similarity index 100% rename from wadsrc/decorate/doom/painelemental.txt rename to wadsrc/static/actors/doom/painelemental.txt diff --git a/wadsrc/decorate/doom/possessed.txt b/wadsrc/static/actors/doom/possessed.txt similarity index 100% rename from wadsrc/decorate/doom/possessed.txt rename to wadsrc/static/actors/doom/possessed.txt diff --git a/wadsrc/decorate/doom/revenant.txt b/wadsrc/static/actors/doom/revenant.txt similarity index 100% rename from wadsrc/decorate/doom/revenant.txt rename to wadsrc/static/actors/doom/revenant.txt diff --git a/wadsrc/decorate/doom/spidermaster.txt b/wadsrc/static/actors/doom/spidermaster.txt similarity index 100% rename from wadsrc/decorate/doom/spidermaster.txt rename to wadsrc/static/actors/doom/spidermaster.txt diff --git a/wadsrc/decorate/doom/stealthmonsters.txt b/wadsrc/static/actors/doom/stealthmonsters.txt similarity index 100% rename from wadsrc/decorate/doom/stealthmonsters.txt rename to wadsrc/static/actors/doom/stealthmonsters.txt diff --git a/wadsrc/decorate/heretic/beast.txt b/wadsrc/static/actors/heretic/beast.txt similarity index 100% rename from wadsrc/decorate/heretic/beast.txt rename to wadsrc/static/actors/heretic/beast.txt diff --git a/wadsrc/decorate/heretic/chicken.txt b/wadsrc/static/actors/heretic/chicken.txt similarity index 100% rename from wadsrc/decorate/heretic/chicken.txt rename to wadsrc/static/actors/heretic/chicken.txt diff --git a/wadsrc/decorate/heretic/clink.txt b/wadsrc/static/actors/heretic/clink.txt similarity index 100% rename from wadsrc/decorate/heretic/clink.txt rename to wadsrc/static/actors/heretic/clink.txt diff --git a/wadsrc/decorate/heretic/dsparil.txt b/wadsrc/static/actors/heretic/dsparil.txt similarity index 100% rename from wadsrc/decorate/heretic/dsparil.txt rename to wadsrc/static/actors/heretic/dsparil.txt diff --git a/wadsrc/decorate/heretic/hereticammo.txt b/wadsrc/static/actors/heretic/hereticammo.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticammo.txt rename to wadsrc/static/actors/heretic/hereticammo.txt diff --git a/wadsrc/decorate/heretic/hereticarmor.txt b/wadsrc/static/actors/heretic/hereticarmor.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticarmor.txt rename to wadsrc/static/actors/heretic/hereticarmor.txt diff --git a/wadsrc/decorate/heretic/hereticartifacts.txt b/wadsrc/static/actors/heretic/hereticartifacts.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticartifacts.txt rename to wadsrc/static/actors/heretic/hereticartifacts.txt diff --git a/wadsrc/decorate/heretic/hereticdecorations.txt b/wadsrc/static/actors/heretic/hereticdecorations.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticdecorations.txt rename to wadsrc/static/actors/heretic/hereticdecorations.txt diff --git a/wadsrc/decorate/heretic/hereticimp.txt b/wadsrc/static/actors/heretic/hereticimp.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticimp.txt rename to wadsrc/static/actors/heretic/hereticimp.txt diff --git a/wadsrc/decorate/heretic/heretickeys.txt b/wadsrc/static/actors/heretic/heretickeys.txt similarity index 100% rename from wadsrc/decorate/heretic/heretickeys.txt rename to wadsrc/static/actors/heretic/heretickeys.txt diff --git a/wadsrc/decorate/heretic/hereticmisc.txt b/wadsrc/static/actors/heretic/hereticmisc.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticmisc.txt rename to wadsrc/static/actors/heretic/hereticmisc.txt diff --git a/wadsrc/decorate/heretic/hereticplayer.txt b/wadsrc/static/actors/heretic/hereticplayer.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticplayer.txt rename to wadsrc/static/actors/heretic/hereticplayer.txt diff --git a/wadsrc/decorate/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt similarity index 100% rename from wadsrc/decorate/heretic/hereticweaps.txt rename to wadsrc/static/actors/heretic/hereticweaps.txt diff --git a/wadsrc/decorate/heretic/ironlich.txt b/wadsrc/static/actors/heretic/ironlich.txt similarity index 100% rename from wadsrc/decorate/heretic/ironlich.txt rename to wadsrc/static/actors/heretic/ironlich.txt diff --git a/wadsrc/decorate/heretic/knight.txt b/wadsrc/static/actors/heretic/knight.txt similarity index 100% rename from wadsrc/decorate/heretic/knight.txt rename to wadsrc/static/actors/heretic/knight.txt diff --git a/wadsrc/decorate/heretic/mummy.txt b/wadsrc/static/actors/heretic/mummy.txt similarity index 100% rename from wadsrc/decorate/heretic/mummy.txt rename to wadsrc/static/actors/heretic/mummy.txt diff --git a/wadsrc/decorate/heretic/snake.txt b/wadsrc/static/actors/heretic/snake.txt similarity index 100% rename from wadsrc/decorate/heretic/snake.txt rename to wadsrc/static/actors/heretic/snake.txt diff --git a/wadsrc/decorate/heretic/wizard.txt b/wadsrc/static/actors/heretic/wizard.txt similarity index 100% rename from wadsrc/decorate/heretic/wizard.txt rename to wadsrc/static/actors/heretic/wizard.txt diff --git a/wadsrc/decorate/hexen/centaur.txt b/wadsrc/static/actors/hexen/centaur.txt similarity index 100% rename from wadsrc/decorate/hexen/centaur.txt rename to wadsrc/static/actors/hexen/centaur.txt diff --git a/wadsrc/decorate/hexen/clericplayer.txt b/wadsrc/static/actors/hexen/clericplayer.txt similarity index 100% rename from wadsrc/decorate/hexen/clericplayer.txt rename to wadsrc/static/actors/hexen/clericplayer.txt diff --git a/wadsrc/decorate/hexen/demons.txt b/wadsrc/static/actors/hexen/demons.txt similarity index 100% rename from wadsrc/decorate/hexen/demons.txt rename to wadsrc/static/actors/hexen/demons.txt diff --git a/wadsrc/decorate/hexen/ettin.txt b/wadsrc/static/actors/hexen/ettin.txt similarity index 100% rename from wadsrc/decorate/hexen/ettin.txt rename to wadsrc/static/actors/hexen/ettin.txt diff --git a/wadsrc/decorate/hexen/fighterplayer.txt b/wadsrc/static/actors/hexen/fighterplayer.txt similarity index 100% rename from wadsrc/decorate/hexen/fighterplayer.txt rename to wadsrc/static/actors/hexen/fighterplayer.txt diff --git a/wadsrc/decorate/hexen/flame.txt b/wadsrc/static/actors/hexen/flame.txt similarity index 100% rename from wadsrc/decorate/hexen/flame.txt rename to wadsrc/static/actors/hexen/flame.txt diff --git a/wadsrc/decorate/hexen/hexenarmor.txt b/wadsrc/static/actors/hexen/hexenarmor.txt similarity index 100% rename from wadsrc/decorate/hexen/hexenarmor.txt rename to wadsrc/static/actors/hexen/hexenarmor.txt diff --git a/wadsrc/decorate/hexen/hexendecorations.txt b/wadsrc/static/actors/hexen/hexendecorations.txt similarity index 100% rename from wadsrc/decorate/hexen/hexendecorations.txt rename to wadsrc/static/actors/hexen/hexendecorations.txt diff --git a/wadsrc/decorate/hexen/hexenkeys.txt b/wadsrc/static/actors/hexen/hexenkeys.txt similarity index 100% rename from wadsrc/decorate/hexen/hexenkeys.txt rename to wadsrc/static/actors/hexen/hexenkeys.txt diff --git a/wadsrc/decorate/hexen/hexenspecialdecs.txt b/wadsrc/static/actors/hexen/hexenspecialdecs.txt similarity index 100% rename from wadsrc/decorate/hexen/hexenspecialdecs.txt rename to wadsrc/static/actors/hexen/hexenspecialdecs.txt diff --git a/wadsrc/decorate/hexen/mageplayer.txt b/wadsrc/static/actors/hexen/mageplayer.txt similarity index 100% rename from wadsrc/decorate/hexen/mageplayer.txt rename to wadsrc/static/actors/hexen/mageplayer.txt diff --git a/wadsrc/decorate/hexen/mana.txt b/wadsrc/static/actors/hexen/mana.txt similarity index 100% rename from wadsrc/decorate/hexen/mana.txt rename to wadsrc/static/actors/hexen/mana.txt diff --git a/wadsrc/decorate/hexen/puzzleitems.txt b/wadsrc/static/actors/hexen/puzzleitems.txt similarity index 100% rename from wadsrc/decorate/hexen/puzzleitems.txt rename to wadsrc/static/actors/hexen/puzzleitems.txt diff --git a/wadsrc/decorate/hexen/scriptprojectiles.txt b/wadsrc/static/actors/hexen/scriptprojectiles.txt similarity index 100% rename from wadsrc/decorate/hexen/scriptprojectiles.txt rename to wadsrc/static/actors/hexen/scriptprojectiles.txt diff --git a/wadsrc/decorate/hexen/speedboots.txt b/wadsrc/static/actors/hexen/speedboots.txt similarity index 100% rename from wadsrc/decorate/hexen/speedboots.txt rename to wadsrc/static/actors/hexen/speedboots.txt diff --git a/wadsrc/decorate/nativeclasses.txt b/wadsrc/static/actors/nativeclasses.txt similarity index 100% rename from wadsrc/decorate/nativeclasses.txt rename to wadsrc/static/actors/nativeclasses.txt diff --git a/wadsrc/decorate/raven/artiegg.txt b/wadsrc/static/actors/raven/artiegg.txt similarity index 100% rename from wadsrc/decorate/raven/artiegg.txt rename to wadsrc/static/actors/raven/artiegg.txt diff --git a/wadsrc/decorate/raven/ravenambient.txt b/wadsrc/static/actors/raven/ravenambient.txt similarity index 100% rename from wadsrc/decorate/raven/ravenambient.txt rename to wadsrc/static/actors/raven/ravenambient.txt diff --git a/wadsrc/decorate/raven/ravenartifacts.txt b/wadsrc/static/actors/raven/ravenartifacts.txt similarity index 100% rename from wadsrc/decorate/raven/ravenartifacts.txt rename to wadsrc/static/actors/raven/ravenartifacts.txt diff --git a/wadsrc/decorate/raven/ravenhealth.txt b/wadsrc/static/actors/raven/ravenhealth.txt similarity index 100% rename from wadsrc/decorate/raven/ravenhealth.txt rename to wadsrc/static/actors/raven/ravenhealth.txt diff --git a/wadsrc/decorate/shared/blood.txt b/wadsrc/static/actors/shared/blood.txt similarity index 100% rename from wadsrc/decorate/shared/blood.txt rename to wadsrc/static/actors/shared/blood.txt diff --git a/wadsrc/decorate/shared/botstuff.txt b/wadsrc/static/actors/shared/botstuff.txt similarity index 100% rename from wadsrc/decorate/shared/botstuff.txt rename to wadsrc/static/actors/shared/botstuff.txt diff --git a/wadsrc/decorate/shared/debris.txt b/wadsrc/static/actors/shared/debris.txt similarity index 100% rename from wadsrc/decorate/shared/debris.txt rename to wadsrc/static/actors/shared/debris.txt diff --git a/wadsrc/decorate/shared/fountain.txt b/wadsrc/static/actors/shared/fountain.txt similarity index 100% rename from wadsrc/decorate/shared/fountain.txt rename to wadsrc/static/actors/shared/fountain.txt diff --git a/wadsrc/decorate/shared/pickups.txt b/wadsrc/static/actors/shared/pickups.txt similarity index 100% rename from wadsrc/decorate/shared/pickups.txt rename to wadsrc/static/actors/shared/pickups.txt diff --git a/wadsrc/decorate/shared/sharedmisc.txt b/wadsrc/static/actors/shared/sharedmisc.txt similarity index 100% rename from wadsrc/decorate/shared/sharedmisc.txt rename to wadsrc/static/actors/shared/sharedmisc.txt diff --git a/wadsrc/decorate/shared/soundsequence.txt b/wadsrc/static/actors/shared/soundsequence.txt similarity index 100% rename from wadsrc/decorate/shared/soundsequence.txt rename to wadsrc/static/actors/shared/soundsequence.txt diff --git a/wadsrc/decorate/shared/splashes.txt b/wadsrc/static/actors/shared/splashes.txt similarity index 100% rename from wadsrc/decorate/shared/splashes.txt rename to wadsrc/static/actors/shared/splashes.txt diff --git a/wadsrc/decorate/strife/beggars.txt b/wadsrc/static/actors/strife/beggars.txt similarity index 100% rename from wadsrc/decorate/strife/beggars.txt rename to wadsrc/static/actors/strife/beggars.txt diff --git a/wadsrc/decorate/strife/merchants.txt b/wadsrc/static/actors/strife/merchants.txt similarity index 100% rename from wadsrc/decorate/strife/merchants.txt rename to wadsrc/static/actors/strife/merchants.txt diff --git a/wadsrc/decorate/strife/peasants.txt b/wadsrc/static/actors/strife/peasants.txt similarity index 100% rename from wadsrc/decorate/strife/peasants.txt rename to wadsrc/static/actors/strife/peasants.txt diff --git a/wadsrc/decorate/strife/questitems.txt b/wadsrc/static/actors/strife/questitems.txt similarity index 100% rename from wadsrc/decorate/strife/questitems.txt rename to wadsrc/static/actors/strife/questitems.txt diff --git a/wadsrc/decorate/strife/ratbuddy.txt b/wadsrc/static/actors/strife/ratbuddy.txt similarity index 100% rename from wadsrc/decorate/strife/ratbuddy.txt rename to wadsrc/static/actors/strife/ratbuddy.txt diff --git a/wadsrc/decorate/strife/strifeammo.txt b/wadsrc/static/actors/strife/strifeammo.txt similarity index 100% rename from wadsrc/decorate/strife/strifeammo.txt rename to wadsrc/static/actors/strife/strifeammo.txt diff --git a/wadsrc/decorate/strife/strifearmor.txt b/wadsrc/static/actors/strife/strifearmor.txt similarity index 100% rename from wadsrc/decorate/strife/strifearmor.txt rename to wadsrc/static/actors/strife/strifearmor.txt diff --git a/wadsrc/decorate/strife/strifebishop.txt b/wadsrc/static/actors/strife/strifebishop.txt similarity index 100% rename from wadsrc/decorate/strife/strifebishop.txt rename to wadsrc/static/actors/strife/strifebishop.txt diff --git a/wadsrc/decorate/strife/strifeitems.txt b/wadsrc/static/actors/strife/strifeitems.txt similarity index 100% rename from wadsrc/decorate/strife/strifeitems.txt rename to wadsrc/static/actors/strife/strifeitems.txt diff --git a/wadsrc/decorate/strife/strifekeys.txt b/wadsrc/static/actors/strife/strifekeys.txt similarity index 100% rename from wadsrc/decorate/strife/strifekeys.txt rename to wadsrc/static/actors/strife/strifekeys.txt diff --git a/wadsrc/decorate/strife/strifeplayer.txt b/wadsrc/static/actors/strife/strifeplayer.txt similarity index 100% rename from wadsrc/decorate/strife/strifeplayer.txt rename to wadsrc/static/actors/strife/strifeplayer.txt diff --git a/wadsrc/decorate/strife/strifestuff.txt b/wadsrc/static/actors/strife/strifestuff.txt similarity index 100% rename from wadsrc/decorate/strife/strifestuff.txt rename to wadsrc/static/actors/strife/strifestuff.txt diff --git a/wadsrc/decorate/strife/zombie.txt b/wadsrc/static/actors/strife/zombie.txt similarity index 100% rename from wadsrc/decorate/strife/zombie.txt rename to wadsrc/static/actors/strife/zombie.txt diff --git a/wadsrc/althudcf.txt b/wadsrc/static/althudcf.txt similarity index 100% rename from wadsrc/althudcf.txt rename to wadsrc/static/althudcf.txt diff --git a/wadsrc/animated.lmp b/wadsrc/static/animated.lmp similarity index 100% rename from wadsrc/animated.lmp rename to wadsrc/static/animated.lmp diff --git a/wadsrc/animdefs.txt b/wadsrc/static/animdefs.txt similarity index 100% rename from wadsrc/animdefs.txt rename to wadsrc/static/animdefs.txt diff --git a/wadsrc/confont.lmp b/wadsrc/static/confont.lmp similarity index 100% rename from wadsrc/confont.lmp rename to wadsrc/static/confont.lmp diff --git a/wadsrc/dbigfont.lmp b/wadsrc/static/dbigfont.lmp similarity index 100% rename from wadsrc/dbigfont.lmp rename to wadsrc/static/dbigfont.lmp diff --git a/wadsrc/decals/decaldef.txt b/wadsrc/static/decaldef.txt similarity index 100% rename from wadsrc/decals/decaldef.txt rename to wadsrc/static/decaldef.txt diff --git a/wadsrc/decorate/decorate.txt b/wadsrc/static/decorate.txt similarity index 100% rename from wadsrc/decorate/decorate.txt rename to wadsrc/static/decorate.txt diff --git a/wadsrc/fontdefs.txt b/wadsrc/static/fontdefs.txt similarity index 100% rename from wadsrc/fontdefs.txt rename to wadsrc/static/fontdefs.txt diff --git a/wadsrc/badpatch.lmp b/wadsrc/static/graphics/-badpatc.lmp similarity index 100% rename from wadsrc/badpatch.lmp rename to wadsrc/static/graphics/-badpatc.lmp diff --git a/wadsrc/artibox.png b/wadsrc/static/graphics/artibox.png similarity index 100% rename from wadsrc/artibox.png rename to wadsrc/static/graphics/artibox.png diff --git a/wadsrc/decals/bal7scr1.png b/wadsrc/static/graphics/bal7scr1.png similarity index 100% rename from wadsrc/decals/bal7scr1.png rename to wadsrc/static/graphics/bal7scr1.png diff --git a/wadsrc/decals/bal7scr2.png b/wadsrc/static/graphics/bal7scr2.png similarity index 100% rename from wadsrc/decals/bal7scr2.png rename to wadsrc/static/graphics/bal7scr2.png diff --git a/wadsrc/decals/bfglite1.png b/wadsrc/static/graphics/bfglite1.png similarity index 100% rename from wadsrc/decals/bfglite1.png rename to wadsrc/static/graphics/bfglite1.png diff --git a/wadsrc/decals/bfglite2.png b/wadsrc/static/graphics/bfglite2.png similarity index 100% rename from wadsrc/decals/bfglite2.png rename to wadsrc/static/graphics/bfglite2.png diff --git a/wadsrc/decals/bfgscrc1.png b/wadsrc/static/graphics/bfgscrc1.png similarity index 100% rename from wadsrc/decals/bfgscrc1.png rename to wadsrc/static/graphics/bfgscrc1.png diff --git a/wadsrc/decals/bfgscrc2.png b/wadsrc/static/graphics/bfgscrc2.png similarity index 100% rename from wadsrc/decals/bfgscrc2.png rename to wadsrc/static/graphics/bfgscrc2.png diff --git a/wadsrc/decals/blast1.png b/wadsrc/static/graphics/blast1.png similarity index 100% rename from wadsrc/decals/blast1.png rename to wadsrc/static/graphics/blast1.png diff --git a/wadsrc/decals/bsmear1.png b/wadsrc/static/graphics/bsmear1.png similarity index 100% rename from wadsrc/decals/bsmear1.png rename to wadsrc/static/graphics/bsmear1.png diff --git a/wadsrc/decals/bsmear2.png b/wadsrc/static/graphics/bsmear2.png similarity index 100% rename from wadsrc/decals/bsmear2.png rename to wadsrc/static/graphics/bsmear2.png diff --git a/wadsrc/decals/bsplat1.png b/wadsrc/static/graphics/bsplat1.png similarity index 100% rename from wadsrc/decals/bsplat1.png rename to wadsrc/static/graphics/bsplat1.png diff --git a/wadsrc/decals/bsplat2.png b/wadsrc/static/graphics/bsplat2.png similarity index 100% rename from wadsrc/decals/bsplat2.png rename to wadsrc/static/graphics/bsplat2.png diff --git a/wadsrc/decals/bsplat3.png b/wadsrc/static/graphics/bsplat3.png similarity index 100% rename from wadsrc/decals/bsplat3.png rename to wadsrc/static/graphics/bsplat3.png diff --git a/wadsrc/decals/bsplat4.png b/wadsrc/static/graphics/bsplat4.png similarity index 100% rename from wadsrc/decals/bsplat4.png rename to wadsrc/static/graphics/bsplat4.png diff --git a/wadsrc/decals/bsplat5.png b/wadsrc/static/graphics/bsplat5.png similarity index 100% rename from wadsrc/decals/bsplat5.png rename to wadsrc/static/graphics/bsplat5.png diff --git a/wadsrc/decals/bsplat6.png b/wadsrc/static/graphics/bsplat6.png similarity index 100% rename from wadsrc/decals/bsplat6.png rename to wadsrc/static/graphics/bsplat6.png diff --git a/wadsrc/decals/bsplat7.png b/wadsrc/static/graphics/bsplat7.png similarity index 100% rename from wadsrc/decals/bsplat7.png rename to wadsrc/static/graphics/bsplat7.png diff --git a/wadsrc/decals/cbalscr1.png b/wadsrc/static/graphics/cbalscr1.png similarity index 100% rename from wadsrc/decals/cbalscr1.png rename to wadsrc/static/graphics/cbalscr1.png diff --git a/wadsrc/decals/cbalscr2.png b/wadsrc/static/graphics/cbalscr2.png similarity index 100% rename from wadsrc/decals/cbalscr2.png rename to wadsrc/static/graphics/cbalscr2.png diff --git a/wadsrc/decals/cbowmark.png b/wadsrc/static/graphics/cbowmark.png similarity index 100% rename from wadsrc/decals/cbowmark.png rename to wadsrc/static/graphics/cbowmark.png diff --git a/wadsrc/decals/chip1.png b/wadsrc/static/graphics/chip1.png similarity index 100% rename from wadsrc/decals/chip1.png rename to wadsrc/static/graphics/chip1.png diff --git a/wadsrc/decals/chip2.png b/wadsrc/static/graphics/chip2.png similarity index 100% rename from wadsrc/decals/chip2.png rename to wadsrc/static/graphics/chip2.png diff --git a/wadsrc/decals/chip3.png b/wadsrc/static/graphics/chip3.png similarity index 100% rename from wadsrc/decals/chip3.png rename to wadsrc/static/graphics/chip3.png diff --git a/wadsrc/decals/chip4.png b/wadsrc/static/graphics/chip4.png similarity index 100% rename from wadsrc/decals/chip4.png rename to wadsrc/static/graphics/chip4.png diff --git a/wadsrc/decals/chip5.png b/wadsrc/static/graphics/chip5.png similarity index 100% rename from wadsrc/decals/chip5.png rename to wadsrc/static/graphics/chip5.png diff --git a/wadsrc/clerface.lmp b/wadsrc/static/graphics/clerface.lmp similarity index 100% rename from wadsrc/clerface.lmp rename to wadsrc/static/graphics/clerface.lmp diff --git a/wadsrc/fiteface.lmp b/wadsrc/static/graphics/fiteface.lmp similarity index 100% rename from wadsrc/fiteface.lmp rename to wadsrc/static/graphics/fiteface.lmp diff --git a/wadsrc/fonta164.lmp b/wadsrc/static/graphics/fonta164.lmp similarity index 100% rename from wadsrc/fonta164.lmp rename to wadsrc/static/graphics/fonta164.lmp diff --git a/wadsrc/fonta165.lmp b/wadsrc/static/graphics/fonta165.lmp similarity index 100% rename from wadsrc/fonta165.lmp rename to wadsrc/static/graphics/fonta165.lmp diff --git a/wadsrc/fonta182.lmp b/wadsrc/static/graphics/fonta182.lmp similarity index 100% rename from wadsrc/fonta182.lmp rename to wadsrc/static/graphics/fonta182.lmp diff --git a/wadsrc/fonta188.lmp b/wadsrc/static/graphics/fonta188.lmp similarity index 100% rename from wadsrc/fonta188.lmp rename to wadsrc/static/graphics/fonta188.lmp diff --git a/wadsrc/fonta191.lmp b/wadsrc/static/graphics/fonta191.lmp similarity index 100% rename from wadsrc/fonta191.lmp rename to wadsrc/static/graphics/fonta191.lmp diff --git a/wadsrc/fonta60.lmp b/wadsrc/static/graphics/fonta60.lmp similarity index 100% rename from wadsrc/fonta60.lmp rename to wadsrc/static/graphics/fonta60.lmp diff --git a/wadsrc/fonta61.lmp b/wadsrc/static/graphics/fonta61.lmp similarity index 100% rename from wadsrc/fonta61.lmp rename to wadsrc/static/graphics/fonta61.lmp diff --git a/wadsrc/fonta62.lmp b/wadsrc/static/graphics/fonta62.lmp similarity index 100% rename from wadsrc/fonta62.lmp rename to wadsrc/static/graphics/fonta62.lmp diff --git a/wadsrc/fonta63.lmp b/wadsrc/static/graphics/fonta63.lmp similarity index 100% rename from wadsrc/fonta63.lmp rename to wadsrc/static/graphics/fonta63.lmp diff --git a/wadsrc/hamoback.png b/wadsrc/static/graphics/hamoback.png similarity index 100% rename from wadsrc/hamoback.png rename to wadsrc/static/graphics/hamoback.png diff --git a/wadsrc/invgeml1.png b/wadsrc/static/graphics/invgeml1.png similarity index 100% rename from wadsrc/invgeml1.png rename to wadsrc/static/graphics/invgeml1.png diff --git a/wadsrc/invgeml2.png b/wadsrc/static/graphics/invgeml2.png similarity index 100% rename from wadsrc/invgeml2.png rename to wadsrc/static/graphics/invgeml2.png diff --git a/wadsrc/invgemr1.png b/wadsrc/static/graphics/invgemr1.png similarity index 100% rename from wadsrc/invgemr1.png rename to wadsrc/static/graphics/invgemr1.png diff --git a/wadsrc/invgemr2.png b/wadsrc/static/graphics/invgemr2.png similarity index 100% rename from wadsrc/invgemr2.png rename to wadsrc/static/graphics/invgemr2.png diff --git a/wadsrc/mageface.lmp b/wadsrc/static/graphics/mageface.lmp similarity index 100% rename from wadsrc/mageface.lmp rename to wadsrc/static/graphics/mageface.lmp diff --git a/wadsrc/decals/plasma1.png b/wadsrc/static/graphics/plasma1.png similarity index 100% rename from wadsrc/decals/plasma1.png rename to wadsrc/static/graphics/plasma1.png diff --git a/wadsrc/decals/plasma2.png b/wadsrc/static/graphics/plasma2.png similarity index 100% rename from wadsrc/decals/plasma2.png rename to wadsrc/static/graphics/plasma2.png diff --git a/wadsrc/decals/scorch1.png b/wadsrc/static/graphics/scorch1.png similarity index 100% rename from wadsrc/decals/scorch1.png rename to wadsrc/static/graphics/scorch1.png diff --git a/wadsrc/selectbo.png b/wadsrc/static/graphics/selectbo.png similarity index 100% rename from wadsrc/selectbo.png rename to wadsrc/static/graphics/selectbo.png diff --git a/wadsrc/stcfn196.lmp b/wadsrc/static/graphics/stcfn196.lmp similarity index 100% rename from wadsrc/stcfn196.lmp rename to wadsrc/static/graphics/stcfn196.lmp diff --git a/wadsrc/stcfn197.lmp b/wadsrc/static/graphics/stcfn197.lmp similarity index 100% rename from wadsrc/stcfn197.lmp rename to wadsrc/static/graphics/stcfn197.lmp diff --git a/wadsrc/stcfn214.lmp b/wadsrc/static/graphics/stcfn214.lmp similarity index 100% rename from wadsrc/stcfn214.lmp rename to wadsrc/static/graphics/stcfn214.lmp diff --git a/wadsrc/stcfn220.lmp b/wadsrc/static/graphics/stcfn220.lmp similarity index 100% rename from wadsrc/stcfn220.lmp rename to wadsrc/static/graphics/stcfn220.lmp diff --git a/wadsrc/stcfn223.lmp b/wadsrc/static/graphics/stcfn223.lmp similarity index 100% rename from wadsrc/stcfn223.lmp rename to wadsrc/static/graphics/stcfn223.lmp diff --git a/wadsrc/stfbany.lmp b/wadsrc/static/graphics/stfbany.lmp similarity index 100% rename from wadsrc/stfbany.lmp rename to wadsrc/static/graphics/stfbany.lmp diff --git a/wadsrc/stkeys6.lmp b/wadsrc/static/graphics/stkeys6.lmp similarity index 100% rename from wadsrc/stkeys6.lmp rename to wadsrc/static/graphics/stkeys6.lmp diff --git a/wadsrc/stkeys7.lmp b/wadsrc/static/graphics/stkeys7.lmp similarity index 100% rename from wadsrc/stkeys7.lmp rename to wadsrc/static/graphics/stkeys7.lmp diff --git a/wadsrc/stkeys8.lmp b/wadsrc/static/graphics/stkeys8.lmp similarity index 100% rename from wadsrc/stkeys8.lmp rename to wadsrc/static/graphics/stkeys8.lmp diff --git a/wadsrc/stpbany.lmp b/wadsrc/static/graphics/stpbany.lmp similarity index 100% rename from wadsrc/stpbany.lmp rename to wadsrc/static/graphics/stpbany.lmp diff --git a/wadsrc/xhairb1.imgz b/wadsrc/static/graphics/xhairb1.imgz similarity index 100% rename from wadsrc/xhairb1.imgz rename to wadsrc/static/graphics/xhairb1.imgz diff --git a/wadsrc/xhairb2.png b/wadsrc/static/graphics/xhairb2.png similarity index 100% rename from wadsrc/xhairb2.png rename to wadsrc/static/graphics/xhairb2.png diff --git a/wadsrc/xhairb3.imgz b/wadsrc/static/graphics/xhairb3.imgz similarity index 100% rename from wadsrc/xhairb3.imgz rename to wadsrc/static/graphics/xhairb3.imgz diff --git a/wadsrc/xhairb4.imgz b/wadsrc/static/graphics/xhairb4.imgz similarity index 100% rename from wadsrc/xhairb4.imgz rename to wadsrc/static/graphics/xhairb4.imgz diff --git a/wadsrc/xhairb5.imgz b/wadsrc/static/graphics/xhairb5.imgz similarity index 100% rename from wadsrc/xhairb5.imgz rename to wadsrc/static/graphics/xhairb5.imgz diff --git a/wadsrc/xhairb6.imgz b/wadsrc/static/graphics/xhairb6.imgz similarity index 100% rename from wadsrc/xhairb6.imgz rename to wadsrc/static/graphics/xhairb6.imgz diff --git a/wadsrc/xhairb7.imgz b/wadsrc/static/graphics/xhairb7.imgz similarity index 100% rename from wadsrc/xhairb7.imgz rename to wadsrc/static/graphics/xhairb7.imgz diff --git a/wadsrc/xhairs1.imgz b/wadsrc/static/graphics/xhairs1.imgz similarity index 100% rename from wadsrc/xhairs1.imgz rename to wadsrc/static/graphics/xhairs1.imgz diff --git a/wadsrc/xhairs2.imgz b/wadsrc/static/graphics/xhairs2.imgz similarity index 100% rename from wadsrc/xhairs2.imgz rename to wadsrc/static/graphics/xhairs2.imgz diff --git a/wadsrc/xhairs3.imgz b/wadsrc/static/graphics/xhairs3.imgz similarity index 100% rename from wadsrc/xhairs3.imgz rename to wadsrc/static/graphics/xhairs3.imgz diff --git a/wadsrc/xhairs4.imgz b/wadsrc/static/graphics/xhairs4.imgz similarity index 100% rename from wadsrc/xhairs4.imgz rename to wadsrc/static/graphics/xhairs4.imgz diff --git a/wadsrc/xhairs5.imgz b/wadsrc/static/graphics/xhairs5.imgz similarity index 100% rename from wadsrc/xhairs5.imgz rename to wadsrc/static/graphics/xhairs5.imgz diff --git a/wadsrc/xhairs6.imgz b/wadsrc/static/graphics/xhairs6.imgz similarity index 100% rename from wadsrc/xhairs6.imgz rename to wadsrc/static/graphics/xhairs6.imgz diff --git a/wadsrc/xhairs7.imgz b/wadsrc/static/graphics/xhairs7.imgz similarity index 100% rename from wadsrc/xhairs7.imgz rename to wadsrc/static/graphics/xhairs7.imgz diff --git a/wadsrc/in_epi1.txt b/wadsrc/static/in_epi1.txt similarity index 100% rename from wadsrc/in_epi1.txt rename to wadsrc/static/in_epi1.txt diff --git a/wadsrc/in_epi2.txt b/wadsrc/static/in_epi2.txt similarity index 100% rename from wadsrc/in_epi2.txt rename to wadsrc/static/in_epi2.txt diff --git a/wadsrc/in_epi3.txt b/wadsrc/static/in_epi3.txt similarity index 100% rename from wadsrc/in_epi3.txt rename to wadsrc/static/in_epi3.txt diff --git a/wadsrc/in_htc1.txt b/wadsrc/static/in_htc1.txt similarity index 100% rename from wadsrc/in_htc1.txt rename to wadsrc/static/in_htc1.txt diff --git a/wadsrc/in_htc2.txt b/wadsrc/static/in_htc2.txt similarity index 100% rename from wadsrc/in_htc2.txt rename to wadsrc/static/in_htc2.txt diff --git a/wadsrc/in_htc3.txt b/wadsrc/static/in_htc3.txt similarity index 100% rename from wadsrc/in_htc3.txt rename to wadsrc/static/in_htc3.txt diff --git a/wadsrc/indexfont.fon b/wadsrc/static/indexfont.fon similarity index 100% rename from wadsrc/indexfont.fon rename to wadsrc/static/indexfont.fon diff --git a/wadsrc/languages/english-us.txt b/wadsrc/static/language.enu similarity index 100% rename from wadsrc/languages/english-us.txt rename to wadsrc/static/language.enu diff --git a/wadsrc/languages/french.txt b/wadsrc/static/language.fr similarity index 100% rename from wadsrc/languages/french.txt rename to wadsrc/static/language.fr diff --git a/wadsrc/languages/italian.txt b/wadsrc/static/language.ita similarity index 100% rename from wadsrc/languages/italian.txt rename to wadsrc/static/language.ita diff --git a/wadsrc/lockdefs.txt b/wadsrc/static/lockdefs.txt similarity index 100% rename from wadsrc/lockdefs.txt rename to wadsrc/static/lockdefs.txt diff --git a/wadsrc/mapinfo/doom1.txt b/wadsrc/static/mapinfo/doom1.txt similarity index 100% rename from wadsrc/mapinfo/doom1.txt rename to wadsrc/static/mapinfo/doom1.txt diff --git a/wadsrc/mapinfo/doom2.txt b/wadsrc/static/mapinfo/doom2.txt similarity index 100% rename from wadsrc/mapinfo/doom2.txt rename to wadsrc/static/mapinfo/doom2.txt diff --git a/wadsrc/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt similarity index 100% rename from wadsrc/mapinfo/doomcommon.txt rename to wadsrc/static/mapinfo/doomcommon.txt diff --git a/wadsrc/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt similarity index 100% rename from wadsrc/mapinfo/heretic.txt rename to wadsrc/static/mapinfo/heretic.txt diff --git a/wadsrc/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt similarity index 100% rename from wadsrc/mapinfo/hexen.txt rename to wadsrc/static/mapinfo/hexen.txt diff --git a/wadsrc/mapinfo/plutonia.txt b/wadsrc/static/mapinfo/plutonia.txt similarity index 100% rename from wadsrc/mapinfo/plutonia.txt rename to wadsrc/static/mapinfo/plutonia.txt diff --git a/wadsrc/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt similarity index 100% rename from wadsrc/mapinfo/strife.txt rename to wadsrc/static/mapinfo/strife.txt diff --git a/wadsrc/mapinfo/tnt.txt b/wadsrc/static/mapinfo/tnt.txt similarity index 100% rename from wadsrc/mapinfo/tnt.txt rename to wadsrc/static/mapinfo/tnt.txt diff --git a/wadsrc/reverbs.txt b/wadsrc/static/reverbs.txt similarity index 100% rename from wadsrc/reverbs.txt rename to wadsrc/static/reverbs.txt diff --git a/wadsrc/sbarinfo.txt b/wadsrc/static/sbarinfo.txt similarity index 100% rename from wadsrc/sbarinfo.txt rename to wadsrc/static/sbarinfo.txt diff --git a/wadsrc/sbigfont.lmp b/wadsrc/static/sbigfont.lmp similarity index 100% rename from wadsrc/sbigfont.lmp rename to wadsrc/static/sbigfont.lmp diff --git a/wadsrc/sndinfo.txt b/wadsrc/static/sndinfo.txt similarity index 100% rename from wadsrc/sndinfo.txt rename to wadsrc/static/sndinfo.txt diff --git a/wadsrc/sndseq.txt b/wadsrc/static/sndseq.txt similarity index 100% rename from wadsrc/sndseq.txt rename to wadsrc/static/sndseq.txt diff --git a/wadsrc/dsempty.lmp b/wadsrc/static/sounds/dsempty.lmp similarity index 100% rename from wadsrc/dsempty.lmp rename to wadsrc/static/sounds/dsempty.lmp diff --git a/wadsrc/icebreak.flac b/wadsrc/static/sounds/icebreak.flac similarity index 100% rename from wadsrc/icebreak.flac rename to wadsrc/static/sounds/icebreak.flac diff --git a/wadsrc/icedeath.flac b/wadsrc/static/sounds/icedeath.flac similarity index 100% rename from wadsrc/icedeath.flac rename to wadsrc/static/sounds/icedeath.flac diff --git a/wadsrc/quake.flac b/wadsrc/static/sounds/quake.flac similarity index 100% rename from wadsrc/quake.flac rename to wadsrc/static/sounds/quake.flac diff --git a/wadsrc/railgunfire.flac b/wadsrc/static/sounds/railgunfire.flac similarity index 100% rename from wadsrc/railgunfire.flac rename to wadsrc/static/sounds/railgunfire.flac diff --git a/wadsrc/secret.flac b/wadsrc/static/sounds/secret.flac similarity index 100% rename from wadsrc/secret.flac rename to wadsrc/static/sounds/secret.flac diff --git a/wadsrc/spark1.flac b/wadsrc/static/sounds/spark1.flac similarity index 100% rename from wadsrc/spark1.flac rename to wadsrc/static/sounds/spark1.flac diff --git a/wadsrc/spark2.flac b/wadsrc/static/sounds/spark2.flac similarity index 100% rename from wadsrc/spark2.flac rename to wadsrc/static/sounds/spark2.flac diff --git a/wadsrc/spark3.flac b/wadsrc/static/sounds/spark3.flac similarity index 100% rename from wadsrc/spark3.flac rename to wadsrc/static/sounds/spark3.flac diff --git a/wadsrc/spaldoom.lmp b/wadsrc/static/spaldoom.lmp similarity index 100% rename from wadsrc/spaldoom.lmp rename to wadsrc/static/spaldoom.lmp diff --git a/wadsrc/spalhtic.lmp b/wadsrc/static/spalhtic.lmp similarity index 100% rename from wadsrc/spalhtic.lmp rename to wadsrc/static/spalhtic.lmp diff --git a/wadsrc/amrka0.png b/wadsrc/static/sprites/amrka0.png similarity index 100% rename from wadsrc/amrka0.png rename to wadsrc/static/sprites/amrka0.png diff --git a/wadsrc/iceca0.png b/wadsrc/static/sprites/iceca0.png similarity index 100% rename from wadsrc/iceca0.png rename to wadsrc/static/sprites/iceca0.png diff --git a/wadsrc/icecb0.png b/wadsrc/static/sprites/icecb0.png similarity index 100% rename from wadsrc/icecb0.png rename to wadsrc/static/sprites/icecb0.png diff --git a/wadsrc/icecc0.png b/wadsrc/static/sprites/icecc0.png similarity index 100% rename from wadsrc/icecc0.png rename to wadsrc/static/sprites/icecc0.png diff --git a/wadsrc/icecd0.png b/wadsrc/static/sprites/icecd0.png similarity index 100% rename from wadsrc/icecd0.png rename to wadsrc/static/sprites/icecd0.png diff --git a/wadsrc/pista0.png b/wadsrc/static/sprites/pista0.png similarity index 100% rename from wadsrc/pista0.png rename to wadsrc/static/sprites/pista0.png diff --git a/wadsrc/crouch/plyca1.lmp b/wadsrc/static/sprites/plyc/plyca1.lmp similarity index 100% rename from wadsrc/crouch/plyca1.lmp rename to wadsrc/static/sprites/plyc/plyca1.lmp diff --git a/wadsrc/crouch/plyca2a8.lmp b/wadsrc/static/sprites/plyc/plyca2a8.lmp similarity index 100% rename from wadsrc/crouch/plyca2a8.lmp rename to wadsrc/static/sprites/plyc/plyca2a8.lmp diff --git a/wadsrc/crouch/plyca3a7.lmp b/wadsrc/static/sprites/plyc/plyca3a7.lmp similarity index 100% rename from wadsrc/crouch/plyca3a7.lmp rename to wadsrc/static/sprites/plyc/plyca3a7.lmp diff --git a/wadsrc/crouch/plyca4a6.lmp b/wadsrc/static/sprites/plyc/plyca4a6.lmp similarity index 100% rename from wadsrc/crouch/plyca4a6.lmp rename to wadsrc/static/sprites/plyc/plyca4a6.lmp diff --git a/wadsrc/crouch/plyca5.lmp b/wadsrc/static/sprites/plyc/plyca5.lmp similarity index 100% rename from wadsrc/crouch/plyca5.lmp rename to wadsrc/static/sprites/plyc/plyca5.lmp diff --git a/wadsrc/crouch/plycb1.lmp b/wadsrc/static/sprites/plyc/plycb1.lmp similarity index 100% rename from wadsrc/crouch/plycb1.lmp rename to wadsrc/static/sprites/plyc/plycb1.lmp diff --git a/wadsrc/crouch/plycb2b8.lmp b/wadsrc/static/sprites/plyc/plycb2b8.lmp similarity index 100% rename from wadsrc/crouch/plycb2b8.lmp rename to wadsrc/static/sprites/plyc/plycb2b8.lmp diff --git a/wadsrc/crouch/plycb3b7.lmp b/wadsrc/static/sprites/plyc/plycb3b7.lmp similarity index 100% rename from wadsrc/crouch/plycb3b7.lmp rename to wadsrc/static/sprites/plyc/plycb3b7.lmp diff --git a/wadsrc/crouch/plycb4b6.lmp b/wadsrc/static/sprites/plyc/plycb4b6.lmp similarity index 100% rename from wadsrc/crouch/plycb4b6.lmp rename to wadsrc/static/sprites/plyc/plycb4b6.lmp diff --git a/wadsrc/crouch/plycb5.lmp b/wadsrc/static/sprites/plyc/plycb5.lmp similarity index 100% rename from wadsrc/crouch/plycb5.lmp rename to wadsrc/static/sprites/plyc/plycb5.lmp diff --git a/wadsrc/crouch/plycc1.lmp b/wadsrc/static/sprites/plyc/plycc1.lmp similarity index 100% rename from wadsrc/crouch/plycc1.lmp rename to wadsrc/static/sprites/plyc/plycc1.lmp diff --git a/wadsrc/crouch/plycc2c8.lmp b/wadsrc/static/sprites/plyc/plycc2c8.lmp similarity index 100% rename from wadsrc/crouch/plycc2c8.lmp rename to wadsrc/static/sprites/plyc/plycc2c8.lmp diff --git a/wadsrc/crouch/plycc3c7.lmp b/wadsrc/static/sprites/plyc/plycc3c7.lmp similarity index 100% rename from wadsrc/crouch/plycc3c7.lmp rename to wadsrc/static/sprites/plyc/plycc3c7.lmp diff --git a/wadsrc/crouch/plycc4c6.lmp b/wadsrc/static/sprites/plyc/plycc4c6.lmp similarity index 100% rename from wadsrc/crouch/plycc4c6.lmp rename to wadsrc/static/sprites/plyc/plycc4c6.lmp diff --git a/wadsrc/crouch/plycc5.lmp b/wadsrc/static/sprites/plyc/plycc5.lmp similarity index 100% rename from wadsrc/crouch/plycc5.lmp rename to wadsrc/static/sprites/plyc/plycc5.lmp diff --git a/wadsrc/crouch/plycd1.lmp b/wadsrc/static/sprites/plyc/plycd1.lmp similarity index 100% rename from wadsrc/crouch/plycd1.lmp rename to wadsrc/static/sprites/plyc/plycd1.lmp diff --git a/wadsrc/crouch/plycd2d8.lmp b/wadsrc/static/sprites/plyc/plycd2d8.lmp similarity index 100% rename from wadsrc/crouch/plycd2d8.lmp rename to wadsrc/static/sprites/plyc/plycd2d8.lmp diff --git a/wadsrc/crouch/plycd3d7.lmp b/wadsrc/static/sprites/plyc/plycd3d7.lmp similarity index 100% rename from wadsrc/crouch/plycd3d7.lmp rename to wadsrc/static/sprites/plyc/plycd3d7.lmp diff --git a/wadsrc/crouch/plycd4d6.lmp b/wadsrc/static/sprites/plyc/plycd4d6.lmp similarity index 100% rename from wadsrc/crouch/plycd4d6.lmp rename to wadsrc/static/sprites/plyc/plycd4d6.lmp diff --git a/wadsrc/crouch/plycd5.lmp b/wadsrc/static/sprites/plyc/plycd5.lmp similarity index 100% rename from wadsrc/crouch/plycd5.lmp rename to wadsrc/static/sprites/plyc/plycd5.lmp diff --git a/wadsrc/crouch/plyce1.lmp b/wadsrc/static/sprites/plyc/plyce1.lmp similarity index 100% rename from wadsrc/crouch/plyce1.lmp rename to wadsrc/static/sprites/plyc/plyce1.lmp diff --git a/wadsrc/crouch/plyce2e8.lmp b/wadsrc/static/sprites/plyc/plyce2e8.lmp similarity index 100% rename from wadsrc/crouch/plyce2e8.lmp rename to wadsrc/static/sprites/plyc/plyce2e8.lmp diff --git a/wadsrc/crouch/plyce3e7.lmp b/wadsrc/static/sprites/plyc/plyce3e7.lmp similarity index 100% rename from wadsrc/crouch/plyce3e7.lmp rename to wadsrc/static/sprites/plyc/plyce3e7.lmp diff --git a/wadsrc/crouch/plyce4e6.lmp b/wadsrc/static/sprites/plyc/plyce4e6.lmp similarity index 100% rename from wadsrc/crouch/plyce4e6.lmp rename to wadsrc/static/sprites/plyc/plyce4e6.lmp diff --git a/wadsrc/crouch/plyce5.lmp b/wadsrc/static/sprites/plyc/plyce5.lmp similarity index 100% rename from wadsrc/crouch/plyce5.lmp rename to wadsrc/static/sprites/plyc/plyce5.lmp diff --git a/wadsrc/crouch/plycf1.lmp b/wadsrc/static/sprites/plyc/plycf1.lmp similarity index 100% rename from wadsrc/crouch/plycf1.lmp rename to wadsrc/static/sprites/plyc/plycf1.lmp diff --git a/wadsrc/crouch/plycf2f8.lmp b/wadsrc/static/sprites/plyc/plycf2f8.lmp similarity index 100% rename from wadsrc/crouch/plycf2f8.lmp rename to wadsrc/static/sprites/plyc/plycf2f8.lmp diff --git a/wadsrc/crouch/plycf3f7.lmp b/wadsrc/static/sprites/plyc/plycf3f7.lmp similarity index 100% rename from wadsrc/crouch/plycf3f7.lmp rename to wadsrc/static/sprites/plyc/plycf3f7.lmp diff --git a/wadsrc/crouch/plycf4f6.lmp b/wadsrc/static/sprites/plyc/plycf4f6.lmp similarity index 100% rename from wadsrc/crouch/plycf4f6.lmp rename to wadsrc/static/sprites/plyc/plycf4f6.lmp diff --git a/wadsrc/crouch/plycf5.lmp b/wadsrc/static/sprites/plyc/plycf5.lmp similarity index 100% rename from wadsrc/crouch/plycf5.lmp rename to wadsrc/static/sprites/plyc/plycf5.lmp diff --git a/wadsrc/crouch/plycg1.lmp b/wadsrc/static/sprites/plyc/plycg1.lmp similarity index 100% rename from wadsrc/crouch/plycg1.lmp rename to wadsrc/static/sprites/plyc/plycg1.lmp diff --git a/wadsrc/crouch/plycg2g8.lmp b/wadsrc/static/sprites/plyc/plycg2g8.lmp similarity index 100% rename from wadsrc/crouch/plycg2g8.lmp rename to wadsrc/static/sprites/plyc/plycg2g8.lmp diff --git a/wadsrc/crouch/plycg3g7.lmp b/wadsrc/static/sprites/plyc/plycg3g7.lmp similarity index 100% rename from wadsrc/crouch/plycg3g7.lmp rename to wadsrc/static/sprites/plyc/plycg3g7.lmp diff --git a/wadsrc/crouch/plycg4g6.lmp b/wadsrc/static/sprites/plyc/plycg4g6.lmp similarity index 100% rename from wadsrc/crouch/plycg4g6.lmp rename to wadsrc/static/sprites/plyc/plycg4g6.lmp diff --git a/wadsrc/crouch/plycg5.lmp b/wadsrc/static/sprites/plyc/plycg5.lmp similarity index 100% rename from wadsrc/crouch/plycg5.lmp rename to wadsrc/static/sprites/plyc/plycg5.lmp diff --git a/wadsrc/crouch/plych0.lmp b/wadsrc/static/sprites/plyc/plych0.lmp similarity index 100% rename from wadsrc/crouch/plych0.lmp rename to wadsrc/static/sprites/plyc/plych0.lmp diff --git a/wadsrc/crouch/plyci0.lmp b/wadsrc/static/sprites/plyc/plyci0.lmp similarity index 100% rename from wadsrc/crouch/plyci0.lmp rename to wadsrc/static/sprites/plyc/plyci0.lmp diff --git a/wadsrc/crouch/plycj0.lmp b/wadsrc/static/sprites/plyc/plycj0.lmp similarity index 100% rename from wadsrc/crouch/plycj0.lmp rename to wadsrc/static/sprites/plyc/plycj0.lmp diff --git a/wadsrc/crouch/plyck0.lmp b/wadsrc/static/sprites/plyc/plyck0.lmp similarity index 100% rename from wadsrc/crouch/plyck0.lmp rename to wadsrc/static/sprites/plyc/plyck0.lmp diff --git a/wadsrc/crouch/plycl0.lmp b/wadsrc/static/sprites/plyc/plycl0.lmp similarity index 100% rename from wadsrc/crouch/plycl0.lmp rename to wadsrc/static/sprites/plyc/plycl0.lmp diff --git a/wadsrc/crouch/plycm0.lmp b/wadsrc/static/sprites/plyc/plycm0.lmp similarity index 100% rename from wadsrc/crouch/plycm0.lmp rename to wadsrc/static/sprites/plyc/plycm0.lmp diff --git a/wadsrc/crouch/plycn0.lmp b/wadsrc/static/sprites/plyc/plycn0.lmp similarity index 100% rename from wadsrc/crouch/plycn0.lmp rename to wadsrc/static/sprites/plyc/plycn0.lmp diff --git a/wadsrc/crouch/plyco0.lmp b/wadsrc/static/sprites/plyc/plyco0.lmp similarity index 100% rename from wadsrc/crouch/plyco0.lmp rename to wadsrc/static/sprites/plyc/plyco0.lmp diff --git a/wadsrc/crouch/plycp0.lmp b/wadsrc/static/sprites/plyc/plycp0.lmp similarity index 100% rename from wadsrc/crouch/plycp0.lmp rename to wadsrc/static/sprites/plyc/plycp0.lmp diff --git a/wadsrc/crouch/plycq0.lmp b/wadsrc/static/sprites/plyc/plycq0.lmp similarity index 100% rename from wadsrc/crouch/plycq0.lmp rename to wadsrc/static/sprites/plyc/plycq0.lmp diff --git a/wadsrc/crouch/plycr0.lmp b/wadsrc/static/sprites/plyc/plycr0.lmp similarity index 100% rename from wadsrc/crouch/plycr0.lmp rename to wadsrc/static/sprites/plyc/plycr0.lmp diff --git a/wadsrc/crouch/plycs0.lmp b/wadsrc/static/sprites/plyc/plycs0.lmp similarity index 100% rename from wadsrc/crouch/plycs0.lmp rename to wadsrc/static/sprites/plyc/plycs0.lmp diff --git a/wadsrc/crouch/plyct0.lmp b/wadsrc/static/sprites/plyc/plyct0.lmp similarity index 100% rename from wadsrc/crouch/plyct0.lmp rename to wadsrc/static/sprites/plyc/plyct0.lmp diff --git a/wadsrc/crouch/plycu0.lmp b/wadsrc/static/sprites/plyc/plycu0.lmp similarity index 100% rename from wadsrc/crouch/plycu0.lmp rename to wadsrc/static/sprites/plyc/plycu0.lmp diff --git a/wadsrc/crouch/plycv0.lmp b/wadsrc/static/sprites/plyc/plycv0.lmp similarity index 100% rename from wadsrc/crouch/plycv0.lmp rename to wadsrc/static/sprites/plyc/plycv0.lmp diff --git a/wadsrc/crouch/plycw0.lmp b/wadsrc/static/sprites/plyc/plycw0.lmp similarity index 100% rename from wadsrc/crouch/plycw0.lmp rename to wadsrc/static/sprites/plyc/plycw0.lmp diff --git a/wadsrc/rsmka0.png b/wadsrc/static/sprites/rsmka0.png similarity index 100% rename from wadsrc/rsmka0.png rename to wadsrc/static/sprites/rsmka0.png diff --git a/wadsrc/rsmkb0.png b/wadsrc/static/sprites/rsmkb0.png similarity index 100% rename from wadsrc/rsmkb0.png rename to wadsrc/static/sprites/rsmkb0.png diff --git a/wadsrc/rsmkc0.png b/wadsrc/static/sprites/rsmkc0.png similarity index 100% rename from wadsrc/rsmkc0.png rename to wadsrc/static/sprites/rsmkc0.png diff --git a/wadsrc/rsmkd0.png b/wadsrc/static/sprites/rsmkd0.png similarity index 100% rename from wadsrc/rsmkd0.png rename to wadsrc/static/sprites/rsmkd0.png diff --git a/wadsrc/rsmke0.png b/wadsrc/static/sprites/rsmke0.png similarity index 100% rename from wadsrc/rsmke0.png rename to wadsrc/static/sprites/rsmke0.png diff --git a/wadsrc/tlgl.png b/wadsrc/static/sprites/tlgla0.png similarity index 100% rename from wadsrc/tlgl.png rename to wadsrc/static/sprites/tlgla0.png diff --git a/wadsrc/static/sprites/tlglb0.png b/wadsrc/static/sprites/tlglb0.png new file mode 100644 index 000000000..829a25526 Binary files /dev/null and b/wadsrc/static/sprites/tlglb0.png differ diff --git a/wadsrc/static/sprites/tlglc0.png b/wadsrc/static/sprites/tlglc0.png new file mode 100644 index 000000000..829a25526 Binary files /dev/null and b/wadsrc/static/sprites/tlglc0.png differ diff --git a/wadsrc/static/sprites/tlgld0.png b/wadsrc/static/sprites/tlgld0.png new file mode 100644 index 000000000..829a25526 Binary files /dev/null and b/wadsrc/static/sprites/tlgld0.png differ diff --git a/wadsrc/static/sprites/tlgle0.png b/wadsrc/static/sprites/tlgle0.png new file mode 100644 index 000000000..829a25526 Binary files /dev/null and b/wadsrc/static/sprites/tlgle0.png differ diff --git a/wadsrc/tnt1a0.png b/wadsrc/static/sprites/tnt1a0.png similarity index 100% rename from wadsrc/tnt1a0.png rename to wadsrc/static/sprites/tnt1a0.png diff --git a/wadsrc/unkna0.png b/wadsrc/static/sprites/unkna0.png similarity index 100% rename from wadsrc/unkna0.png rename to wadsrc/static/sprites/unkna0.png diff --git a/wadsrc/teaminfo.txt b/wadsrc/static/teaminfo.txt similarity index 100% rename from wadsrc/teaminfo.txt rename to wadsrc/static/teaminfo.txt diff --git a/wadsrc/terrain.txt b/wadsrc/static/terrain.txt similarity index 100% rename from wadsrc/terrain.txt rename to wadsrc/static/terrain.txt diff --git a/wadsrc/textcolors.txt b/wadsrc/static/textcolors.txt similarity index 100% rename from wadsrc/textcolors.txt rename to wadsrc/static/textcolors.txt diff --git a/wadsrc/noflat.png b/wadsrc/static/textures/-noflat-.png similarity index 100% rename from wadsrc/noflat.png rename to wadsrc/static/textures/-noflat-.png diff --git a/wadsrc/vga-rom.f16 b/wadsrc/static/vga-rom-font.16 similarity index 100% rename from wadsrc/vga-rom.f16 rename to wadsrc/static/vga-rom-font.16 diff --git a/wadsrc/x11r6rgb.txt b/wadsrc/static/x11r6rgb.txt similarity index 100% rename from wadsrc/x11r6rgb.txt rename to wadsrc/static/x11r6rgb.txt diff --git a/wadsrc/xhairs.txt b/wadsrc/static/xhairs.txt similarity index 100% rename from wadsrc/xhairs.txt rename to wadsrc/static/xhairs.txt diff --git a/wadsrc/xlat/base.txt b/wadsrc/static/xlat/base.txt similarity index 100% rename from wadsrc/xlat/base.txt rename to wadsrc/static/xlat/base.txt diff --git a/wadsrc/xlat/defines.i b/wadsrc/static/xlat/defines.i similarity index 100% rename from wadsrc/xlat/defines.i rename to wadsrc/static/xlat/defines.i diff --git a/wadsrc/xlat/doom.txt b/wadsrc/static/xlat/doom.txt similarity index 100% rename from wadsrc/xlat/doom.txt rename to wadsrc/static/xlat/doom.txt diff --git a/wadsrc/xlat/doom_base.txt b/wadsrc/static/xlat/doom_base.txt similarity index 100% rename from wadsrc/xlat/doom_base.txt rename to wadsrc/static/xlat/doom_base.txt diff --git a/wadsrc/xlat/heretic.txt b/wadsrc/static/xlat/heretic.txt similarity index 100% rename from wadsrc/xlat/heretic.txt rename to wadsrc/static/xlat/heretic.txt diff --git a/wadsrc/xlat/heretic_base.txt b/wadsrc/static/xlat/heretic_base.txt similarity index 100% rename from wadsrc/xlat/heretic_base.txt rename to wadsrc/static/xlat/heretic_base.txt diff --git a/wadsrc/xlat/strife.txt b/wadsrc/static/xlat/strife.txt similarity index 100% rename from wadsrc/xlat/strife.txt rename to wadsrc/static/xlat/strife.txt diff --git a/wadsrc/xlat/strife_base.txt b/wadsrc/static/xlat/strife_base.txt similarity index 100% rename from wadsrc/xlat/strife_base.txt rename to wadsrc/static/xlat/strife_base.txt diff --git a/wadsrc/wadsrc.vcproj b/wadsrc/wadsrc.vcproj index be61c6b98..cac80d07a 100644 --- a/wadsrc/wadsrc.vcproj +++ b/wadsrc/wadsrc.vcproj @@ -22,713 +22,141 @@ Name="Debug|Win32" OutputDirectory="Debug" IntermediateDirectory="Debug" - ConfigurationType="0" + ConfigurationType="10" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" > + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst deleted file mode 100644 index a11685496..000000000 --- a/wadsrc/zdoom.lst +++ /dev/null @@ -1,360 +0,0 @@ -# The big list of all things zdoom.wad. - -@zdoom.pk3 - -vga-rom-font.16 vga-rom.f16 - -graphics/invgeml1.png invgeml1.png -graphics/invgeml2.png invgeml2.png -graphics/invgemr1.png invgemr1.png -graphics/invgemr2.png invgemr2.png -graphics/artibox.png artibox.png -graphics/selectbo.png selectbo.png -graphics/fiteface.lmp fiteface.lmp -graphics/mageface.lmp mageface.lmp -graphics/clerface.lmp clerface.lmp -graphics/hamoback.png hamoback.png - -======== # Decals -decaldef.txt decals/decaldef.txt --------- - -graphics/blast1.png decals/blast1.png -graphics/cbalscr1.png decals/cbalscr1.png -graphics/cbalscr2.png decals/cbalscr2.png -graphics/bal7scr1.png decals/bal7scr1.png -graphics/bal7scr2.png decals/bal7scr2.png -graphics/bfglite1.png decals/bfglite1.png -graphics/bfglite2.png decals/bfglite2.png -graphics/bfgscrc1.png decals/bfgscrc1.png -graphics/bfgscrc2.png decals/bfgscrc2.png -graphics/plasma1.png decals/plasma1.png -graphics/plasma2.png decals/plasma2.png -graphics/scorch1.png decals/scorch1.png -graphics/bsplat1.png decals/bsplat1.png -graphics/bsplat2.png decals/bsplat2.png -graphics/bsplat3.png decals/bsplat3.png -graphics/bsplat4.png decals/bsplat4.png -graphics/bsplat5.png decals/bsplat5.png -graphics/bsplat6.png decals/bsplat6.png -graphics/bsplat7.png decals/bsplat7.png -graphics/bsmear1.png decals/bsmear1.png -graphics/bsmear2.png decals/bsmear2.png -graphics/chip1.png decals/chip1.png -graphics/chip2.png decals/chip2.png -graphics/chip3.png decals/chip3.png -graphics/chip4.png decals/chip4.png -graphics/chip5.png decals/chip5.png -graphics/cbowmark.png decals/cbowmark.png - -======== -# Definition lumps - -animdefs.txt animdefs.txt -terrain.txt terrain.txt -in_epi1.txt in_epi1.txt -in_epi2.txt in_epi2.txt -in_epi3.txt in_epi3.txt -in_htc1.txt in_htc1.txt -in_htc2.txt in_htc2.txt -in_htc3.txt in_htc3.txt -lockdefs.txt lockdefs.txt -teaminfo.txt teaminfo.txt -althudcf.txt althudcf.txt -sbarinfo.txt sbarinfo.txt - -======== -# Doom map format translators - -xlat/doom.txt xlat/doom.txt -xlat/heretic.txt xlat/heretic.txt -xlat/strife.txt xlat/strife.txt -xlat/base.txt xlat/base.txt -xlat/defines.i xlat/defines.i -xlat/doom_base.txt xlat/doom_base.txt -xlat/heretic_base.txt xlat/heretic_base.txt -xlat/strife_base.txt xlat/strife_base.txt - - -======== -# Support lumps - -dehsupp.lmp dehsupp.lmp - -animated.lmp animated.lmp -spaldoom.lmp spaldoom.lmp -spalhtic.lmp spalhtic.lmp - -======== -# Language lumps - -language.enu languages/english-us.txt -language.fr languages/french.txt -language.ita languages/italian.txt - -======== - -x11r6rgb.txt x11r6rgb.txt -graphics/stkeys6.lmp stkeys6.lmp -graphics/stkeys7.lmp stkeys7.lmp -graphics/stkeys8.lmp stkeys8.lmp -dbigfont.lmp dbigfont.lmp # The big Doom font -sbigfont.lmp sbigfont.lmp # The big Strife font -confont.lmp confont.lmp -graphics/fonta60.lmp fonta60.lmp -graphics/fonta61.lmp fonta61.lmp -graphics/fonta62.lmp fonta62.lmp -graphics/fonta63.lmp fonta63.lmp -graphics/fonta164.lmp fonta164.lmp -graphics/fonta165.lmp fonta165.lmp -graphics/fonta182.lmp fonta182.lmp -graphics/fonta188.lmp fonta188.lmp -graphics/fonta191.lmp fonta191.lmp -graphics/stcfn223.lmp stcfn223.lmp -graphics/stcfn220.lmp stcfn220.lmp -graphics/stcfn214.lmp stcfn214.lmp -graphics/stcfn197.lmp stcfn197.lmp -graphics/stcfn196.lmp stcfn196.lmp -graphics/stpbany.lmp stpbany.lmp -graphics/stfbany.lmp stfbany.lmp - -======== -# Crosshairs -xhairs.txt xhairs.txt - -graphics/xhairs1.imgz xhairs1.imgz -graphics/xhairs2.imgz xhairs2.imgz -graphics/xhairs3.imgz xhairs3.imgz -graphics/xhairs4.imgz xhairs4.imgz -graphics/xhairs5.imgz xhairs5.imgz -graphics/xhairs6.imgz xhairs6.imgz -graphics/xhairs7.imgz xhairs7.imgz - -graphics/xhairb1.imgz xhairb1.imgz -graphics/xhairb2.png xhairb2.png -graphics/xhairb3.imgz xhairb3.imgz -graphics/xhairb4.imgz xhairb4.imgz -graphics/xhairb5.imgz xhairb5.imgz -graphics/xhairb6.imgz xhairb6.imgz -graphics/xhairb7.imgz xhairb7.imgz - -# Now some sprites -sprites/tnt1a0.png tnt1a0.png -sprites/unkna0.png unkna0.png -sprites/tlgla0.png tlgl.png -sprites/tlglb0.png tlgl.png -sprites/tlglc0.png tlgl.png -sprites/tlgld0.png tlgl.png -sprites/tlgle0.png tlgl.png -sprites/iceca0.png iceca0.png -sprites/icecb0.png icecb0.png -sprites/icecc0.png icecc0.png -sprites/icecd0.png icecd0.png -sprites/amrka0.png amrka0.png -sprites/pista0.png pista0.png -sprites/rsmka0.png rsmka0.png -sprites/rsmkb0.png rsmkb0.png -sprites/rsmkc0.png rsmkc0.png -sprites/rsmkd0.png rsmkd0.png -sprites/rsmke0.png rsmke0.png - -# crouching DoomPlayer -sprites/plyca1.lmp crouch/plyca1.lmp -sprites/plyca2a8.lmp crouch/plyca2a8.lmp -sprites/plyca3a7.lmp crouch/plyca3a7.lmp -sprites/plyca4a6.lmp crouch/plyca4a6.lmp -sprites/plyca5.lmp crouch/plyca5.lmp -sprites/plycb1.lmp crouch/plycb1.lmp -sprites/plycb2b8.lmp crouch/plycb2b8.lmp -sprites/plycb3b7.lmp crouch/plycb3b7.lmp -sprites/plycb4b6.lmp crouch/plycb4b6.lmp -sprites/plycb5.lmp crouch/plycb5.lmp -sprites/plycc1.lmp crouch/plycc1.lmp -sprites/plycc2c8.lmp crouch/plycc2c8.lmp -sprites/plycc3c7.lmp crouch/plycc3c7.lmp -sprites/plycc4c6.lmp crouch/plycc4c6.lmp -sprites/plycc5.lmp crouch/plycc5.lmp -sprites/plycd1.lmp crouch/plycd1.lmp -sprites/plycd2d8.lmp crouch/plycd2d8.lmp -sprites/plycd3d7.lmp crouch/plycd3d7.lmp -sprites/plycd4d6.lmp crouch/plycd4d6.lmp -sprites/plycd5.lmp crouch/plycd5.lmp -sprites/plyce1.lmp crouch/plyce1.lmp -sprites/plyce2e8.lmp crouch/plyce2e8.lmp -sprites/plyce3e7.lmp crouch/plyce3e7.lmp -sprites/plyce4e6.lmp crouch/plyce4e6.lmp -sprites/plyce5.lmp crouch/plyce5.lmp -sprites/plycf1.lmp crouch/plycf1.lmp -sprites/plycf2f8.lmp crouch/plycf2f8.lmp -sprites/plycf3f7.lmp crouch/plycf3f7.lmp -sprites/plycf4f6.lmp crouch/plycf4f6.lmp -sprites/plycf5.lmp crouch/plycf5.lmp -sprites/plycg1.lmp crouch/plycg1.lmp -sprites/plycg2g8.lmp crouch/plycg2g8.lmp -sprites/plycg3g7.lmp crouch/plycg3g7.lmp -sprites/plycg4g6.lmp crouch/plycg4g6.lmp -sprites/plycg5.lmp crouch/plycg5.lmp -sprites/plych0.lmp crouch/plych0.lmp -sprites/plyci0.lmp crouch/plyci0.lmp -sprites/plycj0.lmp crouch/plycj0.lmp -sprites/plyck0.lmp crouch/plyck0.lmp -sprites/plycl0.lmp crouch/plycl0.lmp -sprites/plycm0.lmp crouch/plycm0.lmp -sprites/plycn0.lmp crouch/plycn0.lmp -sprites/plyco0.lmp crouch/plyco0.lmp -sprites/plycp0.lmp crouch/plycp0.lmp -sprites/plycq0.lmp crouch/plycq0.lmp -sprites/plycr0.lmp crouch/plycr0.lmp -sprites/plycs0.lmp crouch/plycs0.lmp -sprites/plyct0.lmp crouch/plyct0.lmp -sprites/plycu0.lmp crouch/plycu0.lmp -sprites/plycv0.lmp crouch/plycv0.lmp -sprites/plycw0.lmp crouch/plycw0.lmp - -# The patch substituted when a corrupt patch is detected -graphics/-badpatc.lmp badpatch.lmp - -# The texture substituted when an unknown texture is encountered -textures/-noflat-.png noflat.png - -======== -# Sounds - -sndinfo.txt sndinfo.txt -sndseq.txt sndseq.txt -reverbs.txt reverbs.txt - --------- - -sounds/icedth1.flac icedeath.flac -sounds/icebrk1a.flac icebreak.flac - -sounds/dsquake.flac quake.flac -sounds/dsempty.lmp dsempty.lmp -sounds/dssecret.flac secret.flac -sounds/spark1.flac spark1.flac -sounds/spark2.flac spark2.flac -sounds/spark3.flac spark3.flac -sounds/railgf1.flac railgunfire.flac - -======== -# Mapinfos - -mapinfo/doomcommon.txt mapinfo/doomcommon.txt -mapinfo/doom1.txt mapinfo/doom1.txt -mapinfo/doom2.txt mapinfo/doom2.txt -mapinfo/plutonia.txt mapinfo/plutonia.txt -mapinfo/tnt.txt mapinfo/tnt.txt -mapinfo/heretic.txt mapinfo/heretic.txt -mapinfo/hexen.txt mapinfo/hexen.txt -mapinfo/strife.txt mapinfo/strife.txt - -======== -# Strife's helper script -acs/strfhelp.o strfhelp.o - - -======== -# Font color ranges -textcolors.txt textcolors.txt -fontdefs.txt fontdefs.txt -indexfont indexfont.fon - -======== -# Decorate stuff - -decorate.txt decorate/decorate.txt -actors/nativeclasses.txt decorate/nativeclasses.txt -actors/constants.txt decorate/constants.txt - -actors/shared/botstuff.txt decorate/shared/botstuff.txt -actors/shared/sharedmisc.txt decorate/shared/sharedmisc.txt -actors/shared/blood.txt decorate/shared/blood.txt -actors/shared/debris.txt decorate/shared/debris.txt -actors/shared/splashes.txt decorate/shared/splashes.txt -actors/shared/pickups.txt decorate/shared/pickups.txt -actors/shared/fountain.txt decorate/shared/fountain.txt -actors/shared/soundsequence.txt decorate/shared/soundsequence.txt - -actors/doom/doomplayer.txt decorate/doom/doomplayer.txt -actors/doom/possessed.txt decorate/doom/possessed.txt -actors/doom/doomimp.txt decorate/doom/doomimp.txt -actors/doom/demon.txt decorate/doom/demon.txt -actors/doom/lostsoul.txt decorate/doom/lostsoul.txt -actors/doom/cacodemon.txt decorate/doom/cacodemon.txt -actors/doom/bruiser.txt decorate/doom/bruiser.txt -actors/doom/arachnotron.txt decorate/doom/arachnotron.txt -actors/doom/fatso.txt decorate/doom/fatso.txt -actors/doom/revenant.txt decorate/doom/revenant.txt -actors/doom/painelemental.txt decorate/doom/painelemental.txt -actors/doom/archvile.txt decorate/doom/archvile.txt -actors/doom/cyberdemon.txt decorate/doom/cyberdemon.txt -actors/doom/spidermaster.txt decorate/doom/spidermaster.txt -actors/doom/keen.txt decorate/doom/keen.txt -actors/doom/bossbrain.txt decorate/doom/bossbrain.txt - -actors/doom/deadthings.txt decorate/doom/deadthings.txt -actors/doom/doomammo.txt decorate/doom/doomammo.txt -actors/doom/doomarmor.txt decorate/doom/doomarmor.txt -actors/doom/doomartifacts.txt decorate/doom/doomartifacts.txt -actors/doom/doomhealth.txt decorate/doom/doomhealth.txt -actors/doom/doomkeys.txt decorate/doom/doomkeys.txt -actors/doom/doommisc.txt decorate/doom/doommisc.txt -actors/doom/doomdecorations.txt decorate/doom/doomdecorations.txt -actors/doom/doomweapons.txt decorate/doom/doomweapons.txt -actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt - -actors/raven/artiegg.txt decorate/raven/artiegg.txt -actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt -actors/raven/ravenhealth.txt decorate/raven/ravenhealth.txt -actors/raven/ravenambient.txt decorate/raven/ravenambient.txt - -actors/heretic/hereticplayer.txt decorate/heretic/hereticplayer.txt -actors/heretic/hereticammo.txt decorate/heretic/hereticammo.txt -actors/heretic/hereticarmor.txt decorate/heretic/hereticarmor.txt -actors/heretic/hereticartifacts.txt decorate/heretic/hereticartifacts.txt -actors/heretic/heretickeys.txt decorate/heretic/heretickeys.txt -actors/heretic/hereticdecorations.txt decorate/heretic/hereticdecorations.txt -actors/heretic/hereticmisc.txt decorate/heretic/hereticmisc.txt -actors/heretic/hereticweaps.txt decorate/heretic/hereticweaps.txt -actors/heretic/mummy.txt decorate/heretic/mummy.txt -actors/heretic/clink.txt decorate/heretic/clink.txt -actors/heretic/beast.txt decorate/heretic/beast.txt -actors/heretic/snake.txt decorate/heretic/snake.txt -actors/heretic/hereticimp.txt decorate/heretic/hereticimp.txt -actors/heretic/knight.txt decorate/heretic/knight.txt -actors/heretic/wizard.txt decorate/heretic/wizard.txt -actors/heretic/ironlich.txt decorate/heretic/ironlich.txt -actors/heretic/dsparil.txt decorate/heretic/dsparil.txt -actors/heretic/chicken.txt decorate/heretic/chicken.txt - -actors/hexen/fighterplayer.txt decorate/hexen/fighterplayer.txt -actors/hexen/clericplayer.txt decorate/hexen/clericplayer.txt -actors/hexen/mageplayer.txt decorate/hexen/mageplayer.txt -actors/hexen/flame.txt decorate/hexen/flame.txt -actors/hexen/hexenarmor.txt decorate/hexen/hexenarmor.txt -actors/hexen/hexendecorations.txt decorate/hexen/hexendecorations.txt -actors/hexen/hexenkeys.txt decorate/hexen/hexenkeys.txt -actors/hexen/hexenspecialdecs.txt decorate/hexen/hexenspecialdecs.txt -actors/hexen/mana.txt decorate/hexen/mana.txt -actors/hexen/puzzleitems.txt decorate/hexen/puzzleitems.txt -actors/hexen/scriptprojectiles.txt decorate/hexen/scriptprojectiles.txt -actors/hexen/speedboots.txt decorate/hexen/speedboots.txt -actors/hexen/ettin.txt decorate/hexen/ettin.txt -actors/hexen/centaur.txt decorate/hexen/centaur.txt -actors/hexen/demons.txt decorate/hexen/demons.txt - -actors/strife/strifeplayer.txt decorate/strife/strifeplayer.txt -actors/strife/beggars.txt decorate/strife/beggars.txt -actors/strife/merchants.txt decorate/strife/merchants.txt -actors/strife/peasants.txt decorate/strife/peasants.txt -actors/strife/strifebishop.txt decorate/strife/strifebishop.txt -actors/strife/questitems.txt decorate/strife/questitems.txt -actors/strife/ratbuddy.txt decorate/strife/ratbuddy.txt -actors/strife/strifeammo.txt decorate/strife/strifeammo.txt -actors/strife/strifearmor.txt decorate/strife/strifearmor.txt -actors/strife/strifeitems.txt decorate/strife/strifeitems.txt -actors/strife/strifekeys.txt decorate/strife/strifekeys.txt -actors/strife/strifestuff.txt decorate/strife/strifestuff.txt -actors/strife/zombie.txt decorate/strife/zombie.txt - diff --git a/zdoom.sln b/zdoom.sln index d0b69f77f..a07991970 100644 --- a/zdoom.sln +++ b/zdoom.sln @@ -3,14 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 9.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}" ProjectSection(ProjectDependencies) = postProject {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} = {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} - {8997289F-10BF-4678-8BAA-3BB509C84953} = {8997289F-10BF-4678-8BAA-3BB509C84953} - {E83FD370-2E72-4D4C-9427-FF9D9DED1E88} = {E83FD370-2E72-4D4C-9427-FF9D9DED1E88} - {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} - {6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859} - {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} - {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} - {DA47396F-60C1-4BDE-A977-7F7DE461CF77} = {DA47396F-60C1-4BDE-A977-7F7DE461CF77} + {B68E0ABF-B627-48A3-A92F-D8F827A75054} = {B68E0ABF-B627-48A3-A92F-D8F827A75054} {1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F} + {DA47396F-60C1-4BDE-A977-7F7DE461CF77} = {DA47396F-60C1-4BDE-A977-7F7DE461CF77} + {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} + {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} + {6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859} + {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} + {E83FD370-2E72-4D4C-9427-FF9D9DED1E88} = {E83FD370-2E72-4D4C-9427-FF9D9DED1E88} + {8997289F-10BF-4678-8BAA-3BB509C84953} = {8997289F-10BF-4678-8BAA-3BB509C84953} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}" @@ -21,19 +22,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "re2c", "tools\re2c\re2c.vcp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wadsrc", "wadsrc\wadsrc.vcproj", "{1D179D4B-F008-431B-8C72-111F8372584F}" ProjectSection(ProjectDependencies) = postProject - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\makewad.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}" - ProjectSection(ProjectDependencies) = postProject - {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dehsupp", "tools\dehsupp\dehsupp.vcproj", "{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}" ProjectSection(ProjectDependencies) = postProject - {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} + {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updaterevision", "tools\updaterevision\updaterevision.vcproj", "{6077B7D6-349F-4077-B552-3BC302EF5859}" @@ -46,6 +42,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "snes_spc", "snes_spc\snes_s EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumb_static", "dumb\vc6\dumb_static\dumb_static.vcproj", "{8997289F-10BF-4678-8BAA-3BB509C84953}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtoa", "gdtoa\gdtoa.vcproj", "{B68E0ABF-B627-48A3-A92F-D8F827A75054}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zipdir", "tools\zipdir\zipdir.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}" + ProjectSection(ProjectDependencies) = postProject + {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -94,14 +97,6 @@ Global {1D179D4B-F008-431B-8C72-111F8372584F}.Release|Win32.Build.0 = Release|Win32 {1D179D4B-F008-431B-8C72-111F8372584F}.Release|x64.ActiveCfg = Release|Win32 {1D179D4B-F008-431B-8C72-111F8372584F}.Release|x64.Build.0 = Release|Win32 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|Win32.ActiveCfg = Debug|Win32 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|Win32.Build.0 = Debug|Win32 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|x64.ActiveCfg = Debug|x64 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|x64.Build.0 = Debug|x64 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|Win32.ActiveCfg = Release|Win32 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|Win32.Build.0 = Release|Win32 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|x64.ActiveCfg = Release|x64 - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|x64.Build.0 = Release|x64 {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}.Debug|Win32.ActiveCfg = Debug|Win32 {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}.Debug|Win32.Build.0 = Debug|Win32 {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}.Debug|x64.ActiveCfg = Release|Win32 @@ -150,6 +145,22 @@ Global {8997289F-10BF-4678-8BAA-3BB509C84953}.Release|Win32.Build.0 = Release|Win32 {8997289F-10BF-4678-8BAA-3BB509C84953}.Release|x64.ActiveCfg = Release|x64 {8997289F-10BF-4678-8BAA-3BB509C84953}.Release|x64.Build.0 = Release|x64 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Debug|Win32.ActiveCfg = Debug|Win32 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Debug|Win32.Build.0 = Debug|Win32 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Debug|x64.ActiveCfg = Debug|x64 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Debug|x64.Build.0 = Debug|x64 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Release|Win32.ActiveCfg = Release|Win32 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Release|Win32.Build.0 = Release|Win32 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Release|x64.ActiveCfg = Release|x64 + {B68E0ABF-B627-48A3-A92F-D8F827A75054}.Release|x64.Build.0 = Release|x64 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|Win32.ActiveCfg = Debug|Win32 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|Win32.Build.0 = Debug|Win32 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|x64.ActiveCfg = Debug|x64 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Debug|x64.Build.0 = Debug|x64 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|Win32.ActiveCfg = Release|Win32 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|Win32.Build.0 = Release|Win32 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|x64.ActiveCfg = Release|x64 + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/zdoom.vcproj b/zdoom.vcproj index b7a74f2a9..fe04e1ff6 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - @@ -953,6 +943,16 @@ Outputs=""src/$(InputName).h"" /> + + + @@ -1543,17 +1543,7 @@ - - - @@ -1564,10 +1554,20 @@ + + + @@ -1589,17 +1589,7 @@ - - - @@ -1610,10 +1600,20 @@ + + + @@ -1635,17 +1635,7 @@ - - - @@ -1656,7 +1646,17 @@ + + + @@ -1667,8 +1667,8 @@ @@ -1681,17 +1681,7 @@ - - - @@ -1702,7 +1692,17 @@ + + + @@ -1713,8 +1713,8 @@ @@ -1727,17 +1727,7 @@ - - - @@ -1748,7 +1738,17 @@ + + + @@ -1759,8 +1759,8 @@ @@ -1917,6 +1917,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1927,14 +1935,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - + + @@ -2820,6 +2824,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -2829,14 +2841,6 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> - - - @@ -3111,7 +3115,7 @@ /> /dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib/Makefile.in b/zlib/Makefile.in deleted file mode 100644 index 2fd6e45c4..000000000 --- a/zlib/Makefile.in +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -LDFLAGS=libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -LIBS=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 -SHAREDLIBM=libz.so.1 - -AR=ar rc -RANLIB=ranlib -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example$(EXE) minigzip$(EXE) - -check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib/Makefile.mgw b/zlib/Makefile.mgw deleted file mode 100644 index d1e6d3669..000000000 --- a/zlib/Makefile.mgw +++ /dev/null @@ -1,91 +0,0 @@ -# Makefile for zlib, derived from Makefile.dj2. -# Modified for mingw32 by C. Spieler, 6/16/98. -# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003. -# Last updated: 1-Aug-2003. -# Tested under Cygwin and MinGW. - -# Copyright (C) 1995-2003 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile, or to compile and test, type: -# -# make -fmakefile.mgw; make test -fmakefile.mgw -# -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o -fmakefile.mgw - -STATICLIB = libz.a - -#LOC = -DASMV -#LOC = -DDEBUG -g - -CCDV = @../ccdv - -CC = gcc -CFLAGS = $(LOC) -O2 -Wall -fomit-frame-pointer - -AS = $(CC) -ASFLAGS = $(LOC) -Wall - -LD = $(CC) -LDFLAGS = $(LOC) -s - -AR = ar -ARFLAGS = rcs - -OBJS = adler32.o compress.o crc32.o deflate.o gzio.o infback.o \ - inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o -OBJA = - -all: $(STATICLIB) - -test: example minigzip - ./example - echo hello world | minigzip | minigzip -d - -.c.o: - $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< - -.S.o: - $(CCDV) $(AS) $(ASFLAGS) -c -o $@ $< - -$(STATICLIB): $(OBJS) $(OBJA) - $(CCDV) $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA) - -example: example.o $(STATICLIB) - $(CCDV) $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB) - -minigzip: minigzip.o $(STATICLIB) - $(CCDV) $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB) - - -.PHONY: clean - -clean: -ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) - rm -f $(STATICLIB) - rm -f *.o - rm -f *.exe - rm -f foo.gz -else - -del /q /f $(STATICLIB) 2>nul - -del /q /f *.o 2>nul - -del /q /f *.exe 2>nul - -del /q /f foo.gz 2>nul -endif - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib/zlib.vcproj b/zlib/zlib.vcproj index 0c935f8e4..840c6e642 100644 --- a/zlib/zlib.vcproj +++ b/zlib/zlib.vcproj @@ -440,6 +440,14 @@ > + + + +