diff options
author | Michael Jennings <mej@kainx.org> | 1999-08-17 23:01:18 +0000 |
---|---|---|
committer | Michael Jennings <mej@kainx.org> | 1999-08-17 23:01:18 +0000 |
commit | 22b2a193d3c6e13474b1cb844d9f6e30bb22ab4f (patch) | |
tree | 587c860080095d83f061961e1e84e63aad5f5fd3 /libmej | |
download | eterm-22b2a193d3c6e13474b1cb844d9f6e30bb22ab4f.tar.gz |
Initial import of Eterm 0.8.9 sources
SVN revision: 38
Diffstat (limited to 'libmej')
-rw-r--r-- | libmej/Makefile.am | 12 | ||||
-rw-r--r-- | libmej/Makefile.in | 372 | ||||
-rw-r--r-- | libmej/debug.c | 55 | ||||
-rw-r--r-- | libmej/debug.h | 36 | ||||
-rw-r--r-- | libmej/global.h | 47 | ||||
-rw-r--r-- | libmej/mem.c | 407 | ||||
-rw-r--r-- | libmej/mem.h | 82 | ||||
-rw-r--r-- | libmej/snprintf.c | 519 | ||||
-rw-r--r-- | libmej/strings.c | 568 | ||||
-rw-r--r-- | libmej/strings.h | 106 | ||||
-rw-r--r-- | libmej/strptime.c | 272 | ||||
-rw-r--r-- | libmej/strptime.h | 76 |
12 files changed, 2552 insertions, 0 deletions
diff --git a/libmej/Makefile.am b/libmej/Makefile.am new file mode 100644 index 0000000..2ae3dd2 --- /dev/null +++ b/libmej/Makefile.am @@ -0,0 +1,12 @@ +# $Id$ + +lib_LTLIBRARIES = libmej.la + +libmej_la_SOURCES = debug.c mem.c strings.c snprintf.c + +INCLUDES = -I. -I.. -I$(includedir) -I$(prefix)/include + +libmej_la_LDFLAGS = -version-info 8:9:8 + +EXTRA_DIST = debug.h global.h mem.h strings.h strptime.h strptime.c + diff --git a/libmej/Makefile.in b/libmej/Makefile.in new file mode 100644 index 0000000..1eca941 --- /dev/null +++ b/libmej/Makefile.in @@ -0,0 +1,372 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# $Id$ + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +AUTHORS = @AUTHORS@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CTAGS = @CTAGS@ +DATE = @DATE@ +DBX = @DBX@ +DIST_ROOT = @DIST_ROOT@ +DLLTOOL = @DLLTOOL@ +EGCS = @EGCS@ +FEATURE_CMD = @FEATURE_CMD@ +GDB = @GDB@ +GRLIBS = @GRLIBS@ +IMLIB_CONFIG = @IMLIB_CONFIG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MV = @MV@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +PGCC = @PGCC@ +PSTACK = @PSTACK@ +RANLIB = @RANLIB@ +RM = @RM@ +SED = @SED@ +TAR = @TAR@ +THREADLIBS = @THREADLIBS@ +VERSION = @VERSION@ + +lib_LTLIBRARIES = libmej.la + +libmej_la_SOURCES = debug.c mem.c strings.c snprintf.c + +INCLUDES = -I. -I.. -I$(includedir) -I$(prefix)/include + +libmej_la_LDFLAGS = -version-info 8:9:8 + +EXTRA_DIST = debug.h global.h mem.h strings.h strptime.h strptime.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +X_CFLAGS = @X_CFLAGS@ +X_LIBS = @X_LIBS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +libmej_la_LIBADD = +libmej_la_OBJECTS = debug.lo mem.lo strings.lo snprintf.lo +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +GZIP_ENV = --best +DEP_FILES = .deps/debug.P .deps/mem.P .deps/snprintf.P .deps/strings.P +SOURCES = $(libmej_la_SOURCES) +OBJECTS = $(libmej_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu libmej/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libmej.la: $(libmej_la_OBJECTS) $(libmej_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libmej_la_LDFLAGS) $(libmej_la_OBJECTS) $(libmej_la_LIBADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libmej + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu libmej/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-depend \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libmej/debug.c b/libmej/debug.c new file mode 100644 index 0000000..845d34c --- /dev/null +++ b/libmej/debug.c @@ -0,0 +1,55 @@ +/********************************************************* + * DEBUG.C -- Standardized debugging output * + * -- Michael Jennings * + * -- 20 December 1996 * + *********************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "global.h" +#include <stdio.h> +#include <stdlib.h> +#ifndef WITH_DMALLOC +# include <malloc.h> +#endif +#include <stdarg.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#define DEBUG_C +#include "debug.h" + +int +real_dprintf(const char *format,...) +{ + + va_list args; + int n; + + va_start(args, format); + n = fprintf(stderr, "[debug] "); + n += vfprintf(stderr, format, args); + va_end(args); + fflush(stderr); + return (n); +} diff --git a/libmej/debug.h b/libmej/debug.h new file mode 100644 index 0000000..d96afdb --- /dev/null +++ b/libmej/debug.h @@ -0,0 +1,36 @@ +/********************************************************** + * DEBUG.H -- Header file for DEBUG.C * + * -- Michael Jennings * + * -- 20 December 1996 * + **********************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#if !defined(DEBUG_C) && !defined(DEBUG_CC) + extern int real_dprintf(const char *, ...); +#endif + +#ifndef _LIBMEJ_DEBUG_H +# define _LIBMEJ_DEBUG_H + +#include "../src/debug.h" + +#endif /* _LIBMEJ_DEBUG_H */ diff --git a/libmej/global.h b/libmej/global.h new file mode 100644 index 0000000..2a6077b --- /dev/null +++ b/libmej/global.h @@ -0,0 +1,47 @@ +/*************************************************************** + * GLOBAL.H -- Compile-time options header file * + * -- Michael Jennings * + * -- 16 January 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _GLOBAL_H_ + +#define _GLOBAL_H_ + +#include "config.h" +#include "src/feature.h" + +/* Other compile-time defines */ +#ifdef LINUX +# define _GNU_SOURCE +# define __USE_GNU +# define _BSD_SOURCE +#elif defined(IRIX) +# define _MODERN_C_ +# define _BSD_TYPES +# define _SGI_SOURCE +#elif defined(HP_UX) + +#endif + +#endif /* _GLOBAL_H_ */ diff --git a/libmej/mem.c b/libmej/mem.c new file mode 100644 index 0000000..97550fc --- /dev/null +++ b/libmej/mem.c @@ -0,0 +1,407 @@ + +/*************************************************************** + * MEM.C -- Memory allocation handlers * + * -- Michael Jennings * + * -- 07 January 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "global.h" +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <time.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> +#define MEM_C +#include "debug.h" +#include "mem.h" + +/* + * These're added for a pretty obvious reason -- they're implemented towards + * The beginning of each one's respective function. (The ones with capitalized + * letters. I'm not sure that they'll be useful outside of gdb. Maybe. + */ +#if DEBUG >= DEBUG_MALLOC +static int malloc_count = 0; +static int calloc_count = 0; +static int realloc_count = 0; +static int free_count = 0; + +#endif + +MemRec memrec = +{0, 0, 0, (void **) NULL, (size_t *) NULL}; + +char * +SafeStr(register char *str, unsigned short len) +{ + + register unsigned short i; + + for (i = 0; i < len; i++) { + if (iscntrl(str[i])) { + str[i] = '.'; + } + } + + return (str); +} + +void +memrec_init(void) +{ + + memrec.Count = 0; + D_MALLOC(("Constructing memrec\n")); + memrec.Ptrs = (void **) malloc(sizeof(void *)); + + memrec.Size = (size_t *) malloc(sizeof(size_t)); + memrec.init = 1; + +} + +void +memrec_add_var(void *ptr, size_t size) +{ + + memrec.Count++; + if ((memrec.Ptrs = (void **) realloc(memrec.Ptrs, sizeof(void *) * memrec.Count)) == NULL) { + D_MALLOC(("Unable to reallocate pointer list -- %s\n", strerror(errno))); + } + if ((memrec.Size = (size_t *) realloc(memrec.Size, sizeof(size_t) * memrec.Count)) == NULL) { + D_MALLOC(("Unable to reallocate pointer size list -- %s\n", strerror(errno))); + } + D_MALLOC(("Adding variable of size %lu at 0x%08x\n", size, ptr)); + memrec.Ptrs[memrec.Count - 1] = ptr; + memrec.Size[memrec.Count - 1] = size; +#if 0 + memrec_dump(); +#endif +} + +void +memrec_rem_var(void *ptr) +{ + + unsigned long i; + + for (i = 0; i < memrec.Count; i++) + if (memrec.Ptrs[i] == ptr) + break; + if (i == memrec.Count && memrec.Ptrs[i] != ptr) { +#if 0 + memrec_dump(); +#endif + D_MALLOC(("Attempt to remove a pointer not allocated with Malloc/Realloc:" + " 0x%08x\n", ptr)); + return; + } + memrec.Count--; + D_MALLOC(("Removing variable of size %lu at 0x%08x\n", memrec.Size[i], memrec.Ptrs[i])); + memmove(memrec.Ptrs + i, memrec.Ptrs + i + 1, sizeof(void *) * (memrec.Count - i)); + + memmove(memrec.Size + i, memrec.Size + i + 1, sizeof(size_t) * (memrec.Count - i)); + memrec.Ptrs = (void **) realloc(memrec.Ptrs, sizeof(void *) * memrec.Count); + + memrec.Size = (size_t *) realloc(memrec.Size, sizeof(size_t) * memrec.Count); +#if 0 + memrec_dump(); +#endif +} + +void +memrec_chg_var(void *oldp, void *newp, size_t size) +{ + + unsigned long i; + + for (i = 0; i < memrec.Count; i++) + if (memrec.Ptrs[i] == oldp) + break; + if (i == memrec.Count && memrec.Ptrs[i] != oldp) { +#if 0 + memrec_dump(); +#endif + D_MALLOC(("Attempt to move a pointer not allocated with Malloc/Realloc:" + " 0x%08x\n", oldp)); + return; + } + D_MALLOC(("Changing variable of %lu bytes at 0x%08x to one " + "of %lu bytes at 0x%08x\n", memrec.Size[i], memrec.Ptrs[i], size, newp)); + memrec.Ptrs[i] = newp; + memrec.Size[i] = size; +#if 0 + memrec_dump(); +#endif +} + +void +memrec_dump(void) +{ + + unsigned long i, j, k, l, total = 0; + unsigned long len1, len2; + unsigned char *ptr; + unsigned char buff[9]; + + fprintf(stderr, "DUMP :: %lu pointers stored.\n", memrec.Count); + fprintf(stderr, "DUMP :: Pointer | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n"); + fflush(stderr); + fprintf(stderr, "DUMP :: ---------+----------+--------+---------+-------------------------+---------\n"); + fflush(stderr); + len1 = sizeof(void *) * memrec.Count; + + len2 = sizeof(size_t) * memrec.Count; + for (ptr = (unsigned char *) memrec.Ptrs, j = 0; j < len1; j += 8) { + fprintf(stderr, "DUMP :: %07lu | %08X | %06lu | %07X | ", (unsigned long) 0, (unsigned int) memrec.Ptrs, (unsigned long) (sizeof(void *) * memrec.Count), (unsigned int) j); + + l = ((len1 - j < 8) ? (len1 - j) : (8)); + memset(buff, 0, 9); + memcpy(buff, ptr + j, l); + for (k = 0; k < l; k++) { + fprintf(stderr, "%02.2X ", buff[k]); + } + for (; k < 8; k++) { + fprintf(stderr, " "); + } + fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l)); + fflush(stderr); + } + for (ptr = (unsigned char *) memrec.Size, j = 0; j < len2; j += 8) { + fprintf(stderr, "DUMP :: %07lu | %08x | %06lu | %07X | ", (unsigned long) 0, (unsigned int) memrec.Size, sizeof(size_t) * memrec.Count, (unsigned int) j); + l = ((len2 - j < 8) ? (len2 - j) : (8)); + memset(buff, 0, 9); + memcpy(buff, ptr + j, l); + for (k = 0; k < l; k++) { + fprintf(stderr, "%02.2X ", buff[k]); + } + for (; k < 8; k++) { + fprintf(stderr, " "); + } + fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l)); + fflush(stderr); + } + for (i = 0; i < memrec.Count; i++) { + total += memrec.Size[i]; + for (ptr = (unsigned char *) memrec.Ptrs[i], j = 0; j < memrec.Size[i]; j += 8) { + fprintf(stderr, "DUMP :: %07lu | %08x | %06lu | %07X | ", i + 1, (unsigned int) memrec.Ptrs[i], (unsigned long) memrec.Size[i], (unsigned int) j); + l = ((memrec.Size[i] - j < 8) ? (memrec.Size[i] - j) : (8)); + memset(buff, 0, 9); + memcpy(buff, ptr + j, l); + for (k = 0; k < l; k++) { + fprintf(stderr, "%02.2X ", buff[k]); + } + for (; k < 8; k++) { + fprintf(stderr, " "); + } + fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l)); + fflush(stderr); + } + } + fprintf(stderr, "DUMP :: Total allocated memory: %10lu bytes\n\n", total); + fflush(stderr); +} + +/************* Function prototypes ****************/ + +/* Replacements for malloc(), realloc(), calloc(), and free() */ +void *Malloc(size_t); +void *Realloc(void *, size_t); +void *Calloc(size_t, size_t); +void Free(void *); + +/* A handler for SIGSEGV */ +void HandleSigSegv(int); + +void * +Malloc(size_t size) +{ + +#if 0 + char *temp = NULL; + +#endif + void *temp = NULL; + +#if DEBUG >= DEBUG_MALLOC + ++malloc_count; +#ifdef MALLOC_CALL_DEBUG + if (!(malloc_count % MALLOC_MOD)) { + fprintf(stderr, "Calls to malloc(): %d\n", malloc_count); + } +#endif +#endif + +#if DEBUG >= DEBUG_MALLOC + + if (!memrec.init) { + D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); + memrec_init(); + } +#endif + +#if 0 + temp = (char *) malloc(size); +#endif + temp = malloc(size); + if (!temp) + return NULL; +#if DEBUG >= DEBUG_MALLOC + memrec_add_var(temp, size); +#endif + return (temp); +} + +void * +Realloc(void *ptr, size_t size) +{ + + char *temp = NULL; + +#if DEBUG >= DEBUG_MALLOC + ++realloc_count; +# ifdef MALLOC_CALL_DEBUG + if (!(realloc_count % REALLOC_MOD)) { + fprintf(stderr, "Calls to realloc(): %d\n", realloc_count); + } +# endif +#endif +/* + * Redundant. You know the drill :) + * #if DEBUG >= DEBUG_MALLOC + */ + if (!memrec.init) { + D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); + memrec_init(); + } +/* #endif */ + + if (ptr == NULL) { + temp = (char *) Malloc(size); + } else { + temp = (char *) realloc(ptr, size); +#if DEBUG >= DEBUG_MALLOC + memrec_chg_var(ptr, temp, size); +#endif + } + if (!temp) + return NULL; + return (temp); +} + +void * +Calloc(size_t count, size_t size) +{ + + char *temp = NULL; + +#if DEBUG >= DEBUG_MALLOC + ++calloc_count; +#ifdef MALLOC_CALL_DEBUG + if (!(calloc_count % CALLOC_MOD)) { + fprintf(stderr, "Calls to calloc(): %d\n", calloc_count); + } +#endif +#endif + +#if DEBUG >= DEBUG_MALLOC + + if (!memrec.init) { + D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); + memrec_init(); + } +#endif + + temp = (char *) calloc(count, size); +#if DEBUG >= DEBUG_MALLOC + memrec_add_var(temp, size * count); +#endif + if (!temp) + return NULL; + return (temp); +} + +void +Free(void *ptr) +{ + +#if DEBUG >= DEBUG_MALLOC + ++free_count; +#ifdef MALLOC_CALL_DEBUG + if (!(free_count % FREE_MOD)) { + fprintf(stderr, "Calls to free(): %d\n", free_count); + } +#endif +#endif +#if DEBUG >= DEBUG_MALLOC + if (!memrec.init) { + D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); + memrec_init(); + } +#endif + + if (ptr) { +#if DEBUG >= DEBUG_MALLOC + memrec_rem_var(ptr); +#endif + free(ptr); + } else { + D_MALLOC(("Caught attempt to free NULL pointer\n")); + } +} + +void +HandleSigSegv(int sig) +{ + + static unsigned char segv_again = 0; + + /* Reinstate ourselves as the SIGSEGV handler if we're replaced */ + (void) signal(SIGSEGV, HandleSigSegv); + + /* Recursive seg faults are not cool.... */ + if (segv_again) { + printf("RECURSIVE SEGMENTATION FAULT DETECTED!\n"); + _exit(EXIT_FAILURE); + } + segv_again = 1; +#if DEBUG >= DEBUG_MALLOC + fprintf(stderr, "SEGMENTATION FAULT! DUMPING MEMORY TABLE\n"); + memrec_dump(); +#endif + exit(EXIT_FAILURE); +} + +inline void * +fixed_realloc(void *ptr, size_t size) +{ + + if (ptr) + return (realloc(ptr, size)); + else + return (malloc(size)); + +} diff --git a/libmej/mem.h b/libmej/mem.h new file mode 100644 index 0000000..3ab5226 --- /dev/null +++ b/libmej/mem.h @@ -0,0 +1,82 @@ + /*************************************************************** + * MEM.H -- Header file for mem.c * + * -- Michael Jennings * + * -- 07 January 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _MEM_H_ + +#define _MEM_H_ + +typedef struct memrec_struct { + unsigned char init; + unsigned long Count, TotalSize; + void **Ptrs; + size_t *Size; +} MemRec; + +#ifdef WITH_DMALLOC +# include <dmalloc.h> +# define MALLOC(sz) malloc(sz) +# define CALLOC(type,n) calloc((n),(sizeof(type))) +# define REALLOC(mem,sz) fixed_realloc((mem),(sz)) +# define FREE(ptr) free(ptr) +#elif defined(DEBUG) || !defined(NDEBUG) +# define MALLOC(sz) Malloc(sz) +# define CALLOC(type,n) Calloc((n),(sizeof(type))) +# define REALLOC(mem,sz) Realloc((mem),(sz)) +/* # define FREE(ptr) Free(ptr) */ +# define FREE(ptr) { Free(ptr); ptr = NULL; } +# define MALLOC_MOD 25 +# define REALLOC_MOD 25 +# define CALLOC_MOD 25 +# define FREE_MOD 25 +#else +# define MALLOC(sz) malloc(sz) +# define CALLOC(type,n) calloc((n),(sizeof(type))) +# define REALLOC(mem,sz) fixed_realloc((mem),(sz)) +# define FREE(ptr) free(ptr) +#endif + +#ifndef MEM_C + +extern char *SafeStr(char *, unsigned short); +extern MemRec memrec; +extern void memrec_init(void); +void memrec_add_var(void *, size_t); +void memrec_rem_var(void *); +void memrec_chg_var(void *, void *, size_t); +void memrec_dump(void); +extern void *Malloc(size_t); +extern void *Realloc(void *, size_t); +extern void *Calloc(size_t, size_t); +extern void Free(void *); +extern void myalarm(long); +extern void HandleSigSegv(int); +extern char *GarbageCollect(char *, size_t); +extern char *FileGarbageCollect(char *, size_t); +extern void *fixed_realloc(void *, size_t); +#endif /* MEM_C */ + +#endif /* _MEM_H_ */ + diff --git a/libmej/snprintf.c b/libmej/snprintf.c new file mode 100644 index 0000000..6d351e9 --- /dev/null +++ b/libmej/snprintf.c @@ -0,0 +1,519 @@ +#include "global.h" +#include <errno.h> + +static const char cvs_ident[] = "$Id$"; + +/* + * Shamelessly snarfed from Enlightenment... + * which shamelessly snarfed from sane... + * which shamelessly snarfed from LPR + * which probably shamelessly snarfed from.... + * + * Moved comments to end so I can actually read the code.. cleaned out useless + * junk.... + */ + +#ifndef HAVE_SNPRINTF + +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#endif + +#define VA_LOCAL_DECL va_list ap +#define VA_START(f) va_start(ap, f) +#define VA_SHIFT(v,t) ; /* no-op for ANSI */ +#define VA_END va_end(ap) + +/* + * dopr(): poor man's version of doprintf + */ + +static void dopr(char *buffer, const char *format, va_list args); +static void fmtstr(char *value, int ljust, int len, int zpad, int precision); +static void fmtnum(long value, int base, int dosign, + int ljust, int len, int zpad, int precision); +static void fmtdouble(int fmt, double value, + int ljust, int len, int zpad, int precision); +static void dostr(char *); +static char *output; +static void dopr_outch(int c); +static char *end; +int visible_control = 1; + +int +vsnprintf(char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + end = str + count - 1; + dopr(str, fmt, args); + if (count > 0) { + end[0] = 0; + } + return (strlen(str)); +} + +#ifdef HAVE_STDARG_H +int +snprintf(char *str, size_t count, const char *fmt,...) +#else +int +snprintf(va_alist) + va_dcl + +#endif +{ +#ifndef HAVE_STDARG_H + char *str; + size_t count; + char *fmt; + +#endif + VA_LOCAL_DECL; + + VA_START(fmt); + VA_SHIFT(str, char *); + + VA_SHIFT(count, size_t); + VA_SHIFT(fmt, char *); + + (void) vsnprintf(str, count, fmt, ap); + VA_END; + return (strlen(str)); +} + +static void +dopr(char *buffer, const char *format, va_list args) +{ + int ch; + long value; + int longflag = 0; + char *strvalue; + int ljust; + int len; + int zpad; + int precision; + int set_precision; + double dval; + + output = buffer; + while ((ch = *format++)) { + switch (ch) { + case '%': + ljust = len = zpad = 0; + precision = -1; + set_precision = 0; + nextch: + ch = *format++; + switch (ch) { + case 0: + dostr("**end of format**"); + return; + case '-': + ljust = 1; + goto nextch; + case '.': + set_precision = 1; + precision = 0; + goto nextch; + case '*': + len = va_arg(args, int); + + goto nextch; + case '0': /* set zero padding if len not set */ + if (len == 0 && set_precision == 0) + zpad = '0'; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (set_precision) { + precision = precision * 10 + ch - '0'; + } else { + len = len * 10 + ch - '0'; + } + goto nextch; + case 'l': + longflag = 1; + goto nextch; + case 'u': + case 'U': + /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ + if (longflag) { + value = va_arg(args, long); + } else { + value = va_arg(args, int); + } + fmtnum(value, 10, 0, ljust, len, zpad, precision); + break; + case 'o': + case 'O': + /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ + if (longflag) { + value = va_arg(args, long); + } else { + value = va_arg(args, int); + } + fmtnum(value, 8, 0, ljust, len, zpad, precision); + break; + case 'd': + case 'i': + case 'D': + if (longflag) { + value = va_arg(args, long); + } else { + value = va_arg(args, int); + } + fmtnum(value, 10, 1, ljust, len, zpad, precision); + break; + case 'x': + if (longflag) { + value = va_arg(args, long); + } else { + value = va_arg(args, int); + } + fmtnum(value, 16, 0, ljust, len, zpad, precision); + break; + case 'X': + if (longflag) { + value = va_arg(args, long); + } else { + value = va_arg(args, int); + } + fmtnum(value, -16, 0, ljust, len, zpad, precision); + break; + case 's': + strvalue = va_arg(args, char *); + + fmtstr(strvalue, ljust, len, zpad, precision); + break; + case 'c': + ch = va_arg(args, int); + + { + char b[2]; + int vsb = visible_control; + + b[0] = ch; + b[1] = 0; + visible_control = 0; + fmtstr(b, ljust, len, zpad, precision); + visible_control = vsb; + } + break; + case 'f': + case 'g': + dval = va_arg(args, double); + + fmtdouble(ch, dval, ljust, len, zpad, precision); + break; + case '%': + dopr_outch(ch); + continue; + default: + dostr("???????"); + } + longflag = 0; + break; + default: + dopr_outch(ch); + break; + } + } + *output = 0; +} + +/* + * Format '%[-]len[.precision]s' + * - = left justify (ljust) + * len = minimum length + * precision = numbers of chars in string to use + */ +static void +fmtstr(char *value, int ljust, int len, int zpad, int precision) +{ + int padlen, strlen, i, c; /* amount to pad */ + + zpad = 0; + if (value == 0) { + value = "<NULL>"; + } + if (precision > 0) { + strlen = precision; + } else { + /* cheap strlen so you do not have library call */ + for (strlen = 0; (c = value[strlen]); ++strlen) { + if (visible_control && iscntrl(c) && !isspace(c)) { + ++strlen; + } + } + } + padlen = len - strlen; + if (padlen < 0) + padlen = 0; + if (ljust) + padlen = -padlen; + while (padlen > 0) { + dopr_outch(' '); + --padlen; + } + /* output characters */ + for (i = 0; (c = value[i]); ++i) { + if (visible_control && iscntrl(c) && !isspace(c)) { + dopr_outch('^'); + c = ('@' | (c & 0x1F)); + } + dopr_outch(c); + } + while (padlen < 0) { + dopr_outch(' '); + ++padlen; + } +} + +static void +fmtnum(long value, int base, int dosign, int ljust, + int len, int zpad, int precision) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int padlen = 0; /* amount to pad */ + int caps = 0; + + precision = 0; + /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", + * value, base, dosign, ljust, len, zpad )); */ + uvalue = value; + if (dosign) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } + } + if (base < 0) { + caps = 1; + base = -base; + } + do { + convert[place++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned) base]; + uvalue = (uvalue / (unsigned) base); + } + while (uvalue); + convert[place] = 0; + padlen = len - place; + if (padlen < 0) + padlen = 0; + if (ljust) + padlen = -padlen; + /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", + * convert,place,signvalue,padlen)); */ + if (zpad && padlen > 0) { + if (signvalue) { + dopr_outch(signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch(zpad); + --padlen; + } + } + while (padlen > 0) { + dopr_outch(' '); + --padlen; + } + if (signvalue) + dopr_outch(signvalue); + while (place > 0) + dopr_outch(convert[--place]); + while (padlen < 0) { + dopr_outch(' '); + ++padlen; + } +} + +static void +fmtdouble(int fmt, double value, int ljust, int len, int zpad, int precision) +{ + char convert[128]; + char fmtstr[128]; + int l; + + zpad = 0; + if (len == 0) + len = 10; + if (len > (int) sizeof(convert) - 10) { + len = (int) sizeof(convert) - 10; + } + if (precision > (int) sizeof(convert) - 10) { + precision = (int) sizeof(convert) - 10; + } + if (precision > len) + precision = len; + strcpy(fmtstr, "%"); + if (ljust) + strcat(fmtstr, "-"); + if (len) { + sprintf(fmtstr + strlen(fmtstr), "%d", len); + } + if (precision > 0) { + sprintf(fmtstr + strlen(fmtstr), ".%d", precision); + } + l = strlen(fmtstr); + fmtstr[l] = fmt; + fmtstr[l + 1] = 0; + sprintf(convert, fmtstr, value); + dostr(convert); +} + +static void +dostr(char *str) +{ + while (*str) + dopr_outch(*str++); +} + +static void +dopr_outch(int c) +{ + if (end == 0 || output < end) { + *output++ = c; + } +} + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * plp_snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + **************************************************************/ + +/*************************************************************************** + * LPRng - An Extended Print Spooler System + * + * Copyright 1988-1997, Patrick Powell, San Diego, CA + * papowell@sdsu.edu + * See below for conditions of use. + * + *************************************************************************** + * MODULE: snprintf.c + * PURPOSE: LPRng version of printf - absolutely bombproof (hopefully!) + **************************************************************************/ + +/* + * The "Artistic License" + * + * Preamble + * + * The intent of this document is to state the conditions under which a + * Package may be copied, such that the Copyright Holder maintains some + * semblance of artistic control over the development of the package, + * while giving the users of the package the right to use and distribute + * the Package in a more-or-less customary fashion, plus the right to make + * reasonable modifications. + * + * Definitions: + * + * "Package" refers to the collection of files distributed by the + * Copyright Holder, and derivatives of that collection of files + * created through textual modification. + * + * "Standard Version" refers to such a Package if it has not been + * modified, or has been modified in accordance with the wishes + * of the Copyright Holder as specified below. + * + * "Copyright Holder" is whoever is named in the copyright or + * copyrights for the package. + * + * "You" is you, if you are thinking about copying or distributing + * this Package. + * + * "Reasonable copying fee" is whatever you can justify on the + * basis of media cost, duplication charges, time of people involved, + * and so on. (You will not be required to justify it to the + * Copyright Holder, but only to the computing community at large + * as a market that must bear the fee.) + * + * "Freely Available" means that no fee is charged for the item + * itself, though there may be fees involved in handling the item. + * It also means that recipients of the item may redistribute it + * under the same conditions they received it. + * + * 1. You may make and give away verbatim copies of the source form of the + * Standard Version of this Package without restriction, provided that you + * duplicate all of the original copyright notices and associated disclaimers. + * + * 2. You may apply bug fixes, portability fixes and other modifications + * derived from the Public Domain or from the Copyright Holder. A Package + * modified in such a way shall still be considered the Standard Version. + * + * 3. You may otherwise modify your copy of this Package in any way, provided + * that you insert a prominent notice in each changed file stating how and + * when you changed that file, and provided that you do at least ONE of the + * following: + * + * a) place your modifications in the Public Domain or otherwise make them + * Freely Available, such as by posting said modifications to Usenet or + * an equivalent medium, or placing the modifications on a major archive + * site such as uunet.uu.net, or by allowing the Copyright Holder to include + * your modifications in the Standard Version of the Package. + * + * b) use the modified Package only within your corporation or organization. + * + * c) rename any non-standard executables so the names do not conflict + * with standard executables, which must also be provided, and provide + * a separate manual page for each non-standard executable that clearly + * documents how it differs from the Standard Version. + * + * d) make other distribution arrangements with the Copyright Holder. + * + * 4. You may distribute the programs of this Package in object code or + * executable form, provided that you do at least ONE of the following: + * + * a) distribute a Standard Version of the executables and library files, + * together with instructions (in the manual page or equivalent) on where + * to get the Standard Version. + * + * b) accompany the distribution with the machine-readable source of + * the Package with your modifications. + * + * c) give non-standard executables non-standard names, and clearly + * document the differences in manual pages (or equivalent), together + * with instructions on where to get the Standard Version. + * + * d) make other distribution arrangements with the Copyright Holder. + * + * 5. You may charge a reasonable copying fee for any distribution of this + * Package. You may charge any fee you choose for support of this + * Package. You may not charge a fee for this Package itself. However, + * you may distribute this Package in aggregate with other (possibly + * commercial) programs as part of a larger (possibly commercial) software + * distribution provided that you do not advertise this Package as a + * product of your own. + * + * 6. The name of the Copyright Holder may not be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * 7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * The End + */ + +#endif /* HAVE_SNPRINTF */ diff --git a/libmej/strings.c b/libmej/strings.c new file mode 100644 index 0000000..d2b88f8 --- /dev/null +++ b/libmej/strings.c @@ -0,0 +1,568 @@ +/*************************************************************** + * STRINGS.C -- String manipulation routines * + * -- Michael Jennings * + * -- 08 January 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "global.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#ifndef WITH_DMALLOC +# include <malloc.h> +#endif +#include <ctype.h> +#include "debug.h" +#include "mem.h" +#define STRINGS_C +#include "strings.h" + +#ifndef HAVE_MEMMEM +/* Find first occurance of bytestring needle of size needlelen in memory region + haystack of size haystacklen */ +void * +memmem(void *haystack, register size_t haystacklen, void *needle, register size_t needlelen) +{ + + register char *hs = (char *) haystack; + register char *n = (char *) needle; + register unsigned long i; + register len = haystacklen - needlelen; + + for (i = 0; i < len; i++) { + if (!memcmp(hs + i, n, needlelen)) { + return (hs + i); + } + } + return (NULL); +} +#endif + +#ifndef HAVE_USLEEP +void +usleep(unsigned long usec) +{ + + struct timeval delay; + + delay.tv_sec = 0; + delay.tv_usec = usec; + select(0, NULL, NULL, NULL, &delay); + +} + +#endif + +/***** Not needed ****** +#ifndef HAVE_NANOSLEEP +inline void +nanosleep(unsigned long nsec) { + usleep(nsec / 1000); +} +#endif +************************/ + +/* Return the leftmost cnt characters of str */ +char * +LeftStr(const char *str, unsigned long cnt) +{ + + char *tmpstr; + + tmpstr = (char *) MALLOC(cnt + 1); + strncpy(tmpstr, str, cnt); + tmpstr[cnt] = 0; + return (tmpstr); +} + +/* Return cnt characters from str, starting at position index (from 0) */ +char * +MidStr(const char *str, unsigned long index, unsigned long cnt) +{ + + char *tmpstr; + const char *pstr = str; + + tmpstr = (char *) MALLOC(cnt + 1); + pstr += index; + strncpy(tmpstr, pstr, cnt); + tmpstr[cnt] = 0; + return (tmpstr); +} + +/* Return the rightmost characters of str */ +char * +RightStr(const char *str, unsigned long cnt) +{ + + char *tmpstr; + const char *pstr = str; + + tmpstr = (char *) MALLOC(cnt + 1); + pstr += strlen(str); + pstr -= cnt; + strcpy(tmpstr, pstr); + return (tmpstr); +} + +/* Returns TRUE if str matches regular expression pattern, FALSE otherwise */ +#if defined(HAVE_REGEX_H) || defined(IRIX) +unsigned char +Match(register const char *str, register const char *pattern) +{ + + register regex_t *rexp; + register int result; + +#ifndef IRIX + char errbuf[256]; + + rexp = (regex_t *) MALLOC(sizeof(regex_t)); +#endif + +#ifdef IRIX + if ((rexp = compile((const char *) pattern, (char *) NULL, (char *) NULL)) == NULL) { + fprintf(stderr, "Unable to compile regexp %s\n", pattern); + return (FALSE); + } +#else + if ((result = regcomp(rexp, pattern, REG_EXTENDED)) != 0) { + regerror(result, rexp, errbuf, 256); + fprintf(stderr, "Unable to compile regexp %s -- %s.\n", pattern, errbuf); + FREE(rexp); + return (FALSE); + } +#endif + +#ifdef IRIX + result = step((const char *) str, rexp); + FREE(rexp); + return (result); +#else + if (((result = regexec(rexp, str, (size_t) 0, (regmatch_t *) NULL, 0)) + != 0) && (result != REG_NOMATCH)) { + regerror(result, rexp, errbuf, 256); + fprintf(stderr, "Error testing input string %s -- %s.\n", str, errbuf); + FREE(rexp); + return (FALSE); + } + FREE(rexp); + return (!result); +#endif +} +#endif + +/* Return malloc'd pointer to index-th word in str. "..." counts as 1 word. */ +char * +Word(unsigned long index, const char *str) +{ + + char *tmpstr; + char *delim = DEFAULT_DELIM; + register unsigned long i, j, k; + + k = strlen(str) + 1; + if ((tmpstr = (char *) MALLOC(k)) == NULL) { + fprintf(stderr, "Word(%lu, %s): Unable to allocate memory -- %s.\n", + index, str, strerror(errno)); + return ((char *) NULL); + } + *tmpstr = 0; + for (i = 0, j = 0; j < index && str[i]; j++) { + for (; isspace(str[i]); i++); + switch (str[i]) { + case '\"': + delim = "\""; + i++; + break; + case '\'': + delim = "\'"; + i++; + break; + default: + delim = DEFAULT_DELIM; + } + for (k = 0; str[i] && !strchr(delim, str[i]);) { + if (str[i] == '\\') { + if (str[i + 1] == '\'' || str[i + 1] == '\"') { + i++; + } + } + tmpstr[k++] = str[i++]; + } + switch (str[i]) { + case '\"': + case '\'': + i++; + break; + } + tmpstr[k] = 0; + } + + if (j != index) { + FREE(tmpstr); + D_STRINGS(("Word(%lu, %s) returning NULL.\n", index, str)); + return ((char *) NULL); + } else { + tmpstr = (char *) REALLOC(tmpstr, strlen(tmpstr) + 1); + D_STRINGS(("Word(%lu, %s) returning \"%s\".\n", index, str, tmpstr)); + return (tmpstr); + } +} + +/* Return pointer into str to index-th word in str. "..." counts as 1 word. */ +char * +PWord(unsigned long index, char *str) +{ + + register char *tmpstr = str; + register unsigned long j; + + if (!str) + return ((char *) NULL); + for (; isspace(*tmpstr) && *tmpstr; tmpstr++); + for (j = 1; j < index && *tmpstr; j++) { + for (; !isspace(*tmpstr) && *tmpstr; tmpstr++); + for (; isspace(*tmpstr) && *tmpstr; tmpstr++); + } + + if (*tmpstr == '\"' || *tmpstr == '\'') { + tmpstr++; + } + if (*tmpstr == '\0') { + D_STRINGS(("PWord(%lu, %s) returning NULL.\n", index, str)); + return ((char *) NULL); + } else { + D_STRINGS(("PWord(%lu, %s) returning \"%s\"\n", index, str, tmpstr)); + return tmpstr; + } +} + +/* Returns the number of words in str, for use with Word() and PWord(). "..." counts as 1 word. */ +unsigned long +NumWords(const char *str) +{ + + register unsigned long cnt = 0; + char *delim = DEFAULT_DELIM; + register unsigned long i; + + for (i = 0; str[i] && strchr(delim, str[i]); i++); + for (; str[i]; cnt++) { + switch (str[i]) { + case '\"': + delim = "\""; + i++; + break; + case '\'': + delim = "\'"; + i++; + break; + default: + delim = DEFAULT_DELIM; + } + for (; str[i] && !strchr(delim, str[i]); i++); + switch (str[i]) { + case '\"': + case '\'': + i++; + break; + } + for (; str[i] && isspace(str[i]); i++); + } + + D_STRINGS(("NumWords() returning %lu\n", cnt)); + return (cnt); +} + +char * +StripWhitespace(register char *str) +{ + + register unsigned long i, j; + + if ((j = strlen(str))) { + for (i = j - 1; isspace(*(str + i)); i--); + str[j = i + 1] = 0; + for (i = 0; isspace(*(str + i)); i++); + j -= i; + memmove(str, str + i, j + 1); + } + return (str); +} + +char * +LowerStr(char *str) +{ + + register char *tmp; + + for (tmp = str; *tmp; tmp++) + *tmp = tolower(*tmp); + D_STRINGS(("LowerStr() returning %s\n", str)); + return (str); +} + +char * +UpStr(char *str) +{ + + register char *tmp; + + for (tmp = str; *tmp; tmp++) + *tmp = toupper(*tmp); + D_STRINGS(("UpStr() returning %s\n", str)); + return (str); +} + +char * +StrCaseStr(char *haystack, register const char *needle) +{ + + register char *t; + register size_t len = strlen(needle); + + for (t = haystack; t && *t; t++) { + if (!strncasecmp(t, needle, len)) { + return (t); + } + } + return (NULL); +} + +char * +StrCaseChr(char *haystack, register char needle) +{ + + register char *t; + + for (t = haystack; t && *t; t++) { + if (tolower(*t) == tolower(needle)) { + return (t); + } + } + return (NULL); +} + +char * +StrCasePBrk(char *haystack, register char *needle) +{ + + register char *t; + + for (t = haystack; t && *t; t++) { + if (StrCaseChr(needle, *t)) { + return (t); + } + } + return (NULL); +} + +char * +StrRev(register char *str) +{ + + register int i, j; + + i = strlen(str); + for (j = 0, i--; i > j; i--, j++) { + cswap(str[j], str[i]); + } + return (str); + +} + +#if !(HAVE_STRSEP) +char * +strsep(char **str, register char *sep) +{ + + register char *s = *str; + char *sptr; + + D_STRINGS(("StrSep(%s, %s) called.\n", *str, sep)); + sptr = s; + for (; *s && !strchr(sep, *s); s++); + if (!*s) { + if (s != sptr) { + *str = s; + D_STRINGS(("Reached end of string with token \"%s\" in buffer\n", sptr)); + return (sptr); + } else { + D_STRINGS(("Reached end of string\n")); + return ((char *) NULL); + } + } + *s = 0; + *str = s + 1; + D_STRINGS(("Got token \"%s\", *str == \"%s\"\n", sptr, *str)); + return (sptr); +} +#endif + +char * +GarbageCollect(char *buff, size_t len) +{ + + register char *tbuff = buff, *pbuff = buff; + register unsigned long i, j; + + D_STRINGS(("Garbage collecting on %lu bytes at %10.8p\n", len, buff)); + for (i = 0, j = 0; j < len; j++) + if (pbuff[j]) + tbuff[i++] = pbuff[j]; + tbuff[i++] = '\0'; + D_STRINGS(("Garbage collecting gives: \n%s\n", buff)); + return ((char *) REALLOC(buff, sizeof(char) * i)); +} + +char * +FGarbageCollect(char *buff, size_t len) +{ + + register char *tbuff = buff, *pbuff = buff; + char *tmp1, *tmp2; + register unsigned long j; + + D_STRINGS(("File garbage collecting on %lu bytes at %10.8p\n", len, buff)); + for (j = 0; j < len;) { + switch (pbuff[j]) { + case '#': + for (; !strchr("\r\n", pbuff[j]) && j < len; j++) + pbuff[j] = '\0'; /* First null out the line up to the CR and/or LF */ + for (; strchr("\r\n", pbuff[j]) && j < len; j++) + pbuff[j] = '\0'; /* Then null out the CR and/or LF */ + break; + case '\r': + case '\n': + case '\f': + case ' ': + case '\t': + case '\v': + for (; isspace(pbuff[j]) && j < len; j++) + pbuff[j] = '\0'; /* Null out the whitespace */ + break; + default: + /* Find the end of this line and the occurence of the + next mid-line comment. */ + tmp1 = strpbrk(pbuff + j, "\r\n"); + tmp2 = strstr(pbuff + j, " #"); + + /* If either is null, take the non-null one. Otherwise, + take the lesser of the two. */ + if (!tmp1 || !tmp2) { + tbuff = ((tmp1) ? (tmp1) : (tmp2)); + } else { + tbuff = ((tmp1 < tmp2) ? (tmp1) : (tmp2)); + } + + /* Now let j catch up so that pbuff+j = tbuff; i.e., let + pbuff[j] refer to the same character that tbuff does */ + j += tbuff - (pbuff + j); + + /* Finally, change whatever is at pbuff[j] to a newline. + This will accomplish several things at once: + o It will change a \r to a \n if that's what's there + o If it's a \n, it'll stay the same. No biggie. + o If it's a space, it will end the line there and the + next line will begin with a comment, which is handled + above. */ + if (j < len) + pbuff[j++] = '\n'; + + } + } + + /* Change all occurances of a backslash followed by a newline to nulls + and null out all whitespace up to the next non-whitespace character. + This handles support for breaking a string across multiple lines. */ + for (j = 0; j < len; j++) { + if (pbuff[j] == '\\' && pbuff[j + 1] == '\n') { + pbuff[j++] = '\0'; + for (; isspace(pbuff[j]) && j < len; j++) + pbuff[j] = '\0'; /* Null out the whitespace */ + } + } + + /* And the final step, garbage collect the buffer to condense all + those nulls we just put in. */ + return (GarbageCollect(buff, len)); +} + +char * +CondenseWhitespace(char *s) +{ + + register unsigned char gotspc = 0; + register char *pbuff = s, *pbuff2 = s; + + D_STRINGS(("CondenseWhitespace(%s) called.\n", s)); + for (; *pbuff2; pbuff2++) { + if (isspace(*pbuff2)) { + if (!gotspc) { + *pbuff = ' '; + gotspc = 1; + pbuff++; + } + } else { + *pbuff = *pbuff2; + gotspc = 0; + pbuff++; + } + } + if ((pbuff >= s) && (isspace(*(pbuff - 1)))) + pbuff--; + *pbuff = 0; + D_STRINGS(("CondenseWhitespace() returning \"%s\"\n", s)); + return (REALLOC(s, strlen(s) + 1)); +} + +void +HexDump(void *buff, register size_t count) +{ + + register unsigned long j, k, l; + register unsigned char *ptr; + unsigned char buffr[9]; + + fprintf(stderr, " Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n"); + fprintf(stderr, "---------+--------+---------+-------------------------+---------\n"); + for (ptr = (unsigned char *) buff, j = 0; j < count; j += 8) { + fprintf(stderr, " %08x | %06lu | %07X | ", (unsigned int) buff, + (unsigned long) count, (unsigned int) j); + l = ((count - j < 8) ? (count - j) : (8)); + memset(buffr, 0, 9); + memcpy(buffr, ptr + j, l); + for (k = 0; k < l; k++) { + fprintf(stderr, "%02.2X ", buffr[k]); + } + for (; k < 8; k++) { + fprintf(stderr, " "); + } + fprintf(stderr, "| %-8s\n", SafeStr((char *) buffr, l)); + } +} diff --git a/libmej/strings.h b/libmej/strings.h new file mode 100644 index 0000000..342565c --- /dev/null +++ b/libmej/strings.h @@ -0,0 +1,106 @@ +/*************************************************************** + * STRINGS.H -- String manipulation routines * + * -- Michael Jennings * + * -- 08 January 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _STRINGS_H_ + +#define _STRINGS_H_ + +#include "global.h" +#include <sys/types.h> +#include <unistd.h> +#include <ctype.h> + +#ifndef TRUE +# define TRUE ((unsigned char)(1)) +# define FALSE ((unsigned char)(0)) +#endif + +#ifndef swap +# define swap(a, b) (((int)(b)) ^= ((int)(a)) ^= ((int)(b)) ^= ((int)(a))) +#endif + +#ifndef cswap +# define cswap(a, b) ((b) ^= (a) ^= (b) ^= (a)) +#endif + +#define DEFAULT_DELIM " \r\n\f\t\v" + +#define CONST_STRLEN(x) (sizeof(x) - 1) +#define BEG_STRCASECMP(s, constr) (strncasecmp(s, constr, CONST_STRLEN(constr))) + +#ifdef IRIX +# define regex_t char +# define NBRA 9 + extern char *braslist[NBRA]; + extern char *braelist[NBRA]; + extern int nbra, regerrno, reglength; + extern char *loc1, *loc2, *locs; + + extern "C" int step(const char *, const char *); + extern "C" int advance(const char *, char *); + extern "C" char *compile(const char *, char *, char *); +#elif defined(HAVE_REGEX_H) +# include <regex.h> +#endif + +#ifndef STRINGS_C +extern char *LeftStr(const char *, unsigned long); +extern char *MidStr(const char *, unsigned long, unsigned long); +extern char *RightStr(const char *, unsigned long); +#if defined(HAVE_REGEX_H) || defined(IRIX) +extern unsigned char Match(const char *, const char *); +#endif +extern char *Word(unsigned long index, const char *str); +extern char *PWord(unsigned long index, char *str); +extern char *StripWhitespace(char *); +extern char *LowerStr(char *); +extern char *UpStr(char *); +extern char *StrCaseStr(char *, const char *); +extern char *StrCaseChr(char *, char); +extern char *StrCasePBrk(char *, char *); +extern char *StrRev(char *); +#if !(HAVE_STRSEP) +extern char *strsep(char **, char *); +#endif +extern char *SafeStr(char *, unsigned short); +extern char *GarbageCollect(char *, size_t); +extern char *FGarbageCollect(char *, size_t); +extern char *CondenseWhitespace(char *); +extern void HexDump(void *, size_t); +#ifndef HAVE_MEMMEM +extern void *memmem(void *, size_t, void *, size_t); +#endif +#ifndef HAVE_USLEEP +extern void usleep(unsigned long); +#endif +/* +#ifndef HAVE_NANOSLEEP +extern void nanosleep(unsigned long); +#endif +*/ +#endif + +#endif /* _STRINGS_H_ */ diff --git a/libmej/strptime.c b/libmej/strptime.c new file mode 100644 index 0000000..6440e95 --- /dev/null +++ b/libmej/strptime.c @@ -0,0 +1,272 @@ + +/*************************************************************** + * STRPTIME.C -- strptime() for IRIX * + * -- Michael Jennings * + * -- 2 April 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#ifdef IRIX + +#include "global.h" +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#define STRPTIME_C +#include "strptime.h" + +char * +strptime(char *buf, const char *format, struct tm *tm) +{ + + register char c; + register const char *tmp; + register int i, len; + + for (tmp = format; *tmp;) { + if (!(*buf)) + break; + + if ((c = *tmp++) != '%') { + if (!isspace(*buf) && c != *buf++) + return ((char *) NULL); + for (; *buf != 0 && isspace(*buf); buf++); + continue; + } + switch ((c = *tmp++)) { + case 0: + case '%': + if (*buf++ != '%') + return ((char *) NULL); + break; + + case 'C': + buf = strptime(buf, USMap.LocaleDateFormat, tm); + if (!buf) + return ((char *) NULL); + break; + + case 'c': + buf = strptime(buf, "%x %X", tm); + if (!buf) + return ((char *) NULL); + break; + + case 'D': + buf = strptime(buf, "%m/%d/%y", tm); + if (!buf) + return ((char *) NULL); + break; + + case 'R': + buf = strptime(buf, "%H:%M", tm); + if (!buf) + return ((char *) NULL); + break; + + case 'r': + buf = strptime(buf, "%I:%M:%S %p", tm); + if (!buf) + return ((char *) NULL); + break; + + case 'T': + buf = strptime(buf, "%H:%M:%S", tm); + if (!buf) + return ((char *) NULL); + break; + + case 'X': + buf = strptime(buf, USMap.TimeFormat, tm); + if (!buf) + return ((char *) NULL); + break; + + case 'x': + buf = strptime(buf, USMap.DateFormat, tm); + if (!buf) + return ((char *) NULL); + break; + + case 'j': + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf != 0 && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (i > 365) + return ((char *) NULL); + tm->tm_yday = i; + break; + + case 'M': + case 'S': + if (!(*buf) || isspace(*buf)) + break; + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf != 0 && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (i > 59) + return ((char *) NULL); + if (c == 'M') + tm->tm_min = i; + else + tm->tm_sec = i; + + if (*buf && isspace(*buf)) + for (; *tmp && !isspace(*tmp); tmp++); + break; + + case 'H': + case 'I': + case 'k': + case 'l': + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (c == 'H' || c == 'k') { + if (i > 23) + return ((char *) NULL); + } else if (i > 11) + return ((char *) NULL); + tm->tm_hour = i; + if (*buf && isspace(*buf)) + for (; *tmp && !isspace(*tmp); tmp++); + break; + + case 'p': + len = strlen(USMap.AM); + if (!strncasecmp(buf, USMap.AM, len)) { + if (tm->tm_hour > 12) + return ((char *) NULL); + if (tm->tm_hour == 12) + tm->tm_hour = 0; + buf += len; + break; + } + len = strlen(USMap.PM); + if (!strncasecmp(buf, USMap.PM, len)) { + if (tm->tm_hour > 12) + return ((char *) NULL); + if (tm->tm_hour != 12) + tm->tm_hour += 12; + buf += len; + break; + } + return ((char *) NULL); + + case 'A': + case 'a': + for (i = 0; i < NUM_DAYS; i++) { + len = strlen(USMap.Days[i]); + if (!strncasecmp(buf, USMap.Days[i], len)) + break; + len = strlen(USMap.DaysAbbrev[i]); + if (!strncasecmp(buf, USMap.DaysAbbrev[i], len)) + break; + } + if (i == NUM_DAYS) + return ((char *) NULL); + tm->tm_wday = i; + buf += len; + break; + + case 'd': + case 'e': + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (i > 31) + return ((char *) NULL); + tm->tm_mday = i; + if (*buf && isspace(*buf)) + for (; *tmp && !isspace(*tmp); tmp++); + break; + + case 'B': + case 'b': + case 'h': + for (i = 0; i < NUM_MONTHS; i++) { + len = strlen(USMap.Months[i]); + if (!strncasecmp(buf, USMap.Months[i], len)) + break; + len = strlen(USMap.MonthsAbbrev[i]); + if (!strncasecmp(buf, USMap.MonthsAbbrev[i], len)) + break; + } + if (i == NUM_MONTHS) + return ((char *) NULL); + tm->tm_mon = i; + buf += len; + break; + + case 'm': + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (i < 1 || i > 12) + return ((char *) NULL); + tm->tm_mon = i - 1; + if (*buf && isspace(*buf)) + for (; *tmp && !isspace(*tmp); tmp++); + break; + + case 'Y': + case 'y': + if (!(*buf) || isspace(*buf)) + break; + if (!isdigit(*buf)) + return ((char *) NULL); + for (i = 0; *buf && isdigit(*buf); buf++) { + i *= 10; + i += *buf - '0'; + } + if (c == 'Y') + i -= 1900; + if (i < 0) + return ((char *) NULL); + tm->tm_year = i; + if (*buf && isspace(*buf)) + for (; *tmp && !isspace(*tmp); tmp++); + break; + } + } + return (buf); +} + +#endif diff --git a/libmej/strptime.h b/libmej/strptime.h new file mode 100644 index 0000000..888dd7c --- /dev/null +++ b/libmej/strptime.h @@ -0,0 +1,76 @@ +/*************************************************************** + * STRPTIME.H -- Header file for strptime() * + * -- Michael Jennings * + * -- 2 April 1997 * + ***************************************************************/ +/* + * This file is original work by Michael Jennings <mej@tcserv.com>. + * + * Copyright (C) 1997, Michael Jennings + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _STRPTIME_H_ + +#define _STRPTIME_H_ + +#define sizeofone(s) (sizeof(s) / sizeof((s)[0])) + +#define NUM_MONTHS 12 +#define NUM_DAYS 7 + +typedef struct dtmap_struct { + char *Months[NUM_MONTHS]; + char *MonthsAbbrev[NUM_MONTHS]; + char *Days[NUM_DAYS]; + char *DaysAbbrev[NUM_DAYS]; + char *DateFormat; + char *TimeFormat; + char *DateTimeFormat; + char *LocaleDateFormat; + char *AM; + char *PM; +} DTMap; + +static DTMap USMap = { + { "January", "February", "March", "April", + "May", "June", "July", "August", + "September", "October", "November", "December" }, + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, + { "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" }, + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, + "%m/%d/%y", + "%H:%M:%S", + "%a %b %e %T %Z %Y", + "%A, %B, %e, %Y", + "AM", + "PM" +}; + +#ifndef STRPTIME_C +# ifdef __cplusplus +extern "C" { +# else +extern { +# endif + extern char *strptime(char *, const char *, struct tm *); +} +#endif + +#endif /* _STRPTIME_H_ */ |