home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-28 | 31.5 KB | 1,258 lines |
- Newsgroups: comp.sources.unix
- From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
- Subject: v27i117: clc - C Libraries Collection, Part11/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 117
- Archive-Name: clc/part11
-
- #! /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 11 (of 20)."
- # Contents: libs/src/pq/hpq.c libs/src/pset/pset.3
- # libs/src/sio/Sprint.3 libs/src/sio/impl.h libs/src/timer/timer.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/pq/hpq.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/pq/hpq.c'\"
- else
- echo shar: Extracting \"'libs/src/pq/hpq.c'\" \(5510 characters\)
- sed "s/^X//" >'libs/src/pq/hpq.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: hpq.c,v 1.3 1993/04/01 02:15:46 panos Exp $" ;
- Xstatic char version[] = VERSION ;
- X
- X#include "pq.h"
- X#include "hpqimpl.h"
- X
- X#define PRIVATE static
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- X#define PARENT( i ) ( i >> 1 )
- X#define LEFT( i ) ( i << 1 )
- X#define RIGHT( i ) ( LEFT( i ) + 1 )
- X
- Xint pq_errno ;
- X
- X#define INITIAL_ARRAY_SIZE 100 /* entries */
- X
- X
- Xpq_h __hpq_create( func, flags, errnop )
- X int (*func)() ;
- X int flags ;
- X int *errnop ;
- X{
- X register header_s *hp ;
- X int *errp = ( errnop == NULL ) ? &pq_errno : errnop ;
- X char *malloc() ;
- X
- X /*
- X * Check if the user has provided the necessary comparison functions
- X */
- X if ( func == NULL )
- X HANDLE_ERROR( flags, NULL, errp, PQ_ENOFUNC,
- X "HPQ __hpq_create: missing object-object comparator\n" ) ;
- X
- X hp = HHP( malloc( sizeof( header_s ) ) ) ;
- X if ( hp == NULL )
- X HANDLE_ERROR( flags, NULL, errp, PQ_ENOMEM,
- X "HPQ __hpq_create: malloc failed\n" ) ;
- X
- X /*
- X * Allocate object array
- X */
- X hp->objects = (pq_obj *) malloc( INITIAL_ARRAY_SIZE * sizeof( pq_obj ) ) ;
- X if ( hp->objects == NULL )
- X {
- X free( (char *)hp ) ;
- X HANDLE_ERROR( flags, NULL, errp, PQ_ENOMEM,
- X "HPQ __hpq_create: malloc failed\n" ) ;
- X }
- X
- X /*
- X * Initialize the header
- X */
- X hp->is_better = func ;
- X hp->errnop = errp ;
- X hp->flags = flags ;
- X hp->max_size = INITIAL_ARRAY_SIZE ;
- X hp->cur_size = 0 ;
- X return( (pq_h) hp ) ;
- X}
- X
- X
- Xvoid __hpq_destroy( handle )
- X pq_h handle ;
- X{
- X header_s *hp = HHP( handle ) ;
- X
- X free( (char *) hp->objects ) ;
- X free( (char *)hp ) ;
- X}
- X
- X
- Xint __hpq_insert( handle, object )
- X pq_h handle ;
- X pq_obj object ;
- X{
- X register header_s *hp = HHP( handle ) ;
- X register unsigned i, parent ;
- X
- X if ( object == NULL )
- X HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENULLOBJECT,
- X "HPQ __hpq_insert: NULL object\n" ) ;
- X
- X /*
- X * Make sure there is room to store the object
- X */
- X if ( hp->cur_size >= hp->max_size && grow( hp ) == PQ_ERR )
- X return( PQ_ERR ) ;
- X
- X i = hp->cur_size++ ;
- X parent = PARENT( i ) ;
- X while ( i > 0 && (*hp->is_better)( object, hp->objects[ parent ] ) )
- X {
- X hp->objects[ i ] = hp->objects[ parent ] ;
- X i = parent ;
- X parent = PARENT( i ) ;
- X }
- X hp->objects[ i ] = object ;
- X return( PQ_OK ) ;
- X}
- X
- X
- X#define CUTOFF (INITIAL_ARRAY_SIZE * 128)
- X#define INCREMENT CUTOFF
- X
- X/*
- X * Grow the table.
- X * Algorithm:
- X * while the table_size is less than CUTOFF, double the size.
- X * if it grows greater than CUTOFF, increase the size by INCREMENT
- X * (these number are in entries, not bytes)
- X */
- XPRIVATE int grow( hp )
- X header_s *hp ;
- X{
- X unsigned new_size ;
- X char *new_objects ;
- X char *realloc() ;
- X
- X if ( hp->max_size < CUTOFF )
- X new_size = hp->max_size * 2 ;
- X else
- X new_size = hp->max_size + INCREMENT ;
- X
- X new_objects = realloc( (char *)hp->objects, new_size * sizeof( pq_obj ) ) ;
- X if ( new_objects == NULL )
- X HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENOMEM,
- X "HPQ grow: out of memory\n" ) ;
- X
- X hp->max_size = new_size ;
- X hp->objects = (pq_obj *) new_objects ;
- X return( PQ_OK ) ;
- X}
- X
- X
- Xpq_obj __hpq_extract_head( handle )
- X pq_h handle ;
- X{
- X register header_s *hp = HHP( handle ) ;
- X pq_obj object ;
- X void restore_heap() ;
- X
- X if ( hp->cur_size == 0 )
- X return( NULL ) ;
- X
- X object = hp->objects[ 0 ] ;
- X hp->objects[ 0 ] = hp->objects[ --hp->cur_size ] ;
- X restore_heap( hp, 0 ) ;
- X return( object ) ;
- X}
- X
- X
- X#define EXISTS( hp, i ) ( i < hp->cur_size )
- X#define IS_BETTER( hp, i, j ) \
- X ( (*hp->is_better)( hp->objects[ i ], hp->objects[ j ] ) )
- X#define SWAP( hp, i, j ) \
- X { \
- X pq_obj t = hp->objects[ i ] ; \
- X hp->objects[ i ] = hp->objects[ j ] ; \
- X hp->objects[ j ] = t ; \
- X }
- X
- XPRIVATE void restore_heap( hp, start )
- X register header_s *hp ;
- X unsigned start ;
- X{
- X register unsigned current = start ;
- X register unsigned better = current ;
- X
- X for ( ;; )
- X {
- X register unsigned left = LEFT( current ) ;
- X register unsigned right = RIGHT( current ) ;
- X
- X /*
- X * Meaning of variables:
- X *
- X * current: the current tree node
- X * left: its left child
- X * right: its right child
- X * better: the best of current,left,right
- X *
- X * We start the loop with better == current
- X *
- X * The code takes advantage of the fact that the existence of
- X * the right child implies the existence of the left child.
- X * It works by finding the better of the two children (and puts
- X * that in better) and comparing that against current.
- X */
- X if ( EXISTS( hp, right ) )
- X better = IS_BETTER( hp, left, right ) ? left : right ;
- X else if ( EXISTS( hp, left ) )
- X better = left ;
- X
- X if ( better == current || IS_BETTER( hp, current, better ) )
- X break ;
- X else
- X {
- X SWAP( hp, current, better ) ;
- X current = better ;
- X }
- X }
- X}
- X
- X
- Xint __hpq_delete( handle, object )
- X pq_h handle ;
- X register pq_obj object ;
- X{
- X register header_s *hp = HHP( handle ) ;
- X register unsigned i ;
- X
- X if ( object == NULL )
- X HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENULLOBJECT,
- X "HPQ __hpq_delete: NULL object\n" ) ;
- X
- X /*
- X * First find it
- X */
- X for ( i = 0 ;; i++ )
- X {
- X if ( i < hp->cur_size )
- X if ( object == hp->objects[ i ] )
- X break ;
- X else
- X continue ;
- X else
- X HANDLE_ERROR( hp->flags, PQ_ERR, hp->errnop, PQ_ENOTFOUND,
- X "HPQ __hpq_delete: object not found\n" ) ;
- X }
- X
- X hp->objects[ i ] = hp->objects[ --hp->cur_size ] ;
- X restore_heap( hp, i ) ;
- X return( PQ_OK ) ;
- X}
- X
- END_OF_FILE
- if test 5510 -ne `wc -c <'libs/src/pq/hpq.c'`; then
- echo shar: \"'libs/src/pq/hpq.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/pq/hpq.c'
- fi
- if test -f 'libs/src/pset/pset.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/pset/pset.3'\"
- else
- echo shar: Extracting \"'libs/src/pset/pset.3'\" \(5592 characters\)
- sed "s/^X//" >'libs/src/pset/pset.3' <<'END_OF_FILE'
- 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.\" $Id: pset.3,v 3.5 93/11/23 19:46:44 panos Exp $
- X.TH PSET 3X "23 April 1993"
- X.SH NAME
- Xpset_create, pset_destroy, pset_add, pset_insert, pset_remove, pset_delete, pset_remove_index, pset_clear, pset_count, pset_pointer, pset_compact, pset_sort, pset_apply - routines that handle pointer sets
- X.SH SYNOPSIS
- X.LP
- X.nf
- X.ft B
- X#include "pset.h"
- X.LP
- X.ft B
- Xpset_h pset_create( alloc_start, alloc_step )
- Xunsigned alloc_start, alloc_step ;
- X.LP
- X.ft B
- Xvoid pset_destroy( pset )
- Xpset_h pset ;
- X.LP
- X.ft B
- XANY_TYPE *pset_add( pset, ptr )
- Xpset_h pset ;
- XANY_TYPE *ptr ;
- X.LP
- X.ft B
- Xvoid *pset_insert( pset, ptr )
- Xpset_h pset ;
- Xvoid *ptr ;
- X.LP
- X.ft B
- Xvoid pset_remove( pset, ptr )
- Xpset_h pset ;
- XANY_TYPE *ptr ;
- X.LP
- X.ft B
- Xvoid pset_delete( pset, ptr )
- Xpset_h pset ;
- Xvoid *ptr ;
- X.LP
- X.ft B
- Xvoid pset_remove_index( pset, index )
- Xpset_h pset ;
- Xunsigned index ;
- X.LP
- X.ft B
- Xvoid pset_clear( pset )
- Xpset_h pset ;
- X.LP
- X.ft B
- Xunsigned pset_count( pset )
- Xpset_h pset ;
- X.LP
- X.ft B
- Xvoid *pset_pointer( pset, index )
- Xpset_h pset ;
- Xunsigned index ;
- X.LP
- X.ft B
- Xvoid pset_compact( pset )
- Xpset_h pset ;
- X.LP
- X.ft B
- Xvoid pset_sort( pset, compfunc )
- Xpset_h pset ;
- Xint (*compfunc)() ;
- X.LP
- X.ft B
- Xvoid pset_apply( pset, func, arg )
- Xpset_h pset ;
- Xvoid (*func)() ;
- Xvoid *arg ;
- X.SH DESCRIPTION
- XThis library provides functions that handle sets of pointers. Pointers
- Xcan be inserted and deleted from sets and the sets can be enumerated.
- XPointers are inserted in sets in no particular order. However it is
- Xguaranteed
- Xthat a sequence of insertions will result in a set which if enumerated
- Xwill provide the pointers in the same order in which they were inserted
- X(assuming no intervening deletions).
- X.LP
- X.B pset_create()
- Xcreates a pointer set.
- XIt will allocate space for
- X.I alloc_start
- Xpointers before returning.
- X.I alloc_step
- Xdetermines the amount by which the set size is increased in case of
- Xoverflow. If any of these parameters is 0, a default value is used.
- X.LP
- X.B pset_destroy()
- Xdestroys the specified pointer set.
- X.LP
- X.B pset_add()
- Xis a macro that adds a pointer to the specified set.
- XThe pointer can be of any type.
- X.LP
- X.B pset_insert()
- Xinserts a pointer to the specified set.
- XThis is the same operation as
- X.B pset_add().
- X.LP
- X.B pset_remove()
- Xremoves a pointer from the specified set.
- X.LP
- X.B pset_delete()
- Xdeletes a pointer from the specified set.
- XThis is the same operation as
- X.B pset_remove().
- X.LP
- X.B pset_remove_index()
- Xremoves the pointer that is at position
- X.I index
- Xin the set.
- X.I index
- Xshould be in the range [0, \fBpset_count(pset)\fP) (but there is no
- Xcheck to enforce this).
- XAfter this operation, the
- X.I index
- Xposition will be occupied by another pointer (unless it was the last one).
- XNote that this call is a macro, and it may evaluate the
- X.I index
- Xargument more than once.
- X.LP
- X.B pset_clear()
- Xremoves all pointers from the specified set.
- X.LP
- X.B pset_count()
- Xreturns the number of pointers in the specified set.
- X.LP
- X.B pset_pointer()
- Xreturns the pointer at position
- X.I index
- Xin the specified set.
- X.I index
- Xmust be between 0 and
- X.B "pset_count(pset)."
- X.B pset_pointer()
- Xis a macro and it can also be used in the left-hand side of assignments.
- X.LP
- X.B pset_compact()
- Xremoves all NULL pointers from
- X.I pset.
- X.LP
- X.B pset_sort()
- Xsorts the pointers in
- X.I pset
- Xusing the specified function.
- X.I compfunc
- Xis invoked with 2 arguments that are pointers pointing to pointers stored in
- X.I pset.
- XFor example, if the pset holds pointers to objects of type T, then
- Xthe function F whose address is in
- X.I compfunc
- Xshould be defined as:
- XF( T **p1, T **p2 ).
- X.br
- X.I compfunc
- Xshould return a negative, zero or positive value
- Xif its first argument is less than, equal to, or greater than its
- Xsecond argument.
- X.LP
- X.B pset_apply()
- Xapplies
- X.I func
- Xto all pointers in
- X.I pset.
- XIf
- X.I arg
- Xis not
- X.SM NULL
- Xthe function is invoked as:
- X.RS
- X(*func)( arg, p )
- X.RE
- Xwhere
- X.I p
- Xis a pset pointer. If
- X.I arg
- Xis
- X.SM NULL
- Xthe function is invoked as:
- X.RS
- X(*func)( p )
- X.RE
- X.SH EXAMPLE
- XThe following code fragment reads lines from standard input
- Xand places them in a pset. Then it sorts the pset, prints the
- Xsorted contents to standard output and then it eliminates duplicate
- Xlines (which it also prints to standard output).
- X.RS
- X.sp 1
- X.ft B
- X.nf
- Xpset_h ph ;
- Xchar buf[ 80 ] ;
- Xunsigned u ;
- Xint compstr() ;
- Xvoid printstr() ;
- X.sp 1
- Xph = pset_create( 0, 0 ) ;
- Xwhile ( gets( buf ) )
- X.RS
- Xpset_add( strcpy( malloc( strlen( buf ) + 1 ), buf ) ) ;
- X.RE
- Xpset_sort( ph, compstr ) ;
- Xfor ( u = 0 ; u < pset_count( ph ) ; u++ )
- X.RS
- Xprintf( "%s\\n", (char *) pset_pointer( ph, u ) ) ;
- X.RE
- X.RE
- X.fi
- X.ft R
- X.LP
- XThe function
- X.I compstr()
- Xfollows:
- X.sp 1
- X.RS
- X.ft B
- X.nf
- Xint compstr( p1, p2 )
- X.RS
- Xchar **p1, **p2 ;
- X.RE
- X{
- X.RS
- Xreturn( strcmp( *p1, *p2 ) ) ;
- X.RE
- X}
- X.RE
- X.SH "RETURN VALUES"
- X.LP
- X.I pset_h
- Xis a pointer type. Functions that return
- X.I pset_h
- Xwill return
- X.SM NULL
- Xto indicate an error.
- X.LP
- X.B pset_create()
- Xreturns a pointer set handle or
- X.SM NULL
- Xif it fails.
- X.LP
- X.B pset_add()
- Xreturns its second argument if successful or
- X.SM NULL
- Xif it fails.
- X.LP
- X.B pset_insert()
- Xreturns its second argument if successful or
- X.SM NULL
- Xif it fails.
- X.LP
- X.B pset_count()
- Xalways returns the number of pointers in the set.
- X.LP
- X.B pset_pointer()
- Xalways returns a pointer. There is no check if the specified index is within
- Xrange.
- X.SH BUGS
- X.LP
- X.B pset_add(),
- X.B pset_remove(),
- X.B pset_remove_index(),
- X.B pset_count(),
- X.B pset_clear(),
- X.B pset_pointer()
- Xand
- X.B pset_sort()
- Xare macros, therefore the \fI&\fR operator cannot be applied to them.
- END_OF_FILE
- if test 5592 -ne `wc -c <'libs/src/pset/pset.3'`; then
- echo shar: \"'libs/src/pset/pset.3'\" unpacked with wrong size!
- fi
- # end of 'libs/src/pset/pset.3'
- fi
- if test -f 'libs/src/sio/Sprint.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/Sprint.3'\"
- else
- echo shar: Extracting \"'libs/src/sio/Sprint.3'\" \(5277 characters\)
- sed "s/^X//" >'libs/src/sio/Sprint.3' <<'END_OF_FILE'
- 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.\" $Id: Sprint.3,v 8.1 1993/03/13 01:15:34 panos Exp $
- X.TH Sprint 3X "29 May 1992"
- X.SH NAME
- XSprint -- formatted stream output
- X.SH SYNOPSIS
- X.LP
- X.nf
- X.ft B
- Xint Sprint( fd, format [ , ... ] )
- Xint fd ;
- Xchar *format ;
- X.SH DESCRIPTION
- X\fBSprint()\fR provides formatted output conversion. The formatting is
- Xcontrolled by the \fIformat\fR argument. All characters in
- X\fIformat\fR that do not specify a conversion are printed. A conversion
- Xis specified by a '%' followed by a string that ends with a
- Xconversion type character. The string may contain flags, a field width,
- Xa precision, and a modifier.
- X.LP
- XPossible flags (more that one can be specified and they can be in any order)
- Xinclude:
- X.TP 10
- X.B \'-'
- Xspecifies left adjustment of the converted argument. The default
- Xis right adjustment. This flag is meaningful only if a field width
- Xis specified.
- X.TP
- X.B \'+'
- Xspecifies that a number will always have a sign as a prefix (this
- Xforces a '+' sign to appear if the number is positive).
- X.TP
- X.B \' '
- Xprefixes a \fIspace\fR to the number if the number has not a sign
- X(therefore the '+' flag overrides this flag).
- X.TP
- X.B \'#'
- XThe meaning of '#' depends on the conversion type character: for \fBo\fR
- Xconversions the first digit will be 0; for \fBx\fR or \fBX\fR conversions
- X\fB0x\fR or \fB0X\fR respectively will be prefixed to the number (if it
- Xis not zero); for \fBe\fR, \fBE\fR, \fBf\fR, \fBg\fR, and \fBG\fR conversions
- Xthe number will always have a decimal point.
- X.TP
- X.B \'0'
- Xspecifies padding with zeros instead of spaces.
- X.LP
- XThe field width is specified by a number. This number indicates the
- X\fIminimum\fR width for the field. A '*' may be used instead of the number.
- XIn that case the width is the value of the next argument which should
- Xbe an \fBint\fR.
- XA negative width value specifies left adjustment with a width equal
- Xto the absolute width value.
- X.LP
- XA precision is specified by a '.' followed by a number. The meaning of
- Xthe precision depends on the type conversion character. For a string
- Xconversion, precision determines how many characters are printed from
- Xthe string. For integer conversions, precision determines the
- Xnumber of digits used to print the number (zero padding is done if
- Xthe precision exceeds the length of the number). For floating point
- Xconversions, precision determines the number of digits after the
- Xdecimal point (\fBe\fR, \fBE\fR, \fBf\fR) or the number of
- Xsignificant digits (\fBg\fR, \fBG\fR).
- XA '*' may be used instead of a number to specify the precision. In that
- Xcase the precision is the value of the next argument which should
- Xbe an \fBint\fR.
- XThe behavior of \fBSprint()\fR is undefined if the precision is negative.
- X.LP
- XThe length modifier is \fBl\fR and indicates that the argument is
- Xa \fBlong\fR integer.
- X.LP
- XThe type conversion characters are:
- X\fBd, i, o, x, X, u, c, s, f, e, E, g, G, p, n, %\fR.
- XFor floating point conversions the argument should be of type \fIdouble\fR.
- X.TP 10
- X.B d,i
- Xspecify signed decimal conversion.
- X.TP
- X.B u
- Xspecifies unsigned decimal conversion.
- X.TP
- X.B o
- Xspecifies octal conversion.
- X.TP
- X.B x,X
- Xspecify hexadecimal conversion. For
- X.B x
- Xthe hex digits used are 0123456789abcdef. For
- X.B X
- Xthe hex digits used are 0123456789ABCDEF.
- XThere is no leading
- X.B 0x
- Xor
- X.B 0X
- X(use the '#' flag for that).
- X.TP
- X.B c
- Xspecifies character conversion; the argument should be of type
- X\fIchar\fR.
- X.TP
- X.B s
- Xspecifies string conversion; the argument should be of type
- X\fIchar *\fR.
- X.TP
- X.B f
- Xspecifies conversion to the form [-]ddd.dddd. The number
- Xof digits after the decimal point depends on precision; the default is 6.
- XIf the precision is 0, the decimal point is not printed (this can
- Xbe overriden with the '#' flag).
- X.B e,E
- Xspecify conversion to the form [-]ddd.dddd[eE][+-]ddd.
- XThe number of digits after the decimal point depends on precision;
- Xthe default is 6. If the precision is 0, the decimal point is not printed
- X(this can be overriden with the '#' flag).
- XThe exponent is at least 2 digit wide.
- X.TP
- X.B g,G
- Xspecify a conversion using the
- X.B e,E
- Xformat respectively if the
- Xexponent is less than -4 or greater than or equal to the precision;
- Xotherwise the
- X.B f
- Xformat is used.
- X.TP
- X.B p
- Xis used to print pointers (type \fIvoid *\fR,
- Xor \fIchar *\fR if the compiler does not support the former).
- X.TP
- X.B n
- Xexpects a \fIint *\fR argument and puts in that integer
- Xthe number of characters already printed by this call.
- X.TP
- X.B %
- Xis used to print a \fI%\fR.
- X.LP
- XIf an unknown conversion character is specified, the percent sign
- Xfollowed by that character will be printed.
- X.SH RETURN VALUE
- X.LP
- XIf no error occured, \fBSprint()\fR returns the number of characters
- Xprinted. In case of error, it returns \fBSIO_ERR\fR.
- X.SH BUGS
- X.LP
- XThis is a list of differences between \fBSprint()\fR and the ANSI C Standard
- X\fBprintf()\fR:
- X.LP
- X\fBSprint()\fR does not support non-removal of trailing zeroes for
- X\fBg\fR and \fBG\fR conversions when the '#' flag is used.
- X.LP
- X\fBSprint()\fR does not support the h and L modifiers.
- X.LP
- XThe current implementation assumes that \fIsizeof(int)==sizeof(long)\fR.
- X.LP
- X\fBSprint()\fR supports "%p" only if \fIsizeof(pointer)<=sizeof(int)\fR.
- END_OF_FILE
- if test 5277 -ne `wc -c <'libs/src/sio/Sprint.3'`; then
- echo shar: \"'libs/src/sio/Sprint.3'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/Sprint.3'
- fi
- if test -f 'libs/src/sio/impl.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/impl.h'\"
- else
- echo shar: Extracting \"'libs/src/sio/impl.h'\" \(5528 characters\)
- sed "s/^X//" >'libs/src/sio/impl.h' <<'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
- X/*
- X * $Id: impl.h,v 8.1 1993/03/13 01:15:06 panos Exp $
- X */
- X
- X#ifndef SIO_BUFFER_SIZE
- X
- X#include "sioconf.h"
- X
- X#ifdef HAS_MMAP
- X#include <sys/types.h>
- X
- X
- X/*
- X * A struct map_unit describes a memory mapped area of a file.
- X *
- X * addr is the address where the file is mapped. If addr is NULL
- X * the other fields are meaningless.
- X * valid_bytes indicates how many bytes are _valid_ in that unit
- X * mapped_bytes of a unit is how many bytes are mapped in that
- X * unit ( valid <= mapped ).
- X * Normally mapped_bytes will be equal to valid_bytes until
- X * we reach the end of the file. Then if the file size is not a multiple
- X * of the unit size, only the rest of the file will be mapped at the
- X * unit, leaving part of what was mapped at the unit before still
- X * visible (this happens because I chose not to unmap a unit before
- X * remapping it). In that case valid_bytes shows the size of the "new"
- X * mapping and mapped_bytes shows how many bytes are really mapped.
- X * mapped_bytes is used in Sdone() to unmap the units.
- X */
- Xstruct map_unit
- X{
- X caddr_t addr ;
- X size_t valid_bytes ;
- X size_t mapped_bytes ;
- X} ;
- X
- X
- X/*
- X * Meaning of fields used when memory mapping:
- X *
- X * file_offset: it is the offset in the file where the next
- X * mapping should be done
- X *
- X * file_size: size of the file (obtained from stat(2))
- X */
- Xstruct mmap_descriptor
- X{
- X off_t file_offset ;
- X off_t file_size ;
- X struct map_unit first_unit ;
- X struct map_unit second_unit ;
- X} ;
- X
- Xtypedef struct mmap_descriptor mapd_s ;
- X
- X#endif /* HAS_MMAP */
- X
- Xtypedef enum { FAILURE, SUCCESS } status_e ;
- X
- X/*
- X * Descriptor management: convert a descriptor pointer to an input or
- X * output descriptor pointer
- X */
- X#define IDP( dp ) (&(dp)->descriptor.input_descriptor)
- X#define ODP( dp ) (&(dp)->descriptor.output_descriptor)
- X
- X#define DESCRIPTOR_INITIALIZED( dp ) ((dp)->initialized)
- X
- X/*
- X * Internal constants
- X */
- X#define SIO_BUFFER_SIZE 8192
- X#define SIO_NO_TIED_FD (-1)
- X
- Xtypedef enum { NO = 0, YES = 1 } boolean_e ;
- X
- X#ifndef FALSE
- X#define FALSE 0
- X#define TRUE 1
- X#endif
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- X#ifdef MIN
- X#undef MIN
- X#endif
- X#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
- X
- X#define NUL '\0'
- X
- X#define PRIVATE static
- X
- X#ifdef DEBUG
- X
- Xstatic char *itoa( num )
- X unsigned num ;
- X{
- X#define NUMBUF_SIZE 15
- X static char numbuf[ NUMBUF_SIZE ] ;
- X register char *p = &numbuf[ NUMBUF_SIZE ] ;
- X
- X *--p = '\0' ;
- X do
- X {
- X *--p = num % 10 + '0' ;
- X num /= 10 ;
- X }
- X while ( num ) ;
- X return( p ) ;
- X}
- X
- X# define ASSERT( expr ) \
- X if ( ! (expr) ) \
- X { \
- X char *s1 = "SIO assertion << expr >> failed: File: " ; \
- X char *s2 = __FILE__ ; \
- X char *s3 = ", line: " ; \
- X char *s4 = itoa( __LINE__ ) ; \
- X char *s5 = "\n" ; \
- X (void) write( 2, s1, strlen( s1 ) ) ; \
- X (void) write( 2, s2, strlen( s2 ) ) ; \
- X (void) write( 2, s3, strlen( s3 ) ) ; \
- X (void) write( 2, s4, strlen( s4 ) ) ; \
- X (void) write( 2, s5, strlen( s5 ) ) ; \
- X exit ( 1 ) ; \
- X }
- X#else
- X# define ASSERT( expr )
- X#endif
- X
- X
- X#include <errno.h>
- Xextern int errno ;
- X
- X/*
- X * IO_SETUP initializes a descriptor if it is not already initialized.
- X * It checks if the stream is of the right type (input or output).
- X * CONTROL_SETUP checks if the descriptor is initialized and if the
- X * stream is of the right type (input or output).
- X *
- X * fd: file descriptor
- X * dp: descriptor pointer
- X * op: operation
- X * ev: error value (if __sio_init fails; __sio_init should set errno)
- X *
- X * IO_SETUP will call __sio_init if the descriptor is not initialized.
- X * Possible errors:
- X * 1. Using CONTROL_SETUP on an uninitialized descriptor.
- X * 2. The operation is not appropriate for the descriptor (e.g.
- X * a read operation on an descriptor used for writing).
- X * Both errors set errno to EBADF.
- X */
- X#define CONTROL_SETUP( dp, type, ev ) \
- X { \
- X if ( ! DESCRIPTOR_INITIALIZED( dp ) || dp->stream_type != type ) \
- X { \
- X errno = EBADF ; \
- X return( ev ) ; \
- X } \
- X }
- X
- X
- X#define IO_SETUP( fd, dp, type, ev ) \
- X { \
- X if ( DESCRIPTOR_INITIALIZED( dp ) ) \
- X { \
- X if ( dp->stream_type != type ) \
- X { \
- X errno = EBADF ; \
- X return( ev ) ; \
- X } \
- X } \
- X else if ( __sio_init( dp, fd, type ) == SIO_ERR ) \
- X return( ev ) ; \
- X }
- X
- X
- X/*
- X * Internal functions that are visible
- X */
- Xint __sio_readf(), __sio_writef(), __sio_pwritef() ;
- Xint __sio_extend_buffer(), __sio_init(), __sio_converter(), __sio_more() ;
- Xstatus_e __sio_switch() ;
- X
- X
- X#ifdef HAS_MEMOPS
- X#include <memory.h>
- X#define sio_memcopy( from, to, nbytes ) (void) memcpy( to, from, nbytes )
- X#define sio_memscan( from, nbytes, ch ) memchr( from, ch, nbytes )
- X#endif
- X
- X#ifdef HAS_BCOPY
- X#define sio_memcopy( from, to, nbytes ) (void) bcopy( from, to, nbytes )
- X#endif
- X
- X#ifndef sio_memcopy
- X#define sio_memcopy __sio_memcopy
- X#define NEED_MEMCOPY
- Xvoid __sio_memcopy() ;
- X#endif
- X
- X#ifndef sio_memscan
- Xchar *sio_memscan() ;
- X#endif
- X
- X#endif /* SIO_BUFFER_SIZE */
- X
- END_OF_FILE
- if test 5528 -ne `wc -c <'libs/src/sio/impl.h'`; then
- echo shar: \"'libs/src/sio/impl.h'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/impl.h'
- fi
- if test -f 'libs/src/timer/timer.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/timer/timer.c'\"
- else
- echo shar: Extracting \"'libs/src/timer/timer.c'\" \(5559 characters\)
- sed "s/^X//" >'libs/src/timer/timer.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: timer.c,v 5.1 93/11/26 12:16:33 panos Exp $" ;
- Xstatic char *version = VERSION ;
- X
- X#include "timemacros.h"
- X#include "impl.h"
- X#include "defs.h"
- X
- X#define TIMER_H_NULL ((timer_h)NULL)
- X
- X
- Xint timer_errno ;
- X
- X
- X
- X/*
- X * Create a timer of the specified type.
- X * Returns a timer handle
- X */
- Xtimer_h timer_create( type, flags, errnop )
- X enum timer_types type ;
- X int flags ;
- X int *errnop ;
- X{
- X int *errp = ( errnop != NULL ) ? errnop : &timer_errno ;
- X timer_s *tp ;
- X
- X if ( type != TIMER_REAL && type != TIMER_VIRTUAL && type != TIMER_PROF )
- X HANDLE_ERROR( flags, TIMER_H_NULL, errp, TIMER_EBADTYPE,
- X "TIMER timer_create: bad timer type\n" ) ;
- X
- X tp = TIMER_ALLOC() ;
- X if ( tp == NULL )
- X {
- X *errp = TIMER_ENOMEM ;
- X return( TIMER_H_NULL ) ;
- X }
- X
- X tp->t_state = INACTIVE ;
- X tp->t_act = IDLE ;
- X tp->t_blocked = FALSE ;
- X
- X tp->t_errnop = errp ;
- X tp->t_flags = flags & TIMER_CREATE_FLAGS ;
- X tp->t_action.ta_func = NULL ;
- X tp->t_action.ta_arg = NULL ;
- X tp->t_action.ta_flags = TIMER_NOFLAGS ;
- X if ( __ostimer_newtimer( tp, type ) == TIMER_ERR )
- X {
- X TIMER_FREE( tp ) ;
- X return( TIMER_H_NULL ) ;
- X }
- X return( (timer_h) tp ) ;
- X}
- X
- X
- Xvoid timer_destroy( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING )
- X {
- X __ostimer_remove( tp->t_ostimer, tp ) ;
- X tp->t_state = DESTROYED ;
- X }
- X
- X if ( tp->t_act == IDLE || tp->t_act == PENDING )
- X TIMER_FREE( tp ) ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xint timer_start( handle, itvp, time_type, ap )
- X timer_h handle ;
- X struct itimerval *itvp ;
- X enum timer_timetypes time_type ;
- X struct timer_action *ap ;
- X{
- X int result ;
- X int ok_to_start ;
- X timer_s *tp = TP( handle ) ;
- X struct os_timer *otp = tp->t_ostimer ;
- X
- X __ostimer_blockall() ;
- X
- X /*
- X * We allow invoking timer_start from within the user-specified action
- X * after the timer has expired. However, we do not allow this for
- X * timers that have a t_interval (these timers stay at the TICKING state).
- X */
- X ok_to_start = tp->t_state == INACTIVE &&
- X ( tp->t_act == IDLE || tp->t_act == INVOKED ) ;
- X
- X if ( ! ok_to_start )
- X {
- X __ostimer_unblockall() ;
- X HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADSTATE,
- X "TIMER timer_start: timer state does not allow this operation\n" ) ;
- X }
- X
- X if ( itvp->it_value.tv_sec < 0 || itvp->it_value.tv_usec < 0 )
- X {
- X __ostimer_unblockall() ;
- X HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADTIME,
- X "TIMER timer_start: neg time value)\n" ) ;
- X }
- X
- X tp->t_action = *ap ;
- X tp->t_action.ta_flags &= TIMER_START_FLAGS ;
- X
- X result = __ostimer_add( otp, tp, itvp, time_type ) ;
- X __ostimer_unblockall() ;
- X return( result ) ;
- X}
- X
- X
- Xvoid timer_stop( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING )
- X {
- X __ostimer_remove( tp->t_ostimer, tp ) ;
- X tp->t_state = INACTIVE ;
- X }
- X
- X if ( tp->t_act == SCHEDULED )
- X tp->t_act = INVOKED ; /* to avoid the invocation */
- X else if ( tp->t_act == PENDING )
- X tp->t_act = IDLE ;
- X
- X tp->t_blocked = FALSE ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xvoid timer_block( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING ||
- X tp->t_state == INACTIVE &&
- X ( tp->t_act == PENDING || tp->t_act == SCHEDULED ) )
- X tp->t_blocked = TRUE ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xvoid timer_unblock( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_blocked )
- X {
- X tp->t_blocked = FALSE ;
- X if ( tp->t_act == PENDING )
- X {
- X tp->t_act = SCHEDULED ;
- X (void) __timer_invoke( tp ) ;
- X }
- X }
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xunsigned timer_expirations( handle )
- X timer_h handle ;
- X{
- X return( TP( handle )->t_count ) ;
- X}
- X
- X
- X
- X/*
- X * Invoke the action of the specified timer
- X * All timer interrupts should be blocked when this function is invoked
- X * Returns TRUE if
- X */
- Xenum timer_state __timer_invoke( tp )
- X register timer_s *tp ;
- X{
- X enum timer_state state ;
- X
- X /*
- X * The reason for the infinite loop is that the timer may reexpire
- X * while its function is being invoked.
- X */
- X for ( ;; )
- X {
- X /*
- X * This is the INVOKE part
- X */
- X if ( tp->t_blocked )
- X tp->t_act = PENDING ;
- X else
- X {
- X if ( tp->t_state != DESTROYED && tp->t_act == SCHEDULED )
- X {
- X void (*func)() = tp->t_action.ta_func ;
- X void *arg = tp->t_action.ta_arg ;
- X int flags = tp->t_action.ta_flags ;
- X
- X tp->t_act = INVOKED ;
- X tp->t_expirations = tp->t_count ;
- X tp->t_count = 0 ;
- X if ( func != NULL )
- X {
- X int unblock_all_intrs = ! ( flags & TIMER_BLOCK_ALL ) ;
- X int unblock_all_but_same_intr = ! ( flags & TIMER_BLOCK_SAME ) ;
- X
- X if ( unblock_all_intrs )
- X __ostimer_unblockall() ;
- X else if ( unblock_all_but_same_intr )
- X __ostimer_unblockall_except( tp->t_ostimer ) ;
- X
- X (*func)( tp, arg ) ;
- X
- X if ( unblock_all_intrs || unblock_all_but_same_intr )
- X __ostimer_blockall() ;
- X }
- X else if ( arg != NULL )
- X {
- X int *ip = (int *) arg ;
- X
- X if ( flags & TIMER_INC_VAR )
- X *ip += tp->t_expirations ;
- X else
- X *ip = 1 ;
- X }
- X }
- X }
- X
- X state = tp->t_state ;
- X
- X /*
- X * This is the RETURN part
- X */
- X if ( tp->t_state == DESTROYED )
- X TIMER_FREE( tp ) ;
- X else
- X {
- X if ( tp->t_act == INVOKED )
- X tp->t_act = IDLE ;
- X else if ( tp->t_act == SCHEDULED )
- X continue ;
- X }
- X break ;
- X }
- X return( state ) ;
- X}
- X
- END_OF_FILE
- if test 5559 -ne `wc -c <'libs/src/timer/timer.c'`; then
- echo shar: \"'libs/src/timer/timer.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/timer/timer.c'
- fi
- echo shar: End of archive 11 \(of 20\).
- cp /dev/null ark11isdone
- 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
-