aboutsummaryrefslogtreecommitdiff
path: root/goo
diff options
context:
space:
mode:
Diffstat (limited to 'goo')
-rw-r--r--goo/CMakeFiles/CMakeDirectoryInformation.cmake16
-rw-r--r--goo/CMakeFiles/goo.dir/DependInfo.cmake11
-rw-r--r--goo/CMakeFiles/goo.dir/build.make121
-rw-r--r--goo/CMakeFiles/goo.dir/cmake_clean.cmake9
-rw-r--r--goo/CMakeFiles/goo.dir/cmake_clean_target.cmake3
-rw-r--r--goo/CMakeFiles/goo.dir/depend.internal3
-rw-r--r--goo/CMakeFiles/goo.dir/depend.make3
-rw-r--r--goo/CMakeFiles/goo.dir/flags.make17
-rw-r--r--goo/CMakeFiles/goo.dir/link.txt2
-rw-r--r--goo/CMakeFiles/goo.dir/progress.make2
-rw-r--r--goo/CMakeFiles/goo_objs.dir/C.includecache28
-rw-r--r--goo/CMakeFiles/goo_objs.dir/CXX.includecache226
-rw-r--r--goo/CMakeFiles/goo_objs.dir/DependInfo.cmake38
-rw-r--r--goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.obin0 -> 936 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/GHash.cc.obin0 -> 10144 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/GList.cc.obin0 -> 6720 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/GString.cc.obin0 -> 27360 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/Trace.cc.obin0 -> 928 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/build.make221
-rw-r--r--goo/CMakeFiles/goo_objs.dir/cmake_clean.cmake16
-rw-r--r--goo/CMakeFiles/goo_objs.dir/depend.internal65
-rw-r--r--goo/CMakeFiles/goo_objs.dir/depend.make65
-rw-r--r--goo/CMakeFiles/goo_objs.dir/flags.make17
-rw-r--r--goo/CMakeFiles/goo_objs.dir/gfile.cc.obin0 -> 11064 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/gmem.cc.obin0 -> 5680 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/gmempp.cc.obin0 -> 928 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/parseargs.c.obin0 -> 5688 bytes
-rw-r--r--goo/CMakeFiles/goo_objs.dir/progress.make10
-rw-r--r--goo/CMakeFiles/progress.marks1
-rw-r--r--goo/CMakeLists.txt30
-rw-r--r--goo/FixedPoint.cc134
-rw-r--r--goo/FixedPoint.h180
-rw-r--r--goo/GHash.cc385
-rw-r--r--goo/GHash.h78
-rw-r--r--goo/GList.cc123
-rw-r--r--goo/GList.h106
-rw-r--r--goo/GMutex.h101
-rw-r--r--goo/GString.cc853
-rw-r--r--goo/GString.h151
-rw-r--r--goo/Makefile505
-rw-r--r--goo/Trace.cc114
-rw-r--r--goo/Trace.h43
-rw-r--r--goo/cmake_install.cmake44
-rw-r--r--goo/gfile.cc779
-rw-r--r--goo/gfile.h144
-rw-r--r--goo/gmem.cc396
-rw-r--r--goo/gmem.h95
-rw-r--r--goo/gmempp.cc51
-rw-r--r--goo/gmempp.h48
-rw-r--r--goo/gtypes.h29
-rw-r--r--goo/libgoo.abin0 -> 73528 bytes
-rw-r--r--goo/parseargs.c195
-rw-r--r--goo/parseargs.h72
53 files changed, 5530 insertions, 0 deletions
diff --git a/goo/CMakeFiles/CMakeDirectoryInformation.cmake b/goo/CMakeFiles/CMakeDirectoryInformation.cmake
new file mode 100644
index 0000000..aef4d6c
--- /dev/null
+++ b/goo/CMakeFiles/CMakeDirectoryInformation.cmake
@@ -0,0 +1,16 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# Relative path conversion top directories.
+set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/calvin/src/xpdf-4.04")
+set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/calvin/src/xpdf-4.04")
+
+# Force unix paths in dependencies.
+set(CMAKE_FORCE_UNIX_PATHS 1)
+
+
+# The C and CXX include file regular expressions for this directory.
+set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$")
+set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$")
+set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})
+set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})
diff --git a/goo/CMakeFiles/goo.dir/DependInfo.cmake b/goo/CMakeFiles/goo.dir/DependInfo.cmake
new file mode 100644
index 0000000..19fab21
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/DependInfo.cmake
@@ -0,0 +1,11 @@
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+ )
+# The set of files for implicit dependencies of each language:
+
+# Targets to which this target links.
+set(CMAKE_TARGET_LINKED_INFO_FILES
+ )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/goo/CMakeFiles/goo.dir/build.make b/goo/CMakeFiles/goo.dir/build.make
new file mode 100644
index 0000000..9af066d
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/build.make
@@ -0,0 +1,121 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/calvin/src/xpdf-4.04
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/calvin/src/xpdf-4.04
+
+# Include any dependencies generated for this target.
+include goo/CMakeFiles/goo.dir/depend.make
+
+# Include the progress variables for this target.
+include goo/CMakeFiles/goo.dir/progress.make
+
+# Include the compile flags for this target's objects.
+include goo/CMakeFiles/goo.dir/flags.make
+
+# Object files for target goo
+goo_OBJECTS =
+
+# External object files for target goo
+goo_EXTERNAL_OBJECTS = \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GHash.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GList.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GString.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gfile.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gmem.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gmempp.cc.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/parseargs.c.o" \
+"/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/Trace.cc.o"
+
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/GHash.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/GList.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/GString.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/gfile.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/gmem.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/parseargs.c.o
+goo/libgoo.a: goo/CMakeFiles/goo_objs.dir/Trace.cc.o
+goo/libgoo.a: goo/CMakeFiles/goo.dir/build.make
+goo/libgoo.a: goo/CMakeFiles/goo.dir/link.txt
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Linking CXX static library libgoo.a"
+ cd /home/calvin/src/xpdf-4.04/goo && $(CMAKE_COMMAND) -P CMakeFiles/goo.dir/cmake_clean_target.cmake
+ cd /home/calvin/src/xpdf-4.04/goo && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/goo.dir/link.txt --verbose=$(VERBOSE)
+
+# Rule to build all files generated by this target.
+goo/CMakeFiles/goo.dir/build: goo/libgoo.a
+
+.PHONY : goo/CMakeFiles/goo.dir/build
+
+goo/CMakeFiles/goo.dir/clean:
+ cd /home/calvin/src/xpdf-4.04/goo && $(CMAKE_COMMAND) -P CMakeFiles/goo.dir/cmake_clean.cmake
+.PHONY : goo/CMakeFiles/goo.dir/clean
+
+goo/CMakeFiles/goo.dir/depend:
+ cd /home/calvin/src/xpdf-4.04 && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/calvin/src/xpdf-4.04 /home/calvin/src/xpdf-4.04/goo /home/calvin/src/xpdf-4.04 /home/calvin/src/xpdf-4.04/goo /home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo.dir/DependInfo.cmake --color=$(COLOR)
+.PHONY : goo/CMakeFiles/goo.dir/depend
+
diff --git a/goo/CMakeFiles/goo.dir/cmake_clean.cmake b/goo/CMakeFiles/goo.dir/cmake_clean.cmake
new file mode 100644
index 0000000..9b2dd65
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/cmake_clean.cmake
@@ -0,0 +1,9 @@
+file(REMOVE_RECURSE
+ "libgoo.a"
+ "libgoo.pdb"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang C CXX)
+ include(CMakeFiles/goo.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/goo/CMakeFiles/goo.dir/cmake_clean_target.cmake b/goo/CMakeFiles/goo.dir/cmake_clean_target.cmake
new file mode 100644
index 0000000..539e57d
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/cmake_clean_target.cmake
@@ -0,0 +1,3 @@
+file(REMOVE_RECURSE
+ "libgoo.a"
+)
diff --git a/goo/CMakeFiles/goo.dir/depend.internal b/goo/CMakeFiles/goo.dir/depend.internal
new file mode 100644
index 0000000..756f521
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/depend.internal
@@ -0,0 +1,3 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
diff --git a/goo/CMakeFiles/goo.dir/depend.make b/goo/CMakeFiles/goo.dir/depend.make
new file mode 100644
index 0000000..756f521
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/depend.make
@@ -0,0 +1,3 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
diff --git a/goo/CMakeFiles/goo.dir/flags.make b/goo/CMakeFiles/goo.dir/flags.make
new file mode 100644
index 0000000..d049736
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/flags.make
@@ -0,0 +1,17 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# compile C with /usr/bin/cc
+# compile CXX with /usr/bin/c++
+C_DEFINES =
+
+C_INCLUDES = -I/home/calvin/src/xpdf-4.04
+
+C_FLAGS =
+
+CXX_DEFINES =
+
+CXX_INCLUDES = -I/home/calvin/src/xpdf-4.04
+
+CXX_FLAGS =
+
diff --git a/goo/CMakeFiles/goo.dir/link.txt b/goo/CMakeFiles/goo.dir/link.txt
new file mode 100644
index 0000000..e4ddd3b
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/link.txt
@@ -0,0 +1,2 @@
+/usr/bin/ar qc libgoo.a CMakeFiles/goo_objs.dir/FixedPoint.cc.o CMakeFiles/goo_objs.dir/GHash.cc.o CMakeFiles/goo_objs.dir/GList.cc.o CMakeFiles/goo_objs.dir/GString.cc.o CMakeFiles/goo_objs.dir/gfile.cc.o CMakeFiles/goo_objs.dir/gmem.cc.o CMakeFiles/goo_objs.dir/gmempp.cc.o CMakeFiles/goo_objs.dir/parseargs.c.o CMakeFiles/goo_objs.dir/Trace.cc.o
+/usr/bin/ranlib libgoo.a
diff --git a/goo/CMakeFiles/goo.dir/progress.make b/goo/CMakeFiles/goo.dir/progress.make
new file mode 100644
index 0000000..225de34
--- /dev/null
+++ b/goo/CMakeFiles/goo.dir/progress.make
@@ -0,0 +1,2 @@
+CMAKE_PROGRESS_1 =
+
diff --git a/goo/CMakeFiles/goo_objs.dir/C.includecache b/goo/CMakeFiles/goo_objs.dir/C.includecache
new file mode 100644
index 0000000..f78a288
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/C.includecache
@@ -0,0 +1,28 @@
+#IncludeRegexLine: ^[ ]*[#%][ ]*(include|import)[ ]*[<"]([^">]+)([">])
+
+#IncludeRegexScan: ^.*$
+
+#IncludeRegexComplain: ^$
+
+#IncludeRegexTransform:
+
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/parseargs.c
+stdio.h
+-
+stddef.h
+-
+string.h
+-
+stdlib.h
+-
+ctype.h
+-
+parseargs.h
+/home/calvin/src/xpdf-4.04/goo/parseargs.h
+
+/home/calvin/src/xpdf-4.04/goo/parseargs.h
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
diff --git a/goo/CMakeFiles/goo_objs.dir/CXX.includecache b/goo/CMakeFiles/goo_objs.dir/CXX.includecache
new file mode 100644
index 0000000..5a977ed
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/CXX.includecache
@@ -0,0 +1,226 @@
+#IncludeRegexLine: ^[ ]*[#%][ ]*(include|import)[ ]*[<"]([^">]+)([">])
+
+#IncludeRegexScan: ^.*$
+
+#IncludeRegexComplain: ^$
+
+#IncludeRegexTransform:
+
+/home/calvin/src/xpdf-4.04/goo/FixedPoint.cc
+aconf.h
+-
+gmempp.h
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+FixedPoint.h
+/home/calvin/src/xpdf-4.04/goo/FixedPoint.h
+
+/home/calvin/src/xpdf-4.04/goo/FixedPoint.h
+aconf.h
+-
+stdio.h
+-
+stdlib.h
+-
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/GHash.cc
+aconf.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+gmempp.h
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+GString.h
+/home/calvin/src/xpdf-4.04/goo/GString.h
+GHash.h
+/home/calvin/src/xpdf-4.04/goo/GHash.h
+
+/home/calvin/src/xpdf-4.04/goo/GHash.h
+aconf.h
+-
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/GList.cc
+aconf.h
+-
+stdlib.h
+-
+string.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+gmempp.h
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+GList.h
+/home/calvin/src/xpdf-4.04/goo/GList.h
+
+/home/calvin/src/xpdf-4.04/goo/GList.h
+aconf.h
+-
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/GString.cc
+aconf.h
+-
+stdlib.h
+-
+stddef.h
+-
+string.h
+-
+ctype.h
+-
+math.h
+-
+limits.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+gmempp.h
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+GString.h
+/home/calvin/src/xpdf-4.04/goo/GString.h
+
+/home/calvin/src/xpdf-4.04/goo/GString.h
+aconf.h
+-
+limits.h
+-
+stdarg.h
+-
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/Trace.cc
+aconf.h
+-
+stdio.h
+-
+stdarg.h
+-
+sys/types.h
+-
+sys/time.h
+-
+unistd.h
+-
+GString.h
+/home/calvin/src/xpdf-4.04/goo/GString.h
+Trace.h
+/home/calvin/src/xpdf-4.04/goo/Trace.h
+
+/home/calvin/src/xpdf-4.04/goo/Trace.h
+aconf.h
+-
+
+/home/calvin/src/xpdf-4.04/goo/gfile.cc
+aconf.h
+-
+windows.h
+-
+time.h
+-
+direct.h
+-
+shobjidl.h
+-
+shlguid.h
+-
+sys/types.h
+-
+sys/stat.h
+-
+fcntl.h
+-
+time.h
+-
+limits.h
+-
+string.h
+-
+pwd.h
+-
+unixlib.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+gmempp.h
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+GString.h
+/home/calvin/src/xpdf-4.04/goo/GString.h
+gfile.h
+/home/calvin/src/xpdf-4.04/goo/gfile.h
+
+/home/calvin/src/xpdf-4.04/goo/gfile.h
+aconf.h
+-
+stdio.h
+-
+stdlib.h
+-
+stddef.h
+-
+sys/stat.h
+-
+win32lib.h
+-
+windows.h
+-
+unistd.h
+-
+sys/types.h
+-
+gtypes.h
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+/home/calvin/src/xpdf-4.04/goo/gmem.cc
+aconf.h
+-
+stdio.h
+-
+stdlib.h
+-
+stddef.h
+-
+stdint.h
+-
+string.h
+-
+limits.h
+-
+windows.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+pthread.h
+-
+
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+stdio.h
+-
+aconf.h
+-
+
+/home/calvin/src/xpdf-4.04/goo/gmempp.cc
+aconf.h
+-
+gmem.h
+/home/calvin/src/xpdf-4.04/goo/gmem.h
+
+/home/calvin/src/xpdf-4.04/goo/gmempp.h
+stdlib.h
+-
+
+/home/calvin/src/xpdf-4.04/goo/gtypes.h
+
+aconf.h
+aconf2.h
+-
+
+aconf2.h
+AvailabilityMacros.h
+-
+
diff --git a/goo/CMakeFiles/goo_objs.dir/DependInfo.cmake b/goo/CMakeFiles/goo_objs.dir/DependInfo.cmake
new file mode 100644
index 0000000..dd5d27c
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/DependInfo.cmake
@@ -0,0 +1,38 @@
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+ "C"
+ "CXX"
+ )
+# The set of files for implicit dependencies of each language:
+set(CMAKE_DEPENDS_CHECK_C
+ "/home/calvin/src/xpdf-4.04/goo/parseargs.c" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/parseargs.c.o"
+ )
+set(CMAKE_C_COMPILER_ID "GNU")
+
+# The include file search paths:
+set(CMAKE_C_TARGET_INCLUDE_PATH
+ "."
+ )
+set(CMAKE_DEPENDS_CHECK_CXX
+ "/home/calvin/src/xpdf-4.04/goo/FixedPoint.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/GHash.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GHash.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/GList.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GList.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/GString.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/GString.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/Trace.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/Trace.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/gfile.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gfile.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/gmem.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gmem.cc.o"
+ "/home/calvin/src/xpdf-4.04/goo/gmempp.cc" "/home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/gmempp.cc.o"
+ )
+set(CMAKE_CXX_COMPILER_ID "GNU")
+
+# The include file search paths:
+set(CMAKE_CXX_TARGET_INCLUDE_PATH
+ "."
+ )
+
+# Targets to which this target links.
+set(CMAKE_TARGET_LINKED_INFO_FILES
+ )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o b/goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
new file mode 100644
index 0000000..35cc649
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/GHash.cc.o b/goo/CMakeFiles/goo_objs.dir/GHash.cc.o
new file mode 100644
index 0000000..c187373
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/GHash.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/GList.cc.o b/goo/CMakeFiles/goo_objs.dir/GList.cc.o
new file mode 100644
index 0000000..22a64f9
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/GList.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/GString.cc.o b/goo/CMakeFiles/goo_objs.dir/GString.cc.o
new file mode 100644
index 0000000..19329b5
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/GString.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/Trace.cc.o b/goo/CMakeFiles/goo_objs.dir/Trace.cc.o
new file mode 100644
index 0000000..f43e9c3
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/Trace.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/build.make b/goo/CMakeFiles/goo_objs.dir/build.make
new file mode 100644
index 0000000..5b104e6
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/build.make
@@ -0,0 +1,221 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/calvin/src/xpdf-4.04
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/calvin/src/xpdf-4.04
+
+# Include any dependencies generated for this target.
+include goo/CMakeFiles/goo_objs.dir/depend.make
+
+# Include the progress variables for this target.
+include goo/CMakeFiles/goo_objs.dir/progress.make
+
+# Include the compile flags for this target's objects.
+include goo/CMakeFiles/goo_objs.dir/flags.make
+
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/FixedPoint.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/FixedPoint.cc.o -c /home/calvin/src/xpdf-4.04/goo/FixedPoint.cc
+
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/FixedPoint.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/FixedPoint.cc > CMakeFiles/goo_objs.dir/FixedPoint.cc.i
+
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/FixedPoint.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/FixedPoint.cc -o CMakeFiles/goo_objs.dir/FixedPoint.cc.s
+
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/GHash.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object goo/CMakeFiles/goo_objs.dir/GHash.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/GHash.cc.o -c /home/calvin/src/xpdf-4.04/goo/GHash.cc
+
+goo/CMakeFiles/goo_objs.dir/GHash.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/GHash.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/GHash.cc > CMakeFiles/goo_objs.dir/GHash.cc.i
+
+goo/CMakeFiles/goo_objs.dir/GHash.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/GHash.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/GHash.cc -o CMakeFiles/goo_objs.dir/GHash.cc.s
+
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/GList.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object goo/CMakeFiles/goo_objs.dir/GList.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/GList.cc.o -c /home/calvin/src/xpdf-4.04/goo/GList.cc
+
+goo/CMakeFiles/goo_objs.dir/GList.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/GList.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/GList.cc > CMakeFiles/goo_objs.dir/GList.cc.i
+
+goo/CMakeFiles/goo_objs.dir/GList.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/GList.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/GList.cc -o CMakeFiles/goo_objs.dir/GList.cc.s
+
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/GString.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object goo/CMakeFiles/goo_objs.dir/GString.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/GString.cc.o -c /home/calvin/src/xpdf-4.04/goo/GString.cc
+
+goo/CMakeFiles/goo_objs.dir/GString.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/GString.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/GString.cc > CMakeFiles/goo_objs.dir/GString.cc.i
+
+goo/CMakeFiles/goo_objs.dir/GString.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/GString.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/GString.cc -o CMakeFiles/goo_objs.dir/GString.cc.s
+
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gfile.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building CXX object goo/CMakeFiles/goo_objs.dir/gfile.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/gfile.cc.o -c /home/calvin/src/xpdf-4.04/goo/gfile.cc
+
+goo/CMakeFiles/goo_objs.dir/gfile.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/gfile.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/gfile.cc > CMakeFiles/goo_objs.dir/gfile.cc.i
+
+goo/CMakeFiles/goo_objs.dir/gfile.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/gfile.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/gfile.cc -o CMakeFiles/goo_objs.dir/gfile.cc.s
+
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: goo/gmem.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Building CXX object goo/CMakeFiles/goo_objs.dir/gmem.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/gmem.cc.o -c /home/calvin/src/xpdf-4.04/goo/gmem.cc
+
+goo/CMakeFiles/goo_objs.dir/gmem.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/gmem.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/gmem.cc > CMakeFiles/goo_objs.dir/gmem.cc.i
+
+goo/CMakeFiles/goo_objs.dir/gmem.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/gmem.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/gmem.cc -o CMakeFiles/goo_objs.dir/gmem.cc.s
+
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: goo/gmempp.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_7) "Building CXX object goo/CMakeFiles/goo_objs.dir/gmempp.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/gmempp.cc.o -c /home/calvin/src/xpdf-4.04/goo/gmempp.cc
+
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/gmempp.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/gmempp.cc > CMakeFiles/goo_objs.dir/gmempp.cc.i
+
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/gmempp.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/gmempp.cc -o CMakeFiles/goo_objs.dir/gmempp.cc.s
+
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o: goo/parseargs.c
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_8) "Building C object goo/CMakeFiles/goo_objs.dir/parseargs.c.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -o CMakeFiles/goo_objs.dir/parseargs.c.o -c /home/calvin/src/xpdf-4.04/goo/parseargs.c
+
+goo/CMakeFiles/goo_objs.dir/parseargs.c.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/goo_objs.dir/parseargs.c.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/parseargs.c > CMakeFiles/goo_objs.dir/parseargs.c.i
+
+goo/CMakeFiles/goo_objs.dir/parseargs.c.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/goo_objs.dir/parseargs.c.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/parseargs.c -o CMakeFiles/goo_objs.dir/parseargs.c.s
+
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/CMakeFiles/goo_objs.dir/flags.make
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/Trace.cc
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/calvin/src/xpdf-4.04/CMakeFiles --progress-num=$(CMAKE_PROGRESS_9) "Building CXX object goo/CMakeFiles/goo_objs.dir/Trace.cc.o"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/goo_objs.dir/Trace.cc.o -c /home/calvin/src/xpdf-4.04/goo/Trace.cc
+
+goo/CMakeFiles/goo_objs.dir/Trace.cc.i: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/goo_objs.dir/Trace.cc.i"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/calvin/src/xpdf-4.04/goo/Trace.cc > CMakeFiles/goo_objs.dir/Trace.cc.i
+
+goo/CMakeFiles/goo_objs.dir/Trace.cc.s: cmake_force
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/goo_objs.dir/Trace.cc.s"
+ cd /home/calvin/src/xpdf-4.04/goo && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/calvin/src/xpdf-4.04/goo/Trace.cc -o CMakeFiles/goo_objs.dir/Trace.cc.s
+
+goo_objs: goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/GHash.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/GList.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/GString.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/gfile.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/gmem.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/parseargs.c.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/Trace.cc.o
+goo_objs: goo/CMakeFiles/goo_objs.dir/build.make
+
+.PHONY : goo_objs
+
+# Rule to build all files generated by this target.
+goo/CMakeFiles/goo_objs.dir/build: goo_objs
+
+.PHONY : goo/CMakeFiles/goo_objs.dir/build
+
+goo/CMakeFiles/goo_objs.dir/clean:
+ cd /home/calvin/src/xpdf-4.04/goo && $(CMAKE_COMMAND) -P CMakeFiles/goo_objs.dir/cmake_clean.cmake
+.PHONY : goo/CMakeFiles/goo_objs.dir/clean
+
+goo/CMakeFiles/goo_objs.dir/depend:
+ cd /home/calvin/src/xpdf-4.04 && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/calvin/src/xpdf-4.04 /home/calvin/src/xpdf-4.04/goo /home/calvin/src/xpdf-4.04 /home/calvin/src/xpdf-4.04/goo /home/calvin/src/xpdf-4.04/goo/CMakeFiles/goo_objs.dir/DependInfo.cmake --color=$(COLOR)
+.PHONY : goo/CMakeFiles/goo_objs.dir/depend
+
diff --git a/goo/CMakeFiles/goo_objs.dir/cmake_clean.cmake b/goo/CMakeFiles/goo_objs.dir/cmake_clean.cmake
new file mode 100644
index 0000000..48b5aea
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/cmake_clean.cmake
@@ -0,0 +1,16 @@
+file(REMOVE_RECURSE
+ "CMakeFiles/goo_objs.dir/FixedPoint.cc.o"
+ "CMakeFiles/goo_objs.dir/GHash.cc.o"
+ "CMakeFiles/goo_objs.dir/GList.cc.o"
+ "CMakeFiles/goo_objs.dir/GString.cc.o"
+ "CMakeFiles/goo_objs.dir/Trace.cc.o"
+ "CMakeFiles/goo_objs.dir/gfile.cc.o"
+ "CMakeFiles/goo_objs.dir/gmem.cc.o"
+ "CMakeFiles/goo_objs.dir/gmempp.cc.o"
+ "CMakeFiles/goo_objs.dir/parseargs.c.o"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang C CXX)
+ include(CMakeFiles/goo_objs.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/goo/CMakeFiles/goo_objs.dir/depend.internal b/goo/CMakeFiles/goo_objs.dir/depend.internal
new file mode 100644
index 0000000..aaa855f
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/depend.internal
@@ -0,0 +1,65 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ /home/calvin/src/xpdf-4.04/goo/parseargs.c
+ /home/calvin/src/xpdf-4.04/goo/parseargs.h
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
+ /home/calvin/src/xpdf-4.04/goo/FixedPoint.cc
+ /home/calvin/src/xpdf-4.04/goo/FixedPoint.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o
+ /home/calvin/src/xpdf-4.04/goo/GHash.cc
+ /home/calvin/src/xpdf-4.04/goo/GHash.h
+ /home/calvin/src/xpdf-4.04/goo/GString.h
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o
+ /home/calvin/src/xpdf-4.04/goo/GList.cc
+ /home/calvin/src/xpdf-4.04/goo/GList.h
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o
+ /home/calvin/src/xpdf-4.04/goo/GString.cc
+ /home/calvin/src/xpdf-4.04/goo/GString.h
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o
+ /home/calvin/src/xpdf-4.04/goo/GString.h
+ /home/calvin/src/xpdf-4.04/goo/Trace.cc
+ /home/calvin/src/xpdf-4.04/goo/Trace.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o
+ /home/calvin/src/xpdf-4.04/goo/GString.h
+ /home/calvin/src/xpdf-4.04/goo/gfile.cc
+ /home/calvin/src/xpdf-4.04/goo/gfile.h
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.h
+ /home/calvin/src/xpdf-4.04/goo/gtypes.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o
+ /home/calvin/src/xpdf-4.04/goo/gmem.cc
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ aconf.h
+ aconf2.h
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
+ /home/calvin/src/xpdf-4.04/goo/gmem.h
+ /home/calvin/src/xpdf-4.04/goo/gmempp.cc
+ aconf.h
+ aconf2.h
diff --git a/goo/CMakeFiles/goo_objs.dir/depend.make b/goo/CMakeFiles/goo_objs.dir/depend.make
new file mode 100644
index 0000000..73ddd5e
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/depend.make
@@ -0,0 +1,65 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o: goo/parseargs.c
+goo/CMakeFiles/goo_objs.dir/parseargs.c.o: goo/parseargs.h
+
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/FixedPoint.cc
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/FixedPoint.h
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/gmempp.h
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/GHash.cc
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/GHash.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/GString.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/gmempp.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/GHash.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/GList.cc
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/GList.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/gmempp.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/GList.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/GString.cc
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/GString.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/gmempp.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/GString.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/GString.h
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/Trace.cc
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/Trace.h
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/Trace.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/GString.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gfile.cc
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gfile.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gmempp.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: goo/gtypes.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/gfile.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: goo/gmem.cc
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/gmem.cc.o: aconf2.h
+
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: goo/gmem.h
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: goo/gmempp.cc
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: aconf.h
+goo/CMakeFiles/goo_objs.dir/gmempp.cc.o: aconf2.h
+
diff --git a/goo/CMakeFiles/goo_objs.dir/flags.make b/goo/CMakeFiles/goo_objs.dir/flags.make
new file mode 100644
index 0000000..333c351
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/flags.make
@@ -0,0 +1,17 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# compile C with /usr/bin/cc
+# compile CXX with /usr/bin/c++
+C_DEFINES =
+
+C_INCLUDES = -I/home/calvin/src/xpdf-4.04
+
+C_FLAGS = -fPIC
+
+CXX_DEFINES =
+
+CXX_INCLUDES = -I/home/calvin/src/xpdf-4.04
+
+CXX_FLAGS = -fPIC
+
diff --git a/goo/CMakeFiles/goo_objs.dir/gfile.cc.o b/goo/CMakeFiles/goo_objs.dir/gfile.cc.o
new file mode 100644
index 0000000..52c7f2f
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/gfile.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/gmem.cc.o b/goo/CMakeFiles/goo_objs.dir/gmem.cc.o
new file mode 100644
index 0000000..7cd4f45
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/gmem.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/gmempp.cc.o b/goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
new file mode 100644
index 0000000..3df2d88
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/parseargs.c.o b/goo/CMakeFiles/goo_objs.dir/parseargs.c.o
new file mode 100644
index 0000000..4a12c30
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/parseargs.c.o
Binary files differ
diff --git a/goo/CMakeFiles/goo_objs.dir/progress.make b/goo/CMakeFiles/goo_objs.dir/progress.make
new file mode 100644
index 0000000..64ccb15
--- /dev/null
+++ b/goo/CMakeFiles/goo_objs.dir/progress.make
@@ -0,0 +1,10 @@
+CMAKE_PROGRESS_1 = 6
+CMAKE_PROGRESS_2 = 7
+CMAKE_PROGRESS_3 = 8
+CMAKE_PROGRESS_4 =
+CMAKE_PROGRESS_5 = 9
+CMAKE_PROGRESS_6 = 10
+CMAKE_PROGRESS_7 = 11
+CMAKE_PROGRESS_8 =
+CMAKE_PROGRESS_9 = 12
+
diff --git a/goo/CMakeFiles/progress.marks b/goo/CMakeFiles/progress.marks
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/goo/CMakeFiles/progress.marks
@@ -0,0 +1 @@
+7
diff --git a/goo/CMakeLists.txt b/goo/CMakeLists.txt
new file mode 100644
index 0000000..f3f6932
--- /dev/null
+++ b/goo/CMakeLists.txt
@@ -0,0 +1,30 @@
+#========================================================================
+#
+# goo/CMakeLists.txt
+#
+# CMake script for the goo library.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+include_directories("${PROJECT_SOURCE_DIR}")
+include_directories("${PROJECT_BINARY_DIR}")
+
+add_library(goo_objs OBJECT
+ FixedPoint.cc
+ GHash.cc
+ GList.cc
+ GString.cc
+ gfile.cc
+ gmem.cc
+ gmempp.cc
+ parseargs.c
+ Trace.cc
+)
+set_property(TARGET goo_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
+
+add_library(goo
+ $<TARGET_OBJECTS:goo_objs>
+)
diff --git a/goo/FixedPoint.cc b/goo/FixedPoint.cc
new file mode 100644
index 0000000..503a06a
--- /dev/null
+++ b/goo/FixedPoint.cc
@@ -0,0 +1,134 @@
+//========================================================================
+//
+// FixedPoint.cc
+//
+// Fixed point type, with C++ operators.
+//
+// Copyright 2004 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#if USE_FIXEDPOINT
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmempp.h"
+#include "FixedPoint.h"
+
+#define ln2 ((FixedPoint)0.69314718)
+
+FixedPoint FixedPoint::sqrt(FixedPoint x) {
+ FixedPoint y0, y1, z;
+
+ if (x.val <= 0) {
+ y1.val = 0;
+ } else {
+ y1.val = x.val == 1 ? 2 : x.val >> 1;
+ do {
+ y0.val = y1.val;
+ z = x / y0;
+ y1.val = (y0.val + z.val) >> 1;
+ } while (::abs(y0.val - y1.val) > 1);
+ }
+ return y1;
+}
+
+FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
+ FixedPoint t, t2, lnx0, lnx, z0, z;
+ int d, n, i;
+
+ if (y.val <= 0) {
+ z.val = 0;
+ } else {
+ // y * ln(x)
+ t = (x - 1) / (x + 1);
+ t2 = t * t;
+ d = 1;
+ lnx = 0;
+ do {
+ lnx0 = lnx;
+ lnx += t / d;
+ t *= t2;
+ d += 2;
+ } while (::abs(lnx.val - lnx0.val) > 2);
+ lnx.val <<= 1;
+ t = y * lnx;
+ // exp(y * ln(x))
+ n = floor(t / ln2);
+ t -= ln2 * n;
+ t2 = t;
+ d = 1;
+ i = 1;
+ z = 1;
+ do {
+ z0 = z;
+ z += t2 / d;
+ t2 *= t;
+ ++i;
+ d *= i;
+ } while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift));
+ if (n >= 0) {
+ z.val <<= n;
+ } else if (n < 0) {
+ z.val >>= -n;
+ }
+ }
+ return z;
+}
+
+int FixedPoint::mul(int x, int y) {
+ FixPtInt64 z;
+
+ z = ((FixPtInt64)x * y) >> fixptShift;
+ if (z > 0x7fffffffLL) {
+ return 0x7fffffff;
+ } else if (z < -0x80000000LL) {
+ return 0x80000000;
+ } else {
+ return (int)z;
+ }
+}
+
+int FixedPoint::div(int x, int y) {
+ FixPtInt64 z;
+
+ z = ((FixPtInt64)x << fixptShift) / y;
+ if (z > 0x7fffffffLL) {
+ return 0x7fffffff;
+ } else if (z < -0x80000000LL) {
+ return 0x80000000;
+ } else {
+ return (int)z;
+ }
+}
+
+GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
+ FixPtInt64 z;
+
+ z = ((FixPtInt64)x.val << fixptShift) / y.val;
+ if ((z == 0 && x != 0) ||
+ z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
+ return gFalse;
+ }
+ result->val = (int)z;
+ return gTrue;
+}
+
+GBool FixedPoint::checkDet(FixedPoint m11, FixedPoint m12,
+ FixedPoint m21, FixedPoint m22,
+ FixedPoint epsilon) {
+ FixPtInt64 det, e;
+
+ det = (FixPtInt64)m11.val * (FixPtInt64)m22.val
+ - (FixPtInt64)m12.val * (FixPtInt64)m21.val;
+ e = (FixPtInt64)epsilon.val << fixptShift;
+ // NB: this comparison has to be >= not > because epsilon can be
+ // truncated to zero as a fixed point value.
+ return det >= e || det <= -e;
+}
+
+#endif // USE_FIXEDPOINT
diff --git a/goo/FixedPoint.h b/goo/FixedPoint.h
new file mode 100644
index 0000000..9f0c324
--- /dev/null
+++ b/goo/FixedPoint.h
@@ -0,0 +1,180 @@
+//========================================================================
+//
+// FixedPoint.h
+//
+// Fixed point type, with C++ operators.
+//
+// Copyright 2004 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef FIXEDPOINT_H
+#define FIXEDPOINT_H
+
+#include <aconf.h>
+
+#if USE_FIXEDPOINT
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gtypes.h"
+
+#define fixptShift 16
+#define fixptMaskL ((1 << fixptShift) - 1)
+#define fixptMaskH (~fixptMaskL)
+
+typedef long long FixPtInt64;
+
+class FixedPoint {
+public:
+
+ FixedPoint() { val = 0; }
+ FixedPoint(const FixedPoint &x) { val = x.val; }
+ FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
+ FixedPoint(int x) { val = x << fixptShift; }
+ FixedPoint(Guint x) { val = x << fixptShift; }
+ FixedPoint(long x) { val = (int)x << fixptShift; }
+
+ operator float()
+ { return (float) val * ((float)1 / (float)(1 << fixptShift)); }
+ operator double()
+ { return (double) val * (1.0 / (double)(1 << fixptShift)); }
+ operator int()
+ { return val >> fixptShift; }
+
+ int get16Dot16() { return val; }
+
+ FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }
+
+ bool operator ==(FixedPoint x) const { return val == x.val; }
+ bool operator ==(double x) const { return *this == (FixedPoint)x; }
+ bool operator ==(int x) const { return *this == (FixedPoint)x; }
+ bool operator ==(Guint x) const { return *this == (FixedPoint)x; }
+ bool operator ==(long x) const { return *this == (FixedPoint)x; }
+
+ bool operator !=(FixedPoint x) const { return val != x.val; }
+ bool operator !=(double x) const { return *this != (FixedPoint)x; }
+ bool operator !=(int x) const { return *this != (FixedPoint)x; }
+ bool operator !=(Guint x) const { return *this != (FixedPoint)x; }
+ bool operator !=(long x) const { return *this != (FixedPoint)x; }
+
+ bool operator <(FixedPoint x) const { return val < x.val; }
+ bool operator <(double x) const { return *this < (FixedPoint)x; }
+ bool operator <(int x) const { return *this < (FixedPoint)x; }
+ bool operator <(Guint x) const { return *this < (FixedPoint)x; }
+ bool operator <(long x) const { return *this < (FixedPoint)x; }
+
+ bool operator <=(FixedPoint x) const { return val <= x.val; }
+ bool operator <=(double x) const { return *this <= (FixedPoint)x; }
+ bool operator <=(int x) const { return *this <= (FixedPoint)x; }
+ bool operator <=(Guint x) const { return *this <= (FixedPoint)x; }
+ bool operator <=(long x) const { return *this <= (FixedPoint)x; }
+
+ bool operator >(FixedPoint x) const { return val > x.val; }
+ bool operator >(double x) const { return *this > (FixedPoint)x; }
+ bool operator >(int x) const { return *this > (FixedPoint)x; }
+ bool operator >(Guint x) const { return *this > (FixedPoint)x; }
+ bool operator >(long x) const { return *this > (FixedPoint)x; }
+
+ bool operator >=(FixedPoint x) const { return val >= x.val; }
+ bool operator >=(double x) const { return *this >= (FixedPoint)x; }
+ bool operator >=(int x) const { return *this >= (FixedPoint)x; }
+ bool operator >=(Guint x) const { return *this >= (FixedPoint)x; }
+ bool operator >=(long x) const { return *this >= (FixedPoint)x; }
+
+ FixedPoint operator -() { return make(-val); }
+
+ FixedPoint operator +(FixedPoint x) { return make(val + x.val); }
+ FixedPoint operator +(double x) { return *this + (FixedPoint)x; }
+ FixedPoint operator +(int x) { return *this + (FixedPoint)x; }
+ FixedPoint operator +(Guint x) { return *this + (FixedPoint)x; }
+ FixedPoint operator +(long x) { return *this + (FixedPoint)x; }
+
+ FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; }
+ FixedPoint operator +=(double x) { return *this += (FixedPoint)x; }
+ FixedPoint operator +=(int x) { return *this += (FixedPoint)x; }
+ FixedPoint operator +=(Guint x) { return *this += (FixedPoint)x; }
+ FixedPoint operator +=(long x) { return *this += (FixedPoint)x; }
+
+ FixedPoint operator -(FixedPoint x) { return make(val - x.val); }
+ FixedPoint operator -(double x) { return *this - (FixedPoint)x; }
+ FixedPoint operator -(int x) { return *this - (FixedPoint)x; }
+ FixedPoint operator -(Guint x) { return *this - (FixedPoint)x; }
+ FixedPoint operator -(long x) { return *this - (FixedPoint)x; }
+
+ FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; }
+ FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; }
+ FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; }
+ FixedPoint operator -=(Guint x) { return *this -= (FixedPoint)x; }
+ FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; }
+
+ FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); }
+ FixedPoint operator *(double x) { return *this * (FixedPoint)x; }
+ FixedPoint operator *(int x) { return *this * (FixedPoint)x; }
+ FixedPoint operator *(Guint x) { return *this * (FixedPoint)x; }
+ FixedPoint operator *(long x) { return *this * (FixedPoint)x; }
+
+ FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; }
+ FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; }
+ FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; }
+ FixedPoint operator *=(Guint x) { return *this *= (FixedPoint)x; }
+ FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; }
+
+ FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); }
+ FixedPoint operator /(double x) { return *this / (FixedPoint)x; }
+ FixedPoint operator /(int x) { return *this / (FixedPoint)x; }
+ FixedPoint operator /(Guint x) { return *this / (FixedPoint)x; }
+ FixedPoint operator /(long x) { return *this / (FixedPoint)x; }
+
+ FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; }
+ FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; }
+ FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; }
+ FixedPoint operator /=(Guint x) { return *this /= (FixedPoint)x; }
+ FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; }
+
+ static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); }
+
+ static int floor(FixedPoint x) { return x.val >> fixptShift; }
+
+ static int ceil(FixedPoint x)
+ { return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1)
+ : (x.val >> fixptShift); }
+
+ static int round(FixedPoint x)
+ { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; }
+
+ // Computes (x+y)/2 avoiding overflow and LSbit accuracy issues.
+ static FixedPoint avg(FixedPoint x, FixedPoint y)
+ { return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }
+
+ static FixedPoint sqrt(FixedPoint x);
+
+ static FixedPoint pow(FixedPoint x, FixedPoint y);
+
+ // Compute *result = x/y; return false if there is an underflow or
+ // overflow.
+ static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);
+
+ // Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case
+ // where the multiplications overflow.
+ static GBool checkDet(FixedPoint m11, FixedPoint m12,
+ FixedPoint m21, FixedPoint m22,
+ FixedPoint epsilon);
+
+private:
+
+ static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }
+
+ static int mul(int x, int y);
+ static int div(int x, int y);
+
+ int val; // fixed point: (n-fixptShift).(fixptShift)
+};
+
+#endif // USE_FIXEDPOINT
+
+#endif
diff --git a/goo/GHash.cc b/goo/GHash.cc
new file mode 100644
index 0000000..e6b3244
--- /dev/null
+++ b/goo/GHash.cc
@@ -0,0 +1,385 @@
+//========================================================================
+//
+// GHash.cc
+//
+// Copyright 2001-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GString.h"
+#include "GHash.h"
+
+//------------------------------------------------------------------------
+
+struct GHashBucket {
+ GString *key;
+ union {
+ void *p;
+ int i;
+ } val;
+ GHashBucket *next;
+};
+
+struct GHashIter {
+ int h;
+ GHashBucket *p;
+};
+
+//------------------------------------------------------------------------
+
+GHash::GHash(GBool deleteKeysA) {
+ int h;
+
+ deleteKeys = deleteKeysA;
+ size = 7;
+ tab = (GHashBucket **)gmallocn(size, sizeof(GHashBucket *));
+ for (h = 0; h < size; ++h) {
+ tab[h] = NULL;
+ }
+ len = 0;
+}
+
+GHash::~GHash() {
+ GHashBucket *p;
+ int h;
+
+ for (h = 0; h < size; ++h) {
+ while (tab[h]) {
+ p = tab[h];
+ tab[h] = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ delete p;
+ }
+ }
+ gfree(tab);
+}
+
+void GHash::add(GString *key, void *val) {
+ GHashBucket *p;
+ int h;
+
+ // expand the table if necessary
+ if (len >= size) {
+ expand();
+ }
+
+ // add the new symbol
+ p = new GHashBucket;
+ p->key = key;
+ p->val.p = val;
+ h = hash(key);
+ p->next = tab[h];
+ tab[h] = p;
+ ++len;
+}
+
+void GHash::add(GString *key, int val) {
+ GHashBucket *p;
+ int h;
+
+ // expand the table if necessary
+ if (len >= size) {
+ expand();
+ }
+
+ // add the new symbol
+ p = new GHashBucket;
+ p->key = key;
+ p->val.i = val;
+ h = hash(key);
+ p->next = tab[h];
+ tab[h] = p;
+ ++len;
+}
+
+void GHash::replace(GString *key, void *val) {
+ GHashBucket *p;
+ int h;
+
+ if ((p = find(key, &h))) {
+ p->val.p = val;
+ if (deleteKeys) {
+ delete key;
+ }
+ } else {
+ add(key, val);
+ }
+}
+
+void GHash::replace(GString *key, int val) {
+ GHashBucket *p;
+ int h;
+
+ if ((p = find(key, &h))) {
+ p->val.i = val;
+ if (deleteKeys) {
+ delete key;
+ }
+ } else {
+ add(key, val);
+ }
+}
+
+void *GHash::lookup(GString *key) {
+ GHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ return p->val.p;
+}
+
+int GHash::lookupInt(GString *key) {
+ GHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ return p->val.i;
+}
+
+void *GHash::lookup(const char *key) {
+ GHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ return p->val.p;
+}
+
+int GHash::lookupInt(const char *key) {
+ GHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ return p->val.i;
+}
+
+void *GHash::remove(GString *key) {
+ GHashBucket *p;
+ GHashBucket **q;
+ void *val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.p;
+ delete p;
+ --len;
+ return val;
+}
+
+int GHash::removeInt(GString *key) {
+ GHashBucket *p;
+ GHashBucket **q;
+ int val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.i;
+ delete p;
+ --len;
+ return val;
+}
+
+void *GHash::remove(const char *key) {
+ GHashBucket *p;
+ GHashBucket **q;
+ void *val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.p;
+ delete p;
+ --len;
+ return val;
+}
+
+int GHash::removeInt(const char *key) {
+ GHashBucket *p;
+ GHashBucket **q;
+ int val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.i;
+ delete p;
+ --len;
+ return val;
+}
+
+void GHash::startIter(GHashIter **iter) {
+ *iter = new GHashIter;
+ (*iter)->h = -1;
+ (*iter)->p = NULL;
+}
+
+GBool GHash::getNext(GHashIter **iter, GString **key, void **val) {
+ if (!*iter) {
+ return gFalse;
+ }
+ if ((*iter)->p) {
+ (*iter)->p = (*iter)->p->next;
+ }
+ while (!(*iter)->p) {
+ if (++(*iter)->h == size) {
+ delete *iter;
+ *iter = NULL;
+ return gFalse;
+ }
+ (*iter)->p = tab[(*iter)->h];
+ }
+ *key = (*iter)->p->key;
+ *val = (*iter)->p->val.p;
+ return gTrue;
+}
+
+GBool GHash::getNext(GHashIter **iter, GString **key, int *val) {
+ if (!*iter) {
+ return gFalse;
+ }
+ if ((*iter)->p) {
+ (*iter)->p = (*iter)->p->next;
+ }
+ while (!(*iter)->p) {
+ if (++(*iter)->h == size) {
+ delete *iter;
+ *iter = NULL;
+ return gFalse;
+ }
+ (*iter)->p = tab[(*iter)->h];
+ }
+ *key = (*iter)->p->key;
+ *val = (*iter)->p->val.i;
+ return gTrue;
+}
+
+void GHash::killIter(GHashIter **iter) {
+ delete *iter;
+ *iter = NULL;
+}
+
+void GHash::expand() {
+ GHashBucket **oldTab;
+ GHashBucket *p;
+ int oldSize, h, i;
+
+ oldSize = size;
+ oldTab = tab;
+ size = 2*size + 1;
+ tab = (GHashBucket **)gmallocn(size, sizeof(GHashBucket *));
+ for (h = 0; h < size; ++h) {
+ tab[h] = NULL;
+ }
+ for (i = 0; i < oldSize; ++i) {
+ while (oldTab[i]) {
+ p = oldTab[i];
+ oldTab[i] = oldTab[i]->next;
+ h = hash(p->key);
+ p->next = tab[h];
+ tab[h] = p;
+ }
+ }
+ gfree(oldTab);
+}
+
+GHashBucket *GHash::find(GString *key, int *h) {
+ GHashBucket *p;
+
+ *h = hash(key);
+ for (p = tab[*h]; p; p = p->next) {
+ if (!p->key->cmp(key)) {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+GHashBucket *GHash::find(const char *key, int *h) {
+ GHashBucket *p;
+
+ *h = hash(key);
+ for (p = tab[*h]; p; p = p->next) {
+ if (!p->key->cmp(key)) {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+int GHash::hash(GString *key) {
+ const char *p;
+ unsigned int h;
+ int i;
+
+ h = 0;
+ for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) {
+ h = 17 * h + (int)(*p & 0xff);
+ }
+ return (int)(h % size);
+}
+
+int GHash::hash(const char *key) {
+ const char *p;
+ unsigned int h;
+
+ h = 0;
+ for (p = key; *p; ++p) {
+ h = 17 * h + (int)(*p & 0xff);
+ }
+ return (int)(h % size);
+}
diff --git a/goo/GHash.h b/goo/GHash.h
new file mode 100644
index 0000000..179753a
--- /dev/null
+++ b/goo/GHash.h
@@ -0,0 +1,78 @@
+//========================================================================
+//
+// GHash.h
+//
+// Copyright 2001-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef GHASH_H
+#define GHASH_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+class GString;
+struct GHashBucket;
+struct GHashIter;
+
+//------------------------------------------------------------------------
+
+class GHash {
+public:
+
+ GHash(GBool deleteKeysA = gFalse);
+ ~GHash();
+ void add(GString *key, void *val);
+ void add(GString *key, int val);
+ void replace(GString *key, void *val);
+ void replace(GString *key, int val);
+ void *lookup(GString *key);
+ int lookupInt(GString *key);
+ void *lookup(const char *key);
+ int lookupInt(const char *key);
+ void *remove(GString *key);
+ int removeInt(GString *key);
+ void *remove(const char *key);
+ int removeInt(const char *key);
+ int getLength() { return len; }
+ void startIter(GHashIter **iter);
+ GBool getNext(GHashIter **iter, GString **key, void **val);
+ GBool getNext(GHashIter **iter, GString **key, int *val);
+ void killIter(GHashIter **iter);
+
+private:
+
+ void expand();
+ GHashBucket *find(GString *key, int *h);
+ GHashBucket *find(const char *key, int *h);
+ int hash(GString *key);
+ int hash(const char *key);
+
+ GBool deleteKeys; // set if key strings should be deleted
+ int size; // number of buckets
+ int len; // number of entries
+ GHashBucket **tab;
+};
+
+#define deleteGHash(hash, T) \
+ do { \
+ GHash *_hash = (hash); \
+ { \
+ GHashIter *_iter; \
+ GString *_key; \
+ void *_p; \
+ _hash->startIter(&_iter); \
+ while (_hash->getNext(&_iter, &_key, &_p)) { \
+ delete (T*)_p; \
+ } \
+ delete _hash; \
+ } \
+ } while(0)
+
+#endif
diff --git a/goo/GList.cc b/goo/GList.cc
new file mode 100644
index 0000000..c194818
--- /dev/null
+++ b/goo/GList.cc
@@ -0,0 +1,123 @@
+//========================================================================
+//
+// GList.cc
+//
+// Copyright 2001-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "gmem.h"
+#include "gmempp.h"
+#include "GList.h"
+
+//------------------------------------------------------------------------
+// GList
+//------------------------------------------------------------------------
+
+GList::GList() {
+ size = 8;
+ data = (void **)gmallocn(size, sizeof(void*));
+ length = 0;
+ inc = 0;
+}
+
+GList::GList(int sizeA) {
+ size = sizeA ? sizeA : 8;
+ data = (void **)gmallocn(size, sizeof(void*));
+ length = 0;
+ inc = 0;
+}
+
+GList::~GList() {
+ gfree(data);
+}
+
+GList *GList::copy() {
+ GList *ret;
+
+ ret = new GList(length);
+ ret->length = length;
+ memcpy(ret->data, data, length * sizeof(void *));
+ ret->inc = inc;
+ return ret;
+}
+
+void GList::append(void *p) {
+ if (length >= size) {
+ expand();
+ }
+ data[length++] = p;
+}
+
+void GList::append(GList *list) {
+ int i;
+
+ while (length + list->length > size) {
+ expand();
+ }
+ for (i = 0; i < list->length; ++i) {
+ data[length++] = list->data[i];
+ }
+}
+
+void GList::insert(int i, void *p) {
+ if (length >= size) {
+ expand();
+ }
+ if (i < 0) {
+ i = 0;
+ }
+ if (i < length) {
+ memmove(data+i+1, data+i, (length - i) * sizeof(void *));
+ }
+ data[i] = p;
+ ++length;
+}
+
+void *GList::del(int i) {
+ void *p;
+
+ p = data[i];
+ if (i < length - 1) {
+ memmove(data+i, data+i+1, (length - i - 1) * sizeof(void *));
+ }
+ --length;
+ if (size - length >= ((inc > 0) ? inc : size/2)) {
+ shrink();
+ }
+ return p;
+}
+
+void GList::sort(int (*cmp)(const void *obj1, const void *obj2)) {
+ qsort(data, length, sizeof(void *), cmp);
+}
+
+void GList::reverse() {
+ void *t;
+ int n, i;
+
+ n = length / 2;
+ for (i = 0; i < n; ++i) {
+ t = data[i];
+ data[i] = data[length - 1 - i];
+ data[length - 1 - i] = t;
+ }
+}
+
+void GList::expand() {
+ size += (inc > 0) ? inc : size;
+ data = (void **)greallocn(data, size, sizeof(void*));
+}
+
+void GList::shrink() {
+ size -= (inc > 0) ? inc : size/2;
+ data = (void **)greallocn(data, size, sizeof(void*));
+}
diff --git a/goo/GList.h b/goo/GList.h
new file mode 100644
index 0000000..0050437
--- /dev/null
+++ b/goo/GList.h
@@ -0,0 +1,106 @@
+//========================================================================
+//
+// GList.h
+//
+// Copyright 2001-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef GLIST_H
+#define GLIST_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+//------------------------------------------------------------------------
+// GList
+//------------------------------------------------------------------------
+
+class GList {
+public:
+
+ // Create an empty list.
+ GList();
+
+ // Create an empty list with space for <size1> elements.
+ GList(int sizeA);
+
+ // Destructor - does not free pointed-to objects.
+ ~GList();
+
+ //----- general
+
+ // Get the number of elements.
+ int getLength() { return length; }
+
+ // Returns a (shallow) copy of this list.
+ GList *copy();
+
+ //----- ordered list support
+
+ // Return the <i>th element.
+ // Assumes 0 <= i < length.
+ void *get(int i) { return data[i]; }
+
+ // Replace the <i>th element.
+ // Assumes 0 <= i < length.
+ void put(int i, void *p) { data[i] = p; }
+
+ // Append an element to the end of the list.
+ void append(void *p);
+
+ // Append another list to the end of this one.
+ void append(GList *list);
+
+ // Insert an element at index <i>.
+ // Assumes 0 <= i <= length.
+ void insert(int i, void *p);
+
+ // Deletes and returns the element at index <i>.
+ // Assumes 0 <= i < length.
+ void *del(int i);
+
+ // Sort the list accoring to the given comparison function.
+ // NB: this sorts an array of pointers, so the pointer args need to
+ // be double-dereferenced.
+ void sort(int (*cmp)(const void *ptr1, const void *ptr2));
+
+ // Reverse the list.
+ void reverse();
+
+ //----- control
+
+ // Set allocation increment to <inc>. If inc > 0, that many
+ // elements will be allocated every time the list is expanded.
+ // If inc <= 0, the list will be doubled in size.
+ void setAllocIncr(int incA) { inc = incA; }
+
+private:
+
+ void expand();
+ void shrink();
+
+ void **data; // the list elements
+ int size; // size of data array
+ int length; // number of elements on list
+ int inc; // allocation increment
+};
+
+#define deleteGList(list, T) \
+ do { \
+ GList *_list = (list); \
+ { \
+ int _i; \
+ for (_i = 0; _i < _list->getLength(); ++_i) { \
+ delete (T*)_list->get(_i); \
+ } \
+ delete _list; \
+ } \
+ } while (0)
+
+#endif
diff --git a/goo/GMutex.h b/goo/GMutex.h
new file mode 100644
index 0000000..aef4aec
--- /dev/null
+++ b/goo/GMutex.h
@@ -0,0 +1,101 @@
+//========================================================================
+//
+// GMutex.h
+//
+// Portable mutex macros.
+// Portable atomic increment/decrement.
+//
+// Copyright 2002-2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef GMUTEX_H
+#define GMUTEX_H
+
+#include <aconf.h>
+#ifdef _WIN32
+# include <windows.h>
+# include <intrin.h>
+#else
+# include <pthread.h>
+#endif
+
+//------------------------------------------------------------------------
+// GMutex
+//------------------------------------------------------------------------
+
+// Usage:
+//
+// GMutex m;
+// gInitMutex(&m);
+// ...
+// gLockMutex(&m);
+// ... critical section ...
+// gUnlockMutex(&m);
+// ...
+// gDestroyMutex(&m);
+
+#ifdef _WIN32
+
+typedef CRITICAL_SECTION GMutex;
+
+#define gInitMutex(m) InitializeCriticalSection(m)
+#define gDestroyMutex(m) DeleteCriticalSection(m)
+#define gLockMutex(m) EnterCriticalSection(m)
+#define gUnlockMutex(m) LeaveCriticalSection(m)
+
+#else // assume pthreads
+
+typedef pthread_mutex_t GMutex;
+
+#define gInitMutex(m) pthread_mutex_init(m, NULL)
+#define gDestroyMutex(m) pthread_mutex_destroy(m)
+#define gLockMutex(m) pthread_mutex_lock(m)
+#define gUnlockMutex(m) pthread_mutex_unlock(m)
+
+#endif
+
+//------------------------------------------------------------------------
+// atomic increment/decrement
+//------------------------------------------------------------------------
+
+// NB: this must be "long" to work on Windows
+typedef long GAtomicCounter;
+
+// Increment *counter by one and return the final value (after the
+// increment).
+static inline GAtomicCounter gAtomicIncrement(GAtomicCounter *counter) {
+ GAtomicCounter newVal;
+
+#if defined(_WIN32)
+ newVal = _InterlockedIncrement(counter);
+#elif defined(__GNUC__) || defined(__xlC__)
+ // __GNUC__ also covers LLVM/clang
+ newVal = __sync_add_and_fetch(counter, 1);
+#elif defined(__SUNPRO_CC)
+ newVal = atomic_inc_ulong_nv((ulong_t *)counter);
+#else
+# error "gAtomicIncrement is not defined for this compiler/platform"
+#endif
+ return newVal;
+}
+
+// Decrement *counter by one and return the final value (after the
+// decrement).
+static inline GAtomicCounter gAtomicDecrement(GAtomicCounter *counter) {
+ GAtomicCounter newVal;
+
+#if defined(_WIN32)
+ newVal = _InterlockedDecrement(counter);
+#elif defined(__GNUC__) || defined(__xlC__)
+ // __GNUC__ also covers LLVM/clang
+ newVal = __sync_sub_and_fetch(counter, 1);
+#elif defined(__SUNPRO_CC)
+ newVal = atomic_dec_ulong_nv((ulong_t *)counter);
+#else
+# error "gAtomicDecrement is not defined for this compiler/platform"
+#endif
+ return newVal;
+}
+
+#endif // GMUTEX_H
diff --git a/goo/GString.cc b/goo/GString.cc
new file mode 100644
index 0000000..54de35b
--- /dev/null
+++ b/goo/GString.cc
@@ -0,0 +1,853 @@
+//========================================================================
+//
+// GString.cc
+//
+// Simple variable-length string type.
+//
+// Copyright 1996-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <limits.h>
+#include "gmem.h"
+#include "gmempp.h"
+#include "GString.h"
+
+//------------------------------------------------------------------------
+
+union GStringFormatArg {
+ int i;
+ Guint ui;
+ long l;
+ Gulong ul;
+#ifdef LLONG_MAX
+ long long ll;
+#endif
+#ifdef ULLONG_MAX
+ unsigned long long ull;
+#endif
+ double f;
+ char c;
+ char *s;
+ GString *gs;
+};
+
+enum GStringFormatType {
+ fmtIntDecimal,
+ fmtIntHex,
+ fmtIntOctal,
+ fmtIntBinary,
+ fmtUIntDecimal,
+ fmtUIntHex,
+ fmtUIntOctal,
+ fmtUIntBinary,
+ fmtLongDecimal,
+ fmtLongHex,
+ fmtLongOctal,
+ fmtLongBinary,
+ fmtULongDecimal,
+ fmtULongHex,
+ fmtULongOctal,
+ fmtULongBinary,
+#ifdef LLONG_MAX
+ fmtLongLongDecimal,
+ fmtLongLongHex,
+ fmtLongLongOctal,
+ fmtLongLongBinary,
+#endif
+#ifdef ULLONG_MAX
+ fmtULongLongDecimal,
+ fmtULongLongHex,
+ fmtULongLongOctal,
+ fmtULongLongBinary,
+#endif
+ fmtDouble,
+ fmtDoubleTrim,
+ fmtChar,
+ fmtString,
+ fmtGString,
+ fmtSpace
+};
+
+static const char *formatStrings[] = {
+ "d", "x", "o", "b", "ud", "ux", "uo", "ub",
+ "ld", "lx", "lo", "lb", "uld", "ulx", "ulo", "ulb",
+#ifdef LLONG_MAX
+ "lld", "llx", "llo", "llb",
+#endif
+#ifdef ULLONG_MAX
+ "ulld", "ullx", "ullo", "ullb",
+#endif
+ "f", "g",
+ "c",
+ "s",
+ "t",
+ "w",
+ NULL
+};
+
+//------------------------------------------------------------------------
+
+static inline int size(int len) {
+ int delta;
+ for (delta = 8; delta < len && delta < 0x100000; delta <<= 1) ;
+ if (len > INT_MAX - delta) {
+ gMemError("Integer overflow in GString::size()");
+ }
+ // this is ((len + 1) + (delta - 1)) & ~(delta - 1)
+ return (len + delta) & ~(delta - 1);
+}
+
+inline void GString::resize(int length1) {
+ char *s1;
+
+ if (length1 < 0) {
+ gMemError("GString::resize() with negative length");
+ }
+ if (!s) {
+ s = new char[size(length1)];
+ } else if (size(length1) != size(length)) {
+ s1 = new char[size(length1)];
+ if (length1 < length) {
+ memcpy(s1, s, length1);
+ s1[length1] = '\0';
+ } else {
+ memcpy(s1, s, length + 1);
+ }
+ delete[] s;
+ s = s1;
+ }
+}
+
+GString::GString() {
+ s = NULL;
+ resize(length = 0);
+ s[0] = '\0';
+}
+
+GString::GString(const char *sA) {
+ int n = (int)strlen(sA);
+
+ s = NULL;
+ resize(length = n);
+ memcpy(s, sA, n + 1);
+}
+
+GString::GString(const char *sA, int lengthA) {
+ s = NULL;
+ resize(length = lengthA);
+ memcpy(s, sA, length * sizeof(char));
+ s[length] = '\0';
+}
+
+GString::GString(GString *str, int idx, int lengthA) {
+ s = NULL;
+ resize(length = lengthA);
+ memcpy(s, str->getCString() + idx, length);
+ s[length] = '\0';
+}
+
+GString::GString(GString *str) {
+ s = NULL;
+ resize(length = str->getLength());
+ memcpy(s, str->getCString(), length + 1);
+}
+
+GString::GString(GString *str1, GString *str2) {
+ int n1 = str1->getLength();
+ int n2 = str2->getLength();
+
+ s = NULL;
+ if (n1 > INT_MAX - n2) {
+ gMemError("Integer overflow in GString::GString()");
+ }
+ resize(length = n1 + n2);
+ memcpy(s, str1->getCString(), n1);
+ memcpy(s + n1, str2->getCString(), n2 + 1);
+}
+
+GString *GString::fromInt(int x) {
+ char buf[24]; // enough space for 64-bit ints plus a little extra
+ const char *p;
+ int len;
+
+ formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len);
+ return new GString(p, len);
+}
+
+GString *GString::format(const char *fmt, ...) {
+ va_list argList;
+ GString *s;
+
+ s = new GString();
+ va_start(argList, fmt);
+ s->appendfv(fmt, argList);
+ va_end(argList);
+ return s;
+}
+
+GString *GString::formatv(const char *fmt, va_list argList) {
+ GString *s;
+
+ s = new GString();
+ s->appendfv(fmt, argList);
+ return s;
+}
+
+GString::~GString() {
+ delete[] s;
+}
+
+GString *GString::clear() {
+ s[length = 0] = '\0';
+ resize(0);
+ return this;
+}
+
+GString *GString::append(char c) {
+ if (length > INT_MAX - 1) {
+ gMemError("Integer overflow in GString::append()");
+ }
+ resize(length + 1);
+ s[length++] = c;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::append(GString *str) {
+ int n = str->getLength();
+
+ if (length > INT_MAX - n) {
+ gMemError("Integer overflow in GString::append()");
+ }
+ resize(length + n);
+ memcpy(s + length, str->getCString(), n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(const char *str) {
+ int n = (int)strlen(str);
+
+ if (length > INT_MAX - n) {
+ gMemError("Integer overflow in GString::append()");
+ }
+ resize(length + n);
+ memcpy(s + length, str, n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(const char *str, int lengthA) {
+ if (lengthA < 0 || length > INT_MAX - lengthA) {
+ gMemError("Integer overflow in GString::append()");
+ }
+ resize(length + lengthA);
+ memcpy(s + length, str, lengthA);
+ length += lengthA;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::appendf(const char *fmt, ...) {
+ va_list argList;
+
+ va_start(argList, fmt);
+ appendfv(fmt, argList);
+ va_end(argList);
+ return this;
+}
+
+GString *GString::appendfv(const char *fmt, va_list argList) {
+ GStringFormatArg *args;
+ int argsLen, argsSize;
+ GStringFormatArg arg;
+ int idx, width, prec;
+ GBool reverseAlign, zeroFill;
+ GStringFormatType ft;
+ char buf[65];
+ int len, i;
+ const char *p0, *p1;
+ const char *str;
+
+ argsLen = 0;
+ argsSize = 8;
+ args = (GStringFormatArg *)gmallocn(argsSize, sizeof(GStringFormatArg));
+
+ p0 = fmt;
+ while (*p0) {
+ if (*p0 == '{') {
+ ++p0;
+ if (*p0 == '{') {
+ ++p0;
+ append('{');
+ } else {
+
+ // parse the format string
+ if (!(*p0 >= '0' && *p0 <= '9')) {
+ break;
+ }
+ idx = *p0 - '0';
+ for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ idx = 10 * idx + (*p0 - '0');
+ }
+ if (*p0 != ':') {
+ break;
+ }
+ ++p0;
+ if (*p0 == '-') {
+ reverseAlign = gTrue;
+ ++p0;
+ } else {
+ reverseAlign = gFalse;
+ }
+ width = 0;
+ zeroFill = *p0 == '0';
+ for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ width = 10 * width + (*p0 - '0');
+ }
+ if (width < 0) {
+ width = 0;
+ }
+ if (*p0 == '.') {
+ ++p0;
+ prec = 0;
+ for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ prec = 10 * prec + (*p0 - '0');
+ }
+ } else {
+ prec = 0;
+ }
+ for (ft = (GStringFormatType)0;
+ formatStrings[ft];
+ ft = (GStringFormatType)(ft + 1)) {
+ if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) {
+ break;
+ }
+ }
+ if (!formatStrings[ft]) {
+ break;
+ }
+ p0 += strlen(formatStrings[ft]);
+ if (*p0 != '}') {
+ break;
+ }
+ ++p0;
+
+ // fetch the argument
+ if (idx > argsLen) {
+ break;
+ }
+ if (idx == argsLen) {
+ if (argsLen == argsSize) {
+ argsSize *= 2;
+ args = (GStringFormatArg *)greallocn(args, argsSize,
+ sizeof(GStringFormatArg));
+ }
+ switch (ft) {
+ case fmtIntDecimal:
+ case fmtIntHex:
+ case fmtIntOctal:
+ case fmtIntBinary:
+ case fmtSpace:
+ args[argsLen].i = va_arg(argList, int);
+ break;
+ case fmtUIntDecimal:
+ case fmtUIntHex:
+ case fmtUIntOctal:
+ case fmtUIntBinary:
+ args[argsLen].ui = va_arg(argList, Guint);
+ break;
+ case fmtLongDecimal:
+ case fmtLongHex:
+ case fmtLongOctal:
+ case fmtLongBinary:
+ args[argsLen].l = va_arg(argList, long);
+ break;
+ case fmtULongDecimal:
+ case fmtULongHex:
+ case fmtULongOctal:
+ case fmtULongBinary:
+ args[argsLen].ul = va_arg(argList, Gulong);
+ break;
+#ifdef LLONG_MAX
+ case fmtLongLongDecimal:
+ case fmtLongLongHex:
+ case fmtLongLongOctal:
+ case fmtLongLongBinary:
+ args[argsLen].ll = va_arg(argList, long long);
+ break;
+#endif
+#ifdef ULLONG_MAX
+ case fmtULongLongDecimal:
+ case fmtULongLongHex:
+ case fmtULongLongOctal:
+ case fmtULongLongBinary:
+ args[argsLen].ull = va_arg(argList, unsigned long long);
+ break;
+#endif
+ case fmtDouble:
+ case fmtDoubleTrim:
+ args[argsLen].f = va_arg(argList, double);
+ break;
+ case fmtChar:
+ args[argsLen].c = (char)va_arg(argList, int);
+ break;
+ case fmtString:
+ args[argsLen].s = va_arg(argList, char *);
+ break;
+ case fmtGString:
+ args[argsLen].gs = va_arg(argList, GString *);
+ break;
+ }
+ ++argsLen;
+ }
+
+ // format the argument
+ arg = args[idx];
+ switch (ft) {
+ case fmtIntDecimal:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
+ break;
+ case fmtIntHex:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
+ break;
+ case fmtIntOctal:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtIntBinary:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtUIntDecimal:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 10,
+ &str, &len);
+ break;
+ case fmtUIntHex:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16,
+ &str, &len);
+ break;
+ case fmtUIntOctal:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtUIntBinary:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtLongDecimal:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
+ break;
+ case fmtLongHex:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
+ break;
+ case fmtLongOctal:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtLongBinary:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtULongDecimal:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 10,
+ &str, &len);
+ break;
+ case fmtULongHex:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16,
+ &str, &len);
+ break;
+ case fmtULongOctal:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtULongBinary:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+#ifdef LLONG_MAX
+ case fmtLongLongDecimal:
+ formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
+ break;
+ case fmtLongLongHex:
+ formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
+ break;
+ case fmtLongLongOctal:
+ formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtLongLongBinary:
+ formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+#endif
+#ifdef ULLONG_MAX
+ case fmtULongLongDecimal:
+ formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 10,
+ &str, &len);
+ break;
+ case fmtULongLongHex:
+ formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 16,
+ &str, &len);
+ break;
+ case fmtULongLongOctal:
+ formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 8,
+ &str, &len);
+ break;
+ case fmtULongLongBinary:
+ formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 2,
+ &str, &len);
+ break;
+#endif
+ case fmtDouble:
+ formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len);
+ break;
+ case fmtDoubleTrim:
+ formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len);
+ break;
+ case fmtChar:
+ buf[0] = arg.c;
+ str = buf;
+ len = 1;
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtString:
+ if (arg.s) {
+ str = arg.s;
+ len = (int)strlen(str);
+ } else {
+ str = "(null)";
+ len = 6;
+ }
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtGString:
+ if (arg.gs) {
+ str = arg.gs->getCString();
+ len = arg.gs->getLength();
+ } else {
+ str = "(null)";
+ len = 6;
+ }
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtSpace:
+ str = buf;
+ len = 0;
+ width = arg.i;
+ break;
+ }
+
+ // append the formatted arg, handling width and alignment
+ if (!reverseAlign && len < width) {
+ for (i = len; i < width; ++i) {
+ append(' ');
+ }
+ }
+ append(str, len);
+ if (reverseAlign && len < width) {
+ for (i = len; i < width; ++i) {
+ append(' ');
+ }
+ }
+ }
+
+ } else if (*p0 == '}') {
+ ++p0;
+ if (*p0 == '}') {
+ ++p0;
+ }
+ append('}');
+
+ } else {
+ for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ;
+ append(p0, (int)(p1 - p0));
+ p0 = p1;
+ }
+ }
+
+ gfree(args);
+ return this;
+}
+
+#ifdef LLONG_MAX
+void GString::formatInt(long long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len) {
+#else
+void GString::formatInt(long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len) {
+#endif
+ static char vals[17] = "0123456789abcdef";
+ GBool neg;
+ int start, i, j;
+
+ i = bufSize;
+ if ((neg = x < 0)) {
+ x = -x;
+ }
+ start = neg ? 1 : 0;
+ if (x == 0) {
+ buf[--i] = '0';
+ } else {
+ while (i > start && x) {
+ buf[--i] = vals[x % base];
+ x /= base;
+ }
+ }
+ if (zeroFill) {
+ for (j = bufSize - i; i > start && j < width - start; ++j) {
+ buf[--i] = '0';
+ }
+ }
+ if (neg) {
+ buf[--i] = '-';
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
+#ifdef ULLONG_MAX
+void GString::formatUInt(unsigned long long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len) {
+#else
+void GString::formatUInt(Gulong x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len) {
+#endif
+ static char vals[17] = "0123456789abcdef";
+ int i, j;
+
+ i = bufSize;
+ if (x == 0) {
+ buf[--i] = '0';
+ } else {
+ while (i > 0 && x) {
+ buf[--i] = vals[x % base];
+ x /= base;
+ }
+ }
+ if (zeroFill) {
+ for (j = bufSize - i; i > 0 && j < width; ++j) {
+ buf[--i] = '0';
+ }
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
+void GString::formatDouble(double x, char *buf, int bufSize, int prec,
+ GBool trim, const char **p, int *len) {
+ GBool neg, started;
+ double x2;
+ int d, i, j;
+
+ if ((neg = x < 0)) {
+ x = -x;
+ }
+ x = floor(x * pow(10.0, prec) + 0.5);
+ i = bufSize;
+ started = !trim;
+ for (j = 0; j < prec && i > 1; ++j) {
+ x2 = floor(0.1 * (x + 0.5));
+ d = (int)floor(x - 10 * x2 + 0.5);
+ if (started || d != 0) {
+ buf[--i] = (char)('0' + d);
+ started = gTrue;
+ }
+ x = x2;
+ }
+ if (i > 1 && started) {
+ buf[--i] = '.';
+ }
+ if (i > 1) {
+ do {
+ x2 = floor(0.1 * (x + 0.5));
+ d = (int)floor(x - 10 * x2 + 0.5);
+ buf[--i] = (char)('0' + d);
+ x = x2;
+ } while (i > 1 && x);
+ }
+ if (neg) {
+ buf[--i] = '-';
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
+GString *GString::insert(int i, char c) {
+ int j;
+
+ if (length > INT_MAX - 1) {
+ gMemError("Integer overflow in GString::insert()");
+ }
+ resize(length + 1);
+ for (j = length + 1; j > i; --j)
+ s[j] = s[j-1];
+ s[i] = c;
+ ++length;
+ return this;
+}
+
+GString *GString::insert(int i, GString *str) {
+ int n = str->getLength();
+ int j;
+
+ if (length > INT_MAX - n) {
+ gMemError("Integer overflow in GString::insert()");
+ }
+ resize(length + n);
+ for (j = length; j >= i; --j)
+ s[j+n] = s[j];
+ memcpy(s+i, str->getCString(), n);
+ length += n;
+ return this;
+}
+
+GString *GString::insert(int i, const char *str) {
+ int n = (int)strlen(str);
+ int j;
+
+ if (length > INT_MAX - n) {
+ gMemError("Integer overflow in GString::insert()");
+ }
+ resize(length + n);
+ for (j = length; j >= i; --j)
+ s[j+n] = s[j];
+ memcpy(s+i, str, n);
+ length += n;
+ return this;
+}
+
+GString *GString::insert(int i, const char *str, int lengthA) {
+ int j;
+
+ if (lengthA < 0 || length > INT_MAX - lengthA) {
+ gMemError("Integer overflow in GString::insert()");
+ }
+ resize(length + lengthA);
+ for (j = length; j >= i; --j)
+ s[j+lengthA] = s[j];
+ memcpy(s+i, str, lengthA);
+ length += lengthA;
+ return this;
+}
+
+GString *GString::del(int i, int n) {
+ int j;
+
+ if (i >= 0 && n > 0 && i <= INT_MAX - n) {
+ if (i + n > length) {
+ n = length - i;
+ }
+ for (j = i; j <= length - n; ++j) {
+ s[j] = s[j + n];
+ }
+ resize(length -= n);
+ }
+ return this;
+}
+
+GString *GString::upperCase() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (islower(s[i] & 0xff)) {
+ s[i] = (char)toupper(s[i] & 0xff);
+ }
+ }
+ return this;
+}
+
+GString *GString::lowerCase() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (isupper(s[i] & 0xff)) {
+ s[i] = (char)tolower(s[i] & 0xff);
+ }
+ }
+ return this;
+}
+
+int GString::cmp(GString *str) {
+ int n1, n2, i, x;
+ char *p1, *p2;
+
+ n1 = length;
+ n2 = str->length;
+ for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
+ x = (*p1 & 0xff) - (*p2 & 0xff);
+ if (x != 0) {
+ return x;
+ }
+ }
+ return n1 - n2;
+}
+
+int GString::cmpN(GString *str, int n) {
+ int n1, n2, i, x;
+ char *p1, *p2;
+
+ n1 = length;
+ n2 = str->length;
+ for (i = 0, p1 = s, p2 = str->s;
+ i < n1 && i < n2 && i < n;
+ ++i, ++p1, ++p2) {
+ x = (*p1 & 0xff) - (*p2 & 0xff);
+ if (x != 0) {
+ return x;
+ }
+ }
+ if (i == n) {
+ return 0;
+ }
+ return n1 - n2;
+}
+
+int GString::cmp(const char *sA) {
+ int n1, i, x;
+ const char *p1, *p2;
+
+ n1 = length;
+ for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
+ x = (*p1 & 0xff) - (*p2 & 0xff);
+ if (x != 0) {
+ return x;
+ }
+ }
+ if (i < n1) {
+ return 1;
+ }
+ if (*p2) {
+ return -1;
+ }
+ return 0;
+}
+
+int GString::cmpN(const char *sA, int n) {
+ int n1, i, x;
+ const char *p1, *p2;
+
+ n1 = length;
+ for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
+ x = (*p1 & 0xff) - (*p2 & 0xff);
+ if (x != 0) {
+ return x;
+ }
+ }
+ if (i == n) {
+ return 0;
+ }
+ if (i < n1) {
+ return 1;
+ }
+ if (*p2) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/goo/GString.h b/goo/GString.h
new file mode 100644
index 0000000..6b342f8
--- /dev/null
+++ b/goo/GString.h
@@ -0,0 +1,151 @@
+//========================================================================
+//
+// GString.h
+//
+// Simple variable-length string type.
+//
+// Copyright 1996-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef GSTRING_H
+#define GSTRING_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include <limits.h> // for LLONG_MAX and ULLONG_MAX
+#include <stdarg.h>
+#include "gtypes.h"
+
+class GString {
+public:
+
+ // Create an empty string.
+ GString();
+
+ // Create a string from a C string.
+ GString(const char *sA);
+
+ // Create a string from <lengthA> chars at <sA>. This string
+ // can contain null characters.
+ GString(const char *sA, int lengthA);
+
+ // Create a string from <lengthA> chars at <idx> in <str>.
+ GString(GString *str, int idx, int lengthA);
+
+ // Copy a string.
+ GString(GString *str);
+ GString *copy() { return new GString(this); }
+
+ // Concatenate two strings.
+ GString(GString *str1, GString *str2);
+
+ // Convert an integer to a string.
+ static GString *fromInt(int x);
+
+ // Create a formatted string. Similar to printf, but without the
+ // string overflow issues. Formatting elements consist of:
+ // {<arg>:[<width>][.<precision>]<type>}
+ // where:
+ // - <arg> is the argument number (arg 0 is the first argument
+ // following the format string) -- NB: args must be first used in
+ // order; they can be reused in any order
+ // - <width> is the field width -- negative to reverse the alignment;
+ // starting with a leading zero to zero-fill (for integers)
+ // - <precision> is the number of digits to the right of the decimal
+ // point (for floating point numbers)
+ // - <type> is one of:
+ // d, x, o, b -- int in decimal, hex, octal, binary
+ // ud, ux, uo, ub -- unsigned int
+ // ld, lx, lo, lb, uld, ulx, ulo, ulb -- long, unsigned long
+ // lld, llx, llo, llb, ulld, ullx, ullo, ullb
+ // -- long long, unsigned long long
+ // f, g -- double
+ // c -- char
+ // s -- string (char *)
+ // t -- GString *
+ // w -- blank space; arg determines width
+ // To get literal curly braces, use {{ or }}.
+ static GString *format(const char *fmt, ...);
+ static GString *formatv(const char *fmt, va_list argList);
+
+ // Destructor.
+ ~GString();
+
+ // Get length.
+ int getLength() { return length; }
+
+ // Get C string.
+ char *getCString() { return s; }
+
+ // Get <i>th character.
+ char getChar(int i) { return s[i]; }
+
+ // Change <i>th character.
+ void setChar(int i, char c) { s[i] = c; }
+
+ // Clear string to zero length.
+ GString *clear();
+
+ // Append a character or string.
+ GString *append(char c);
+ GString *append(GString *str);
+ GString *append(const char *str);
+ GString *append(const char *str, int lengthA);
+
+ // Append a formatted string.
+ GString *appendf(const char *fmt, ...);
+ GString *appendfv(const char *fmt, va_list argList);
+
+ // Insert a character or string.
+ GString *insert(int i, char c);
+ GString *insert(int i, GString *str);
+ GString *insert(int i, const char *str);
+ GString *insert(int i, const char *str, int lengthA);
+
+ // Delete a character or range of characters.
+ GString *del(int i, int n = 1);
+
+ // Convert string to all-upper/all-lower case.
+ GString *upperCase();
+ GString *lowerCase();
+
+ // Compare two strings: -1:< 0:= +1:>
+ int cmp(GString *str);
+ int cmpN(GString *str, int n);
+ int cmp(const char *sA);
+ int cmpN(const char *sA, int n);
+
+private:
+
+ int length;
+ char *s;
+
+ void resize(int length1);
+#ifdef LLONG_MAX
+ static void formatInt(long long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len);
+#else
+ static void formatInt(long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len);
+#endif
+#ifdef ULLONG_MAX
+ static void formatUInt(unsigned long long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len);
+#else
+ static void formatUInt(Gulong x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ const char **p, int *len);
+#endif
+ static void formatDouble(double x, char *buf, int bufSize, int prec,
+ GBool trim, const char **p, int *len);
+};
+
+#endif
diff --git a/goo/Makefile b/goo/Makefile
new file mode 100644
index 0000000..5904ab2
--- /dev/null
+++ b/goo/Makefile
@@ -0,0 +1,505 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.18
+
+# Default target executed when no arguments are given to make.
+default_target: all
+
+.PHONY : default_target
+
+# Allow only one "make -f Makefile2" at a time, but pass parallelism.
+.NOTPARALLEL:
+
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/calvin/src/xpdf-4.04
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/calvin/src/xpdf-4.04
+
+#=============================================================================
+# Targets provided globally by CMake.
+
+# Special rule for the target install/strip
+install/strip: preinstall
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
+ /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
+.PHONY : install/strip
+
+# Special rule for the target install/strip
+install/strip/fast: preinstall/fast
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
+ /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
+.PHONY : install/strip/fast
+
+# Special rule for the target install/local
+install/local: preinstall
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
+ /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
+.PHONY : install/local
+
+# Special rule for the target install/local
+install/local/fast: preinstall/fast
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
+ /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
+.PHONY : install/local/fast
+
+# Special rule for the target install
+install: preinstall
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
+ /usr/bin/cmake -P cmake_install.cmake
+.PHONY : install
+
+# Special rule for the target install
+install/fast: preinstall/fast
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
+ /usr/bin/cmake -P cmake_install.cmake
+.PHONY : install/fast
+
+# Special rule for the target list_install_components
+list_install_components:
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
+.PHONY : list_install_components
+
+# Special rule for the target list_install_components
+list_install_components/fast: list_install_components
+
+.PHONY : list_install_components/fast
+
+# Special rule for the target rebuild_cache
+rebuild_cache:
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
+ /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : rebuild_cache
+
+# Special rule for the target rebuild_cache
+rebuild_cache/fast: rebuild_cache
+
+.PHONY : rebuild_cache/fast
+
+# Special rule for the target edit_cache
+edit_cache:
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
+ /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
+.PHONY : edit_cache
+
+# Special rule for the target edit_cache
+edit_cache/fast: edit_cache
+
+.PHONY : edit_cache/fast
+
+# The main all target
+all: cmake_check_build_system
+ cd /home/calvin/src/xpdf-4.04 && $(CMAKE_COMMAND) -E cmake_progress_start /home/calvin/src/xpdf-4.04/CMakeFiles /home/calvin/src/xpdf-4.04/goo//CMakeFiles/progress.marks
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/all
+ $(CMAKE_COMMAND) -E cmake_progress_start /home/calvin/src/xpdf-4.04/CMakeFiles 0
+.PHONY : all
+
+# The main clean target
+clean:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/clean
+.PHONY : clean
+
+# The main clean target
+clean/fast: clean
+
+.PHONY : clean/fast
+
+# Prepare targets for installation.
+preinstall: all
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/preinstall
+.PHONY : preinstall
+
+# Prepare targets for installation.
+preinstall/fast:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/preinstall
+.PHONY : preinstall/fast
+
+# clear depends
+depend:
+ cd /home/calvin/src/xpdf-4.04 && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
+.PHONY : depend
+
+# Convenience name for target.
+goo/CMakeFiles/goo.dir/rule:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/CMakeFiles/goo.dir/rule
+.PHONY : goo/CMakeFiles/goo.dir/rule
+
+# Convenience name for target.
+goo: goo/CMakeFiles/goo.dir/rule
+
+.PHONY : goo
+
+# fast build rule for target.
+goo/fast:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo.dir/build.make goo/CMakeFiles/goo.dir/build
+.PHONY : goo/fast
+
+# Convenience name for target.
+goo/CMakeFiles/goo_objs.dir/rule:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 goo/CMakeFiles/goo_objs.dir/rule
+.PHONY : goo/CMakeFiles/goo_objs.dir/rule
+
+# Convenience name for target.
+goo_objs: goo/CMakeFiles/goo_objs.dir/rule
+
+.PHONY : goo_objs
+
+# fast build rule for target.
+goo_objs/fast:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/build
+.PHONY : goo_objs/fast
+
+FixedPoint.o: FixedPoint.cc.o
+
+.PHONY : FixedPoint.o
+
+# target to build an object file
+FixedPoint.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.o
+.PHONY : FixedPoint.cc.o
+
+FixedPoint.i: FixedPoint.cc.i
+
+.PHONY : FixedPoint.i
+
+# target to preprocess a source file
+FixedPoint.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.i
+.PHONY : FixedPoint.cc.i
+
+FixedPoint.s: FixedPoint.cc.s
+
+.PHONY : FixedPoint.s
+
+# target to generate assembly for a file
+FixedPoint.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/FixedPoint.cc.s
+.PHONY : FixedPoint.cc.s
+
+GHash.o: GHash.cc.o
+
+.PHONY : GHash.o
+
+# target to build an object file
+GHash.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GHash.cc.o
+.PHONY : GHash.cc.o
+
+GHash.i: GHash.cc.i
+
+.PHONY : GHash.i
+
+# target to preprocess a source file
+GHash.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GHash.cc.i
+.PHONY : GHash.cc.i
+
+GHash.s: GHash.cc.s
+
+.PHONY : GHash.s
+
+# target to generate assembly for a file
+GHash.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GHash.cc.s
+.PHONY : GHash.cc.s
+
+GList.o: GList.cc.o
+
+.PHONY : GList.o
+
+# target to build an object file
+GList.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GList.cc.o
+.PHONY : GList.cc.o
+
+GList.i: GList.cc.i
+
+.PHONY : GList.i
+
+# target to preprocess a source file
+GList.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GList.cc.i
+.PHONY : GList.cc.i
+
+GList.s: GList.cc.s
+
+.PHONY : GList.s
+
+# target to generate assembly for a file
+GList.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GList.cc.s
+.PHONY : GList.cc.s
+
+GString.o: GString.cc.o
+
+.PHONY : GString.o
+
+# target to build an object file
+GString.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GString.cc.o
+.PHONY : GString.cc.o
+
+GString.i: GString.cc.i
+
+.PHONY : GString.i
+
+# target to preprocess a source file
+GString.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GString.cc.i
+.PHONY : GString.cc.i
+
+GString.s: GString.cc.s
+
+.PHONY : GString.s
+
+# target to generate assembly for a file
+GString.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/GString.cc.s
+.PHONY : GString.cc.s
+
+Trace.o: Trace.cc.o
+
+.PHONY : Trace.o
+
+# target to build an object file
+Trace.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/Trace.cc.o
+.PHONY : Trace.cc.o
+
+Trace.i: Trace.cc.i
+
+.PHONY : Trace.i
+
+# target to preprocess a source file
+Trace.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/Trace.cc.i
+.PHONY : Trace.cc.i
+
+Trace.s: Trace.cc.s
+
+.PHONY : Trace.s
+
+# target to generate assembly for a file
+Trace.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/Trace.cc.s
+.PHONY : Trace.cc.s
+
+gfile.o: gfile.cc.o
+
+.PHONY : gfile.o
+
+# target to build an object file
+gfile.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gfile.cc.o
+.PHONY : gfile.cc.o
+
+gfile.i: gfile.cc.i
+
+.PHONY : gfile.i
+
+# target to preprocess a source file
+gfile.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gfile.cc.i
+.PHONY : gfile.cc.i
+
+gfile.s: gfile.cc.s
+
+.PHONY : gfile.s
+
+# target to generate assembly for a file
+gfile.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gfile.cc.s
+.PHONY : gfile.cc.s
+
+gmem.o: gmem.cc.o
+
+.PHONY : gmem.o
+
+# target to build an object file
+gmem.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmem.cc.o
+.PHONY : gmem.cc.o
+
+gmem.i: gmem.cc.i
+
+.PHONY : gmem.i
+
+# target to preprocess a source file
+gmem.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmem.cc.i
+.PHONY : gmem.cc.i
+
+gmem.s: gmem.cc.s
+
+.PHONY : gmem.s
+
+# target to generate assembly for a file
+gmem.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmem.cc.s
+.PHONY : gmem.cc.s
+
+gmempp.o: gmempp.cc.o
+
+.PHONY : gmempp.o
+
+# target to build an object file
+gmempp.cc.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmempp.cc.o
+.PHONY : gmempp.cc.o
+
+gmempp.i: gmempp.cc.i
+
+.PHONY : gmempp.i
+
+# target to preprocess a source file
+gmempp.cc.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmempp.cc.i
+.PHONY : gmempp.cc.i
+
+gmempp.s: gmempp.cc.s
+
+.PHONY : gmempp.s
+
+# target to generate assembly for a file
+gmempp.cc.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/gmempp.cc.s
+.PHONY : gmempp.cc.s
+
+parseargs.o: parseargs.c.o
+
+.PHONY : parseargs.o
+
+# target to build an object file
+parseargs.c.o:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/parseargs.c.o
+.PHONY : parseargs.c.o
+
+parseargs.i: parseargs.c.i
+
+.PHONY : parseargs.i
+
+# target to preprocess a source file
+parseargs.c.i:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/parseargs.c.i
+.PHONY : parseargs.c.i
+
+parseargs.s: parseargs.c.s
+
+.PHONY : parseargs.s
+
+# target to generate assembly for a file
+parseargs.c.s:
+ cd /home/calvin/src/xpdf-4.04 && $(MAKE) $(MAKESILENT) -f goo/CMakeFiles/goo_objs.dir/build.make goo/CMakeFiles/goo_objs.dir/parseargs.c.s
+.PHONY : parseargs.c.s
+
+# Help Target
+help:
+ @echo "The following are some of the valid targets for this Makefile:"
+ @echo "... all (the default if no target is provided)"
+ @echo "... clean"
+ @echo "... depend"
+ @echo "... edit_cache"
+ @echo "... install"
+ @echo "... install/local"
+ @echo "... install/strip"
+ @echo "... list_install_components"
+ @echo "... rebuild_cache"
+ @echo "... goo"
+ @echo "... goo_objs"
+ @echo "... FixedPoint.o"
+ @echo "... FixedPoint.i"
+ @echo "... FixedPoint.s"
+ @echo "... GHash.o"
+ @echo "... GHash.i"
+ @echo "... GHash.s"
+ @echo "... GList.o"
+ @echo "... GList.i"
+ @echo "... GList.s"
+ @echo "... GString.o"
+ @echo "... GString.i"
+ @echo "... GString.s"
+ @echo "... Trace.o"
+ @echo "... Trace.i"
+ @echo "... Trace.s"
+ @echo "... gfile.o"
+ @echo "... gfile.i"
+ @echo "... gfile.s"
+ @echo "... gmem.o"
+ @echo "... gmem.i"
+ @echo "... gmem.s"
+ @echo "... gmempp.o"
+ @echo "... gmempp.i"
+ @echo "... gmempp.s"
+ @echo "... parseargs.o"
+ @echo "... parseargs.i"
+ @echo "... parseargs.s"
+.PHONY : help
+
+
+
+#=============================================================================
+# Special targets to cleanup operation of make.
+
+# Special rule to run CMake to check the build system integrity.
+# No rule that depends on this can have commands that come from listfiles
+# because they might be regenerated.
+cmake_check_build_system:
+ cd /home/calvin/src/xpdf-4.04 && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
+.PHONY : cmake_check_build_system
+
diff --git a/goo/Trace.cc b/goo/Trace.cc
new file mode 100644
index 0000000..4b730e5
--- /dev/null
+++ b/goo/Trace.cc
@@ -0,0 +1,114 @@
+//========================================================================
+//
+// Trace.cc
+//
+// Nested tracing.
+//
+// Copyright 2020 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#if ENABLE_TRACING
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "GString.h"
+#include "Trace.h"
+
+// NB: This module is NOT thread-safe.
+
+static bool traceInitialized = false;
+static FILE *traceOut = NULL;
+
+static void traceInit() {
+ if (traceInitialized) {
+ return;
+ }
+ //~ this could read an env var to set up an output file
+ GString *fileName = GString::format("/tmp/trace.{0:d}", (int)getpid());
+ traceOut = fopen(fileName->getCString(), "w");
+ delete fileName;
+ traceInitialized = true;
+}
+
+static void traceHeader(char flag, void *handle) {
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ if (handle) {
+ fprintf(traceOut, "%c %ld %06ld %p ", flag, tv.tv_sec, tv.tv_usec, handle);
+ } else {
+ fprintf(traceOut, "%c %ld %06ld 0x0 ", flag, tv.tv_sec, tv.tv_usec);
+ }
+}
+
+void traceBegin(void *nestHandle, const char *fmt, ...) {
+ traceInit();
+ if (!traceOut) {
+ return;
+ }
+ traceHeader('B', nestHandle);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(traceOut, fmt, args);
+ va_end(args);
+ fprintf(traceOut, "\n");
+}
+
+void traceEnd(void *nestHandle, const char *fmt, ...) {
+ traceInit();
+ if (!traceOut) {
+ return;
+ }
+ traceHeader('E', nestHandle);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(traceOut, fmt, args);
+ va_end(args);
+ fprintf(traceOut, "\n");
+}
+
+void traceAlloc(void *resourceHandle, const char *fmt, ...) {
+ traceInit();
+ if (!traceOut) {
+ return;
+ }
+ traceHeader('A', resourceHandle);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(traceOut, fmt, args);
+ va_end(args);
+ fprintf(traceOut, "\n");
+}
+
+void traceFree(void *resourceHandle, const char *fmt, ...) {
+ traceInit();
+ if (!traceOut) {
+ return;
+ }
+ traceHeader('F', resourceHandle);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(traceOut, fmt, args);
+ va_end(args);
+ fprintf(traceOut, "\n");
+}
+
+void traceMessage(const char *fmt, ...) {
+ traceInit();
+ if (!traceOut) {
+ return;
+ }
+ traceHeader('M', NULL);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(traceOut, fmt, args);
+ va_end(args);
+ fprintf(traceOut, "\n");
+}
+
+#endif // ENABLE_TRACING
diff --git a/goo/Trace.h b/goo/Trace.h
new file mode 100644
index 0000000..9f53ac5
--- /dev/null
+++ b/goo/Trace.h
@@ -0,0 +1,43 @@
+//========================================================================
+//
+// Trace.h
+//
+// Nested tracing.
+//
+// Copyright 2020 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef TRACING_H
+#define TRACING_H
+
+#include <aconf.h>
+
+#if ENABLE_TRACING
+
+// Enter a nesting level.
+extern void traceBegin(void *nestHandle, const char *fmt, ...);
+
+// Exit a nesting level.
+extern void traceEnd(void *nestHandle, const char *fmt, ...);
+
+// Mark a resource as allocated.
+extern void traceAlloc(void *resourceHandle, const char *fmt, ...);
+
+// Mark a resource as freed.
+extern void traceFree(void *resourceHandle, const char *fmt, ...);
+
+// Misc message.
+extern void traceMessage(const char *fmt, ...);
+
+#else // ENABLE_TRACING
+
+static inline void traceBegin(void *nestHandle, const char *fmt, ...) {}
+static inline void traceEnd(void *nestHandle, const char *fmt, ...) {}
+static inline void traceAlloc(void *resourceHandle, const char *fmt, ...) {}
+static inline void traceFree(void *nestHandle, const char *fmt, ...) {}
+static inline void traceMessage(const char *fmt, ...) {}
+
+#endif // ENABLE_TRACING
+
+#endif // TRACING_H
diff --git a/goo/cmake_install.cmake b/goo/cmake_install.cmake
new file mode 100644
index 0000000..d9838e2
--- /dev/null
+++ b/goo/cmake_install.cmake
@@ -0,0 +1,44 @@
+# Install script for directory: /home/calvin/src/xpdf-4.04/goo
+
+# Set the install prefix
+if(NOT DEFINED CMAKE_INSTALL_PREFIX)
+ set(CMAKE_INSTALL_PREFIX "/usr/local")
+endif()
+string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+
+# Set the install configuration name.
+if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
+ if(BUILD_TYPE)
+ string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
+ CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
+ else()
+ set(CMAKE_INSTALL_CONFIG_NAME "")
+ endif()
+ message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
+endif()
+
+# Set the component getting installed.
+if(NOT CMAKE_INSTALL_COMPONENT)
+ if(COMPONENT)
+ message(STATUS "Install component: \"${COMPONENT}\"")
+ set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
+ else()
+ set(CMAKE_INSTALL_COMPONENT)
+ endif()
+endif()
+
+# Install shared libraries without execute permission?
+if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
+ set(CMAKE_INSTALL_SO_NO_EXE "1")
+endif()
+
+# Is this installation the result of a crosscompile?
+if(NOT DEFINED CMAKE_CROSSCOMPILING)
+ set(CMAKE_CROSSCOMPILING "FALSE")
+endif()
+
+# Set default install directory permissions.
+if(NOT DEFINED CMAKE_OBJDUMP)
+ set(CMAKE_OBJDUMP "/usr/bin/objdump")
+endif()
+
diff --git a/goo/gfile.cc b/goo/gfile.cc
new file mode 100644
index 0000000..9ec8bae
--- /dev/null
+++ b/goo/gfile.cc
@@ -0,0 +1,779 @@
+//========================================================================
+//
+// gfile.cc
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef _WIN32
+# undef WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <time.h>
+# include <direct.h>
+# include <shobjidl.h>
+# include <shlguid.h>
+#else
+# if !defined(ACORN)
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# endif
+# include <time.h>
+# include <limits.h>
+# include <string.h>
+# if !defined(VMS) && !defined(ACORN)
+# include <pwd.h>
+# endif
+# if defined(VMS) && (__DECCXX_VER < 50200000)
+# include <unixlib.h>
+# endif
+#endif // _WIN32
+#include "gmem.h"
+#include "gmempp.h"
+#include "GString.h"
+#include "gfile.h"
+
+// Some systems don't define this, so just make it something reasonably
+// large.
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+//------------------------------------------------------------------------
+
+GString *getHomeDir() {
+#ifdef VMS
+ //---------- VMS ----------
+ return new GString("SYS$LOGIN:");
+
+#elif defined(_WIN32)
+ //---------- Win32 ----------
+ char *s;
+ GString *ret;
+
+ if ((s = getenv("USERPROFILE")))
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+ return ret;
+
+#elif defined(__EMX__)
+ //---------- OS/2+EMX ----------
+ char *s;
+ GString *ret;
+
+ if ((s = getenv("HOME")))
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+ return ret;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ return new GString("@");
+
+#else
+ //---------- Unix ----------
+ char *s;
+ struct passwd *pw;
+ GString *ret;
+
+ if ((s = getenv("HOME"))) {
+ ret = new GString(s);
+ } else {
+ if ((s = getenv("USER")))
+ pw = getpwnam(s);
+ else
+ pw = getpwuid(getuid());
+ if (pw)
+ ret = new GString(pw->pw_dir);
+ else
+ ret = new GString(".");
+ }
+ return ret;
+#endif
+}
+
+GString *getCurrentDir() {
+ char buf[PATH_MAX+1];
+
+#if defined(__EMX__)
+ if (_getcwd2(buf, sizeof(buf)))
+#elif defined(_WIN32)
+ if (GetCurrentDirectoryA(sizeof(buf), buf))
+#elif defined(ACORN)
+ if (strcpy(buf, "@"))
+#else
+ if (getcwd(buf, sizeof(buf)))
+#endif
+ return new GString(buf);
+ return new GString();
+}
+
+GString *appendToPath(GString *path, const char *fileName) {
+#if defined(VMS)
+ //---------- VMS ----------
+ //~ this should handle everything necessary for file
+ //~ requesters, but it's certainly not complete
+ char *p0, *p1, *p2;
+ char *q1;
+
+ p0 = path->getCString();
+ p1 = p0 + path->getLength() - 1;
+ if (!strcmp(fileName, "-")) {
+ if (*p1 == ']') {
+ for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
+ if (*p2 == '[')
+ ++p2;
+ path->del(p2 - p0, p1 - p2);
+ } else if (*p1 == ':') {
+ path->append("[-]");
+ } else {
+ path->clear();
+ path->append("[-]");
+ }
+ } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
+ if (*p1 == ']') {
+ path->insert(p1 - p0, '.');
+ path->insert(p1 - p0 + 1, fileName, q1 - fileName);
+ } else if (*p1 == ':') {
+ path->append('[');
+ path->append(']');
+ path->append(fileName, q1 - fileName);
+ } else {
+ path->clear();
+ path->append(fileName, q1 - fileName);
+ }
+ } else {
+ if (*p1 != ']' && *p1 != ':')
+ path->clear();
+ path->append(fileName);
+ }
+ return path;
+
+#elif defined(_WIN32)
+ //---------- Win32 ----------
+ GString *tmp;
+ char buf[256];
+ char *fp;
+
+ tmp = new GString(path);
+ tmp->append('/');
+ tmp->append(fileName);
+ GetFullPathNameA(tmp->getCString(), sizeof(buf), buf, &fp);
+ delete tmp;
+ path->clear();
+ path->append(buf);
+ return path;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ char *p;
+ int i;
+
+ path->append(".");
+ i = path->getLength();
+ path->append(fileName);
+ for (p = path->getCString() + i; *p; ++p) {
+ if (*p == '/') {
+ *p = '.';
+ } else if (*p == '.') {
+ *p = '/';
+ }
+ }
+ return path;
+
+#elif defined(__EMX__)
+ //---------- OS/2+EMX ----------
+ int i;
+
+ // appending "." does nothing
+ if (!strcmp(fileName, "."))
+ return path;
+
+ // appending ".." goes up one directory
+ if (!strcmp(fileName, "..")) {
+ for (i = path->getLength() - 2; i >= 0; --i) {
+ if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
+ path->getChar(i) == ':')
+ break;
+ }
+ if (i <= 0) {
+ if (path->getChar(0) == '/' || path->getChar(0) == '\\') {
+ path->del(1, path->getLength() - 1);
+ } else if (path->getLength() >= 2 && path->getChar(1) == ':') {
+ path->del(2, path->getLength() - 2);
+ } else {
+ path->clear();
+ path->append("..");
+ }
+ } else {
+ if (path->getChar(i-1) == ':')
+ ++i;
+ path->del(i, path->getLength() - i);
+ }
+ return path;
+ }
+
+ // otherwise, append "/" and new path component
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/' &&
+ path->getChar(path->getLength() - 1) != '\\')
+ path->append('/');
+ path->append(fileName);
+ return path;
+
+#else
+ //---------- Unix ----------
+ int i;
+
+ // appending "." does nothing
+ if (!strcmp(fileName, "."))
+ return path;
+
+ // appending ".." goes up one directory
+ if (!strcmp(fileName, "..")) {
+ for (i = path->getLength() - 2; i >= 0; --i) {
+ if (path->getChar(i) == '/')
+ break;
+ }
+ if (i <= 0) {
+ if (path->getChar(0) == '/') {
+ path->del(1, path->getLength() - 1);
+ } else {
+ path->clear();
+ path->append("..");
+ }
+ } else {
+ path->del(i, path->getLength() - i);
+ }
+ return path;
+ }
+
+ // otherwise, append "/" and new path component
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/')
+ path->append('/');
+ path->append(fileName);
+ return path;
+#endif
+}
+
+GString *grabPath(char *fileName) {
+#ifdef VMS
+ //---------- VMS ----------
+ char *p;
+
+ if ((p = strrchr(fileName, ']')))
+ return new GString(fileName, p + 1 - fileName);
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, p + 1 - fileName);
+ return new GString();
+
+#elif defined(__EMX__) || defined(_WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ char *p;
+
+ if ((p = strrchr(fileName, '/')))
+ return new GString(fileName, (int)(p - fileName));
+ if ((p = strrchr(fileName, '\\')))
+ return new GString(fileName, (int)(p - fileName));
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, (int)(p + 1 - fileName));
+ return new GString();
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ char *p;
+
+ if ((p = strrchr(fileName, '.')))
+ return new GString(fileName, p - fileName);
+ return new GString();
+
+#else
+ //---------- Unix ----------
+ char *p;
+
+ if ((p = strrchr(fileName, '/')))
+ return new GString(fileName, (int)(p - fileName));
+ return new GString();
+#endif
+}
+
+GBool isAbsolutePath(char *path) {
+#ifdef VMS
+ //---------- VMS ----------
+ return strchr(path, ':') ||
+ (path[0] == '[' && path[1] != '.' && path[1] != '-');
+
+#elif defined(__EMX__) || defined(_WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ return path[0] == '/' || path[0] == '\\' || path[1] == ':';
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ return path[0] == '$';
+
+#else
+ //---------- Unix ----------
+ return path[0] == '/';
+#endif
+}
+
+GString *makePathAbsolute(GString *path) {
+#ifdef VMS
+ //---------- VMS ----------
+ char buf[PATH_MAX+1];
+
+ if (!isAbsolutePath(path->getCString())) {
+ if (getcwd(buf, sizeof(buf))) {
+ path->insert(0, buf);
+ }
+ }
+ return path;
+
+#elif defined(_WIN32)
+ //---------- Win32 ----------
+ char buf[MAX_PATH];
+ char *fp;
+
+ buf[0] = '\0';
+ if (!GetFullPathNameA(path->getCString(), MAX_PATH, buf, &fp)) {
+ path->clear();
+ return path;
+ }
+ path->clear();
+ path->append(buf);
+ return path;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ path->insert(0, '@');
+ return path;
+
+#else
+ //---------- Unix and OS/2+EMX ----------
+ struct passwd *pw;
+ char buf[PATH_MAX+1];
+ GString *s;
+ char *p1, *p2;
+ int n;
+
+ if (path->getChar(0) == '~') {
+ if (path->getChar(1) == '/' ||
+#ifdef __EMX__
+ path->getChar(1) == '\\' ||
+#endif
+ path->getLength() == 1) {
+ path->del(0, 1);
+ s = getHomeDir();
+ path->insert(0, s);
+ delete s;
+ } else {
+ p1 = path->getCString() + 1;
+#ifdef __EMX__
+ for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
+#else
+ for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
+#endif
+ if ((n = (int)(p2 - p1)) > PATH_MAX)
+ n = PATH_MAX;
+ strncpy(buf, p1, n);
+ buf[n] = '\0';
+ if ((pw = getpwnam(buf))) {
+ path->del(0, (int)(p2 - p1 + 1));
+ path->insert(0, pw->pw_dir);
+ }
+ }
+ } else if (!isAbsolutePath(path->getCString())) {
+ if (getcwd(buf, sizeof(buf))) {
+#ifndef __EMX__
+ path->insert(0, '/');
+#endif
+ path->insert(0, buf);
+ }
+ }
+ return path;
+#endif
+}
+
+GBool pathIsFile(const char *path) {
+#ifdef _WIN32
+ wchar_t wPath[winMaxLongPath + 1];
+ fileNameToUCS2(path, wPath, winMaxLongPath + 1);
+ DWORD attr = GetFileAttributesW(wPath);
+ return attr != INVALID_FILE_ATTRIBUTES &&
+ !(attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));
+#else
+ struct stat statBuf;
+ return stat(path, &statBuf) == 0 && S_ISREG(statBuf.st_mode);
+#endif
+}
+
+time_t getModTime(char *fileName) {
+#ifdef _WIN32
+ //~ should implement this, but it's (currently) only used in xpdf
+ return 0;
+#else
+ struct stat statBuf;
+
+ if (stat(fileName, &statBuf)) {
+ return 0;
+ }
+ return statBuf.st_mtime;
+#endif
+}
+
+GBool openTempFile(GString **name, FILE **f,
+ const char *mode, const char *ext) {
+#if defined(_WIN32)
+ //---------- Win32 ----------
+ char tempPath[MAX_PATH + 1];
+ GString *s, *s2;
+ FILE *f2;
+ DWORD n;
+ int t, i;
+
+ // this has the standard race condition problem, but I haven't found
+ // a better way to generate temp file names with extensions on
+ // Windows
+ n = GetTempPathA(sizeof(tempPath), tempPath);
+ if (n > 0 && n <= sizeof(tempPath)) {
+ s = new GString(tempPath);
+ if (tempPath[n-1] != '\\') {
+ s->append('\\');
+ }
+ } else {
+ s = new GString(".\\");
+ }
+ s->appendf("xpdf_{0:d}_{1:d}_",
+ (int)GetCurrentProcessId(), (int)GetCurrentThreadId());
+ t = (int)time(NULL);
+ for (i = 0; i < 1000; ++i) {
+ s2 = GString::format("{0:t}{1:d}", s, t + i);
+ if (ext) {
+ s2->append(ext);
+ }
+ if (!(f2 = fopen(s2->getCString(), "r"))) {
+ if (!(f2 = fopen(s2->getCString(), mode))) {
+ delete s2;
+ delete s;
+ return gFalse;
+ }
+ *name = s2;
+ *f = f2;
+ delete s;
+ return gTrue;
+ }
+ fclose(f2);
+ delete s2;
+ }
+ delete s;
+ return gFalse;
+#elif defined(VMS) || defined(__EMX__) || defined(ACORN)
+ //---------- non-Unix ----------
+ char *s;
+
+ // There is a security hole here: an attacker can create a symlink
+ // with this file name after the tmpnam call and before the fopen
+ // call. I will happily accept fixes to this function for non-Unix
+ // OSs.
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ if (ext) {
+ (*name)->append(ext);
+ }
+ if (!(*f = fopen((*name)->getCString(), mode))) {
+ delete (*name);
+ *name = NULL;
+ return gFalse;
+ }
+ return gTrue;
+#else
+ //---------- Unix ----------
+ char *s;
+ int fd;
+
+ if (ext) {
+#if HAVE_MKSTEMPS
+ if ((s = getenv("TMPDIR"))) {
+ *name = new GString(s);
+ } else {
+ *name = new GString("/tmp");
+ }
+ (*name)->append("/XXXXXX")->append(ext);
+ fd = mkstemps((*name)->getCString(), (int)strlen(ext));
+#else
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ (*name)->append(ext);
+ fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+#endif
+ } else {
+#if HAVE_MKSTEMP
+ if ((s = getenv("TMPDIR"))) {
+ *name = new GString(s);
+ } else {
+ *name = new GString("/tmp");
+ }
+ (*name)->append("/XXXXXX");
+ fd = mkstemp((*name)->getCString());
+#else // HAVE_MKSTEMP
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+#endif // HAVE_MKSTEMP
+ }
+ if (fd < 0 || !(*f = fdopen(fd, mode))) {
+ delete *name;
+ *name = NULL;
+ return gFalse;
+ }
+ return gTrue;
+#endif
+}
+
+GBool createDir(char *path, int mode) {
+#ifdef _WIN32
+ return !_mkdir(path);
+#else
+ return !mkdir(path, mode);
+#endif
+}
+
+GBool executeCommand(char *cmd) {
+#ifdef VMS
+ return system(cmd) ? gTrue : gFalse;
+#else
+ return system(cmd) ? gFalse : gTrue;
+#endif
+}
+
+#ifdef _WIN32
+GString *fileNameToUTF8(char *path) {
+ GString *s;
+ char *p;
+
+ s = new GString();
+ for (p = path; *p; ++p) {
+ if (*p & 0x80) {
+ s->append((char)(0xc0 | ((*p >> 6) & 0x03)));
+ s->append((char)(0x80 | (*p & 0x3f)));
+ } else {
+ s->append(*p);
+ }
+ }
+ return s;
+}
+
+GString *fileNameToUTF8(wchar_t *path) {
+ GString *s;
+ wchar_t *p;
+
+ s = new GString();
+ for (p = path; *p; ++p) {
+ if (*p < 0x80) {
+ s->append((char)*p);
+ } else if (*p < 0x800) {
+ s->append((char)(0xc0 | ((*p >> 6) & 0x1f)));
+ s->append((char)(0x80 | (*p & 0x3f)));
+ } else {
+ s->append((char)(0xe0 | ((*p >> 12) & 0x0f)));
+ s->append((char)(0x80 | ((*p >> 6) & 0x3f)));
+ s->append((char)(0x80 | (*p & 0x3f)));
+ }
+ }
+ return s;
+}
+
+wchar_t *fileNameToUCS2(const char *path, wchar_t *out, size_t outSize) {
+ const char *p;
+ size_t i;
+
+ for (p = path, i = 0; *p && i < outSize - 1; ++i) {
+ if ((p[0] & 0xe0) == 0xc0 &&
+ p[1] && (p[1] & 0xc0) == 0x80) {
+ out[i] = (wchar_t)(((p[0] & 0x1f) << 6) |
+ (p[1] & 0x3f));
+ p += 2;
+ } else if ((p[0] & 0xf0) == 0xe0 &&
+ (p[1] & 0xc0) == 0x80 &&
+ (p[2] & 0xc0) == 0x80) {
+ out[i] = (wchar_t)(((p[0] & 0x0f) << 12) |
+ ((p[1] & 0x3f) << 6) |
+ (p[2] & 0x3f));
+ p += 3;
+ } else {
+ out[i] = (wchar_t)(p[0] & 0xff);
+ p += 1;
+ }
+ }
+ out[i] = (wchar_t)0;
+ return out;
+}
+#endif
+
+FILE *openFile(const char *path, const char *mode) {
+#if defined(_WIN32)
+ wchar_t wPath[winMaxLongPath + 1];
+ wchar_t wMode[8];
+ int i;
+
+ fileNameToUCS2(path, wPath, winMaxLongPath + 1);
+ for (i = 0; mode[i] && i < sizeof(wMode)/sizeof(wchar_t) - 1; ++i) {
+ wMode[i] = (wchar_t)(mode[i] & 0xff);
+ }
+ wMode[i] = (wchar_t)0;
+ readWindowsShortcut(wPath, winMaxLongPath + 1);
+ return _wfopen(wPath, wMode);
+#elif defined(VMS)
+ return fopen(path, mode, "ctx=stm");
+#else
+ return fopen(path, mode);
+#endif
+}
+
+#ifdef _WIN32
+void readWindowsShortcut(wchar_t *wPath, size_t wPathSize) {
+ size_t n = wcslen(wPath);
+ if (n < 4 || wcscmp(wPath + n - 4, L".lnk")) {
+ return;
+ }
+ IShellLinkW *shellLink;
+ HRESULT hres;
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ IID_IShellLinkW, (LPVOID *)&shellLink);
+ bool needCoUninit = false;
+ if (hres == CO_E_NOTINITIALIZED) {
+ CoInitialize(NULL);
+ needCoUninit = true;
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ IID_IShellLinkW, (LPVOID *)&shellLink);
+ }
+ if (FAILED(hres)) {
+ return;
+ }
+ IPersistFile *persistFile;
+ hres = shellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
+ if (FAILED(hres)) {
+ return;
+ }
+ hres = persistFile->Load(wPath, STGM_READ);
+ if (FAILED(hres)) {
+ fprintf(stderr, "IPersistFile.Load failed: 0x%08x\n", hres);
+ exit(1);
+ }
+ wchar_t target[winMaxLongPath + 1];
+ hres = shellLink->GetPath(target, winMaxLongPath + 1, NULL, 0);
+ if (FAILED(hres)) {
+ return;
+ }
+ shellLink->Release();
+ if (needCoUninit) {
+ CoUninitialize();
+ }
+ if (wcslen(target) > wPathSize - 1) {
+ return;
+ }
+ wcscpy(wPath, target);
+}
+#endif
+
+int makeDir(const char *path, int mode) {
+#ifdef _WIN32
+ wchar_t wPath[winMaxLongPath + 1];
+ return _wmkdir(fileNameToUCS2(path, wPath, winMaxLongPath + 1));
+#else
+ return mkdir(path, (mode_t)mode);
+#endif
+}
+
+char *getLine(char *buf, int size, FILE *f) {
+ int c, i;
+
+ i = 0;
+ while (i < size - 1) {
+ if ((c = fgetc(f)) == EOF) {
+ break;
+ }
+ buf[i++] = (char)c;
+ if (c == '\x0a') {
+ break;
+ }
+ if (c == '\x0d') {
+ c = fgetc(f);
+ if (c == '\x0a' && i < size - 1) {
+ buf[i++] = (char)c;
+ } else if (c != EOF) {
+ ungetc(c, f);
+ }
+ break;
+ }
+ }
+ buf[i] = '\0';
+ if (i == 0) {
+ return NULL;
+ }
+ return buf;
+}
+
+int gfseek(FILE *f, GFileOffset offset, int whence) {
+#if HAVE_FSEEKO
+ return fseeko(f, offset, whence);
+#elif HAVE_FSEEK64
+ return fseek64(f, offset, whence);
+#elif HAVE_FSEEKI64
+ return _fseeki64(f, offset, whence);
+#else
+ return fseek(f, offset, whence);
+#endif
+}
+
+GFileOffset gftell(FILE *f) {
+#if HAVE_FSEEKO
+ return ftello(f);
+#elif HAVE_FSEEK64
+ return ftell64(f);
+#elif HAVE_FSEEKI64
+ return _ftelli64(f);
+#else
+ return ftell(f);
+#endif
+}
+
+void fixCommandLine(int *argc, char **argv[]) {
+#ifdef _WIN32
+ int argcw;
+ wchar_t **argvw;
+ GString *arg;
+ int i;
+
+ argvw = CommandLineToArgvW(GetCommandLineW(), &argcw);
+ if (!argvw || argcw < 0) {
+ return;
+ }
+
+ *argc = argcw;
+
+ *argv = (char **)gmallocn(argcw + 1, sizeof(char *));
+ for (i = 0; i < argcw; ++i) {
+ arg = fileNameToUTF8(argvw[i]);
+ (*argv)[i] = copyString(arg->getCString());
+ delete arg;
+ }
+ (*argv)[argcw] = NULL;
+
+ LocalFree(argvw);
+#endif
+}
diff --git a/goo/gfile.h b/goo/gfile.h
new file mode 100644
index 0000000..202e6ee
--- /dev/null
+++ b/goo/gfile.h
@@ -0,0 +1,144 @@
+//========================================================================
+//
+// gfile.h
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef GFILE_H
+#define GFILE_H
+
+#include <aconf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#if defined(_WIN32)
+# include <sys/stat.h>
+# ifdef FPTEX
+# include <win32lib.h>
+# else
+# include <windows.h>
+# endif
+#elif defined(ACORN)
+#elif defined(ANDROID)
+#else
+# include <unistd.h>
+# include <sys/types.h>
+#endif
+#include "gtypes.h"
+
+// Windows 10 supports long paths - with a registry setting, and only
+// with Unicode (...W) functions.
+#ifdef _WIN32
+# define winMaxLongPath 32767
+#endif
+
+class GString;
+
+//------------------------------------------------------------------------
+
+// Get home directory path.
+extern GString *getHomeDir();
+
+// Get current directory.
+extern GString *getCurrentDir();
+
+// Append a file name to a path string. <path> may be an empty
+// string, denoting the current directory). Returns <path>.
+extern GString *appendToPath(GString *path, const char *fileName);
+
+// Grab the path from the front of the file name. If there is no
+// directory component in <fileName>, returns an empty string.
+extern GString *grabPath(char *fileName);
+
+// Is this an absolute path or file name?
+extern GBool isAbsolutePath(char *path);
+
+// Make this path absolute by prepending current directory (if path is
+// relative) or prepending user's directory (if path starts with '~').
+extern GString *makePathAbsolute(GString *path);
+
+// Returns true if [path] exists and is a regular file.
+extern GBool pathIsFile(const char *path);
+
+// Get the modification time for <fileName>. Returns 0 if there is an
+// error.
+extern time_t getModTime(char *fileName);
+
+// Create a temporary file and open it for writing. If <ext> is not
+// NULL, it will be used as the file name extension. Returns both the
+// name and the file pointer. For security reasons, all writing
+// should be done to the returned file pointer; the file may be
+// reopened later for reading, but not for writing. The <mode> string
+// should be "w" or "wb". Returns true on success.
+extern GBool openTempFile(GString **name, FILE **f,
+ const char *mode, const char *ext);
+
+// Create a directory. Returns true on success.
+extern GBool createDir(char *path, int mode);
+
+// Execute <command>. Returns true on success.
+extern GBool executeCommand(char *cmd);
+
+#ifdef _WIN32
+// Convert a file name from Latin-1 to UTF-8.
+extern GString *fileNameToUTF8(char *path);
+
+// Convert a file name from UCS-2 to UTF-8.
+extern GString *fileNameToUTF8(wchar_t *path);
+
+// Convert a file name from UTF-8 to UCS-2. [out] has space for
+// [outSize] wchar_t elements (including the trailing zero). Returns
+// [out].
+extern wchar_t *fileNameToUCS2(const char *path, wchar_t *out, size_t outSize);
+#endif
+
+// Open a file. On Windows, this converts the path from UTF-8 to
+// UCS-2 and calls _wfopen(). On other OSes, this simply calls fopen().
+extern FILE *openFile(const char *path, const char *mode);
+
+#ifdef _WIN32
+// If [wPath] is a Windows shortcut (.lnk file), read the target path
+// and store it back into [wPath].
+extern void readWindowsShortcut(wchar_t *wPath, size_t wPathSize);
+#endif
+
+// Create a directory. On Windows, this converts the path from UTF-8
+// to UCS-2 and calls _wmkdir(), ignoring the mode argument. On other
+// OSes, this simply calls mkdir().
+extern int makeDir(const char *path, int mode);
+
+// Just like fgets, but handles Unix, Mac, and/or DOS end-of-line
+// conventions.
+extern char *getLine(char *buf, int size, FILE *f);
+
+// Type used by gfseek/gftell for file offsets. This will be 64 bits
+// on systems that support it.
+#if HAVE_FSEEKO
+typedef off_t GFileOffset;
+#define GFILEOFFSET_MAX 0x7fffffffffffffffLL
+#elif HAVE_FSEEK64
+typedef long long GFileOffset;
+#define GFILEOFFSET_MAX 0x7fffffffffffffffLL
+#elif HAVE_FSEEKI64
+typedef __int64 GFileOffset;
+#define GFILEOFFSET_MAX 0x7fffffffffffffffLL
+#else
+typedef long GFileOffset;
+#define GFILEOFFSET_MAX LONG_MAX
+#endif
+
+// Like fseek, but uses a 64-bit file offset if available.
+extern int gfseek(FILE *f, GFileOffset offset, int whence);
+
+// Like ftell, but returns a 64-bit file offset if available.
+extern GFileOffset gftell(FILE *f);
+
+// On Windows, this gets the Unicode command line and converts it to
+// UTF-8. On other systems, this is a nop.
+extern void fixCommandLine(int *argc, char **argv[]);
+
+#endif
diff --git a/goo/gmem.cc b/goo/gmem.cc
new file mode 100644
index 0000000..7291f20
--- /dev/null
+++ b/goo/gmem.cc
@@ -0,0 +1,396 @@
+/*
+ * gmem.c
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996-2003 Glyph & Cog, LLC
+ */
+
+#include <aconf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+// older compilers won't define SIZE_MAX in stdint.h without this
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+#endif
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#if MULTITHREADED && defined(_WIN32)
+# include <windows.h>
+#endif
+#include "gmem.h"
+
+#ifdef DEBUG_MEM
+
+typedef struct _GMemHdr {
+ unsigned int magic;
+ int index;
+ size_t size;
+ struct _GMemHdr *next, *prev;
+} GMemHdr;
+
+#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
+#define gMemTrlSize (sizeof(long))
+
+#define gMemMagic 0xabcd9999
+
+#if ULONG_MAX > 0xffffffffL
+#define gMemDeadVal 0xdeadbeefdeadbeefUL
+#else
+#define gMemDeadVal 0xdeadbeefUL
+#endif
+
+/* round data size so trailer will be aligned */
+#define gMemDataSize(size) \
+ (int)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
+
+#define gMemDataSize64(size) \
+ (size_t)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
+
+static GMemHdr *gMemHead = NULL;
+static GMemHdr *gMemTail = NULL;
+
+static int gMemIndex = 0;
+static int gMemAlloc = 0;
+static size_t gMemInUse = 0;
+static size_t gMaxMemInUse = 0;
+
+#if MULTITHREADED
+# ifdef _WIN32
+ static CRITICAL_SECTION gMemMutex;
+ static INIT_ONCE gMemMutexInitStruct = INIT_ONCE_STATIC_INIT;
+ static BOOL CALLBACK gMemMutexInitFunc(PINIT_ONCE initOnce, PVOID param,
+ PVOID *context) {
+ InitializeCriticalSection(&gMemMutex);
+ return TRUE;
+ }
+# define gMemInitMutex InitOnceExecuteOnce(&gMemMutexInitStruct, \
+ &gMemMutexInitFunc, NULL, NULL)
+# define gMemLock EnterCriticalSection(&gMemMutex);
+# define gMemUnlock LeaveCriticalSection(&gMemMutex);
+# else
+# include <pthread.h>
+ static pthread_mutex_t gMemMutex = PTHREAD_MUTEX_INITIALIZER;
+# define gMemInitMutex
+# define gMemLock pthread_mutex_lock(&gMemMutex)
+# define gMemUnlock pthread_mutex_unlock(&gMemMutex)
+# endif
+#else
+# define gMemInitMutex
+# define gMemLock
+# define gMemUnlock
+#endif
+
+#endif /* DEBUG_MEM */
+
+#ifdef DEBUG_MEM
+void *gmalloc(int size, int ignore) GMEM_EXCEP {
+ int size1;
+ char *mem;
+ GMemHdr *hdr;
+ void *data;
+ unsigned long *trl, *p;
+
+ gMemInitMutex;
+ if (size < 0) {
+ gMemError("Invalid memory allocation size");
+ }
+ if (size == 0) {
+ return NULL;
+ }
+ size1 = gMemDataSize(size);
+ if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
+ gMemError("Out of memory");
+ }
+ hdr = (GMemHdr *)mem;
+ data = (void *)(mem + gMemHdrSize);
+ trl = (unsigned long *)(mem + gMemHdrSize + size1);
+ hdr->magic = gMemMagic;
+ hdr->size = size;
+ gMemLock;
+ if (ignore) {
+ hdr->index = -1;
+ } else {
+ hdr->index = gMemIndex++;
+ }
+ if (gMemTail) {
+ gMemTail->next = hdr;
+ hdr->prev = gMemTail;
+ gMemTail = hdr;
+ } else {
+ hdr->prev = NULL;
+ gMemHead = gMemTail = hdr;
+ }
+ hdr->next = NULL;
+ ++gMemAlloc;
+ gMemInUse += size;
+ if (gMemInUse > gMaxMemInUse) {
+ gMaxMemInUse = gMemInUse;
+ }
+ gMemUnlock;
+ for (p = (unsigned long *)data; p <= trl; ++p) {
+ *p = gMemDeadVal;
+ }
+ return data;
+}
+#else
+void *gmalloc(int size) GMEM_EXCEP {
+ void *p;
+
+ if (size < 0) {
+ gMemError("Invalid memory allocation size");
+ }
+ if (size == 0) {
+ return NULL;
+ }
+ if (!(p = malloc(size))) {
+ gMemError("Out of memory");
+ }
+ return p;
+}
+#endif
+
+void *grealloc(void *p, int size) GMEM_EXCEP {
+#ifdef DEBUG_MEM
+ GMemHdr *hdr;
+ void *q;
+ int oldSize;
+
+ if (size < 0) {
+ gMemError("Invalid memory allocation size");
+ }
+ if (size == 0) {
+ if (p) {
+ gfree(p);
+ }
+ return NULL;
+ }
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ oldSize = (int)hdr->size;
+ q = gmalloc(size);
+ memcpy(q, p, size < oldSize ? size : oldSize);
+ gfree(p);
+ } else {
+ q = gmalloc(size);
+ }
+ return q;
+#else
+ void *q;
+
+ if (size < 0) {
+ gMemError("Invalid memory allocation size");
+ }
+ if (size == 0) {
+ if (p) {
+ free(p);
+ }
+ return NULL;
+ }
+ if (p) {
+ q = realloc(p, size);
+ } else {
+ q = malloc(size);
+ }
+ if (!q) {
+ gMemError("Out of memory");
+ }
+ return q;
+#endif
+}
+
+void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
+ int n;
+
+ if (nObjs == 0) {
+ return NULL;
+ }
+ n = nObjs * objSize;
+ if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
+ gMemError("Bogus memory allocation size");
+ }
+ return gmalloc(n);
+}
+
+#ifdef DEBUG_MEM
+void *gmalloc64(size_t size, int ignore) GMEM_EXCEP {
+ size_t size1;
+ char *mem;
+ GMemHdr *hdr;
+ void *data;
+ unsigned long *trl, *p;
+
+ gMemInitMutex;
+ if (size == 0) {
+ return NULL;
+ }
+ size1 = gMemDataSize64(size);
+ if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
+ gMemError("Out of memory");
+ }
+ hdr = (GMemHdr *)mem;
+ data = (void *)(mem + gMemHdrSize);
+ trl = (unsigned long *)(mem + gMemHdrSize + size1);
+ hdr->magic = gMemMagic;
+ hdr->size = size;
+ gMemLock;
+ if (ignore) {
+ hdr->index = -1;
+ } else {
+ hdr->index = gMemIndex++;
+ }
+ if (gMemTail) {
+ gMemTail->next = hdr;
+ hdr->prev = gMemTail;
+ gMemTail = hdr;
+ } else {
+ hdr->prev = NULL;
+ gMemHead = gMemTail = hdr;
+ }
+ hdr->next = NULL;
+ ++gMemAlloc;
+ gMemInUse += size;
+ if (gMemInUse > gMaxMemInUse) {
+ gMaxMemInUse = gMemInUse;
+ }
+ gMemUnlock;
+ for (p = (unsigned long *)data; p <= trl; ++p) {
+ *p = gMemDeadVal;
+ }
+ return data;
+}
+#else
+void *gmalloc64(size_t size) GMEM_EXCEP {
+ void *p;
+
+ if (size == 0) {
+ return NULL;
+ }
+ if (!(p = malloc(size))) {
+ gMemError("Out of memory");
+ }
+ return p;
+}
+#endif
+
+void *gmallocn64(int nObjs, size_t objSize) GMEM_EXCEP {
+ size_t n;
+
+ if (nObjs == 0) {
+ return NULL;
+ }
+ n = nObjs * objSize;
+ if (nObjs < 0 || (size_t)nObjs >= SIZE_MAX / objSize) {
+ gMemError("Bogus memory allocation size");
+ }
+ return gmalloc64(n);
+}
+
+void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
+ int n;
+
+ if (nObjs == 0) {
+ if (p) {
+ gfree(p);
+ }
+ return NULL;
+ }
+ n = nObjs * objSize;
+ if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
+ gMemError("Bogus memory allocation size");
+ }
+ return grealloc(p, n);
+}
+
+void gfree(void *p) {
+#ifdef DEBUG_MEM
+ size_t size;
+ GMemHdr *hdr;
+ unsigned long *trl, *clr;
+
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ gMemLock;
+ if (hdr->magic == gMemMagic &&
+ ((hdr->prev == NULL) == (hdr == gMemHead)) &&
+ ((hdr->next == NULL) == (hdr == gMemTail))) {
+ if (hdr->prev) {
+ hdr->prev->next = hdr->next;
+ } else {
+ gMemHead = hdr->next;
+ }
+ if (hdr->next) {
+ hdr->next->prev = hdr->prev;
+ } else {
+ gMemTail = hdr->prev;
+ }
+ --gMemAlloc;
+ gMemInUse -= hdr->size;
+ gMemUnlock;
+ size = gMemDataSize64(hdr->size);
+ trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
+ if (*trl != gMemDeadVal) {
+ fprintf(stderr, "Overwrite past end of block %d at address %p\n",
+ hdr->index, p);
+ }
+ for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
+ *clr = gMemDeadVal;
+ }
+ free(hdr);
+ } else {
+ gMemUnlock;
+ fprintf(stderr, "Attempted to free bad address %p\n", p);
+ }
+ }
+#else
+ if (p) {
+ free(p);
+ }
+#endif
+}
+
+void gMemError(const char *msg) GMEM_EXCEP {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+#endif
+}
+
+#ifdef DEBUG_MEM
+void gMemReport(FILE *f) {
+ GMemHdr *p;
+ int left;
+
+ fprintf(f, "%d memory allocations in all\n", gMemIndex);
+ fprintf(f, "maximum memory in use: %zd bytes\n", gMaxMemInUse);
+ left = 0;
+ if (gMemAlloc > 0) {
+ for (p = gMemHead; p; p = p->next) {
+ if (p->index >= 0) {
+ if (!left) {
+ fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
+ fprintf(f, " index size\n");
+ fprintf(f, "-------- --------\n");
+ left = 1;
+ }
+ fprintf(f, "%8d %8zd\n", p->index, p->size);
+ }
+ }
+ }
+ if (!left) {
+ fprintf(f, "No memory blocks left allocated\n");
+ }
+}
+#endif
+
+char *copyString(const char *s) {
+ char *s1;
+
+ s1 = (char *)gmalloc((int)strlen(s) + 1);
+ strcpy(s1, s);
+ return s1;
+}
diff --git a/goo/gmem.h b/goo/gmem.h
new file mode 100644
index 0000000..f131c17
--- /dev/null
+++ b/goo/gmem.h
@@ -0,0 +1,95 @@
+/*
+ * gmem.h
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996-2003 Glyph & Cog, LLC
+ */
+
+#ifndef GMEM_H
+#define GMEM_H
+
+#include <stdio.h>
+#include <aconf.h>
+
+#if USE_EXCEPTIONS
+
+class GMemException {
+public:
+ GMemException() {}
+ ~GMemException() {}
+};
+
+// This used to be:
+// #define GMEM_EXCEP throw(GMemException)
+// but the throw decl was never really very useful, and is deprecated
+// as of C++11 and illegal as of C++17.
+#define GMEM_EXCEP
+
+#else // USE_EXCEPTIONS
+
+#define GMEM_EXCEP
+
+#endif // USE_EXCEPTIONS
+
+/*
+ * Same as malloc, but prints error message and exits if malloc()
+ * returns NULL.
+ */
+#ifdef DEBUG_MEM
+extern void *gmalloc(int size, int ignore = 0) GMEM_EXCEP;
+#else
+extern void *gmalloc(int size) GMEM_EXCEP;
+#endif
+
+/*
+ * Same as realloc, but prints error message and exits if realloc()
+ * returns NULL. If <p> is NULL, calls malloc instead of realloc().
+ */
+extern void *grealloc(void *p, int size) GMEM_EXCEP;
+
+/*
+ * These are similar to gmalloc and grealloc, but take an object count
+ * and size. The result is similar to allocating nObjs * objSize
+ * bytes, but there is an additional error check that the total size
+ * doesn't overflow an int.
+ */
+extern void *gmallocn(int nObjs, int objSize) GMEM_EXCEP;
+extern void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP;
+
+/*
+ * Same as gmalloc and gmallocn, but allow a 64-bit size on 64-bit
+ * systems.
+ */
+#ifdef DEBUG_MEM
+extern void *gmalloc64(size_t size, int ignore = 0) GMEM_EXCEP;
+#else
+extern void *gmalloc64(size_t size) GMEM_EXCEP;
+#endif
+extern void *gmallocn64(int nObjs, size_t objSize) GMEM_EXCEP;
+
+/*
+ * Same as free, but checks for and ignores NULL pointers.
+ */
+extern void gfree(void *p);
+
+/*
+ * Report a memory error.
+ */
+extern void gMemError(const char *msg) GMEM_EXCEP;
+
+#ifdef DEBUG_MEM
+/*
+ * Report on unfreed memory.
+ */
+extern void gMemReport(FILE *f);
+#else
+#define gMemReport(f)
+#endif
+
+/*
+ * Allocate memory and copy a string into it.
+ */
+extern char *copyString(const char *s);
+
+#endif
diff --git a/goo/gmempp.cc b/goo/gmempp.cc
new file mode 100644
index 0000000..fe5790b
--- /dev/null
+++ b/goo/gmempp.cc
@@ -0,0 +1,51 @@
+//========================================================================
+//
+// gmempp.cc
+//
+// Use gmalloc/gfree for C++ new/delete operators.
+//
+// Copyright 1996-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+#include "gmem.h"
+// NB: do not include gmempp.h here.
+
+#ifdef DEBUG_MEM
+
+void *operator new(size_t size) {
+ return gmalloc((int)size, 1);
+}
+
+void *operator new(size_t size, int dummy) {
+ return gmalloc((int)size, 0);
+}
+
+void *operator new[](size_t size) {
+ return gmalloc((int)size, 1);
+}
+
+void *operator new[](size_t size, int dummy) {
+ return gmalloc((int)size, 0);
+}
+
+void operator delete(void *p) {
+ gfree(p);
+}
+
+// This is only called if a constructor throws an exception.
+void operator delete(void *p, int dummy) {
+ gfree(p);
+}
+
+void operator delete[](void *p) {
+ gfree(p);
+}
+
+// This is only called if a constructor throws an exception.
+void operator delete[](void *p, int dummy) {
+ gfree(p);
+}
+
+#endif
diff --git a/goo/gmempp.h b/goo/gmempp.h
new file mode 100644
index 0000000..27f7fe7
--- /dev/null
+++ b/goo/gmempp.h
@@ -0,0 +1,48 @@
+//========================================================================
+//
+// gmempp.h
+//
+// Redefine the new and delete operators to call the debugging malloc.
+//
+// This is a hack: some libraries (Qt) allocate global objects and
+// never free them, so this file #define's new to have an argument, so
+// that we can differentiate our new calls from external library new
+// calls. Calls from external libraries will not be counted when
+// un-freed memory is listed. There's no guarantee that this will
+// work in all cases: if some external library also defines a new
+// operator that takes the same extra argument, things will break
+// horribly.
+//
+// This entire .h file is wrapped in '#ifdef DEBUG_MEM'. I.e., if you
+// don't define DEBUG_MEM, this hack goes away and can't cause any
+// problems. Do not define DEBUG_MEM in production code.
+//
+// To use this .h file, it must be #included *after* all system
+// includes. Calls to new in any modules that do not include this .h
+// file will not be counted as un-freed memory.
+//
+//========================================================================
+
+#ifndef GMEMPP_H
+#define GMEMPP_H
+
+#ifdef DEBUG_MEM
+
+#include <stdlib.h>
+
+extern void *operator new(size_t size, int dummy);
+extern void *operator new[](size_t size, int dummy);
+
+// These have to be defined (and declared) to avoid a compiler warning
+// with Visual Studio.
+extern void operator delete(void *p, int dummy);
+extern void operator delete[](void *p, int dummy);
+
+// This transforms 'new Foo(...)' into 'new (1) Foo(...)', which
+// forces a call to the operator new variant with the 'int dummy' arg.
+#define debug_new new (1)
+#define new debug_new
+
+#endif // DEBUG_MEM
+
+#endif // GMEMPP_H
diff --git a/goo/gtypes.h b/goo/gtypes.h
new file mode 100644
index 0000000..9f64f57
--- /dev/null
+++ b/goo/gtypes.h
@@ -0,0 +1,29 @@
+/*
+ * gtypes.h
+ *
+ * Some useful simple types.
+ *
+ * Copyright 1996-2003 Glyph & Cog, LLC
+ */
+
+#ifndef GTYPES_H
+#define GTYPES_H
+
+/*
+ * These have stupid names to avoid conflicts with some (but not all)
+ * C++ compilers which define them.
+ */
+typedef int GBool;
+#define gTrue 1
+#define gFalse 0
+
+/*
+ * These have stupid names to avoid conflicts with <sys/types.h>,
+ * which on various systems defines some random subset of these.
+ */
+typedef unsigned char Guchar;
+typedef unsigned short Gushort;
+typedef unsigned int Guint;
+typedef unsigned long Gulong;
+
+#endif
diff --git a/goo/libgoo.a b/goo/libgoo.a
new file mode 100644
index 0000000..9af04b8
--- /dev/null
+++ b/goo/libgoo.a
Binary files differ
diff --git a/goo/parseargs.c b/goo/parseargs.c
new file mode 100644
index 0000000..2f5844f
--- /dev/null
+++ b/goo/parseargs.c
@@ -0,0 +1,195 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996-2003 Glyph & Cog, LLC
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "parseargs.h"
+
+static ArgDesc *findArg(ArgDesc *args, char *arg);
+static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]);
+
+GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
+ ArgDesc *arg;
+ int i, j;
+ GBool ok;
+
+ ok = gTrue;
+ i = 1;
+ while (i < *argc) {
+ if (!strcmp(argv[i], "--")) {
+ --*argc;
+ for (j = i; j < *argc; ++j) {
+ argv[j] = argv[j+1];
+ }
+ break;
+ } else if ((arg = findArg(args, argv[i]))) {
+ if (!grabArg(arg, i, argc, argv)) {
+ ok = gFalse;
+ }
+ } else if (argv[i][0] == '-') {
+ ok = gFalse;
+ break;
+ } else {
+ break;
+ }
+ }
+ return ok;
+}
+
+void printUsage(const char *program, const char *otherArgs, ArgDesc *args) {
+ ArgDesc *arg;
+ char *typ;
+ int w, w1;
+
+ w = 0;
+ for (arg = args; arg->arg; ++arg) {
+ if ((w1 = (int)strlen(arg->arg)) > w)
+ w = w1;
+ }
+
+ fprintf(stderr, "Usage: %s [options]", program);
+ if (otherArgs)
+ fprintf(stderr, " %s", otherArgs);
+ fprintf(stderr, "\n");
+
+ for (arg = args; arg->arg; ++arg) {
+ fprintf(stderr, " %s", arg->arg);
+ w1 = 9 + w - (int)strlen(arg->arg);
+ switch (arg->kind) {
+ case argInt:
+ case argIntDummy:
+ typ = " <int>";
+ break;
+ case argFP:
+ case argFPDummy:
+ typ = " <number>";
+ break;
+ case argString:
+ case argStringDummy:
+ typ = " <string>";
+ break;
+ case argFlag:
+ case argFlagDummy:
+ default:
+ typ = "";
+ break;
+ }
+ fprintf(stderr, "%-*s", w1, typ);
+ if (arg->usage)
+ fprintf(stderr, ": %s", arg->usage);
+ fprintf(stderr, "\n");
+ }
+}
+
+static ArgDesc *findArg(ArgDesc *args, char *arg) {
+ ArgDesc *p;
+
+ for (p = args; p->arg; ++p) {
+ if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
+ return p;
+ }
+ return NULL;
+}
+
+static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) {
+ int n;
+ int j;
+ GBool ok;
+
+ ok = gTrue;
+ n = 0;
+ switch (arg->kind) {
+ case argFlag:
+ *(GBool *)arg->val = gTrue;
+ n = 1;
+ break;
+ case argInt:
+ if (i + 1 < *argc && isInt(argv[i+1])) {
+ *(int *)arg->val = atoi(argv[i+1]);
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ case argFP:
+ if (i + 1 < *argc && isFP(argv[i+1])) {
+ *(double *)arg->val = atof(argv[i+1]);
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ case argString:
+ if (i + 1 < *argc) {
+ strncpy((char *)arg->val, argv[i+1], arg->size - 1);
+ ((char *)arg->val)[arg->size - 1] = '\0';
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Internal error in arg table\n");
+ n = 1;
+ break;
+ }
+ if (n > 0) {
+ *argc -= n;
+ for (j = i; j < *argc; ++j)
+ argv[j] = argv[j+n];
+ }
+ return ok;
+}
+
+GBool isInt(char *s) {
+ if (*s == '-' || *s == '+')
+ ++s;
+ while (isdigit(*s & 0xff))
+ ++s;
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
+
+GBool isFP(char *s) {
+ int n;
+
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ while (isdigit(*s & 0xff)) {
+ ++s;
+ ++n;
+ }
+ if (*s == '.')
+ ++s;
+ while (isdigit(*s & 0xff)) {
+ ++s;
+ ++n;
+ }
+ if (n > 0 && (*s == 'e' || *s == 'E')) {
+ ++s;
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ if (!isdigit(*s & 0xff))
+ return gFalse;
+ do {
+ ++s;
+ } while (isdigit(*s & 0xff));
+ }
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
diff --git a/goo/parseargs.h b/goo/parseargs.h
new file mode 100644
index 0000000..b4daa3f
--- /dev/null
+++ b/goo/parseargs.h
@@ -0,0 +1,72 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996-2003 Glyph & Cog, LLC
+ */
+
+#ifndef PARSEARGS_H
+#define PARSEARGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gtypes.h"
+
+/*
+ * Argument kinds.
+ */
+typedef enum {
+ argFlag, /* flag (present / not-present) */
+ /* [val: GBool *] */
+ argInt, /* integer arg */
+ /* [val: int *] */
+ argFP, /* floating point arg */
+ /* [val: double *] */
+ argString, /* string arg */
+ /* [val: char *] */
+ /* dummy entries -- these show up in the usage listing only; */
+ /* useful for X args, for example */
+ argFlagDummy,
+ argIntDummy,
+ argFPDummy,
+ argStringDummy
+} ArgKind;
+
+/*
+ * Argument descriptor.
+ */
+typedef struct {
+ const char *arg; /* the command line switch */
+ ArgKind kind; /* kind of arg */
+ void *val; /* place to store value */
+ int size; /* for argString: size of string */
+ const char *usage; /* usage string */
+} ArgDesc;
+
+/*
+ * Parse command line. Removes all args which are found in the arg
+ * descriptor list <args>. Stops parsing if "--" is found (and removes
+ * it). Returns gFalse if there was an error.
+ */
+extern GBool parseArgs(ArgDesc *args, int *argc, char *argv[]);
+
+/*
+ * Print usage message, based on arg descriptor list.
+ */
+extern void printUsage(const char *program, const char *otherArgs,
+ ArgDesc *args);
+
+/*
+ * Check if a string is a valid integer or floating point number.
+ */
+extern GBool isInt(char *s);
+extern GBool isFP(char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif