Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pdf/goo
diff options
context:
space:
mode:
authorArturo Espinosa <unammx@src.gnome.org>1999-04-17 02:59:58 (GMT)
committer Arturo Espinosa <unammx@src.gnome.org>1999-04-17 02:59:58 (GMT)
commitd9f9a6449f377b4c933b75d57541b19c6d088994 (patch)
tree04f7f0c54447ef792fbf83bc5039174f4681b3bb /pdf/goo
Initial revision
Diffstat (limited to 'pdf/goo')
-rw-r--r--pdf/goo/GString.cc196
-rw-r--r--pdf/goo/GString.h92
-rw-r--r--pdf/goo/Makefile.in69
-rw-r--r--pdf/goo/gfile.cc455
-rw-r--r--pdf/goo/gfile.h108
-rw-r--r--pdf/goo/gmem.c182
-rw-r--r--pdf/goo/gmem.h53
-rw-r--r--pdf/goo/gmempp.cc23
-rw-r--r--pdf/goo/gtypes.h29
-rw-r--r--pdf/goo/makefile.w3264
-rw-r--r--pdf/goo/parseargs.c190
-rw-r--r--pdf/goo/parseargs.h71
-rw-r--r--pdf/goo/vms_directory.c214
-rw-r--r--pdf/goo/vms_dirent.h67
-rw-r--r--pdf/goo/vms_make.com26
-rw-r--r--pdf/goo/vms_sys_dirent.h54
-rw-r--r--pdf/goo/vms_unix_time.h102
-rw-r--r--pdf/goo/vms_unix_times.c42
-rw-r--r--pdf/goo/vms_unlink.c22
19 files changed, 2059 insertions, 0 deletions
diff --git a/pdf/goo/GString.cc b/pdf/goo/GString.cc
new file mode 100644
index 0000000..e089091
--- /dev/null
+++ b/pdf/goo/GString.cc
@@ -0,0 +1,196 @@
+//========================================================================
+//
+// GString.cc
+//
+// Simple variable-length string type.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include "GString.h"
+
+static inline int size(int len) {
+ int delta;
+
+ delta = len < 256 ? 7 : 255;
+ return ((len + 1) + delta) & ~delta;
+}
+
+inline void GString::resize(int length1) {
+ char *s1;
+
+ if (!s) {
+ s = new char[size(length1)];
+ } else if (size(length1) != size(length)) {
+ s1 = new char[size(length1)];
+ memcpy(s1, s, length + 1);
+ delete[] s;
+ s = s1;
+ }
+}
+
+GString::GString() {
+ s = NULL;
+ resize(length = 0);
+ s[0] = '\0';
+}
+
+GString::GString(char *s1) {
+ int n = strlen(s1);
+
+ s = NULL;
+ resize(length = n);
+ memcpy(s, s1, n + 1);
+}
+
+GString::GString(char *s1, int length1) {
+ s = NULL;
+ resize(length = length1);
+ memcpy(s, s1, length * sizeof(char));
+ 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;
+ resize(length = n1 + n2);
+ memcpy(s, str1->getCString(), n1);
+ memcpy(s + n1, str2->getCString(), n2 + 1);
+}
+
+GString::~GString() {
+ delete[] s;
+}
+
+GString *GString::clear() {
+ s[length = 0] = '\0';
+ resize(0);
+ return this;
+}
+
+GString *GString::append(char c) {
+ resize(length + 1);
+ s[length++] = c;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::append(GString *str) {
+ int n = str->getLength();
+
+ resize(length + n);
+ memcpy(s + length, str->getCString(), n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(char *str) {
+ int n = strlen(str);
+
+ resize(length + n);
+ memcpy(s + length, str, n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(char *str, int length1) {
+ resize(length + length1);
+ memcpy(s + length, str, length1);
+ length += length1;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::insert(int i, char c) {
+ int j;
+
+ 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;
+
+ 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, char *str) {
+ int n = strlen(str);
+ int j;
+
+ 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, char *str, int length1) {
+ int j;
+
+ resize(length + length1);
+ for (j = length; j >= i; --j)
+ s[j+length1] = s[j];
+ memcpy(s+i, str, length1);
+ length += length1;
+ return this;
+}
+
+GString *GString::del(int i, int n) {
+ int j;
+
+ if (n > 0) {
+ 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]))
+ s[i] = toupper(s[i]);
+ }
+ return this;
+}
+
+GString *GString::lowerCase() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (isupper(s[i]))
+ s[i] = tolower(s[i]);
+ }
+ return this;
+}
diff --git a/pdf/goo/GString.h b/pdf/goo/GString.h
new file mode 100644
index 0000000..904f425
--- /dev/null
+++ b/pdf/goo/GString.h
@@ -0,0 +1,92 @@
+//========================================================================
+//
+// GString.h
+//
+// Simple variable-length string type.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GSTRING_H
+#define GSTRING_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <string.h>
+
+class GString {
+public:
+
+ // Create an empty string.
+ GString();
+
+ // Create a string from a C string.
+ GString(char *s1);
+
+ // Create a string from <length1> chars at <s1>. This string
+ // can contain null characters.
+ GString (char *s1, int length1);
+
+ // Copy a string.
+ GString(GString *str);
+ GString *copy() { return new GString(this); }
+
+ // Concatenate two strings.
+ GString(GString *str1, GString *str2);
+
+ // 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(char *str);
+ GString *append(char *str, int length1);
+
+ // Insert a character or string.
+ GString *insert(int i, char c);
+ GString *insert(int i, GString *str);
+ GString *insert(int i, char *str);
+ GString *insert(int i, char *str, int length1);
+
+ // 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:>
+ // These functions assume the strings do not contain null characters.
+ int cmp(GString *str) { return strcmp(s, str->getCString()); }
+ int cmpN(GString *str, int n) { return strncmp(s, str->getCString(), n); }
+ int cmp(char *s1) { return strcmp(s, s1); }
+ int cmpN(char *s1, int n) { return strncmp(s, s1, n); }
+
+private:
+
+ int length;
+ char *s;
+
+ void resize(int length1);
+};
+
+#endif
diff --git a/pdf/goo/Makefile.in b/pdf/goo/Makefile.in
new file mode 100644
index 0000000..d50866d
--- /dev/null
+++ b/pdf/goo/Makefile.in
@@ -0,0 +1,69 @@
+#========================================================================
+#
+# Goo library Makefile
+#
+# Copyright 1996 Derek B. Noonburg
+#
+#========================================================================
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CFLAGS = @CFLAGS@ @DEFS@ @OPTIONS@ -I$(srcdir)
+CXXFLAGS = @CXXFLAGS@ @DEFS@ @OPTIONS@ -I$(srcdir)
+
+CC = @CC@
+CXX = @CXX@
+AR = @AR@
+RANLIB = @RANLIB@
+
+LIBPREFIX = @LIBPREFIX@
+
+#------------------------------------------------------------------------
+
+.SUFFIXES: .cc
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) -c $<
+
+#------------------------------------------------------------------------
+
+CXX_SRC = \
+ $(srcdir)/GString.cc \
+ $(srcdir)/gmempp.cc \
+ $(srcdir)/gfile.cc
+
+C_SRC = \
+ $(srcdir)/gmem.c \
+ $(srcdir)/parseargs.c
+
+#------------------------------------------------------------------------
+
+GOO_CXX_OBJS = GString.o gmempp.o gfile.o
+GOO_C_OBJS = gmem.o parseargs.o
+GOO_OBJS = $(GOO_CXX_OBJS) $(GOO_C_OBJS)
+
+$(LIBPREFIX)Goo.a: $(GOO_OBJS)
+ rm -f $(LIBPREFIX)Goo.a
+ $(AR) $(LIBPREFIX)Goo.a $(GOO_OBJS)
+ $(RANLIB) $(LIBPREFIX)Goo.a
+
+#------------------------------------------------------------------------
+
+clean:
+ rm -f $(GOO_OBJS) $(LIBPREFIX)Goo.a
+
+#------------------------------------------------------------------------
+
+distdepend:
+ cp Makefile.in Makefile.in.bak
+ sed '/^#----- dependences -----/q' Makefile.in.bak >Makefile.in
+ $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >>Makefile.in
+ $(CC) $(CFLAGS) -MM $(C_SRC) >>Makefile.in
+
+#----- dependences -----
+GString.o: ./GString.cc GString.h
+gmempp.o: ./gmempp.cc gmem.h
+gfile.o: ./gfile.cc GString.h gfile.h gtypes.h
+gmem.o: ./gmem.c gmem.h
+parseargs.o: ./parseargs.c parseargs.h gtypes.h
diff --git a/pdf/goo/gfile.cc b/pdf/goo/gfile.cc
new file mode 100644
index 0000000..f6aac95
--- /dev/null
+++ b/pdf/goo/gfile.cc
@@ -0,0 +1,455 @@
+//========================================================================
+//
+// gfile.cc
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef WIN32
+extern "C" {
+#include <sys/stat.h>
+#include <kpathsea/win32lib.h>
+}
+#else // !WIN32
+#include <sys/stat.h>
+#include <limits.h>
+#include <string.h>
+#ifndef VMS
+#include <pwd.h>
+#endif
+#endif // WIN32
+#if defined(VMS) && (__DECCXX_VER < 50200000)
+#include <unixlib.h>
+#endif
+#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(__EMX__) || defined(WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ char *s;
+ GString *ret;
+
+ if ((s = getenv("HOME")))
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+ return ret;
+
+#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 (!GetCurrentDirectory(sizeof(buf), buf))
+#else
+ if (!getcwd(buf, sizeof(buf)))
+#endif
+ return new GString();
+ return new GString(buf);
+}
+
+GString *appendToPath(GString *path, 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);
+ GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
+ delete tmp;
+ path->clear();
+ path->append(buf);
+ return path;
+
+#else
+ //---------- Unix and 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) {
+#ifdef __EMX__
+ if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
+ path->getChar(i) == ':')
+#else
+ if (path->getChar(i) == '/')
+#endif
+ break;
+ }
+ if (i <= 0) {
+#ifdef __EMX__
+ 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(0) == '/') {
+ path->del(1, path->getLength() - 1);
+ } else {
+ path->clear();
+ path->append("..");
+ }
+#endif
+ } else {
+#ifdef __EMX__
+ if (path->getChar(i) == ':')
+ ++i;
+#endif
+ path->del(i, path->getLength() - i);
+ }
+ return path;
+ }
+
+ // otherwise, append "/" and new path component
+#ifdef __EMX__
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/' &&
+ path->getChar(path->getLength() - 1) != '\\')
+#else
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/')
+#endif
+ 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, p - fileName);
+ if ((p = strrchr(fileName, '\\')))
+ return new GString(fileName, p - fileName);
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, p + 1 - fileName);
+ return new GString();
+
+#else
+ //---------- Unix ----------
+ char *p;
+
+ if ((p = strrchr(fileName, '/')))
+ return new GString(fileName, 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] == ':';
+
+#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))) {
+ if (path->getChar(0) == '[') {
+ if (path->getChar(1) != '.')
+ path->insert(0, '.');
+ path->insert(0, buf);
+ } else {
+ path->insert(0, '[');
+ path->insert(1, ']');
+ path->insert(1, buf);
+ }
+ }
+ }
+ return path;
+
+#elif WIN32
+ //---------- Win32 ----------
+ char buf[_MAX_PATH];
+ char *fp;
+
+ buf[0] = '\0';
+ if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
+ path->clear();
+ return path;
+ }
+ path->clear();
+ path->append(buf);
+ 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 = p2 - p1) > PATH_MAX)
+ n = PATH_MAX;
+ strncpy(buf, p1, n);
+ buf[n] = '\0';
+ if ((pw = getpwnam(buf))) {
+ path->del(0, p2 - p1 + 1);
+ path->insert(0, pw->pw_dir);
+ }
+ }
+ } else if (!isAbsolutePath(path->getCString())) {
+ if (getcwd(buf, sizeof(buf))) {
+ path->insert(0, '/');
+ path->insert(0, buf);
+ }
+ }
+ return path;
+#endif
+}
+
+//------------------------------------------------------------------------
+// GDir and GDirEntry
+//------------------------------------------------------------------------
+
+GDirEntry::GDirEntry(char *dirPath, char *name1, GBool doStat) {
+#ifdef VMS
+ char *p;
+#elif WIN32
+ int fa;
+ GString *s;
+#else
+ struct stat st;
+ GString *s;
+#endif
+
+ name = new GString(name1);
+ dir = gFalse;
+ if (doStat) {
+#ifdef VMS
+ if (!strcmp(name1, "-") ||
+ ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5)))
+ dir = gTrue;
+#else
+ s = new GString(dirPath);
+ appendToPath(s, name1);
+#ifdef WIN32
+ fa = GetFileAttributes(s->getCString());
+ dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
+#else
+ if (stat(s->getCString(), &st) == 0)
+ dir = S_ISDIR(st.st_mode);
+#endif
+ delete s;
+#endif
+ }
+}
+
+GDirEntry::~GDirEntry() {
+ delete name;
+}
+
+GDir::GDir(char *name, GBool doStat1) {
+ path = new GString(name);
+ doStat = doStat1;
+#ifdef WIN32
+ GString *tmp;
+
+ tmp = path->copy();
+ tmp->append("/*.*");
+ hnd = FindFirstFile(tmp->getCString(), &ffd);
+ delete tmp;
+#else
+ dir = opendir(name);
+#endif
+#ifdef VMS
+ needParent = strchr(name, '[') != NULL;
+#endif
+}
+
+GDir::~GDir() {
+ delete path;
+#ifdef WIN32
+ if (hnd) {
+ FindClose(hnd);
+ hnd = NULL;
+ }
+#else
+ if (dir)
+ closedir(dir);
+#endif
+}
+
+GDirEntry *GDir::getNextEntry() {
+ struct dirent *ent;
+ GDirEntry *e;
+
+ e = NULL;
+#ifdef WIN32
+ e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
+ if (hnd && !FindNextFile(hnd, &ffd)) {
+ FindClose(hnd);
+ hnd = NULL;
+ }
+#else
+ if (dir) {
+#ifdef VMS
+ if (needParent) {
+ e = new GDirEntry(path->getCString(), "-", doStat);
+ needParent = gFalse;
+ return e;
+ }
+#endif
+ ent = readdir(dir);
+#ifndef VMS
+ if (ent && !strcmp(ent->d_name, "."))
+ ent = readdir(dir);
+#endif
+ if (ent)
+ e = new GDirEntry(path->getCString(), ent->d_name, doStat);
+ }
+#endif
+ return e;
+}
+
+void GDir::rewind() {
+#ifdef WIN32
+ GString *tmp;
+
+ if (hnd)
+ FindClose(hnd);
+ tmp = path->copy();
+ tmp->append("/*.*");
+ hnd = FindFirstFile(tmp->getCString(), &ffd);
+#else
+ if (dir)
+ rewinddir(dir);
+#endif
+#ifdef VMS
+ needParent = strchr(path->getCString(), '[') != NULL;
+#endif
+}
diff --git a/pdf/goo/gfile.h b/pdf/goo/gfile.h
new file mode 100644
index 0000000..f1923cd
--- /dev/null
+++ b/pdf/goo/gfile.h
@@ -0,0 +1,108 @@
+//========================================================================
+//
+// gfile.h
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GFILE_H
+#define GFILE_H
+
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef WIN32
+# include <kpathsea/win32lib.h>
+#else
+# include <unistd.h>
+# include <sys/types.h>
+# ifdef VMS
+# include "vms_dirent.h"
+# elif HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+# else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+# endif
+#endif
+#include "gtypes.h"
+
+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, 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 '~').
+GString *makePathAbsolute(GString *path);
+
+//------------------------------------------------------------------------
+// GDir and GDirEntry
+//------------------------------------------------------------------------
+
+class GDirEntry {
+public:
+
+ GDirEntry(char *dirPath, char *name1, GBool doStat);
+ ~GDirEntry();
+ GString *getName() { return name; }
+ GBool isDir() { return dir; }
+
+private:
+
+ GString *name; // dir/file name
+ GBool dir; // is it a directory?
+};
+
+class GDir {
+public:
+
+ GDir(char *name, GBool doStat1 = gTrue);
+ ~GDir();
+ GDirEntry *getNextEntry();
+ void rewind();
+
+private:
+
+ GString *path; // directory path
+ GBool doStat; // call stat() for each entry?
+#ifdef VMS
+ GBool needParent; // need to return an entry for [-]
+#endif
+#ifdef WIN32
+ WIN32_FIND_DATA ffd;
+ HANDLE hnd;
+#else
+ DIR *dir; // the DIR structure from opendir()
+#endif
+};
+
+#endif
diff --git a/pdf/goo/gmem.c b/pdf/goo/gmem.c
new file mode 100644
index 0000000..4ae5481
--- /dev/null
+++ b/pdf/goo/gmem.c
@@ -0,0 +1,182 @@
+/*
+ * gmem.c
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include "gmem.h"
+
+#ifdef DEBUG_MEM
+typedef struct _GMemHdr {
+ int size;
+ int index;
+ struct _GMemHdr *next;
+} GMemHdr;
+
+#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
+#define gMemTrlSize (sizeof(long))
+
+#if gmemTrlSize==8
+#define gMemDeadVal 0xdeadbeefdeadbeef
+#else
+#define gMemDeadVal 0xdeadbeef
+
+/* round data size so trailer will be aligned */
+#define gMemDataSize(size) \
+ ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
+
+#endif
+
+static GMemHdr *gMemList = NULL;
+static int gMemIndex = 0;
+static int gMemAlloc = 0;
+#endif
+
+void *gmalloc(int size) {
+#if DEBUG_MEM
+ int size1;
+ char *mem;
+ GMemHdr *hdr;
+ void *data;
+ long *trl, *p;
+
+ if (size == 0)
+ return NULL;
+ size1 = gMemDataSize(size);
+ if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ hdr = (GMemHdr *)mem;
+ data = (void *)(mem + gMemHdrSize);
+ trl = (long *)(mem + gMemHdrSize + size1);
+ hdr->size = size;
+ hdr->index = gMemIndex++;
+ hdr->next = gMemList;
+ gMemList = hdr;
+ ++gMemAlloc;
+ for (p = (long *)data; p <= trl; ++p)
+ *p = gMemDeadVal;
+ return data;
+#else
+ void *p;
+
+ if (size == 0)
+ return NULL;
+ if (!(p = malloc(size))) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ return p;
+#endif
+}
+
+void *grealloc(void *p, int size) {
+#if DEBUG_MEM
+ GMemHdr *hdr;
+ void *q;
+ int oldSize;
+
+ if (size == 0) {
+ if (p)
+ gfree(p);
+ return NULL;
+ }
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ oldSize = 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) {
+ if (p)
+ free(p);
+ return NULL;
+ }
+ if (p)
+ q = realloc(p, size);
+ else
+ q = malloc(size);
+ if (!q) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ return q;
+#endif
+}
+
+void gfree(void *p) {
+#ifdef DEBUG_MEM
+ int size;
+ GMemHdr *hdr;
+ GMemHdr *prevHdr, *q;
+ long *trl, *clr;
+
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ for (prevHdr = NULL, q = gMemList; q; prevHdr = q, q = q->next) {
+ if (q == hdr)
+ break;
+ }
+ if (q) {
+ if (prevHdr)
+ prevHdr->next = hdr->next;
+ else
+ gMemList = hdr->next;
+ --gMemAlloc;
+ size = gMemDataSize(hdr->size);
+ trl = (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 = (long *)hdr; clr <= trl; ++clr)
+ *clr = gMemDeadVal;
+ free(hdr);
+ } else {
+ fprintf(stderr, "Attempted to free bad address %p\n", p);
+ }
+ }
+#else
+ if (p)
+ free(p);
+#endif
+}
+
+#ifdef DEBUG_MEM
+void gMemReport(FILE *f) {
+ GMemHdr *p;
+
+ fprintf(f, "%d memory allocations in all\n", gMemIndex);
+ if (gMemAlloc > 0) {
+ fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
+ fprintf(f, " index size\n");
+ fprintf(f, "-------- --------\n");
+ for (p = gMemList; p; p = p->next)
+ fprintf(f, "%8d %8d\n", p->index, p->size);
+ } else {
+ fprintf(f, "No memory blocks left allocated\n");
+ }
+}
+#endif
+
+char *copyString(char *s) {
+ char *s1;
+
+ s1 = (char *)gmalloc(strlen(s) + 1);
+ strcpy(s1, s);
+ return s1;
+}
diff --git a/pdf/goo/gmem.h b/pdf/goo/gmem.h
new file mode 100644
index 0000000..7ab5ddb
--- /dev/null
+++ b/pdf/goo/gmem.h
@@ -0,0 +1,53 @@
+/*
+ * gmem.h
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#ifndef GMEM_H
+#define GMEM_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Same as malloc, but prints error message and exits if malloc()
+ * returns NULL.
+ */
+extern void *gmalloc(int size);
+
+/*
+ * 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);
+
+/*
+ * Same as free, but checks for and ignores NULL pointers.
+ */
+extern void gfree(void *p);
+
+#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(char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pdf/goo/gmempp.cc b/pdf/goo/gmempp.cc
new file mode 100644
index 0000000..41dd441
--- /dev/null
+++ b/pdf/goo/gmempp.cc
@@ -0,0 +1,23 @@
+//========================================================================
+//
+// gmempp.cc
+//
+// Use gmalloc/gfree for C++ new/delete operators.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#include "gmem.h"
+
+#ifdef DEBUG_MEM
+void *operator new(long size) {
+ return gmalloc((int)size);
+}
+#endif
+
+#ifdef DEBUG_MEM
+void operator delete(void *p) {
+ gfree(p);
+}
+#endif
diff --git a/pdf/goo/gtypes.h b/pdf/goo/gtypes.h
new file mode 100644
index 0000000..6593267
--- /dev/null
+++ b/pdf/goo/gtypes.h
@@ -0,0 +1,29 @@
+/*
+ * gtypes.h
+ *
+ * Some useful simple types.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#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/pdf/goo/makefile.w32 b/pdf/goo/makefile.w32
new file mode 100644
index 0000000..b582dce
--- /dev/null
+++ b/pdf/goo/makefile.w32
@@ -0,0 +1,64 @@
+# Generated automatically from Makefile.in by configure.
+#========================================================================
+#
+# Goo library Makefile
+#
+# Copyright 1996 Derek B. Noonburg
+#
+#========================================================================
+
+srcdir = .
+
+CFLAGS = -O2 -DHAVE_DIRENT_H=1 -I$(srcdir)
+CXXFLAGS = -O2 -DHAVE_DIRENT_H=1 -I$(srcdir)
+
+CC = gcc
+CXX = gcc
+AR = ar rc
+RANLIB = ranlib
+
+LIBPREFIX = lib
+
+#------------------------------------------------------------------------
+
+.SUFFIXES: .cc
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) -c $<
+
+#------------------------------------------------------------------------
+
+CXX_SRC = \
+ $(srcdir)/GString.cc \
+ $(srcdir)/gmempp.cc \
+ $(srcdir)/gfile.cc
+
+C_SRC = \
+ $(srcdir)/gmem.c \
+ $(srcdir)/parseargs.c
+
+#------------------------------------------------------------------------
+
+GOO_CXX_OBJS = GString.o gmempp.o gfile.o
+GOO_C_OBJS = gmem.o parseargs.o
+GOO_OBJS = $(GOO_CXX_OBJS) $(GOO_C_OBJS)
+
+$(LIBPREFIX)Goo.a: $(GOO_OBJS)
+ del $(LIBPREFIX)Goo.a
+ $(AR) $(LIBPREFIX)Goo.a $(GOO_OBJS)
+ $(RANLIB) $(LIBPREFIX)Goo.a
+
+#------------------------------------------------------------------------
+
+clean:
+ del *.o
+ del $(LIBPREFIX)Goo.a
+# rm -f Makefile.bak
+
+#------------------------------------------------------------------------
+
+depend:
+ $(CXX) $(CXXFLAGS) -M $(CXX_SRC) >Makefile.dep
+ $(CC) $(CFLAGS) -M $(C_SRC) >>Makefile.dep
+
+#include Makefile.dep
diff --git a/pdf/goo/parseargs.c b/pdf/goo/parseargs.c
new file mode 100644
index 0000000..ceba887
--- /dev/null
+++ b/pdf/goo/parseargs.c
@@ -0,0 +1,190 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#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 {
+ ++i;
+ }
+ }
+ return ok;
+}
+
+void printUsage(char *program, char *otherArgs, ArgDesc *args) {
+ ArgDesc *arg;
+ char *typ;
+ int w, w1;
+
+ w = 0;
+ for (arg = args; arg->arg; ++arg) {
+ if ((w1 = 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 - strlen(arg->arg);
+ switch (arg->kind) {
+ case argInt:
+ case argIntDummy:
+ typ = " <int>";
+ break;
+ case argFP:
+ case argFPDummy:
+ typ = " <fp>";
+ 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))
+ ++s;
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
+
+GBool isFP(char *s) {
+ int n;
+
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (*s == '.')
+ ++s;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (n > 0 && (*s == 'e' || *s == 'E')) {
+ ++s;
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ if (!isdigit(*s))
+ return gFalse;
+ do {
+ ++s;
+ } while (isdigit(*s));
+ }
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
diff --git a/pdf/goo/parseargs.h b/pdf/goo/parseargs.h
new file mode 100644
index 0000000..e0aa2be
--- /dev/null
+++ b/pdf/goo/parseargs.h
@@ -0,0 +1,71 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#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 {
+ char *arg; /* the command line switch */
+ ArgKind kind; /* kind of arg */
+ void *val; /* place to store value */
+ int size; /* for argString: size of string */
+ 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(char *program, 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
diff --git a/pdf/goo/vms_directory.c b/pdf/goo/vms_directory.c
new file mode 100644
index 0000000..92d9493
--- /dev/null
+++ b/pdf/goo/vms_directory.c
@@ -0,0 +1,214 @@
+/*
+ * DIRECTORY.C - VMS emulation routines for UNIX Directory
+ * callable routines
+ *
+ * Author: Patrick L. Mahan
+ * Location: TGV, Inc
+ * Date: 19-November-1991
+ *
+ * Purpose: Provides emulation of the BSD directory routines
+ * which are used by some of the X11 R4 release
+ * software.
+ *
+ * Side effects: This is only a partial emulation. Not all of
+ * the required information is passed to the user.
+ *
+ * Modification History
+ *
+ * Date | Who | Version | History
+ * ------------+-----------+---------------+----------------------------
+ * 19-Nov-1991 | PLM | 1.0 | First Write
+ * 20-Apr-1992 | PLM | 1.1 | Added validation check for
+ * | | | for the directory
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rmsdef.h>
+#include <descrip.h>
+#include <lib$routines.h>
+#include "vms_dirent.h"
+
+#define NOWILD 0x00000001
+#define MULTIPLE 0x00000002
+
+static unsigned long context = 0;
+
+static struct dsc$descriptor_s *create_descriptor ( name )
+char *name;
+{
+ struct dsc$descriptor_s *retdescrip;
+
+ retdescrip = (struct dsc$descriptor_s *)calloc(1, sizeof(struct dsc$descriptor_s));
+
+ if (retdescrip == NULL) return ((struct dsc$descriptor_s *)NULL);
+
+ retdescrip->dsc$b_dtype = DSC$K_DTYPE_T;
+ retdescrip->dsc$b_class = DSC$K_CLASS_S;
+ retdescrip->dsc$w_length = strlen(name);
+ retdescrip->dsc$a_pointer = name;
+
+ return (retdescrip);
+}
+
+static int Check_Directory( dirname )
+char *dirname;
+{
+ static char *tmpdir, *cp;
+ FILE *tfp;
+ int status;
+
+ status = 1;
+
+ tmpdir = calloc(strlen(dirname)+15,sizeof(char));
+
+ strcpy(tmpdir, dirname);
+
+ cp = strrchr(tmpdir, '.');
+
+ if (cp != NULL) {
+ *cp = ']';
+ cp = strrchr(tmpdir, ']');
+ *cp = '.';
+ strcat(tmpdir, "dir");
+ }
+ else {
+ char *tmp1;
+ tmp1 = calloc(strlen(dirname)+1,sizeof(char));
+ cp = strchr(tmpdir, '[');
+ cp++;
+ strcpy(tmp1, cp);
+ cp = strrchr(tmp1, ']');
+ *cp = '\0';
+ cp = strchr(tmpdir, '[');
+ cp++;
+ *cp = '\0';
+ strcat(tmpdir, "000000]");
+ strcat(tmpdir, tmp1);
+ strcat(tmpdir, ".dir");
+ }
+
+ tfp = fopen(tmpdir, "r");
+
+ if (tfp == NULL) status = 0;
+
+ fclose(tfp);
+
+ return (status);
+}
+
+DIR *opendir( dirname )
+char *dirname;
+{
+ DIR *retdir;
+ struct dsc$descriptor_s filedescriptor;
+ char *filepathname;
+
+ retdir = (DIR *) calloc(1, sizeof(DIR));
+
+ if (retdir == NULL) return ((DIR *)NULL);
+
+ if (!Check_Directory(dirname)) return ((DIR *)NULL);
+
+ filepathname = (char *)calloc(256, sizeof(char));
+
+ strcpy(filepathname, dirname);
+ strcat(filepathname, "*.*.*");
+
+ retdir->dd_fd = (unsigned long) create_descriptor(filepathname);
+ retdir->dd_loc = 0;
+ retdir->dd_size = strlen(filepathname);
+ retdir->dd_bsize = 0;
+ retdir->dd_off = 0;
+ retdir->dd_buf = filepathname;
+
+ return (retdir);
+}
+
+struct dirent *readdir( dirp )
+DIR *dirp;
+{
+ static struct dirent *retdirent;
+ struct dsc$descriptor_s retfilenamedesc;
+ struct dsc$descriptor_s searchpathdesc = *((struct dsc$descriptor_s *)dirp->dd_fd);
+ char retfilename[256];
+ char *sp;
+ unsigned long istatus;
+ unsigned long rms_status;
+ unsigned long flags;
+
+ retdirent = (struct dirent *)NULL;
+
+ flags = MULTIPLE;
+
+ retfilenamedesc.dsc$b_dtype = DSC$K_DTYPE_T;
+ retfilenamedesc.dsc$b_class = DSC$K_CLASS_S;
+ retfilenamedesc.dsc$w_length = 255;
+ retfilenamedesc.dsc$a_pointer= retfilename;
+
+ istatus = lib$find_file (&searchpathdesc,
+ &retfilenamedesc,
+ &dirp->dd_loc,
+ 0, 0,
+ &rms_status,
+ &flags);
+
+ if (!(istatus & 1) && (istatus != RMS$_NMF) && (istatus != RMS$_FNF))
+ {
+ lib$signal (istatus);
+ return (retdirent);
+ }
+ else if ((istatus == RMS$_NMF) || (istatus == RMS$_FNF))
+ return (retdirent);
+
+ retfilename[retfilenamedesc.dsc$w_length] = '\0';
+
+ sp = strchr(retfilename, ' ');
+ if (sp != NULL) *sp = '\0';
+
+ sp = strrchr(retfilename, ']');
+ if (sp != NULL)
+ sp++;
+ else
+ sp = retfilename;
+
+ retdirent = (struct dirent *)calloc(1, sizeof(struct dirent));
+
+ strcpy(retdirent->d_name, sp);
+ retdirent->d_namlen = strlen(sp);
+ retdirent->d_fileno = 0;
+ retdirent->d_off = 0;
+ retdirent->d_reclen = DIRSIZ(retdirent);
+
+ return (retdirent);
+}
+
+long telldir( dirp )
+DIR *dirp;
+{
+ return(0);
+}
+
+void seekdir( dirp, loc )
+DIR *dirp;
+int loc;
+{
+ return;
+}
+
+void rewinddir( dirp )
+DIR *dirp;
+{
+ lib$find_file_end (&dirp->dd_loc);
+}
+
+void closedir( dirp )
+DIR *dirp;
+{
+ lib$find_file_end (&dirp->dd_loc);
+
+ cfree ((void *) dirp->dd_fd);
+ cfree (dirp->dd_buf);
+ cfree (dirp);
+}
diff --git a/pdf/goo/vms_dirent.h b/pdf/goo/vms_dirent.h
new file mode 100644
index 0000000..13e21a0
--- /dev/null
+++ b/pdf/goo/vms_dirent.h
@@ -0,0 +1,67 @@
+/* @(#)dirent.h 1.7 89/06/25 SMI */
+
+/*
+ * Filesystem-independent directory information.
+ */
+
+#ifndef __dirent_h
+#define __dirent_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Make sure we don't get the V7 RTL dirent functions. These are broken. */
+
+#ifndef __CRTL_VER
+# define __CRTL_VER __VMS_VER
+#endif
+#if __CRTL_VER >= 70000000
+#include <dirent.h>
+#endif
+
+#include <types.h>
+
+#define opendir goo_opendir
+#define readdir goo_readdir
+#define closedir goo_closedir
+#define seekdir goo_seekdir
+#define telldir goo_telldir
+#define rewinddir goo_rewindir
+#define DIR GOO_DIR
+
+#ifndef _POSIX_SOURCE
+#define d_ino d_fileno /* compatability */
+#ifndef NULL
+#define NULL 0
+#endif
+#endif /* !_POSIX_SOURCE */
+
+/*
+ * Definitions for library routines operating on directories.
+ */
+typedef struct __dirdesc {
+ unsigned long dd_fd; /* file descriptor */
+ long dd_loc; /* buf offset of entry from last readddir() */
+ long dd_size; /* amount of valid data in buffer */
+ long dd_bsize; /* amount of entries read at a time */
+ long dd_off; /* Current offset in dir (for telldir) */
+ char *dd_buf; /* directory data buffer */
+} DIR;
+
+#include "vms_sys_dirent.h"
+
+extern DIR *opendir(char *dirname);
+extern struct dirent *readdir(DIR *dirp);
+extern void closedir(DIR *dirp);
+#ifndef _POSIX_SOURCE
+extern void seekdir(DIR *dirp, int loc);
+extern long telldir(DIR *dirp);
+#endif /* POSIX_SOURCE */
+extern void rewinddir(DIR *dirp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dirent_h */
diff --git a/pdf/goo/vms_make.com b/pdf/goo/vms_make.com
new file mode 100644
index 0000000..88b6458
--- /dev/null
+++ b/pdf/goo/vms_make.com
@@ -0,0 +1,26 @@
+$!========================================================================
+$!
+$! Goo library compile script for VMS.
+$!
+$! Copyright 1996 Derek B. Noonburg
+$!
+$!========================================================================
+$!
+$ GOO_OBJS = "GString.obj,gmempp.obj,gfile.obj,gmem.obj,parseargs.obj" + -
+ ",vms_directory.obj,vms_unix_times.obj"
+$ if f$extract(1,3,f$getsyi("Version")) .lts. "7.0"
+$ then
+$ GOO_OBJS = GOO_OBJS + ",vms_unlink.obj"
+$ CCOMP vms_unlink.c
+$ endif
+$!
+$ CXXCOMP GString.cc
+$ CXXCOMP gmempp.cc
+$ CXXCOMP gfile.cc
+$ CCOMP gmem.c
+$ CCOMP parseargs.c
+$ CCOMP vms_directory.c
+$ CCOMP vms_unix_times.c
+$!
+$ lib/cre libgoo.olb
+$ lib libgoo 'GOO_OBJS
diff --git a/pdf/goo/vms_sys_dirent.h b/pdf/goo/vms_sys_dirent.h
new file mode 100644
index 0000000..2c20d71
--- /dev/null
+++ b/pdf/goo/vms_sys_dirent.h
@@ -0,0 +1,54 @@
+/* @(#)dirent.h 1.4 89/06/16 SMI */
+
+/*
+ * Filesystem-independent directory information.
+ * Directory entry structures are of variable length.
+ * Each directory entry is a struct dirent containing its file number, the
+ * offset of the next entry (a cookie interpretable only the filesystem
+ * type that generated it), the length of the entry, and the length of the
+ * name contained in the entry. These are followed by the name. The
+ * entire entry is padded with null bytes to a 4 byte boundary. All names
+ * are guaranteed null terminated. The maximum length of a name in a
+ * directory is MAXNAMLEN, plus a null byte.
+ */
+
+#ifndef __sys_dirent_h
+#define __sys_dirent_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define dirent GOO_dirent
+
+struct dirent {
+ long d_off; /* offset of next disk dir entry */
+ unsigned long d_fileno; /* file number of entry */
+ unsigned short d_reclen; /* length of this record */
+ unsigned short d_namlen; /* length of string in d_name */
+ char d_name[255+1]; /* name (up to MAXNAMLEN + 1) */
+};
+
+#ifndef _POSIX_SOURCE
+/*
+ * It's unlikely to change, but make sure that sizeof d_name above is
+ * at least MAXNAMLEN + 1 (more may be added for padding).
+ */
+#define MAXNAMLEN 255
+/*
+ * The macro DIRSIZ(dp) gives the minimum amount of space required to represent
+ * a directory entry. For any directory entry dp->d_reclen >= DIRSIZ(dp).
+ * Specific filesystem types may use this macro to construct the value
+ * for d_reclen.
+ */
+#undef DIRSIZ
+#define DIRSIZ(dp) \
+ (((sizeof(struct dirent) - (MAXNAMLEN+1) + ((dp)->d_namlen+1)) +3) & ~3)
+
+#endif /* !_POSIX_SOURCE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__sys_dirent_h */
diff --git a/pdf/goo/vms_unix_time.h b/pdf/goo/vms_unix_time.h
new file mode 100644
index 0000000..f8e8382
--- /dev/null
+++ b/pdf/goo/vms_unix_time.h
@@ -0,0 +1,102 @@
+/* @(#)time.h 2.9 87/01/17 SMI; from UCB 7.1 6/4/86 */
+
+/*
+ Definitions of various structures used on UNIX for
+ time-related syscalls.
+*/
+
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef _UNIX_TIME_
+#define _UNIX_TIME_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Structure returned by gettimeofday(2) system call,
+ * and used in other calls.
+ */
+#ifndef __DECC
+struct timeval
+{
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+#else
+#if (__DECC_VER < 50200000) && (__VMS_VER < 70000000)
+struct timeval
+{
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+#endif /* __DECC_VER */
+#endif /* __DECC */
+struct timezone
+{
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+#define DST_GB 7 /* Great Britain and Eire */
+#define DST_RUM 8 /* Rumania */
+#define DST_TUR 9 /* Turkey */
+#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
+
+/*
+ * Operations on timevals.
+ *
+ * NB: timercmp does not work for >= or <=.
+ */
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec || \
+ (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+#ifndef __DECC
+struct itimerval
+{
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+#else
+#if (__DECC_VER < 50200000) && (__VMS_VER < 70000000)
+struct itimerval
+{
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+#endif /* __DECC_VER */
+#endif /* __DECC */
+
+#ifndef KERNEL
+#include <time.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*!_UNIX_TIME_*/
+
diff --git a/pdf/goo/vms_unix_times.c b/pdf/goo/vms_unix_times.c
new file mode 100644
index 0000000..004c0d0
--- /dev/null
+++ b/pdf/goo/vms_unix_times.c
@@ -0,0 +1,42 @@
+/*
+ * UNIX-style Time Functions
+ *
+ */
+#include <stdio.h>
+#include <signal.h>
+#include <time.h>
+#include "vms_unix_time.h"
+
+/*
+ * gettimeofday(2) - Returns the current time
+ *
+ * NOTE: The timezone portion is useless on VMS.
+ * Even on UNIX, it is only provided for backwards
+ * compatibilty and is not guaranteed to be correct.
+ */
+
+#if (__VMS_VER < 70000000)
+int gettimeofday(tv, tz)
+struct timeval *tv;
+struct timezone *tz;
+{
+ timeb_t tmp_time;
+
+ ftime(&tmp_time);
+
+ if (tv != NULL)
+ {
+ tv->tv_sec = tmp_time.time;
+ tv->tv_usec = tmp_time.millitm * 1000;
+ }
+
+ if (tz != NULL)
+ {
+ tz->tz_minuteswest = tmp_time.timezone;
+ tz->tz_dsttime = tmp_time.dstflag;
+ }
+
+ return (0);
+
+} /*** End gettimeofday() ***/
+#endif
diff --git a/pdf/goo/vms_unlink.c b/pdf/goo/vms_unlink.c
new file mode 100644
index 0000000..e2cf687
--- /dev/null
+++ b/pdf/goo/vms_unlink.c
@@ -0,0 +1,22 @@
+/*
+ * vms_unlink.c
+ *
+ * A UNIX-style unlink() function for VMS.
+ *
+ * Thanks to Patrick Moreau (pmoreau@cena.dgac.fr).
+ */
+
+#include <descrip.h>
+#include <string.h>
+#include <lib$routines.h>
+
+int unlink(char *filename) {
+ static struct dsc$descriptor_s file_desc;
+
+ file_desc.dsc$w_length = strlen(filename);
+ file_desc.dsc$b_dtype = DSC$K_DTYPE_T;
+ file_desc.dsc$b_class = DSC$K_CLASS_S;
+ file_desc.dsc$a_pointer= filename;
+
+ return (lib$delete_file(&file_desc));
+}