home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-05-07 | 39.3 KB | 1,580 lines |
- Newsgroups: comp.sources.unix
- From: decvax!concert.net!woods%robohack (Greg A. Woods)
- Subject: v26i239: uutraf - UUCP Traffic Analysis and Reporting, Part04/04
- Sender: unix-sources-moderator@efficacy.home.vix.com
- Approved: vixie@efficacy.home.vix.com
-
- Submitted-By: decvax!concert.net!woods%robohack (Greg A. Woods)
- Posting-Number: Volume 26, Issue 239
- Archive-Name: uutraf/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 4)."
- # Contents: dlst.shar
- # Wrapped by woods@robohack.uucp on Thu Nov 12 02:48:46 EST 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'dlst.shar' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dlst.shar'\"
- else
- echo shar: Extracting \"'dlst.shar'\" \(36973 characters\)
- sed "s/^X//" >'dlst.shar' <<'END_OF_FILE'
- X#! /bin/sh
- X# This is a shell archive. Remove anything before this line, then unpack
- X# it by saving it into a file and typing "sh file". To overwrite existing
- X# files, type "sh file -c". You can also feed this as standard input via
- X# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- X# will see the following message at the end:
- X# "End of shell archive."
- X# Contents: README Makefile-dist dlst.3 dlst.h list.c alist.c llist.c
- X# Wrapped by woods@robohack on Sun Nov 8 16:36:52 1992
- XPATH=/bin:/usr/bin:/usr/ucb ; export PATH
- Xif test -f 'README' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'README'\"
- Xelse
- Xecho shar: Extracting \"'README'\" \(1701 characters\)
- Xsed "s/^X//" >'README' <<'END_OF_FILE'
- XX
- XX libdlst - dynamic lists
- XX
- XXThis is a simple set of C language tools for building lists. It has
- XXbeen designed in an object-oriented fashion, and can be easily
- XXextended to offer support for all sorts of lists. Currently a
- XXdoubly-linked list type, and an array-list type, are offered.
- XX
- XXSorry, but the documentation is a bit sparse yet....
- XX
- XXIf you wish add support for new types of lists, please examine dlst.h.
- XX
- XXNote that this code uses <sccsid.h>, <sysdefs.h>, and <libc.h>. If
- XXyour compiler does not search the current directory for <>'ed files,
- XXthen you'll have to install these files in INCDIR or /usr/include, or
- XXwherever the "standard places" are, before you build the library.
- XX
- XXIf this package did not include the above required headers, you'll
- XXfind them with the package in which dlst was shipped (probably as
- XXexternhdr.shar). Go back and install them first.
- XX
- XXYou should save a copy of the original Makefile, then edit it to your
- XXrequirements. When you're ready, just type 'make'! If all goes well,
- XXyou should be able to 'make install', and be ready to use the library.
- XX
- XXNOTE: This library is a re-write of an idea presented in "Object
- XX Oriented Programming in C", David Brumbaugh; The_C_Users_
- XX Journal; July 1990, Vol. 8, No. 7. The linked-list sort
- XX routine in llist.c is used (i.e. translated to C from Pascal)
- XX with apologies (though not many!) to R. Sedgewick, from his
- XX book "Algorithms", 1983, p. 149.
- XX
- XXThis library is in the public domain. Use as you see fit.
- XX
- XX#ident "@(#)dlst:README 1.4 92/10/12 16:34:32 (woods)"
- XX--
- XX Greg A. Woods
- XX
- XXwoods@robohack.UUCP woods@Elegant.COM VE3TCP UniForum Canada & ECI
- XX+1 416 443-1734 [home] +1 416 362-XRSA [work] Toronto, Ontario; CANADA
- XEND_OF_FILE
- Xif test 1701 -ne `wc -c <'README'`; then
- X echo shar: \"'README'\" unpacked with wrong size!
- Xfi
- X# end of 'README'
- Xfi
- Xif test -f 'Makefile-dist' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'Makefile-dist'\"
- Xelse
- Xecho shar: Extracting \"'Makefile-dist'\" \(3470 characters\)
- Xsed "s/^X//" >'Makefile-dist' <<'END_OF_FILE'
- XX#! /bin/make -f
- XX#
- XX# a very simple Makefile for libdlst
- XX#
- XX
- XX#ident "@(#)dlst:Makefile 1.6 92/10/12 16:34:09 (woods)"
- XX
- XXSHELL = /bin/sh
- XX
- XXLOCAL = /usr/local
- XX
- XXBINDIR = $(LOCAL)/bin
- XXLIBDIR = $(LOCAL)/lib
- XXINCDIR = $(LOCAL)/include
- XXMANEXT = 3
- XXMANDIR = $(LOCAL)/man/man$(MANEXT)
- XX
- XX# Select the right definition for your system, unless you are compiling on
- XX# one of the following: SunOS, ULTRIX, AIX, XENIX.
- XX#
- XX# v7: SYSTYPE= -DV7 /* UNTESTED "The Real Thing!"(tm) ;-) */
- XX# any BSD: SYSTYPE= -DBSD
- XX# SysIII: SYSTYPE= -DSYSIII /* UNTESTED */
- XX# SysV: SYSTYPE= -DSYSV /* generic AT&T or USG unix */
- XX# SysVr1: SYSTYPE= -DSYSVR1 /* UNTESTED i.e. the original SysV */
- XX# SysVr2: SYSTYPE= -DSYSVR2 /* yes, 3b1'ers, this is you too! */
- XX# SysVr3: SYSTYPE= -DSYSVR3
- XX# SysVr4: SYSTYPE= -DSYSVR4
- XX# any P1003.1:SYSTYPE= -D_POSIX_SOURCE
- XX#
- XXSYSTYPE = -DSYSVR3
- XX
- XX# NOTE: you'll have to define DUMB_VOID if your compiler doesn't fully
- XX# understand the 'void' keyword. (The most common error indicating this
- XX# symptom is "operands of ':' have incompatible types" for invocations of the
- XX# lst_top()/lst_bottom() macros.) If it doesn't understand 'void' at all,
- XX# then you should also define REDEF_VOID.
- XX#
- XX#DEFS = $(SYSTYPE) -DDUMB_VOID
- XX#DEFS = $(SYSTYPE) -DDUMB_VOID -DREDEF_VOID
- XX#
- XXDEFS = $(SYSTYPE)
- XX
- XX# Use 'make DEBUG=-DDEBUG' to compile in debugging code
- XX# Use 'make DEBUG=-DNDEBUG' to turn off assert()s
- XX#
- XXDEBUG =
- XX
- XX# Use 'make OPTIM= SDB=-g' to build for a debugger
- XX#
- XXOPTIM = -O
- XXSDB =
- XX
- XXCFLAGS = $(OPTIM) $(SDB) -I$(INCDIR) $(DEFS) $(DEBUG)
- XXLDFLAGS = -L$(LIBDIR)
- XX
- XX# Another sample:
- XX#
- XX#CFLAGS = $(OPTIM) $(SDB) -I$(LOCAL)/include $(DEBUG) $(DEFS) -pipe -ansi \
- XX# -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings \
- XX# -Dscanf=DONT_USE_SCANF -Dgets=DONT_USE_GETS
- XX#CC = gcc
- XX
- XXLINTARGS = -ax
- XX
- XXLIB = dlst
- XXLIBRARY = lib$(LIB).a
- XXLINTLIB = llib-l$(LIB).ln
- XXMANPAGES = $(LIB).nro
- XX
- XXOBJECTS = list.o alist.o llist.o
- XXSOURCES = list.c alist.c llist.c
- XXINCLUDES = $(LIB).h
- XXOTHER = README Makefile-dist
- XXDOCS = $(LIB).3
- XX
- XX# for making distributions only!
- XX#
- XXEXTERN_HDRS = ../../head/sccsid.h ../../head/sysdefs.h ../../head/libc.h
- XX
- XXdefault: $(LIBRARY)
- XX
- XXall: $(LIBRARY) $(LINTLIB)
- XX
- XXlib$(LIB).a: $(OBJECTS)
- XX ar ru $(LIBRARY) $(OBJECTS)
- XX -ranlib $(LIBRARY)
- XX
- XXlist.o: $(INCLUDES)
- XXalist.o: $(INCLUDES)
- XXllist.o: $(INCLUDES)
- XX
- XXinstall: $(LIBRARY) $(LINTLIB) $(INCLUDES) $(DOCS)
- XX cp $(LIBRARY) $(LIBDIR)
- XX cp llib-l$(LIB).ln $(LIBDIR)
- XX cp $(INCLUDES) $(INCDIR)
- XX cp $(DOCS) $(MANDIR)
- XX
- XXlintlibrary $(LINTLIB): $(SOURCES) $(INCLUDES)
- XX lint $(LINTARGS) -o $(LIB) $(DEFS) -I$(INCDIR) $(SOURCES)
- XX
- XXlint:
- XX lint $(LINTARGS) -p $(DEFS) -I$(INCDIR) $(SOURCES)
- XX
- XXclean:
- XX rm -f $(OBJECTS) core
- XX
- XXclobber: clean
- XX rm -f $(LIBRARY) $(LINTLIB)
- XX
- XXshar: $(LIB).shar
- XX
- XX# using 'make dist' prevents ever patching Makefile-dist...
- XX#
- XXdist: $(LIB).shar Makefile-dist
- XX
- XXfulldist: fullshar Makefile-dist
- XX
- XXcleandist:
- XX rm -f $(LIB).shar
- XX
- XXMakefile-dist: Makefile
- XX @echo "Are you sure? [<DEL> to abort] \c"; read junk
- XX rm -f Makefile-dist
- XX cp Makefile Makefile-dist
- XX
- XX$(LIB).shar: $(OTHER) $(DOCS) $(INCLUDES) $(SOURCES)
- XX shar -b -t 'Please read the file README first' \
- XX $(OTHER) $(DOCS) $(INCLUDES) $(SOURCES) > $(LIB).shar
- XX
- XXfullshar: $(OTHER) $(DOCS) $(INCLUDES) $(SOURCES) externhdr.shar
- XX shar -b -t 'Please read the file README first' \
- XX $(OTHER) $(DOCS) $(INCLUDES) $(SOURCES) externhdr.shar > $(LIB).shar
- XX
- XXexternhdr.shar: $(EXTERN_HDRS) Makefile
- XX shar -b -t 'Please install in local include directory' \
- XX $(EXTERN_HDRS) > externhdr.shar
- XEND_OF_FILE
- Xif test 3470 -ne `wc -c <'Makefile-dist'`; then
- X echo shar: \"'Makefile-dist'\" unpacked with wrong size!
- Xfi
- X# end of 'Makefile-dist'
- Xfi
- Xif test -f 'dlst.3' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'dlst.3'\"
- Xelse
- Xecho shar: Extracting \"'dlst.3'\" \(6210 characters\)
- Xsed "s/^X//" >'dlst.3' <<'END_OF_FILE'
- XX'\"
- XX'\" dlst.3 - dlst library manual page
- XX'\"
- XX'\" command-line control (-rXn) for the .TH arguments:
- XX.nr X
- XX.if \nX=0 .ds x} DLST 3 "Local Libraries" "\&"
- XX.if \nX=1 .ds x} DLST 3 "Local Libraries"
- XX.if \nX=2 .ds x} DLST 3 "" "\&"
- XX.if \nX=3 .ds x} DLST "" "" "\&"
- XX.\"
- XX.\" Fixed-width "code" font. (`.ds C CW')
- XX.\"
- XX.ds C CW
- XX.\".fp 7 \*C \" you may need to load this font too
- XX.\"
- XX.\" Use this as .ft \*C (remember the .ft P)
- XX.\"
- XX.\" In-line select a font for programme text appearing `inline' in
- XX.\" the text. Use the same selection choices as for code blocks.
- XX.\" Prepend `\&' in case the trailing arg starts w/ a period.
- XX.\"
- XX.\" Usage:
- XX.\" .eP foo (`foo' in code font)
- XX.\" .eP foo mp (`foomp', `foo' in code font, `mp' not)
- XX.\" .eP foo mp ka (`kafoomp', `foo' in code font, rest not)
- XX.\"
- XX.\" Sorry it's not too intuitive, but that's troff for ya! Anything
- XX.\" better would be many lines of if's checking no. of args.
- XX.\"
- XX.de eP
- XX. nh
- XX\&\\$3\c
- XX. ft \\*C
- XX\\$1\fP\\$2\" fixed-width font (not broke...)
- XX. hy
- XX..
- XX.\" A wee bit of neat stuff to get tabs to work with .ft \*C
- XX.\"
- XX.ft \*C
- XX.nr x \w' '\" find width of 8 spaces.
- XX.ft P
- XX.rm DT
- XX.de DT\"default tabs
- XX.\" set tabs using width calculated above
- XX.ta \nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu
- XX..
- XX.\"
- XX.TH \*(x}
- XX.SH NAME
- XXdlst: lst_\(**, alist_\(**, llist_\(** \- dynamic list operations
- XX.SH SYNOPSIS
- XX.nf
- XX.eP "cc ... -ldlst"
- XX.PP
- XX.eP "#include <sysdefs.h>"
- XX.eP "#include <sys/types.h>"
- XX.eP "#include <dlst.h>"
- XX.PP
- XX.eP "lst_t \(**lst_new()"
- XX.eP "void lst_destroy(list)"
- XX.eP "bool lst_attop(list)"
- XX.eP "bool lst_atbottom(list)"
- XX.eP "bool lst_isempty(list)"
- XX.eP "bool lst_add(list, datum)"
- XX.eP "bool lst_find(list, datum, cmpfn)"
- XX.eP "bool lst_prev(list)"
- XX.eP "bool lst_next(list)"
- XX.eP "cmp_t lst_cmp(list, datum_1, datum_2)"
- XX.eP "VOID lst_top(list)"
- XX.eP "VOID lst_bottom(list)"
- XX.eP "VOID lst_seek(list, where, from)"
- XX.eP "VOID lst_replace(list, datum)"
- XX.eP "VOID lst_delete(list)"
- XX.eP "VOID lst_display(list, dispfn)"
- XX.eP "UnivPtr lst_current(list)"
- XX.eP "UnivPtr lst_car(list)"
- XX.eP "UnivPtr lst_cdr(list)"
- XX.eP "size_t lst_total(list)"
- XX.eP "size_t lst_ltell(list)"
- XX.PP
- XX.eP "llst_t \(**llst_new()"
- XX.eP "void llst_destroy(llist)"
- XX.eP "bool llst_attop(llist)"
- XX.eP "bool llst_atbottom(llist)"
- XX.eP "bool llst_isempty(llist)"
- XX.eP "bool llst_add(llist, datum)"
- XX.eP "bool llst_find(llist, datum, cmpfn)"
- XX.eP "bool llst_prev(llist)"
- XX.eP "bool llst_next(llist)"
- XX.eP "cmp_t llst_cmp(llist, datum_1, datum_2)"
- XX.eP "VOID llst_top(llist)"
- XX.eP "VOID llst_bottom(llist)"
- XX.eP "VOID llst_seek(llist, where, from)"
- XX.eP "VOID llst_replace(llist, datum)"
- XX.eP "VOID llst_delete(llist)"
- XX.eP "VOID llst_display(llist, dispf)"
- XX.eP "UnivPtr llst_current(llist)"
- XX.eP "UnivPtr llst_car(llist)"
- XX.eP "UnivPtr llst_cdr(llist)"
- XX.eP "size_t llst_total(llist)"
- XX.eP "size_t llst_ltell(llist)"
- XX.eP "VOID llst_sort(llist, cmpfn)"
- XX.PP
- XX.eP "alst_t \(**alst_new()"
- XX.eP "void alst_destroy(alist)"
- XX.eP "bool alst_attop(alist)"
- XX.eP "bool alst_atbottom(alist)"
- XX.eP "bool alst_isempty(alist)"
- XX.eP "bool alst_add(alist, datum)"
- XX.eP "bool alst_find(alist, datum, cmpfn)"
- XX.eP "bool alst_prev(alist)"
- XX.eP "bool alst_next(alist)"
- XX.eP "cmp_t alst_cmp(alist, datum_1, datum_2)"
- XX.eP "VOID alst_top(alist)"
- XX.eP "VOID alst_seek(alist, where, from)"
- XX.eP "VOID alst_bottom(alist)"
- XX.eP "VOID alst_replace(alist, datum)"
- XX.eP "VOID alst_delete(alist)"
- XX.eP "VOID alst_display(alist, dispfn)"
- XX.eP "UnivPtr alst_current(alist)"
- XX.eP "UnivPtr alst_car(alist)"
- XX.eP "UnivPtr alst_cdr(alist)"
- XX.eP "size_t alst_total(alist)"
- XX.eP "size_t alst_ltell(alist)"
- XX.PP
- XX.fi
- XXThe following declarations describe the argument types for the above
- XXfunctions:
- XX.nf
- XX.eP "lst_t \(**list;"
- XX.eP "llst_t \(**llist;"
- XX.eP "alst_t \(**alist;"
- XX.eP "UnivPtr datum, datum_1, datum_2;"
- XX.eP "cmp_t (\(**cmpfn)(UnivPtr datum_1, UnivPtr datum_2);"
- XX.eP "void (\(**dispfn)(UnivPtr datum);"
- XX.eP "size_t where; /\(** list element "index" \(**/"
- XX.eP "int from; /\(** ala lseek()'s SEEK_SET, etc. \(**/"
- XX.fi
- XX.SH DESCRIPTION
- XX.\" arguments in bold, functions in italic,
- XXFor the time being, I'm going to assume you can intuit the meaning of
- XXthe functions based on their name and return value. At some point
- XXI'm going to experiment with some literate programming techniques to
- XXprovide documentation for each function. There's always the ultimate
- XXsource of information and enlightenment!
- XX.eP ":-)"
- XX.SS "Generic Lists"
- XXThe macros prefixed with
- XX.eP lst_
- XXform the interface to the generic list object type.
- XX.SS "Double-Linked Lists"
- XXThe macros prefixed with
- XX.eP llst_
- XXform the interface to the doubly-linked list object type.
- XX.SS "Lists in Arrays"
- XXThe macros prefixed with
- XX.eP lst_
- XXform the interface to the array list object type.
- XX.\".SH RETURNS
- XX.SH CAVEATS
- XXThis library was written as an experiment in object oriented
- XXprogramming using standard C, and thus may not be the most optimal
- XXrepresentation of they underlying data structures. For example, most
- XXfunction calls are through a jump table, and the user-visible calls
- XXare in fact pre-processor macros.
- XX.PP
- XXThe
- XX.eP alst_t
- XXfunctions are not complete, and must be further sub-classed to
- XXimplement any useful function. They are provided only as an example.
- XX.\".SH FILES
- XX.\" lists of associated files
- XX.SH NOTES
- XXThis library depends upon a custom localisation header
- XX.eP <sysdefs.h>
- XXto make it portable to non-ANSI C compilers. Particular attention
- XXmust be paid to the use of the keyword
- XX.eP void
- XXand the macro
- XX.eP VOID .
- XX.\".SH "SEE ALSO"
- XX.\" just plain old list of comma-separated function(S).
- XX.SH AUTHOR
- XXGreg A. Woods
- XX.eP <woods@robohack.UUCP>
- XX.SH HISTORY
- XXThis library began life as a set of routines to wrap around the
- XXlinked-list sort routine, and then was re-written using an idea
- XXpresented in ``Object Oriented Programming in C'', by David Brumbaugh;
- XX.IR "The C Users Journal" ;
- XXJuly 1990, Vol. 8, No. 7.
- XX.PP
- XXThe linked-list sort routine in
- XX.eP llist.c
- XXis used (i.e. translated to C from Pascal) with apologies (though not
- XXmany! -- the translation was ugly!) to R. Sedgewick, from his book
- XX.IR "Algorithms" ,
- XX1983, p. 149.
- XX.SH COPYRIGHT
- XXThe
- XX.B dlst
- XXlibrary and this manual page are in the Public Domain.
- XX.PP
- XX.eP "#ident ``@(#)dlst:dlst.3 1.3 92/07/12 15:04:31 (woods)''
- XEND_OF_FILE
- Xif test 6210 -ne `wc -c <'dlst.3'`; then
- X echo shar: \"'dlst.3'\" unpacked with wrong size!
- Xfi
- X# end of 'dlst.3'
- Xfi
- Xif test -f 'dlst.h' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'dlst.h'\"
- Xelse
- Xecho shar: Extracting \"'dlst.h'\" \(5567 characters\)
- Xsed "s/^X//" >'dlst.h' <<'END_OF_FILE'
- XX/*
- XX * dlst.h - dynamic list classes
- XX */
- XX
- XX#define SID_H "@(#)dlst:dlst.h 1.5 92/07/12 14:59:15 (woods)"
- XX#define SID_NM dlst_sccsid
- XX#include <sccsid.h>
- XX
- XX/* WARNING: these are bound to cause trouble for someone! */
- XX#ifndef DLST_HAVE_BOOL
- XXtypedef int bool; /* boolean result */
- XX#endif
- XX#ifndef DLST_HAVE_CMP_T
- XXtypedef int cmp_t; /* comparison result */
- XX#endif
- XX
- XX#ifndef TRUE
- XX# define TRUE 1
- XX#endif
- XX#ifndef FALSE
- XX# define FALSE 0
- XX#endif
- XX
- XX/*
- XX * generic list base class methods definition
- XX *
- XX * NOTE: The proper way to do this is to define the arguments to the
- XX * methods with prototyping, but since that's not available we'll do it
- XX * below with a set of macros for "sending" the messages.
- XX */
- XX#define LIST_CLASS \
- XX bool (*attop)(), \
- XX (*atbottom)(), \
- XX (*isempty)(), \
- XX (*add)(), \
- XX (*prev)(), \
- XX (*next)(), \
- XX (*seek)(), \
- XX (*find)(); \
- XX cmp_t (*cmp)(); \
- XX VOID (*top)(), \
- XX (*bottom)(), \
- XX (*replace)(), \
- XX (*delete)(), \
- XX (*display)(); \
- XX UnivPtr (*current)(), \
- XX (*cdr)(), \
- XX (*car)(); \
- XX size_t (*total)(), \
- XX (*ltell)();
- XX
- XXtypedef struct list {
- XX LIST_CLASS
- XX} lst_t;
- XX
- XX/*
- XX * constructor and destructor
- XX */
- XXextern lst_t *new_list();
- XXextern void destroy_list();
- XX
- XX/*
- XX * method "messages"
- XX *
- XX * NOTE: make sure we don't de-reference NULL!
- XX */
- XX#define lst_new new_list
- XX#define lst_destroy(list) destroy_list(list)
- XX#define lst_attop(list) ((list) ? ((*((list)->attop))(list)) : 0)
- XX#define lst_atbottom(list) ((list) ? ((*((list)->atbottom))(list)) : 0)
- XX#define lst_isempty(list) ((list) ? ((*((list)->isempty))(list)) : 0)
- XX#define lst_add(list, el) ((list) ? ((*((list)->add))(list, el)) : 0)
- XX#define lst_find(list, el, fn) ((list) ? ((*((list)->find))(list, el, fn)) : 0)
- XX#define lst_cmp(list, a, b) ((list) ? ((*((list)->cmp))(list, a, b)) : (cmp_t) 0)
- XX#define lst_prev(list) ((list) ? ((*((list)->prev))(list)) : 0)
- XX#define lst_next(list) ((list) ? ((*((list)->next))(list)) : 0)
- XX#define lst_top(list) ((list) ? ((*((list)->top))(list)) : (VOID) 0)
- XX#define lst_bottom(list) ((list) ? ((*((list)->bottom))(list)) : (VOID) 0)
- XX#define lst_seek(list, w, s) ((list) ? ((*((list)->seek))(list, w, s)) : 0)
- XX#define lst_replace(list, el) ((list) ? ((*((list)->replace))(list, el)) : (VOID) 0)
- XX#define lst_delete(list) ((list) ? ((*((list)->delete))(list)) : (VOID) 0)
- XX#define lst_display(list, f) ((list) ? ((*((list)->display))(list, f)) : (VOID) 0)
- XX#define lst_current(list) ((list) ? ((*((list)->current))(list)) : (UnivPtr) 0)
- XX#define lst_car(list) ((list) ? ((*((list)->car))(list)) : (UnivPtr) 0)
- XX#define lst_cdr(list) ((list) ? ((*((list)->cdr))(list)) : (UnivPtr) 0)
- XX#define lst_total(list) ((list) ? ((*((list)->total))(list)) : (size_t) 0)
- XX#define lst_ltell(list) ((list) ? ((*((list)->ltell))(list)) : (size_t) 0)
- XX
- XX/*
- XX * a doubly linked list sub-class methods definition.
- XX *
- XX * NOTE: data elements are also defined.
- XX */
- XXtypedef struct llist_element {
- XX struct llist_element *nxt;
- XX struct llist_element *prv;
- XX UnivPtr d;
- XX} llel_t;
- XX
- XX#define LINKED_LIST_CLASS \
- XX LIST_CLASS \
- XX VOID (*sort)(); \
- XX llel_t *first_el; \
- XX llel_t *last_el; \
- XX llel_t *curr_el; \
- XX size_t num_el;
- XX
- XXtypedef struct llist {
- XX LINKED_LIST_CLASS
- XX} llst_t;
- XX
- XX/*
- XX * constructor and destructor
- XX */
- XXextern llst_t *new_llist();
- XXextern void destroy_llist();
- XX
- XX/*
- XX * method "messages"
- XX */
- XX#define llst_new new_llist
- XX#define llst_destroy(list) destroy_llist(list)
- XX#define llst_attop(list) lst_attop(list)
- XX#define llst_atbottom(list) lst_atbottom(list)
- XX#define llst_isempty(list) lst_isempty(list)
- XX#define llst_add(list, el) lst_add(list, el)
- XX#define llst_find(list, el, fn) lst_find(list, el, fn)
- XX#define llst_cmp(list, a, b) lst_cmp(list, a, b)
- XX#define llst_prev(list) lst_prev(list)
- XX#define llst_next(list) lst_next(list)
- XX#define llst_top(list) lst_top(list)
- XX#define llst_seek(list, w, s) lst_seek(list, w, s)
- XX#define llst_bottom(list) lst_bottom(list)
- XX#define llst_replace(list, el) lst_replace(list, el)
- XX#define llst_delete(list) lst_delete(list)
- XX#define llst_display(list, f) lst_display(list, f)
- XX#define llst_current(list) lst_current(list)
- XX#define llst_car(list) lst_car(list)
- XX#define llst_cdr(list) lst_cdr(list)
- XX#define llst_total(list) lst_total(list)
- XX#define llst_ltell(list) lst_ltell(list)
- XX#define llst_sort(list, f) ((list) ? ((*((list)->sort))(list, f)) : (VOID) 0)
- XX
- XX/*
- XX * an array list sub-class methods definition
- XX *
- XX * NOTE: data elements are also defined.
- XX */
- XX#define ARRAY_LIST_CLASS \
- XX LIST_CLASS \
- XX size_t curr_el; \
- XX size_t num_el;
- XX
- XXtypedef struct alist {
- XX ARRAY_LIST_CLASS
- XX} alst_t;
- XX
- XX/*
- XX * constructor and destructor
- XX */
- XXextern alst_t *new_alist();
- XXextern void destroy_alist();
- XX
- XX/*
- XX * method "messages"
- XX */
- XX#define alst_new new_alist
- XX#define alst_destroy(list) destroy_alist(list)
- XX#define alst_attop(list) lst_attop(list)
- XX#define alst_atbottom(list) lst_atbottom(list)
- XX#define alst_isempty(list) lst_isempty(list)
- XX#define alst_add(list, el) lst_add(list, el)
- XX#define alst_find(list, el, fn) lst_find(list, el, fn)
- XX#define alst_cmp(list, a, b) lst_cmp(list, a, b)
- XX#define alst_prev(list) lst_prev(list)
- XX#define alst_next(list) lst_next(list)
- XX#define alst_top(list) lst_top(list)
- XX#define alst_seek(list, w, s) lst_seek(list, w, s)
- XX#define alst_bottom(list) lst_bottom(list)
- XX#define alst_replace(list, el) lst_replace(list, el)
- XX#define alst_delete(list) lst_delete(list)
- XX#define alst_display(list, f) lst_display(list, f)
- XX#define alst_current(list) lst_current(list)
- XX#define alst_car(list) lst_car(list)
- XX#define alst_cdr(list) lst_cdr(list)
- XX#define alst_total(list) lst_total(list)
- XX#define alst_ltell(list) lst_ltell(list)
- XEND_OF_FILE
- Xif test 5567 -ne `wc -c <'dlst.h'`; then
- X echo shar: \"'dlst.h'\" unpacked with wrong size!
- Xfi
- X# end of 'dlst.h'
- Xfi
- Xif test -f 'list.c' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'list.c'\"
- Xelse
- Xecho shar: Extracting \"'list.c'\" \(3792 characters\)
- Xsed "s/^X//" >'list.c' <<'END_OF_FILE'
- XX/*
- XX * list.c - generic list class methods
- XX */
- XX
- XX#define SID "@(#)dlst:list.c 1.5 92/10/03 23:37:50 (woods)"
- XX#include <sccsid.h>
- XX
- XX#if defined(USE_STDDEF) || REALSTDC || (__STDC__ - 0) == 1
- XX# include <stddef.h> /* should do before sysdefs.h */
- XX#endif
- XX#include <sysdefs.h> /* localisation helpers */
- XX#include <sys/types.h> /* for size_t, if avail. */
- XX#include <stdio.h> /* only for "FILE" used in <libc.h> */
- XX#include <assert.h>
- XX#if defined(USG) || defined(SYSV)
- XX# include <malloc.h>
- XX# include <memory.h>
- XX# include <unistd.h>
- XX#endif
- XX#include <libc.h>
- XX#include "dlst.h"
- XX
- XX/*
- XX * Sillyness to keep assigments of invalid_op from making noise
- XX */
- XXtypedef VOID (*voidfn)();
- XXtypedef bool (*boolfn)();
- XXtypedef cmp_t (*cmp_tfn)();
- XXtypedef size_t (*size_tfn)();
- XXtypedef UnivPtr (*UnivPtrFn)();
- XX
- XXstatic void invalid_op();
- XX
- XX/*
- XX * all must have the same types as in LIST_CLASS in list.h
- XX *
- XX * NOTE: Not all of these are defined!
- XX */
- XXstatic bool attop(),
- XX atbottom(),
- XX isempty(),
- XX add(),
- XX prev(),
- XX next(),
- XX seek(),
- XX find();
- XXstatic cmp_t cmp();
- XXstatic VOID top(),
- XX bottom(),
- XX replace(),
- XX delete(),
- XX display();
- XXstatic UnivPtr current(),
- XX cdr(),
- XX car();
- XXstatic size_t total(),
- XX ltell();
- XX
- XX/*
- XX * safety feature
- XX */
- XXstatic void
- XXinvalid_op()
- XX{
- XX assert(0);
- XX return; /* usually not reached! */
- XX}
- XX
- XX/*
- XX * constructor
- XX */
- XXlst_t *
- XXnew_list()
- XX{
- XX lst_t *new;
- XX
- XX if ((new = (lst_t *) malloc(sizeof(lst_t))) == NULL)
- XX return(NULL);
- XX
- XX new->attop = (boolfn) invalid_op;
- XX new->atbottom = (boolfn) invalid_op;
- XX new->isempty = (boolfn) isempty;
- XX new->add = (boolfn) invalid_op;
- XX new->find = (boolfn) invalid_op;
- XX new->cmp = (cmp_tfn) invalid_op;
- XX new->prev = (boolfn) invalid_op;
- XX new->next = (boolfn) invalid_op;
- XX new->top = (voidfn) invalid_op;
- XX new->bottom = (voidfn) invalid_op;
- XX new->seek = seek;
- XX new->replace = (voidfn) invalid_op;
- XX new->delete = (voidfn) invalid_op;
- XX new->display = (voidfn) invalid_op;
- XX new->current = (UnivPtrFn) invalid_op;
- XX new->cdr = (UnivPtrFn) invalid_op;
- XX new->car = (UnivPtrFn) invalid_op;
- XX new->total = (size_tfn) total;
- XX new->ltell = (size_tfn) invalid_op;
- XX
- XX return(new);
- XX}
- XX
- XX/*
- XX * destructor
- XX */
- XXvoid
- XXdestroy_list(this)
- XX lst_t *this;
- XX{
- XX if (this)
- XX free(this);
- XX return;
- XX}
- XX
- XX/*
- XX * methods -- these may not be optimum for all sub-classes
- XX */
- XX
- XXstatic bool
- XXisempty(this)
- XX lst_t *this;
- XX{
- XX return(lst_total(this) == 0);
- XX}
- XX
- XXstatic bool
- XXseek(this, where, from)
- XX lst_t *this;
- XX size_t where; /* destination element or offset */
- XX int from; /* arg. similar to lseek(2s) */
- XX{
- XX size_t count;
- XX
- XX if (!this)
- XX return(FALSE);
- XX /*
- XX * NOTE: upon failure, the current element is always set to the
- XX * top. This is because we don't want to be re-cursive in re-setting
- XX * our position, in case the data is really corrupted.
- XX */
- XX switch (from) {
- XX case SEEK_SET:
- XX lst_top(this);
- XX for (count = (long) 0; count < where; ++count) {
- XX if (lst_atbottom(this)) {
- XX lst_top(this);
- XX return(FALSE);
- XX }
- XX (void) lst_next(this);
- XX }
- XX break;
- XX case SEEK_CUR:
- XX if (where > 0) {
- XX for (count = (long) 0; count < where; ++count) {
- XX if (lst_atbottom(this)) {
- XX lst_top(this);
- XX return(FALSE);
- XX }
- XX (void) lst_next(this);
- XX }
- XX } else if (where < 0) {
- XX for (count = (long) 0; count < where; ++count) {
- XX if (lst_attop(this))
- XX return(FALSE);
- XX (void) lst_prev(this);
- XX }
- XX }
- XX break;
- XX case SEEK_END:
- XX lst_bottom(this);
- XX for (count = (long) 0; count < where; ++count) {
- XX if (lst_attop(this))
- XX return(FALSE);
- XX (void) lst_prev(this);
- XX }
- XX break;
- XX }
- XX return(TRUE);
- XX}
- XX
- XXstatic size_t
- XXtotal(this)
- XX lst_t *this;
- XX{
- XX size_t thisone,
- XX count = (long) 0;
- XX
- XX if (!this)
- XX return(0);
- XX thisone = lst_ltell(this);
- XX lst_top(this);
- XX do {
- XX if (!lst_atbottom(this)) {
- XX ++count;
- XX lst_next(this);
- XX }
- XX } while (!lst_atbottom(this));
- XX lst_seek(this, thisone, SEEK_SET);
- XX return(count);
- XX}
- XEND_OF_FILE
- Xif test 3792 -ne `wc -c <'list.c'`; then
- X echo shar: \"'list.c'\" unpacked with wrong size!
- Xfi
- X# end of 'list.c'
- Xfi
- Xif test -f 'alist.c' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'alist.c'\"
- Xelse
- Xecho shar: Extracting \"'alist.c'\" \(3735 characters\)
- Xsed "s/^X//" >'alist.c' <<'END_OF_FILE'
- XX/*
- XX * alist.c - array list sub-class methods
- XX */
- XX
- XX#define SID "@(#)dlst:alist.c 1.5 92/10/03 23:37:12 (woods)"
- XX#include <sccsid.h>
- XX
- XX/*
- XX * This is a mid-level class. The basic structure, as well as simple
- XX * movement methods have been defined. However, a further sub-class is
- XX * required to define the actual array elements, their addition, deletion,
- XX * and other data-related functions.
- XX */
- XX
- XX#if defined(USE_STDDEF) || REALSTDC || (__STDC__ - 0) == 1
- XX# include <stddef.h> /* should do before sysdefs.h */
- XX#endif
- XX#include <sysdefs.h> /* localisation helpers */
- XX#include <sys/types.h> /* for size_t, if avail. */
- XX#include <stdio.h> /* only for "FILE" used in <libc.h> */
- XX#include <assert.h>
- XX#if defined(USG) || defined(SYSV)
- XX# include <malloc.h>
- XX# include <memory.h>
- XX# include <unistd.h>
- XX#endif
- XX#include <libc.h>
- XX#include "dlst.h"
- XX
- XX/*
- XX * all must have the same types as in LIST_CLASS in list.h
- XX *
- XX * NOTE: Not all of these are defined below!
- XX */
- XXstatic bool attop(),
- XX atbottom(),
- XX isempty(),
- XX add(),
- XX prev(),
- XX next(),
- XX seek(),
- XX find();
- XXstatic cmp_t cmp();
- XXstatic VOID top(),
- XX bottom(),
- XX replace(),
- XX delete(),
- XX display(),
- XX sort();
- XXstatic UnivPtr current(),
- XX cdr(),
- XX car();
- XXstatic size_t total(),
- XX ltell();
- XX
- XX/*
- XX * constructor
- XX */
- XXalst_t *
- XXnew_alist()
- XX{
- XX lst_t *lst;
- XX alst_t *new;
- XX
- XX if ((lst = lst_new()) == NULL)
- XX return(NULL);
- XX
- XX if ((new = (alst_t *) malloc(sizeof(alst_t))) == NULL) {
- XX lst_destroy(lst);
- XX return(NULL);
- XX }
- XX (void) memcpy(new, lst, sizeof(*lst)); /* mucho assumptions! */
- XX lst_destroy(lst);
- XX
- XX new->attop = attop;
- XX new->atbottom = atbottom;
- XX new->next = next;
- XX new->prev = prev;
- XX new->seek = seek;
- XX new->top = top;
- XX new->bottom = bottom;
- XX new->total = total;
- XX return(new);
- XX}
- XX
- XX/*
- XX * destructor
- XX */
- XXvoid
- XXdestroy_alist(this)
- XX alst_t *this;
- XX{
- XX /*
- XX * NOTE: the super (or parent) object has already been
- XX * destroyed in the constructor for this object.
- XX */
- XX if (this)
- XX free(this);
- XX return;
- XX}
- XX
- XXstatic size_t
- XXtotal(this)
- XX alst_t *this;
- XX{
- XX if (!this)
- XX return(0);
- XX return(this->num_el);
- XX}
- XX
- XXstatic bool
- XXattop(this)
- XX alst_t *this;
- XX{
- XX assert(this);
- XX return(this->curr_el == 0);
- XX}
- XX
- XXstatic bool
- XXatbottom(this)
- XX alst_t *this;
- XX{
- XX assert(this);
- XX return(this->curr_el == this->num_el);
- XX}
- XX
- XXstatic bool
- XXnext(this)
- XX alst_t *this;
- XX{
- XX if (!this)
- XX return(FALSE);
- XX assert(this->curr_el >= 0 && this->curr_el <= this->num_el);
- XX if (this->curr_el >= this->num_el) /* >= in case NDEBUG set */
- XX return(FALSE);
- XX this->curr_el++;
- XX return(TRUE);
- XX}
- XX
- XXstatic bool
- XXprev(this)
- XX alst_t *this;
- XX{
- XX if (!this)
- XX return(FALSE);
- XX assert(this->curr_el >= 0 && this->curr_el <= this->num_el);
- XX if (!this->curr_el)
- XX return(FALSE);
- XX this->curr_el--;
- XX return(TRUE);
- XX}
- XX
- XXstatic VOID
- XXtop(this)
- XX alst_t *this;
- XX{
- XX if (!this)
- XX return;
- XX this->curr_el = 0;
- XX return;
- XX}
- XX
- XXstatic VOID
- XXbottom(this)
- XX alst_t *this;
- XX{
- XX if (!this)
- XX return;
- XX this->curr_el = this->num_el - 1;
- XX return;
- XX}
- XX
- XXstatic bool
- XXseek(this, where, from)
- XX alst_t *this;
- XX size_t where; /* destination element or offset */
- XX int from; /* arg. similar to lseek(2s) */
- XX{
- XX if (!this)
- XX return(FALSE);
- XX /*
- XX * NOTE: There is still no major amount of checking in here. The
- XX * seek operation does not change your current element, as the linked
- XX * list implementation does.
- XX */
- XX switch (from) {
- XX case SEEK_SET:
- XX if (where < this->num_el)
- XX this->curr_el = where;
- XX else
- XX return(FALSE);
- XX break;
- XX case SEEK_CUR:
- XX if (where > 0) {
- XX if ((this->curr_el + where) < this->num_el)
- XX this->curr_el += where;
- XX else
- XX return(FALSE);
- XX } else {
- XX if ((this->curr_el - where) > 0)
- XX this->curr_el -= where;
- XX else
- XX return(FALSE);
- XX }
- XX break;
- XX case SEEK_END:
- XX if (where <= this->num_el)
- XX this->curr_el = this->num_el - where;
- XX else
- XX return(FALSE);
- XX break;
- XX }
- XX return(TRUE);
- XX}
- XEND_OF_FILE
- Xif test 3735 -ne `wc -c <'alist.c'`; then
- X echo shar: \"'alist.c'\" unpacked with wrong size!
- Xfi
- X# end of 'alist.c'
- Xfi
- Xif test -f 'llist.c' -a "${1}" != "-c" ; then
- X echo shar: Will not clobber existing file \"'llist.c'\"
- Xelse
- Xecho shar: Extracting \"'llist.c'\" \(8033 characters\)
- Xsed "s/^X//" >'llist.c' <<'END_OF_FILE'
- XX/*
- XX * llist.c - linked list sub-class methods
- XX */
- XX
- XX#define SID "@(#)dlst:llist.c 1.5 92/10/03 23:38:06 (woods)"
- XX#include <sccsid.h>
- XX
- XX#if defined(USE_STDDEF) || REALSTDC || (__STDC__ - 0) == 1
- XX# include <stddef.h> /* should do before sysdefs.h */
- XX#endif
- XX#include <sysdefs.h> /* localisation helpers */
- XX#include <sys/types.h> /* for size_t, if avail. */
- XX#include <stdio.h> /* only for "FILE" used in <libc.h> */
- XX#include <assert.h>
- XX#if defined(USG) || defined(SYSV)
- XX# include <malloc.h>
- XX# include <memory.h>
- XX# include <unistd.h>
- XX#endif
- XX#include <libc.h>
- XX#include "dlst.h"
- XX
- XXstatic void invalid_op();
- XXstatic llel_t *sort_list();
- XXstatic llel_t *merge_list();
- XX
- XX/*
- XX * Sillyness to keep assigments of invalid_op from making noise
- XX */
- XXtypedef VOID (*voidfn)();
- XX
- XX/*
- XX * all must have the same types as in LIST_CLASS in list.h
- XX *
- XX * NOTE: Not all of these are defined below!
- XX */
- XXstatic bool attop(),
- XX atbottom(),
- XX isempty(),
- XX add(),
- XX prev(),
- XX next(),
- XX seek(),
- XX find();
- XXstatic cmp_t cmp();
- XXstatic VOID top(),
- XX bottom(),
- XX replace(),
- XX delete(),
- XX display(),
- XX sort();
- XXstatic UnivPtr current(),
- XX cdr(),
- XX car();
- XXstatic size_t total(),
- XX ltell();
- XX
- XX/*
- XX * safety feature
- XX */
- XXstatic void
- XXinvalid_op()
- XX{
- XX assert(0);
- XX}
- XX
- XX/*
- XX * constructor
- XX */
- XXllst_t *
- XXnew_llist()
- XX{
- XX lst_t *lst;
- XX llst_t *new;
- XX
- XX if ((lst = lst_new()) == NULL)
- XX return(NULL);
- XX
- XX if ((new = (llst_t *) malloc(sizeof(llst_t))) == NULL) {
- XX lst_destroy(lst);
- XX return(NULL);
- XX }
- XX (void) memcpy(new, lst, sizeof(*lst)); /* WARNING: assumptions! */
- XX
- XX lst_destroy(lst); /* throw away original super-object */
- XX
- XX new->attop = attop;
- XX new->atbottom = atbottom;
- XX new->isempty = isempty;
- XX new->top = top;
- XX new->bottom = bottom;
- XX new->next = next;
- XX new->prev = prev;
- XX new->add = add;
- XX new->find = find;
- XX new->current = current;
- XX new->replace = replace;
- XX new->delete = delete;
- XX new->display = (voidfn) invalid_op;
- XX new->ltell = ltell;
- XX new->total = total; /* over-ride super-class definition */
- XX new->sort = (voidfn) sort;
- XX
- XX new->first_el = NULL;
- XX new->last_el = NULL;
- XX new->curr_el = NULL;
- XX new->num_el = 0;
- XX
- XX return(new);
- XX}
- XX
- XX/*
- XX * destructor
- XX */
- XXvoid
- XXdestroy_llist(this)
- XX llst_t *this;
- XX{
- XX if (!this)
- XX return;
- XX llst_bottom(this);
- XX while (this->curr_el)
- XX llst_delete(this);
- XX /*
- XX * NOTE: the super (or parent) object has already been
- XX * destroyed in the constructor for this object.
- XX */
- XX if (this)
- XX free(this);
- XX return;
- XX}
- XX
- XX/*
- XX * methods -- these may not be optimum for all sub-classes
- XX */
- XX
- XXstatic bool
- XXattop(this)
- XX llst_t *this;
- XX{
- XX assert(this);
- XX return(this->curr_el == this->first_el);
- XX}
- XX
- XXstatic bool
- XXatbottom(this)
- XX llst_t *this;
- XX{
- XX assert(this);
- XX return(this->curr_el == this->last_el);
- XX}
- XX
- XXstatic bool
- XXisempty(this)
- XX llst_t *this;
- XX{
- XX assert(this);
- XX return(this->first_el == NULL);
- XX}
- XX
- XXstatic VOID
- XXtop(this)
- XX llst_t *this;
- XX{
- XX if (!this)
- XX return;
- XX this->curr_el = this->first_el;
- XX return;
- XX}
- XX
- XXstatic VOID
- XXbottom(this)
- XX llst_t *this;
- XX{
- XX if (!this)
- XX return;
- XX this->curr_el = this->last_el;
- XX return;
- XX}
- XX
- XXstatic bool
- XXnext(this)
- XX llst_t *this;
- XX{
- XX if (!this)
- XX return(FALSE);
- XX if (!this->curr_el || !this->curr_el->nxt)
- XX return(FALSE);
- XX this->curr_el = this->curr_el->nxt;
- XX return(TRUE);
- XX}
- XX
- XXstatic bool
- XXprev(this)
- XX llst_t *this;
- XX{
- XX if (!this)
- XX return(FALSE);
- XX if (!this->curr_el || !this->curr_el->prv)
- XX return(FALSE);
- XX this->curr_el = this->curr_el->prv;
- XX return(TRUE);
- XX}
- XX
- XXstatic bool
- XXadd(this, datum)
- XX llst_t *this;
- XX UnivPtr datum;
- XX{
- XX llel_t *new;
- XX
- XX if (!this)
- XX return(FALSE);
- XX if ((new = (llel_t *) malloc(sizeof(llel_t))) == NULL)
- XX return(FALSE);
- XX new->d = datum;
- XX this->num_el++;
- XX if (!this->first_el) {
- XX this->first_el = new;
- XX this->last_el = new;
- XX new->prv = NULL;
- XX new->nxt = NULL;
- XX } else if (this->curr_el == this->last_el) {
- XX assert(this->curr_el->nxt == NULL);
- XX this->curr_el->nxt = new;
- XX this->last_el = new;
- XX new->prv = this->curr_el;
- XX new->nxt = NULL;
- XX } else {
- XX new->nxt = this->curr_el->nxt;
- XX this->curr_el->nxt->prv = new;
- XX this->curr_el->nxt = new;
- XX new->prv = this->curr_el;
- XX }
- XX this->curr_el = new;
- XX return(TRUE);
- XX}
- XX
- XXstatic VOID
- XXdelete(this)
- XX llst_t *this;
- XX{
- XX llel_t *old;
- XX
- XX if (!this)
- XX return;
- XX if (!(old = this->curr_el))
- XX return;
- XX if (this->last_el == this->curr_el) {
- XX this->curr_el = this->last_el = old->prv;
- XX this->curr_el->nxt = NULL;
- XX } else if (this->first_el == this->curr_el) {
- XX this->curr_el = this->first_el = old->nxt;
- XX this->curr_el->prv = NULL;
- XX } else {
- XX this->curr_el = old->prv;
- XX old->nxt->prv = this->curr_el;
- XX this->curr_el->nxt = old->nxt;
- XX }
- XX if (old->d)
- XX free(old->d);
- XX free(old);
- XX return;
- XX}
- XX
- XXstatic UnivPtr
- XXcurrent(this)
- XX llst_t *this;
- XX{
- XX if (!this || !this->curr_el)
- XX return(NULL);
- XX return(this->curr_el->d);
- XX}
- XX
- XXstatic VOID
- XXreplace(this, datum)
- XX llst_t *this;
- XX UnivPtr datum;
- XX{
- XX assert(this && this->curr_el);
- XX this->curr_el->d = datum;
- XX return;
- XX}
- XX
- XXstatic size_t
- XXltell(this)
- XX llst_t *this;
- XX{
- XX size_t thisone = 0;
- XX llel_t *elem;
- XX
- XX if (!this)
- XX return(0);
- XX if (!(elem = this->first_el))
- XX return(0);
- XX while (elem != this->curr_el) {
- XX thisone++;
- XX elem = elem->nxt;
- XX }
- XX return(thisone);
- XX}
- XX
- XXstatic size_t
- XXtotal(this)
- XX llst_t *this;
- XX{
- XX#ifdef NO_COUNT
- XX size_t len = 0;
- XX llel_t *elem;
- XX
- XX if (!this)
- XX return(0);
- XX if (!(elem = this->first_el))
- XX return(0);
- XX while (elem) {
- XX len++;
- XX elem = elem->nxt;
- XX }
- XX return(len);
- XX#else
- XX if (!this)
- XX return(0);
- XX return(this->num_el);
- XX#endif
- XX}
- XX
- XXstatic bool
- XXfind(this, el, fn)
- XX llst_t *this;
- XX char *el;
- XX cmp_t (*fn)();
- XX{
- XX if (!this)
- XX return(FALSE);
- XX llst_top(this);
- XX do {
- XX if ((*fn)(el, llst_current(this)) == 0)
- XX return(TRUE);
- XX } while (llst_next(this));
- XX return(FALSE);
- XX}
- XX
- XXstatic VOID
- XXsort(this, fn)
- XX llst_t *this;
- XX cmp_t (*fn)();
- XX{
- XX if (!this)
- XX return;
- XX this->first_el = sort_list(this->first_el, fn);
- XX this->curr_el = this->first_el;
- XX while (this->curr_el && this->curr_el->nxt)
- XX this->curr_el = this->curr_el->nxt;
- XX this->last_el = this->curr_el;
- XX this->curr_el = this->first_el;
- XX return;
- XX}
- XX
- XX/*
- XX * with apologies (though not many!) to R. Sedgewick: Algorithms
- XX * (1983) - p. 149
- XX */
- XXstatic llel_t *
- XXsort_list(lst, fn)
- XX llel_t *lst; /* pointer to first element */
- XX cmp_t (*fn)(); /* comparison function */
- XX{
- XX size_t lst_len = 0; /* number of elements */
- XX llel_t *lst_a;
- XX llel_t *lst_b;
- XX size_t i;
- XX
- XX if (!lst || !lst->nxt) /* recursion termination */
- XX return(lst);
- XX
- XX lst_a = lst;
- XX while (lst_a->nxt) {
- XX lst_len++;
- XX lst_a = lst_a->nxt;
- XX }
- XX
- XX lst_a = lst; /* set head of first half */
- XX for (i = 1; i < (lst_len / 2); i++) /* skip half (note division) */
- XX lst = lst->nxt;
- XX
- XX lst_b = lst->nxt; /* set head of last half */
- XX lst->nxt = NULL; /* terminate lst_a */
- XX lst_b->prv = NULL; /* and the backptr too */
- XX
- XX return(merge_list(sort_list(lst_a, fn), sort_list(lst_b, fn), fn));
- XX}
- XX
- XX
- XX/*
- XX * merge_list - merge two lists
- XX */
- XX/*
- XX * with apologies (though not many!) to R. Sedgewick: Algorithms
- XX * (1983) - p. 148
- XX */
- XXstatic llel_t *
- XXmerge_list(lst_a, lst_b, fn)
- XX llel_t *lst_a; /* pointer to first half */
- XX llel_t *lst_b; /* pointer to second half */
- XX cmp_t (*fn)(); /* data comparison function */
- XX{
- XX llel_t *head; /* head of the merged list */
- XX llel_t *tail; /* walking tail */
- XX
- XX /*
- XX * first, pick the head of the list
- XX */
- XX if (!lst_a && !lst_b)
- XX return(NULL);
- XX else if (!lst_a)
- XX return(lst_b);
- XX else if (!lst_b)
- XX return(lst_a);
- XX
- XX if ((*fn)(lst_a->d, lst_b->d) <= 0) {
- XX head = lst_a;
- XX tail = lst_a;
- XX lst_a = lst_a->nxt;
- XX } else {
- XX head = lst_b;
- XX tail = lst_b;
- XX lst_b = lst_b->nxt;
- XX }
- XX /*
- XX * while there are still elements on both lists, point to
- XX * the list with the next item as determined by strcmp()
- XX */
- XX while (lst_a && lst_b) {
- XX if ((*fn)(lst_a->d, lst_b->d) <= 0) {
- XX tail->nxt = lst_a;
- XX lst_a->prv = tail;
- XX tail = lst_a;
- XX lst_a = lst_a->nxt;
- XX } else {
- XX tail->nxt = lst_b;
- XX lst_b->prv = tail;
- XX tail = lst_b;
- XX lst_b = lst_b->nxt;
- XX }
- XX }
- XX /*
- XX * NOTE: the new list is already terminated. Now, attatch any
- XX * remaining odd lists
- XX */
- XX if (lst_a) {
- XX tail->nxt = lst_a;
- XX lst_a->prv = tail;
- XX } else if (lst_b) {
- XX tail->nxt = lst_b;
- XX lst_b->prv = tail;
- XX }
- XX return(head); /* return the head of the merged lists */
- XX}
- XEND_OF_FILE
- Xif test 8033 -ne `wc -c <'llist.c'`; then
- X echo shar: \"'llist.c'\" unpacked with wrong size!
- Xfi
- X# end of 'llist.c'
- Xfi
- Xecho shar: End of shell archive.
- Xecho "Please read the file README first"
- Xexit 0
- END_OF_FILE
- if test 36973 -ne `wc -c <'dlst.shar'`; then
- echo shar: \"'dlst.shar'\" unpacked with wrong size!
- fi
- # end of 'dlst.shar'
- fi
- echo shar: End of archive 4 \(of 4\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- echo "Please read the file README first"
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-