home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-28 | 27.1 KB | 1,091 lines |
- Newsgroups: comp.sources.unix
- From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
- Subject: v27i118: clc - C Libraries Collection, Part12/20
- References: <1.754527080.23891@gw.home.vix.com>
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
- Posting-Number: Volume 27, Issue 118
- Archive-Name: clc/part12
-
- #! /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 12 (of 20)."
- # Contents: libs/src/dict/Makefile libs/src/dict/rbt.c
- # libs/src/fsma/fsma.c libs/src/xlog/filelog.c
- # Wrapped by panos@eclipse on Sun Nov 28 14:48:16 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/dict/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/dict/Makefile'\"
- else
- echo shar: Extracting \"'libs/src/dict/Makefile'\" \(5819 characters\)
- sed "s/^X//" >'libs/src/dict/Makefile' <<'END_OF_FILE'
- X# (c) Copyright 1993 by Panagiotis Tsirigotis
- X# All rights reserved. The file named COPYRIGHT specifies the terms
- X# and conditions for redistribution.
- X
- X#
- X# $Id: Makefile,v 3.8 93/11/19 20:04:23 panos Exp $
- X#
- X# Based on Library makefile template: *Revision: 1.15 *
- X#
- X
- X#
- X# Available entries:
- X# lib --> creates the library
- X# install --> installs the library (archive, man page(s), header(s))
- X# uninstall --> uninstall the library
- X# clean --> removes all .o and .a files
- X# spotless --> clean + uninstall
- X# lint --> lints a file (usage: make lint MODULE=foo.c)
- X# tags --> creates a tags file (from the SOURCES and HEADERS)
- X# checkout --> checkout all files
- X# dist --> distribution support
- X#
- X
- XNAME = dict
- XVERSION = 1.2.4
- X
- X#
- X# Double-Linked-List implementation
- X#
- XDLL_INCLUDES = dll.h
- XDLL_HEADERS = $(DLL_INCLUDES) dllimpl.h
- XDLL_SOURCES = dll.c
- XDLL_OBJECTS = dll.o
- XDLL_MANFILES = dll.3
- X
- X#
- X# Hash-Table implementation
- X#
- XHT_INCLUDES = ht.h
- XHT_HEADERS = $(HT_INCLUDES) htimpl.h
- XHT_SOURCES = ht.c
- XHT_OBJECTS = ht.o
- XHT_MANFILES = ht.3
- X
- X#
- X# Binary search tree implementation
- X#
- XBST_INCLUDES = bst.h
- XBST_HEADERS = $(BST_INCLUDES) bstimpl.h
- XBST_SOURCES = bst.c rbt.c
- XBST_OBJECTS = bst.o rbt.o
- XBST_MANFILES = bst.3
- X
- XHEADERS = dictimpl.h dict.h \
- X $(DLL_HEADERS) $(HT_HEADERS) $(BST_HEADERS)
- XSOURCES = dict.c \
- X $(DLL_SOURCES) $(HT_SOURCES) $(BST_SOURCES)
- XOBJECTS = dict.o \
- X $(DLL_OBJECTS) $(HT_OBJECTS) $(BST_OBJECTS)
- X
- XMANFILES = dict.3 \
- X $(DLL_MANFILES) $(HT_MANFILES) \
- X $(BST_MANFILES)
- XINCLUDEFILES = dict.h \
- X $(DLL_INCLUDES) $(HT_INCLUDES) \
- X $(BST_INCLUDES)
- X
- XTESTPROGS = dlltest htest bsttest bstcomp
- X
- X# The following variables are used by the 'install' entry and
- X# should be customized:
- X# LIBDIR: where the library will be placed
- X# INCUDEDIR: where the include files will be placed
- X# MANDIR: where the man pages will be placed
- X#
- XLIBDIR = $(HOME)/.links/libraries/$(ARCH)
- XMANDIR = $(HOME)/.links/manpages/man3
- XINCLUDEDIR = $(HOME)/.links/includes
- X
- X#
- X# -DBST_DEBUG : enables 2 debugging functions: bst_getdepth and bst_traverse
- X# bst_getdepth() returns the maximum and minimum depth of the
- X# tree. In the case of a red-black tree, it verifies that
- X# the balancing property holds for every subtree. It prints
- X# a message for each unbalanced subtree it finds.
- X# bst_traverse() does preorder/inorder/postorder traversals
- X# of the tree and applies a user-provided function to each
- X# node.
- X# In order for these functions to be available, the BST_DEBUG
- X# flag must be set, both when compiling the library and when
- X# when compiling programs that use the library, since the
- X# bst.h header file defines data types that are used by
- X# these functions.
- X#
- X# -DDEBUG_RBT : enables code that verifies that left/right rotations do
- X# not involve the anchor of the tree. If the assertion fails,
- X# the program will be terminated.
- X#
- XDEFS = -DBST_DEBUG -DDEBUG_RBT
- XDEBUG = -g # -g or -O
- XVERSION_DEF = -DVERSION=\"DICT\ Version\ $(VERSION)\"
- X
- XCPP_DEFS = -I$(INCLUDEDIR) $(VERSION_DEF) $(DEFS)
- X
- X#
- X# The following variables shouldn't need to be changed
- X#
- XLINT_FLAGS = -hbux
- XCPP_FLAGS = $(CPP_DEFS)
- XCC_FLAGS = $(DEBUG)
- XCFLAGS = $(CPP_FLAGS) $(CC_FLAGS)
- X
- XINSTALL = install -c
- XFMODE = -m 640 # used by install
- XRANLIB = ranlib
- X
- XPAGER = less
- X
- X
- XLIBNAME = lib$(NAME).a
- X
- Xlib: $(LIBNAME)
- X
- Xlibopt: clean
- X make DEBUG=-O "DEFS=$(DEFS)" lib
- X $(INSTALL) $(FMODE) $(LIBNAME) $(LIBDIR)-O
- X
- X$(LIBNAME): $(OBJECTS)
- X ar r $@ $?
- X $(RANLIB) $@
- X
- Xlint:
- X lint $(CPP_FLAGS) $(LINT_FLAGS) $(MODULE) 2>&1 | egrep -v "possible pointer alignment|RCSid" | $(PAGER)
- X
- Xinstall: $(LIBNAME)
- X @if test "$(LIBDIR)" -a "$(INCLUDEDIR)" -a "$(MANDIR)" ;\
- X then \
- X $(INSTALL) $(FMODE) $(LIBNAME) $(LIBDIR) ;\
- X echo "Installed $(LIBNAME) to $(LIBDIR)" ;\
- X for i in $(INCLUDEFILES); do $(INSTALL) $(FMODE) $$i $(INCLUDEDIR) ; done ;\
- X echo Installed $(INCLUDEFILES) to $(INCLUDEDIR) ;\
- X for i in $(MANFILES) ; do $(INSTALL) $(FMODE) $$i $(MANDIR) ; done ;\
- X echo Installed $(MANFILES) to $(MANDIR) ;\
- X else \
- X echo "You forgot to set one of the following variables: LIBDIR,INCLUDEDIR,MANDIR" ;\
- X fi
- X
- Xuninstall:
- X a=`pwd` ; cd $(INCLUDEDIR) ;\
- X if test $$a != `pwd` ; then rm -f $(INCLUDEFILES) ; fi
- X a=`pwd` ; cd $(LIBDIR) ;\
- X if test $$a != `pwd` ; then rm -f $(LIBNAME) ; fi
- X a=`pwd` ; cd $(MANDIR) ;\
- X if test $$a != `pwd` ; then rm -f $(MANFILES) ; fi
- X
- Xclean:
- X rm -f $(OBJECTS) $(LIBNAME) core $(TESTPROGS)
- X
- Xspotless: clean uninstall
- X
- Xtags: $(SOURCES) $(HEADERS)
- X ctags -w $(SOURCES) $(HEADERS)
- X
- Xcheckout:
- X co $(SOURCES) $(HEADERS) $(MANFILES)
- X
- X#
- X# Distribution section
- X# This section contains the 2 targets for distribution support: dist, dirs
- X# "dist" checks out all files to be distributed
- X# "dirs" prints a list of directories to be included in the distribution.
- X# These directories should have a Makefile with a "dist" target
- X#
- XDISTRIBUTION_FILES = $(SOURCES) $(HEADERS) $(MANFILES) COPYRIGHT README \
- X dlltest.c htest.c bsttest.c bstcomp.c \
- X dlltest.out htest.out bsttest.out
- X
- XDIRS =
- X
- Xdist:
- X -co -q $(DISTRIBUTION_FILES)
- X
- Xdirs:
- X @echo $(DIRS)
- X
- X#
- X# PUT HERE THE RULES TO MAKE THE OBJECT FILES
- X#
- Xdll.o: dll.h dllimpl.h dict.h dictimpl.h
- Xht.o: ht.h htimpl.h dict.h dictimpl.h
- Xbst.o: bst.h bstimpl.h dict.h dictimpl.h
- Xrbt.o: bstimpl.h dict.h dictimpl.h
- Xdict.o: dictimpl.h dict.h
- X
- Xdlltest: dlltest.c $(LIBNAME)
- X cc $(CFLAGS) dlltest.c -o $@ $(LIBNAME) -L$(LIBDIR) -lfsma
- X
- Xhtest: htest.c $(LIBNAME)
- X cc $(CFLAGS) -o $@ htest.c $(LIBNAME) -L$(LIBDIR) -lfsma
- X
- Xbsttest: bsttest.c $(LIBNAME)
- X cc $(CFLAGS) -o $@ bsttest.c $(LIBNAME) -L$(LIBDIR) -lfsma
- X
- Xbstcomp: bstcomp.c $(LIBNAME)
- X cc $(CFLAGS) -o $@ bstcomp.c $(LIBNAME) -L$(LIBDIR) -lfsma
- X
- END_OF_FILE
- if test 5819 -ne `wc -c <'libs/src/dict/Makefile'`; then
- echo shar: \"'libs/src/dict/Makefile'\" unpacked with wrong size!
- fi
- # end of 'libs/src/dict/Makefile'
- fi
- if test -f 'libs/src/dict/rbt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/dict/rbt.c'\"
- else
- echo shar: Extracting \"'libs/src/dict/rbt.c'\" \(5816 characters\)
- sed "s/^X//" >'libs/src/dict/rbt.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1993 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: rbt.c,v 3.2 93/09/28 21:05:20 panos Exp $" ;
- X
- X#include "bstimpl.h"
- X
- X/*
- X * Transformation:
- X *
- X * x y
- X * / \ / \
- X * y c ===> a x
- X * / \ / \
- X * a b b c
- X */
- XPRIVATE void right_rotate( hp, x )
- X header_s *hp ;
- X tnode_s *x ;
- X{
- X tnode_s *y = LEFT( x ) ;
- X tnode_s *px = PARENT( x ) ;
- X tnode_s *b = RIGHT( y ) ;
- X
- X#ifdef DEBUG_RBT
- X if ( x == ANCHOR( hp ) )
- X __dict_terminate( "RBT right_rotate", "x is the tree anchor" ) ;
- X#endif
- X
- X /*
- X * First fix 'y' and the tree above it. We need to:
- X * a. Make x the right child of y
- X * b. Determine if x was a left or right child and update the
- X * corresponding field in x's parent.
- X */
- X RIGHT( y ) = x ;
- X PARENT( y ) = px ;
- X if ( x == LEFT( px ) )
- X LEFT( px ) = y ;
- X else
- X RIGHT( px ) = y ;
- X
- X /*
- X * Now fix the tree below 'y'. We need to:
- X * a. Fix the parent of 'x'
- X * b. Change the left child of 'x' to 'b'
- X * c. Change the parent of 'b' to 'x'
- X */
- X PARENT( x ) = y ;
- X LEFT( x ) = b ;
- X PARENT( b ) = x ;
- X}
- X
- X
- X
- X/*
- X * Transformation:
- X *
- X * x y
- X * / \ / \
- X * a y ===> x c
- X * / \ / \
- X * b c a b
- X */
- XPRIVATE void left_rotate( hp, x )
- X header_s *hp ;
- X tnode_s *x ;
- X{
- X tnode_s *y = RIGHT( x ) ;
- X tnode_s *px = PARENT( x ) ;
- X tnode_s *b = LEFT( y ) ;
- X
- X
- X#ifdef DEBUG_RBT
- X if ( x == ANCHOR( hp ) )
- X __dict_terminate( "RBT left_rotate", "x is the tree anchor" ) ;
- X#endif
- X
- X /*
- X * First fix 'y' and the tree above it. We need to:
- X * a. Make x the left child of y
- X * b. Determine if x was a left or right child and update the
- X * corresponding field in x's parent.
- X */
- X LEFT( y ) = x ;
- X PARENT( y ) = px ;
- X if ( x == LEFT( px ) )
- X LEFT( px ) = y ;
- X else
- X RIGHT( px ) = y ;
- X
- X /*
- X * Now fix the tree below 'y'. We need to:
- X * a. Fix the parent of 'x'
- X * b. Change the right child of 'x' to 'b'
- X * c. Change the parent of 'b' to 'x'
- X */
- X PARENT( x ) = y ;
- X RIGHT( x ) = b ;
- X PARENT( b ) = x ;
- X}
- X
- X
- X/*
- X * This function is called after node 'new' is inserted in the tree.
- X * The function makes sure that the red-black properties of the tree
- X * are not violated by the insertion
- X */
- Xvoid __dict_rbt_insfix( hp, new )
- X header_s *hp ;
- X tnode_s *new ;
- X{
- X register tnode_s *x, *y ;
- X register tnode_s *px ;
- X tnode_s *ppx ;
- X
- X x = new ;
- X COLOR( x ) = RED ;
- X
- X /*
- X * Note that the color of the anchor is BLACK so the loop will
- X * always stop there with x equal to the root of the tree.
- X */
- X while ( COLOR( px = PARENT( x ) ) == RED )
- X {
- X ppx = PARENT( px ) ;
- X if ( px == LEFT( ppx ) )
- X {
- X y = RIGHT( ppx ) ; /* y is px's sibling and x's uncle */
- X if ( COLOR( y ) == RED ) /* both px and y are red */
- X {
- X COLOR( px ) = BLACK ;
- X COLOR( y ) = BLACK ;
- X COLOR( ppx ) = RED ; /* grandparent of x gets red */
- X x = ppx ; /* advance x to its grandparent */
- X }
- X else
- X {
- X if ( x == RIGHT( px ) )
- X left_rotate( hp, x = px ) ; /* notice the assignment */
- X /*
- X * px cannot be used anymore because of the possible left rotation
- X * ppx however is still valid
- X */
- X COLOR( PARENT( x ) ) = BLACK ;
- X COLOR( ppx ) = RED ;
- X right_rotate( hp, ppx ) ;
- X }
- X }
- X else /* px == RIGHT( ppx ) */
- X {
- X /*
- X * XXX: The else clause is symmetrical with the 'then' clause
- X * (RIGHT is replaced by LEFT and vice versa). We should
- X * be able to use the same code.
- X */
- X y = LEFT( ppx ) ;
- X if ( COLOR( y ) == RED )
- X {
- X COLOR( px ) = BLACK ;
- X COLOR( y ) = BLACK ;
- X COLOR( ppx ) = RED ;
- X x = ppx ;
- X }
- X else
- X {
- X if ( x == LEFT( px ) )
- X right_rotate( hp, x = px ) ;
- X COLOR( PARENT( x ) ) = BLACK ;
- X COLOR( ppx ) = RED ;
- X left_rotate( hp, ppx ) ;
- X }
- X }
- X }
- X COLOR( ROOT( hp ) ) = BLACK ;
- X}
- X
- X
- Xvoid __dict_rbt_delfix( hp, x )
- X header_s *hp ;
- X tnode_s *x ;
- X{
- X tnode_s *px ; /* parent of x */
- X tnode_s *sx ; /* sibling of x */
- X
- X /*
- X * On exit from the loop x will be either the ROOT or a RED node
- X */
- X while ( x != ROOT( hp ) && COLOR( x ) == BLACK )
- X {
- X px = PARENT( x ) ;
- X if ( x == LEFT( px ) )
- X {
- X sx = RIGHT( px ) ;
- X if ( COLOR( sx ) == RED )
- X {
- X COLOR( sx ) = BLACK ;
- X COLOR( px ) = RED ;
- X left_rotate( hp, px ) ;
- X sx = RIGHT( px ) ;
- X }
- X
- X /*
- X * Now sx is BLACK
- X */
- X if ( COLOR( LEFT( sx ) ) == BLACK && COLOR( RIGHT( sx ) ) == BLACK )
- X {
- X COLOR( sx ) = RED ;
- X x = px ; /* move up the tree */
- X }
- X else
- X {
- X if ( COLOR( RIGHT( sx ) ) == BLACK )
- X {
- X COLOR( LEFT( sx ) ) = BLACK ; /* was RED */
- X COLOR( sx ) = RED ;
- X right_rotate( hp, sx ) ;
- X sx = RIGHT( px ) ;
- X }
- X
- X /*
- X * Now RIGHT( sx ) is RED and sx is BLACK
- X */
- X COLOR( sx ) = COLOR( px ) ;
- X COLOR( px ) = BLACK ;
- X COLOR( RIGHT( sx ) ) = BLACK ;
- X left_rotate( hp, px ) ;
- X x = ROOT( hp ) ; /* exit the loop */
- X }
- X }
- X else
- X {
- X sx = LEFT( px ) ;
- X if ( COLOR( sx ) == RED )
- X {
- X COLOR( sx ) = BLACK ;
- X COLOR( px ) = RED ;
- X right_rotate( hp, px ) ;
- X sx = LEFT( px ) ;
- X }
- X
- X if ( COLOR( LEFT( sx ) ) == BLACK && COLOR( RIGHT( sx ) ) == BLACK )
- X {
- X COLOR( sx ) = RED ;
- X x = px ;
- X }
- X else
- X {
- X if ( COLOR( LEFT( sx ) ) == BLACK )
- X {
- X COLOR( RIGHT( sx ) ) = BLACK ;
- X COLOR( sx ) = RED ;
- X left_rotate( hp, sx ) ;
- X sx = LEFT( px ) ;
- X }
- X
- X COLOR( sx ) = COLOR( px ) ;
- X COLOR( px ) = BLACK ;
- X COLOR( LEFT( sx ) ) = BLACK ;
- X right_rotate( hp, px ) ;
- X x = ROOT( hp ) ;
- X }
- X }
- X }
- X COLOR( x ) = BLACK ;
- X}
- X
- END_OF_FILE
- if test 5816 -ne `wc -c <'libs/src/dict/rbt.c'`; then
- echo shar: \"'libs/src/dict/rbt.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/dict/rbt.c'
- fi
- if test -f 'libs/src/fsma/fsma.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/fsma/fsma.c'\"
- else
- echo shar: Extracting \"'libs/src/fsma/fsma.c'\" \(6107 characters\)
- sed "s/^X//" >'libs/src/fsma/fsma.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: fsma.c,v 5.2 1993/09/16 22:13:12 panos Exp $" ;
- Xstatic char *version = VERSION ;
- X
- X#include "fsma.h"
- X#include "impl.h"
- X
- X#ifdef DEBUG
- X#include <stdio.h>
- X#endif
- X
- X/*
- X * We assume that memory handed by malloc is suitably aligned for any
- X * machine data type (for example, if the CPU wants double's aligned
- X * at an 8-byte boundary, the memory provided by malloc will be so aligned).
- X */
- Xchar *malloc() ;
- Xint free() ;
- X
- X
- XPRIVATE void init_free_list __ARGS( ( unsigned, unsigned, char * ) ) ;
- XPRIVATE void terminate __ARGS( ( char * ) ) ;
- X
- X
- X/*
- X * An allocator manages a linked list of chunks:
- X *
- X * ______________ ______________ ______________
- X * | HEADER |------>| |------>| |
- X * |____________| |____________| |____________|
- X * | | | | | |
- X * | | | | | |
- X * | | | | | |
- X * | | | | | |
- X * | SLOTS | | | | |
- X * | | | | | |
- X * | | | | | |
- X * | | | | | |
- X * | | | | | |
- X * |____________| |____________| |____________|
- X *
- X *
- X * The SLOTS sections are organized as a linked list of slots whose
- X * size is determined by the object size specified in fsm_create
- X */
- X
- Xfsma_h fsm_create( object_size, slots_per_chunk, flags )
- X unsigned object_size ;
- X unsigned slots_per_chunk ;
- X int flags ;
- X{
- X register fsma_h fp ;
- X union __fsma_chunk_header *chp ;
- X char *slots ;
- X unsigned nslots ;
- X unsigned chunk_size ;
- X unsigned slot_size ;
- X int header_inlined ;
- X
- X nslots = ( slots_per_chunk == 0 ) ? SLOTS_PER_CHUNK : slots_per_chunk ;
- X slot_size = ( object_size < MINSIZE ) ? MINSIZE : object_size ;
- X
- X /*
- X * Make sure that the slot_size is a multiple of the pointer size
- X */
- X if ( slot_size % sizeof( __fsma_pointer ) != 0 )
- X slot_size += sizeof( __fsma_pointer ) -
- X slot_size % sizeof( __fsma_pointer ) ;
- X
- X chunk_size = sizeof( union __fsma_chunk_header ) + nslots * slot_size ;
- X
- X chp = CHUNK_HEADER( malloc( chunk_size ) ) ;
- X if ( chp == NULL )
- X if ( flags & FSM_RETURN_ERROR )
- X return( NULL ) ;
- X else
- X terminate( "FSMA fsm_create: malloc failed\n" ) ;
- X
- X slots = (char *) &chp[ 1 ] ;
- X init_free_list( nslots, slot_size, slots ) ;
- X
- X#ifdef DEBUG
- X {
- X int i ;
- X
- X fprintf( stderr, "Size = %d, nslots = %d\n", slot_size, nslots ) ;
- X for ( i = 0 ; i < nslots+1 ; i++ )
- X fprintf( stderr, "slot[ %d ] = %p\n",
- X i, (*(char **) (slots + i * slot_size ))) ;
- X }
- X#endif
- X
- X /*
- X * Check if we can fit the header in an object slot
- X */
- X if ( slot_size >= sizeof( struct __fsma_header ) )
- X {
- X /*
- X * We can do it.
- X * Allocate the first slot
- X */
- X fp = (fsma_h) slots ;
- X slots = *(POINTER *) slots ;
- X header_inlined = TRUE ;
- X }
- X else
- X {
- X fp = (fsma_h) malloc( sizeof( struct __fsma_header ) ) ;
- X if ( fp == NULL )
- X if ( flags & FSM_RETURN_ERROR )
- X {
- X free( (char *) chp ) ;
- X return( NULL ) ;
- X }
- X else
- X terminate( "FSMA fsm_create: malloc of header failed\n" ) ;
- X header_inlined = FALSE ;
- X }
- X
- X chp->next_chunk = NULL ;
- X
- X fp->next_free = (POINTER) slots ;
- X fp->chunk_chain = chp ;
- X fp->slots_in_chunk = nslots ;
- X fp->slot_size = slot_size ;
- X fp->chunk_size = chunk_size ;
- X fp->flags = flags ;
- X fp->is_inlined = header_inlined ;
- X
- X#ifdef DEBUG
- X fprintf( stderr, "Slots/chunk = %d\n", nslots ) ;
- X fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
- X#endif
- X
- X return( (fsma_h) fp ) ;
- X}
- X
- X
- X
- Xvoid fsm_destroy( fp )
- X register fsma_h fp ;
- X{
- X int header_inlined = fp->is_inlined ;
- X register union __fsma_chunk_header *chp, *next_chunk ;
- X register int zero_memory = fp->flags & FSM_ZERO_DESTROY ;
- X register chunk_size = fp->chunk_size ;
- X
- X /*
- X * Free all chunks in the chunk chain
- X */
- X for ( chp = fp->chunk_chain ; chp != NULL ; chp = next_chunk )
- X {
- X next_chunk = chp->next_chunk ;
- X if ( zero_memory )
- X (void) memset( (char *)chp, 0, chunk_size ) ;
- X
- X#ifdef DEBUG
- X fprintf( stderr, "Freeing chunk %p\n", chp ) ;
- X#endif
- X free( (char *)chp ) ;
- X }
- X
- X /*
- X * If fp->inlined is NO, we have to free the handle.
- X * Note that we copied fp->inlined in case it is YES.
- X */
- X if ( ! header_inlined )
- X free( (char *)fp ) ;
- X}
- X
- X
- Xchar *_fsm_alloc( fp )
- X register fsma_h fp ;
- X{
- X register POINTER object ;
- X
- X /*
- X * Check if there are any slots on the free list
- X */
- X if ( fp->next_free == NULL )
- X {
- X /*
- X * Free list exhausted; allocate a new chunk
- X */
- X char *slots ;
- X union __fsma_chunk_header *chp ;
- X
- X chp = CHUNK_HEADER( malloc( fp->chunk_size ) ) ;
- X if ( chp == NULL )
- X if ( fp->flags & FSM_RETURN_ERROR )
- X return( NULL ) ;
- X else
- X terminate( "FSMA fsm_alloc: malloc failed\n" ) ;
- X
- X#ifdef DEBUG
- X fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
- X#endif
- X /*
- X * Put the slots in this chunk in a linked list
- X * and add this list to the free list
- X */
- X slots = (char *) &chp[ 1 ] ;
- X init_free_list( fp->slots_in_chunk, fp->slot_size, slots ) ;
- X fp->next_free = (POINTER) slots ;
- X
- X /*
- X * Put this chunk at the head of the chunk chain
- X */
- X chp->next_chunk = fp->chunk_chain ;
- X fp->chunk_chain = chp ;
- X }
- X
- X object = fp->next_free ;
- X fp->next_free = *(POINTER *)object ;
- X
- X if ( fp->flags & FSM_ZERO_ALLOC )
- X (void) memset( object, 0, fp->slot_size ) ;
- X
- X return( object ) ;
- X}
- X
- X
- Xvoid _fsm_free( fp, object )
- X fsma_h fp ;
- X char *object ;
- X{
- X if ( fp->flags & FSM_ZERO_FREE )
- X (void) memset( object, 0, fp->slot_size ) ;
- X
- X *(POINTER *)object = fp->next_free ;
- X fp->next_free = object ;
- X}
- X
- X
- XPRIVATE void terminate( s )
- X char *s ;
- X{
- X write( 2, s, strlen( s ) ) ;
- X abort() ;
- X exit( 1 ) ;
- X}
- X
- X
- XPRIVATE void init_free_list( nslots, size, slots )
- X unsigned nslots ;
- X register unsigned size ;
- X char *slots ;
- X{
- X register int i ;
- X register char *next ;
- X register POINTER current ;
- X
- X for ( i = 0, current = slots, next = slots + size ; i < nslots - 1 ;
- X i++, current = next, next += size )
- X *(POINTER *)current = next ;
- X *(POINTER *)current = NULL ;
- X}
- X
- END_OF_FILE
- if test 6107 -ne `wc -c <'libs/src/fsma/fsma.c'`; then
- echo shar: \"'libs/src/fsma/fsma.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/fsma/fsma.c'
- fi
- if test -f 'libs/src/xlog/filelog.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/xlog/filelog.c'\"
- else
- echo shar: Extracting \"'libs/src/xlog/filelog.c'\" \(5820 characters\)
- sed "s/^X//" >'libs/src/xlog/filelog.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: filelog.c,v 2.3 1993/10/28 01:35:39 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <varargs.h>
- X#include <fcntl.h>
- X#include <time.h>
- X#ifndef NO_SYSLOG
- X#include <syslog.h>
- X#else
- X#define LOG_ALERT 0
- X#endif
- X
- X#include "sio.h"
- X
- X#include "xlog.h"
- X#include "impl.h"
- X#include "filelog.h"
- X
- XPRIVATE int filelog_init() ;
- XPRIVATE void filelog_fini() ;
- XPRIVATE int filelog_control() ;
- XPRIVATE int filelog_write() ;
- XPRIVATE int filelog_parms() ;
- XPRIVATE int limit_checks() ;
- X
- Xstruct xlog_ops __xlog_filelog_ops =
- X {
- X filelog_init,
- X filelog_fini,
- X filelog_write,
- X filelog_control,
- X filelog_parms
- X } ;
- X
- X
- XPRIVATE int filelog_init( xp, ap )
- X xlog_s *xp ;
- X va_list ap ;
- X{
- X int fd ;
- X struct filelog *flp ;
- X char *filename = va_arg( ap, char * ) ;
- X int flags = va_arg( ap, int ) ;
- X
- X flp = NEW( struct filelog ) ;
- X if ( flp == NULL )
- X return( XLOG_ENOMEM ) ;
- X
- X if ( flags & O_CREAT )
- X fd = open( filename, flags, va_arg( ap, int ) ) ;
- X else
- X fd = open( filename, flags ) ;
- X
- X if ( fd == -1 )
- X {
- X FREE( flp ) ;
- X return( XLOG_EOPEN ) ;
- X }
- X
- X FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
- X (void) Sbuftype( fd, SIO_LINEBUF ) ;
- X flp->fl_fd = fd ;
- X flp->fl_state = FL_OPEN ;
- X xp->xl_data = flp ;
- X return( XLOG_ENOERROR ) ;
- X}
- X
- X
- XPRIVATE void filelog_fini( xp )
- X xlog_s *xp ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X
- X if ( flp->fl_state != FL_CLOSED )
- X {
- X (void) close( flp->fl_fd ) ;
- X flp->fl_state = FL_CLOSED ;
- X }
- X FREE( flp ) ;
- X xp->xl_data = NULL ;
- X}
- X
- X
- X
- XPRIVATE int filelog_control( xp, cmd, ap )
- X xlog_s *xp ;
- X xlog_cmd_e cmd ;
- X va_list ap ;
- X{
- X struct stat st ;
- X struct filelog *flp = FILELOG( xp ) ;
- X int status = XLOG_ENOERROR ;
- X
- X if ( flp->fl_state == FL_ERROR )
- X return( flp->fl_error ) ;
- X
- X switch ( cmd )
- X {
- X case XLOG_GETFD:
- X if ( flp->fl_state == FL_OPEN )
- X *va_arg( ap, int * ) = flp->fl_fd ;
- X else
- X status = XLOG_ENOERROR ;
- X break ;
- X
- X case XLOG_LIMITS:
- X flp->fl_soft_limit = va_arg( ap, unsigned ) ;
- X flp->fl_hard_limit = va_arg( ap, unsigned ) ;
- X flp->fl_issued_warning = FALSE ;
- X FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
- X flp->fl_state = FL_OPEN ;
- X /* FALL THROUGH */
- X
- X case XLOG_SIZECHECK:
- X if ( ! FILELOG_SIZE_CONTROL( flp ) )
- X break ;
- X if ( fstat( flp->fl_fd, &st ) == -1 )
- X {
- X FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
- X flp->fl_state = FL_ERROR ;
- X flp->fl_error = status = XLOG_EFSTAT ;
- X }
- X else
- X {
- X flp->fl_size = st.st_size ;
- X if ( flp->fl_size > flp->fl_soft_limit )
- X status = limit_checks( xp ) ;
- X }
- X break ;
- X }
- X return( status ) ;
- X}
- X
- X
- XPRIVATE int limit_checks( xp )
- X xlog_s *xp ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X char buf[ 100 ] ;
- X
- X if ( ! flp->fl_issued_warning )
- X {
- X if ( xp->xl_use != NULL )
- X xlog_write( (xlog_h) xp->xl_use, buf,
- X strx_nprint( buf, sizeof( buf ),
- X "soft limit exceeded on '%s'", xp->xl_id ),
- X XLOG_NOFLAGS, LOG_ALERT ) ;
- X flp->fl_issued_warning = TRUE ;
- X }
- X
- X if ( flp->fl_size <= flp->fl_hard_limit )
- X return( XLOG_ENOERROR ) ;
- X
- X if ( xp->xl_use != NULL )
- X xlog_write( (xlog_h) xp->xl_use, buf,
- X strx_nprint( buf, sizeof( buf ),
- X "hard limit exceeded on '%s'; log closed", xp->xl_id ),
- X XLOG_NOFLAGS, LOG_ALERT ) ;
- X flp->fl_state = FL_ERROR ;
- X return( XLOG_ESIZE ) ;
- X}
- X
- X
- XPRIVATE int filelog_write( xp, buf, len, flags, ap )
- X xlog_s *xp ;
- X char buf[] ;
- X int len ;
- X int flags ;
- X va_list ap ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X int action_flags = ( xp->xl_flags | flags ) ;
- X int msglen = 0 ;
- X char *percent_m_pos ;
- X int cc ;
- X int status ;
- X time_t current_time ;
- X struct tm *tmp ;
- X time_t time() ;
- X
- X if ( flp->fl_state != FL_OPEN )
- X return( flp->fl_error ) ;
- X
- X (void) time( ¤t_time ) ;
- X tmp = localtime( ¤t_time ) ;
- X cc = Sprint( flp->fl_fd, "%d/%d/%d@%02d:%02d:%02d",
- X tmp->tm_year, tmp->tm_mon+1, tmp->tm_mday,
- X tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
- X msglen += cc ;
- X
- X if ( action_flags & XLOG_PRINT_ID )
- X {
- X cc = Sprint( flp->fl_fd, " %s", xp->xl_id ) ;
- X msglen += cc ;
- X }
- X
- X if ( action_flags & XLOG_PRINT_PID )
- X {
- X cc = Sprint( flp->fl_fd, "[%d]", getpid() ) ;
- X msglen += cc ;
- X }
- X
- X cc = Sprint( flp->fl_fd, ": " ) ;
- X msglen += cc ;
- X
- X if ( ( action_flags & XLOG_NO_ERRNO ) ||
- X ( percent_m_pos = __xlog_add_errno( buf, len ) ) == NULL )
- X {
- X cc = Swrite( flp->fl_fd, buf, len ) ;
- X msglen += cc ;
- X }
- X else
- X {
- X char errno_buf[ 100 ] ;
- X unsigned size = sizeof( errno_buf ) ;
- X int cc_before_errno = percent_m_pos - buf ;
- X char *ep ;
- X
- X /*
- X * XXX: The reason for the repetition of "msglen += cc ;" is that in
- X * the future we may want to check cc for SIO_ERR
- X */
- X ep = __xlog_explain_errno( errno_buf, &size ) ;
- X cc = Swrite( flp->fl_fd, buf, cc_before_errno ) ;
- X msglen += cc ;
- X cc = Swrite( flp->fl_fd, ep, (int)size ) ;
- X msglen += cc ;
- X cc = Swrite( flp->fl_fd, percent_m_pos+2, len-cc_before_errno-2 ) ;
- X msglen += cc ;
- X }
- X /*
- X * Writing a newline will cause a buffer flush since we asked for
- X * line-buffered output
- X */
- X Sputchar( flp->fl_fd, '\n' ) ;
- X msglen++ ;
- X
- X /*
- X * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->xl_flags
- X * because size control is off by default and in order to
- X * be enabled XLOG_LIMITS must be used which overrides xp->xl_flags
- X */
- X if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
- X return( XLOG_ENOERROR ) ;
- X
- X flp->fl_size += msglen ;
- X if ( flp->fl_size <= flp->fl_soft_limit ||
- X ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
- X return( XLOG_ENOERROR ) ;
- X
- X flp->fl_state = FL_SIZE ;
- X return( status ) ;
- X}
- X
- X
- XPRIVATE int filelog_parms( ap )
- X va_list ap ;
- X{
- X return( XLOG_ENOERROR ) ;
- X}
- X
- END_OF_FILE
- if test 5820 -ne `wc -c <'libs/src/xlog/filelog.c'`; then
- echo shar: \"'libs/src/xlog/filelog.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/xlog/filelog.c'
- fi
- echo shar: End of archive 12 \(of 20\).
- cp /dev/null ark12isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 20 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-