OSSP CVS Repository

ossp - Check-in [2951]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2951
Date: 2002-Dec-16 13:24:51 (local)
2002-Dec-16 12:24:51 (UTC)
User:mlelstv
Branch:
Comment: initial snapshot for OSSP al
Tickets:
Inspections:
Files:
ossp-pkg/al/AUTHORS      added-> 1.1
ossp-pkg/al/INSTALL      added-> 1.1
ossp-pkg/al/Makefile.in      added-> 1.1
ossp-pkg/al/NEWS      added-> 1.1
ossp-pkg/al/README      added-> 1.1
ossp-pkg/al/THANKS      added-> 1.1
ossp-pkg/al/TODO      added-> 1.1
ossp-pkg/al/VERSION      added-> 1.1
ossp-pkg/al/aclocal.m4      added-> 1.1
ossp-pkg/al/al-config.in      added-> 1.1
ossp-pkg/al/al.banner      added-> 1.1
ossp-pkg/al/al.c      added-> 1.1
ossp-pkg/al/al.h      added-> 1.1
ossp-pkg/al/al.pod      added-> 1.1
ossp-pkg/al/al_test.c      added-> 1.1
ossp-pkg/al/configure.ac      added-> 1.1
ossp-pkg/al/devtool      added-> 1.1
ossp-pkg/al/devtool.conf      added-> 1.1
ossp-pkg/al/devtool.func      added-> 1.1
ossp-pkg/al/ts.c      added-> 1.1
ossp-pkg/al/ts.h      added-> 1.1

ossp-pkg/al/AUTHORS -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,15 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+ 
+   AUTHORS
+ 
+   This is a list of authors who have written
+   or edited major parts of the OSSP al sources.
+ 
+   Michael van Elst      <mlelstv@dev.de.cw.net>
+ 


ossp-pkg/al/INSTALL -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,18 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+ 
+   INSTALLATION
+ 
+   To install OSSP al into /path/to/al/ perform
+   the following steps in your shell:
+ 
+     $ ./configure --prefix=/path/to/al
+     $ make
+     $ make check
+     $ make install [DESTDIR=/path/to/temp/root]
+ 


ossp-pkg/al/Makefile.in -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,130 ----
+ ##
+ ##  OSSP al - Assembly Line
+ ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ ##  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ ##
+ ##  This file is part of OSSP al, an abstract datatype of a data buffer
+ ##  that can assemble, move and truncate data but avoids actual copying.
+ ##
+ ##  Permission to use, copy, modify, and distribute this software for
+ ##  any purpose with or without fee is hereby granted, provided that
+ ##  the above copyright notice and this permission notice appear in all
+ ##  copies.
+ ##
+ ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ ##  SUCH DAMAGE.
+ ##
+ ##  Makefile.in: make(1) build procedure
+ ##
+ 
+ @SET_MAKE@
+ 
+ DESTDIR     =
+ prefix      = @prefix@
+ exec_prefix = @exec_prefix@
+ bindir      = @bindir@
+ libdir      = @libdir@
+ includedir  = @includedir@
+ mandir      = @mandir@
+ 
+ CC          = @CC@
+ CPPFLAGS    = @CPPFLAGS@
+ CFLAGS      = @DEFS@ @CFLAGS@
+ LDFLAGS     = @LDFLAGS@
+ LIBS        = @LIBS@
+ RM          = rm -f
+ RMDIR       = rmdir
+ SHTOOL      = ./shtool
+ LIBTOOL     = ./libtool
+ TRUE        = true
+ POD2MAN     = pod2man
+ 
+ LIB_NAME    = libal.la
+ LIB_OBJS    = al.lo
+ 
+ TST_NAME    = al_test
+ TST_OBJS    = al_test.o ts.o
+ 
+ .SUFFIXES:
+ .SUFFIXES: .c .o .lo
+ 
+ all: $(LIB_NAME) $(TST_NAME)
+ 
+ .c.o:
+        $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+ 
+ .c.lo:
+        @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+ 
+ $(LIB_NAME): $(LIB_OBJS)
+        @$(LIBTOOL) --mode=link $(CC) -o $(LIB_NAME) $(LIB_OBJS) -rpath $(libdir) \
+            -version-info `$(SHTOOL) version -l txt -d libtool VERSION`
+ 
+ $(TST_NAME): $(TST_OBJS) $(LIB_NAME)
+        @$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $(TST_NAME) $(TST_OBJS) $(LIB_NAME) $(LIBS)
+ 
+ man: al.3
+ al.3: al.pod
+        V1=`$(SHTOOL) version -l txt -d short VERSION`; \
+        V2=`$(SHTOOL) version -l txt -d long VERSION`; \
+        D=`$(SHTOOL) version -l txt -d long VERSION | sed -e 's;.*(;;' -e 's;).*;;'`; \
+        $(POD2MAN) --quotes=none \
+                   --section=3 --center="Assembly Line" \
+                   --release="$$D" --date="OSSP al $$V1" al.pod | \
+        sed -e "s;AL_VERSION_STR;$$V2;" >al.3
+ 
+ check: $(TST_NAME)
+        @$(LIBTOOL) --mode=execute ./$(TST_NAME)
+ 
+ install:
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(prefix)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(bindir)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(includedir)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(libdir)
+        $(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(mandir)/man3
+        $(SHTOOL) install -c -m 755 al-config $(DESTDIR)$(bindir)/
+        $(SHTOOL) install -c -m 644 al.h $(DESTDIR)$(includedir)/
+        $(SHTOOL) install -c -m 644 al.3 $(DESTDIR)$(mandir)/man3/
+        @$(LIBTOOL) --mode=install $(SHTOOL) install -c -m 644 libal.la $(DESTDIR)$(libdir)/
+ 
+ uninstall:
+        @$(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/libal.la
+        -$(RM) $(DESTDIR)$(mandir)/man3/al.3
+        -$(RM) $(DESTDIR)$(includedir)/al.h
+        -$(RM) $(DESTDIR)$(bindir)/al-config
+        -$(RMDIR) $(DESTDIR)$(mandir)/man3 >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(mandir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(libdir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(includedir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(bindir) >/dev/null 2>&1 || $(TRUE)
+        -$(RMDIR) $(DESTDIR)$(prefix) >/dev/null 2>&1 || $(TRUE)
+ 
+ clean:
+        -$(RM) $(LIB_NAME) $(LIB_OBJS)
+        -$(RM) $(TST_NAME) $(TST_OBJS)
+        -$(RM) -r .libs >/dev/null 2>&1 || $(TRUE)
+        -$(RM) *.o *.lo
+ 
+ distclean: clean
+        -$(RM) config.log config.status config.cache
+        -$(RM) Makefile config.h al-config
+        -$(RM) libtool
+ 
+ realclean: distclean
+        -$(RM) al.3
+        -$(RM) configure config.h.in
+        -$(RM) shtool
+        -$(RM) ltmain.sh libtool.m4 config.guess config.sub
+ 


ossp-pkg/al/NEWS -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,15 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+ 
+   NEWS
+ 
+   This is a list of major changes to OSSP al. For more detailed
+   change descriptions, please have a look at the ChangeLog file.
+ 
+   -NONE-
+ 


ossp-pkg/al/README -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,46 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+   Version 
+ 
+   ABSTRACT
+ 
+   COPYRIGHT AND LICENSE
+ 
+   Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+   Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+   Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+   Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ 
+   This file is part of OSSP al, an abstract datatype of a data buffer
+   that can assemble, move and truncate data but avoids actual copying.
+ 
+   Permission to use, copy, modify, and distribute this software for
+   any purpose with or without fee is hereby granted, provided that
+   the above copyright notice and this permission notice appear in all
+   copies.
+ 
+   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+   IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.
+ 
+   HOME AND DOCUMENTATION
+ 
+   The documentation and latest release can be found on
+ 
+   o http://www.ossp.org/pkg/lib/al/
+   o  ftp://ftp.ossp.org/pkg/lib/al/
+ 


ossp-pkg/al/THANKS -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,22 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+ 
+   THANKS
+ 
+   Credit has to be given to the following sponsors for contributing
+   hardware, network and manpower resources (in alphabetical order):
+ 
+     o  Cable & Wireless Deutschland GmbH
+        <http://www.cw.com/de>
+ 
+   Credit has to be given to the following people who contributed ideas,
+   bugfixes, hints, gave platform feedback, etc. (in alphabetical order):
+ 
+     o  Ralf S. Engelschall         <rse@engelschall.com>
+     o  Thomas Lotterer             <thomas@lotterer.net>
+ 


ossp-pkg/al/TODO -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,17 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line
+ 
+   TODO
+ 
+   The following items still have to be done:
+ 
+   -NONE-
+ 
+   CANDO
+ 
+   -NONE-


ossp-pkg/al/VERSION -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,6 ----
+ 
+   VERSION -- Version Information for OSSP al (syntax: Text)
+   [automatically generated and maintained by GNU shtool]
+ 
+   This is OSSP al, Version 0.9.0 (16-Dec-2002)
+ 


ossp-pkg/al/aclocal.m4 -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,229 ----
+ dnl ##
+ dnl ##  al - OSSP Assembly Line
+ dnl ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ dnl ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ dnl ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ dnl ##  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ dnl ##
+ dnl ##  This file is part of OSSP al, an abstract datatype of a data buffer
+ dnl ##  that can assemble, move and truncate data but avoids actual copying.
+ dnl ##
+ dnl ##  Permission to use, copy, modify, and distribute this software for
+ dnl ##  any purpose with or without fee is hereby granted, provided that
+ dnl ##  the above copyright notice and this permission notice appear in all
+ dnl ##  copies.
+ dnl ##
+ dnl ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ dnl ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ dnl ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ dnl ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ dnl ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ dnl ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ dnl ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ dnl ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ dnl ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ dnl ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ dnl ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ dnl ##  SUCH DAMAGE.
+ dnl ##
+ dnl ##  aclocal.m4: GNU Autoconf local macro definitions
+ dnl ##
+ 
+ dnl ##
+ dnl ##  Check whether compiler option works
+ dnl ##
+ dnl ##  configure.in:
+ dnl ##    AC_COMPILER_OPTION(<name>, <display>, <option>,
+ dnl ##                       <action-success>, <action-failure>)
+ dnl ##
+ 
+ AC_DEFUN(AC_COMPILER_OPTION,[dnl
+ AC_MSG_CHECKING(whether compiler option(s) $2 work)
+ AC_CACHE_VAL(ac_cv_compiler_option_$1,[
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $3"
+ AC_TRY_COMPILE([],[], ac_cv_compiler_option_$1=yes, ac_cv_compiler_option_$1=no)
+ CFLAGS="$SAVE_CFLAGS"
+ ])dnl
+ if test ".$ac_cv_compiler_option_$1" = .yes; then
+     ifelse([$4], , :, [$4])
+ else
+     ifelse([$5], , :, [$5])
+ fi
+ AC_MSG_RESULT([$ac_cv_compiler_option_$1])
+ ])dnl
+ 
+ dnl ##
+ dnl ##  Debugging Support
+ dnl ##
+ dnl ##  configure.in:
+ dnl ##    AC_CHECK_DEBUGGING
+ dnl ##
+ 
+ AC_DEFUN(AC_CHECK_DEBUGGING,[dnl
+ AC_ARG_ENABLE(debug,dnl
+ [  --enable-debug          build for debugging (default=no)],
+ [dnl
+ if test ".$ac_cv_prog_gcc" = ".yes"; then
+     case "$CFLAGS" in
+         *-O* ) ;;
+            * ) CFLAGS="$CFLAGS -O2" ;;
+     esac
+     case "$CFLAGS" in
+         *-g* ) ;;
+            * ) CFLAGS="$CFLAGS -g" ;;
+     esac
+     case "$CFLAGS" in
+         *-pipe* ) ;;
+               * ) AC_COMPILER_OPTION(pipe, -pipe, -pipe, CFLAGS="$CFLAGS -pipe") ;;
+     esac
+     AC_COMPILER_OPTION(defdbg, -DDEBUG, -DDEBUG, CFLAGS="$CFLAGS -DDEBUG")
+     CFLAGS="$CFLAGS -pedantic"
+     CFLAGS="$CFLAGS -Wall"
+     WMORE="-Wshadow -Wpointer-arith -Wcast-align -Winline"
+     WMORE="$WMORE -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
+     AC_COMPILER_OPTION(wmore, -W<xxx>, $WMORE, CFLAGS="$CFLAGS $WMORE")
+     AC_COMPILER_OPTION(wnolonglong, -Wno-long-long, -Wno-long-long, CFLAGS="$CFLAGS -Wno-long-long")
+ else
+     case "$CFLAGS" in
+         *-g* ) ;;
+            * ) CFLAGS="$CFLAGS -g" ;;
+     esac
+ fi
+ msg="enabled"
+ ],[
+ if test ".$ac_cv_prog_gcc" = ".yes"; then
+ case "$CFLAGS" in
+     *-pipe* ) ;;
+           * ) AC_COMPILER_OPTION(pipe, -pipe, -pipe, CFLAGS="$CFLAGS -pipe") ;;
+ esac
+ fi
+ case "$CFLAGS" in
+     *-g* ) CFLAGS=`echo "$CFLAGS" |\
+                    sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+ esac
+ case "$CXXFLAGS" in
+     *-g* ) CXXFLAGS=`echo "$CXXFLAGS" |\
+                      sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+ esac
+ msg=disabled
+ ])dnl
+ AC_MSG_CHECKING(for compilation debug mode)
+ AC_MSG_RESULT([$msg])
+ if test ".$msg" = .enabled; then
+     enable_shared=no
+ fi
+ ])
+ 
+ dnl ##
+ dnl ##  Check for an external/extension library.
+ dnl ##  - is aware of <libname>-config style scripts
+ dnl ##  - searches under standard paths include, lib, etc.
+ dnl ##  - searches under subareas like .libs, etc.
+ dnl ##
+ dnl ##  configure.in:
+ dnl ##      AC_CHECK_EXTLIB(<realname>, <libname>, <func>, <header>,
+ dnl ##                      [<success-action> [, <fail-action>]])
+ dnl ##  Makefile.in:
+ dnl ##      CFLAGS  = @CFLAGS@
+ dnl ##      LDFLAGS = @LDFLAGS@
+ dnl ##      LIBS    = @LIBS@
+ dnl ##  shell:
+ dnl ##      $ ./configure --with-<libname>[=DIR]
+ dnl ##
+ 
+ AC_DEFUN(AC_CHECK_EXTLIB,[dnl
+ AC_ARG_WITH($2, [dnl
+ [  --with-]m4_substr([$2[[=DIR]]                     ], 0, 19)[build with external $1 library (default=no)]], [dnl
+     if test ".$with_$2" = .yes; then
+         #   via config script in PATH
+         $2_version=`($2-config --version) 2>/dev/null`
+         if test ".$$2_version" != .; then
+             CPPFLAGS="$CPPFLAGS `$2-config --cflags`"
+             CFLAGS="$CFLAGS `$2-config --cflags`"
+             LDFLAGS="$LDFLAGS `$2-config --ldflags`"
+         fi
+     else
+         if test -d "$with_$2"; then
+             found=0
+             #   via config script
+             for dir in $with_$2/bin $with_$2; do
+                 if test -f "$dir/$2-config" && test ! -f "$dir/$2-config.in"; then
+                     $2_version=`($dir/$2-config --version) 2>/dev/null`
+                     if test ".$$2_version" != .; then
+                         CPPFLAGS="$CPPFLAGS `$dir/$2-config --cflags`"
+                         CFLAGS="$CFLAGS `$dir/$2-config --cflags`"
+                         LDFLAGS="$LDFLAGS `$dir/$2-config --ldflags`"
+                         found=1
+                         break
+                     fi
+                 fi
+             done
+             #   in standard sub-areas
+             if test ".$found" = .0; then
+                 for dir in $with_$2/include/$2 $with_$2/include $with_$2; do
+                     if test -f "$dir/$4"; then
+                         CPPFLAGS="$CPPFLAGS -I$dir"
+                         CFLAGS="$CFLAGS -I$dir"
+                         found=1
+                         break
+                     fi
+                 done
+                 for dir in $with_$2/lib/$2 $with_$2/lib $with_$2; do
+                     if test -f "$dir/lib$2.la" && test -d "$dir/.libs"; then
+                         LDFLAGS="$LDFLAGS -L$dir -L$dir/.libs"
+                         found=1
+                         break
+                     elif test -f "$dir/lib$2.a" || test -f "$dir/lib$2.so"; then
+                         LDFLAGS="$LDFLAGS -L$dir"
+                         found=1
+                         break
+                     fi
+                 done
+             fi
+             #   in any sub-area
+             if test ".$found" = .0; then
+ changequote(, )dnl
+                 for file in x `find $with_$2 -name "$4" -type f -print`; do
+                     test .$file = .x && continue
+                     dir=`echo $file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
+                     CPPFLAGS="$CPPFLAGS -I$dir"
+                     CFLAGS="$CFLAGS -I$dir"
+                 done
+                 for file in x `find $with_$2 -name "lib$2.[aso]" -type f -print`; do
+                     test .$file = .x && continue
+                     dir=`echo $file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
+                     LDFLAGS="$LDFLAGS -L$dir"
+                 done
+ changequote([, ])dnl
+             fi
+         fi
+     fi
+     AC_HAVE_HEADERS($4)
+     AC_CHECK_LIB($2, $3)
+     with_$2=yes
+     ac_var="ac_cv_header_`echo $4 | sed 'y%./+-%__p_%'`"
+     eval "ac_val=\$$ac_var"
+     if test ".$ac_val" != .yes; then
+         with_$2=no
+     fi
+     if test ".$ac_cv_lib_$2_$3" != .yes; then
+         with_$2=no
+     fi
+     if test ".$with_$2" = .no; then
+         AC_ERROR([Unable to find $1 library])
+     fi
+     ], [dnl
+ if test ".$with_$2" = .; then
+     with_$2=no
+ fi
+     ])dnl
+ AC_MSG_CHECKING(whether to build against external $1 library)
+ if test ".$with_$2" = .yes; then
+     ifelse([$5], , :, [$5])
+ else
+     ifelse([$6], , :, [$6])
+ fi
+ AC_MSG_RESULT([$with_$2])
+ ])dnl
+ 


ossp-pkg/al/al-config.in -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,146 ----
+ #!/bin/sh
+ ##
+ ##  OSSP al - Assembly Line
+ ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ ##  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ ##
+ ##  This file is part of OSSP al, an abstract datatype of a data buffer
+ ##  that can assemble, move and truncate data but avoids actual copying.
+ ##
+ ##  Permission to use, copy, modify, and distribute this software for
+ ##  any purpose with or without fee is hereby granted, provided that
+ ##  the above copyright notice and this permission notice appear in all
+ ##  copies.
+ ##
+ ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ ##  SUCH DAMAGE.
+ ##
+ ##  al-config.in: AL library build utility
+ ##
+ 
+ DIFS=' 
+ '
+ 
+ prefix="@prefix@"
+ exec_prefix="@exec_prefix@"
+ 
+ al_prefix="$prefix"
+ al_exec_prefix="$exec_prefix"
+ al_bindir="@bindir@"
+ al_libdir="@libdir@"
+ al_includedir="@includedir@"
+ al_mandir="@mandir@"
+ al_datadir="@datadir@"
+ al_acdir="@datadir@/aclocal"
+ al_cflags="@CFLAGS@"
+ al_ldflags="@LDFLAGS@"
+ al_libs="@LIBS@"
+ al_version="@AL_VERSION_STR@"
+ 
+ help=no
+ version=no
+ 
+ usage="al-config"
+ usage="$usage [--help] [--version] [--all]"
+ usage="$usage [--prefix] [--exec-prefix] [--bindir] [--libdir] [--includedir] [--mandir] [--datadir] [--acdir]"
+ usage="$usage [--cflags] [--ldflags] [--libs]"
+ if [ $# -eq 0 ]; then
+     echo "al-config:Error: Invalid option" 1>&2
+     echo "al-config:Usage: $usage" 1>&2
+     exit 1
+ fi
+ output=''
+ output_extra=''
+ all=no
+ prev=''
+ OIFS="$IFS" IFS="$DIFS"
+ for option
+ do
+     if [ ".$prev" != . ]; then
+         eval "$prev=\$option"
+         prev=''
+         continue
+     fi
+     case "$option" in
+         -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+            *) optarg='' ;;
+     esac
+     case "$option" in
+         --help|-h)
+             echo "Usage: $usage"
+             exit 0
+             ;;
+         --version|-v)
+             echo "OSSP al $al_version"
+             exit 0
+             ;;
+         --all)
+             all=yes
+             ;;
+         --prefix)
+             output="$output $al_prefix"
+             ;;
+         --exec-prefix)
+             output="$output $al_exec_prefix"
+             ;;
+         --bindir)
+             output="$output $al_bindir"
+             ;;
+         --libdir)
+             output="$output $al_libdir"
+             ;;
+         --includedir)
+             output="$output $al_includedir"
+             ;;
+         --mandir)
+             output="$output $al_mandir"
+             ;;
+         --datadir)
+             output="$output $al_datadir"
+             ;;
+         --acdir)
+             output="$output $al_acdir"
+             ;;
+         --cflags)
+             output="$output -I$al_includedir"
+             output_extra="$output_extra $al_cflags"
+             ;;
+         --ldflags)
+             output="$output -L$al_libdir"
+             output_extra="$output_extra $al_ldflags"
+             ;;
+         --libs)
+             output="$output -lal"
+             output_extra="$output_extra $al_libs"
+             ;;
+         * )
+             echo "al-config:Error: Invalid option" 1>&2
+             echo "al-config:Usage: $usage" 1>&2
+             exit 1;
+             ;;
+     esac
+ done
+ IFS="$OIFS"
+ if [ ".$prev" != . ]; then
+     echo "al-config:Error: missing argument to --`echo $prev | sed 's/_/-/g'`" 1>&2
+     exit 1
+ fi
+ if [ ".$output" != . ]; then
+     if [ ".$all" = .yes ]; then
+         output="$output $output_extra"
+     fi
+     echo $output
+ fi
+ 


ossp-pkg/al/al.banner -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,7 ----
+    _        ___  ____ ____  ____          _ 
+   |_|_ _   / _ \/ ___/ ___||  _ \    __ _| |
+   _|_||_| | | | \___ \___ \| |_) |  / _` | |
+  |_||_|_| | |_| |___) |__) |  __/  | (_| | |
+   |_|_|_|  \___/|____/____/|_|      \__,_|_|
+                                    
+   OSSP al - Assembly Line


ossp-pkg/al/al.c -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,1317 ----
+ /*
+ **  OSSP al -- Assembly Line
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ **
+ **  This file is part of OSSP al, an abstract datatype of a data buffer
+ **  that can assemble, move and truncate data but avoids actual copying.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ **  SUCH DAMAGE.
+ **
+ **  al.c: assembly line library implementation
+ */
+ 
+ #include <stddef.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #ifdef TEST
+ #include <stdio.h>
+ #endif
+ 
+ #include "list.h"
+ 
+ #include "al.h"
+ 
+ /* unique library identifier */
+ const char al_id[] = "OSSP al";
+ 
+ /* support for OSSP ex based exception throwing */
+ #ifdef WITH_EX
+ #include "ex.h"
+ #define AL_RC(rv) \
+     (  (rv) != AL_OK && (ex_catching && !ex_shielding) \
+      ? (ex_throw(al_id, NULL, (rv)), (rv)) : (rv) )
+ #else
+ #define AL_RC(rv) (rv)
+ #endif /* WITH_EX */
+ 
+ struct al_buffer_st;
+ typedef struct al_buffer_st al_buffer_t;
+ 
+ typedef struct {
+     void           *(*malloc)(size_t); /* malloc(3) style function (for al_chunk_t) */
+     void            (*free)(void *);   /* free(3)   style function (for al_chunk_t) */
+     void           *(*balloc)(size_t); /* malloc(3) style function (for al_buffer_t) */
+     void            (*bfree)(void *);  /* free(3)   style function (for al_buffer_t) */
+     size_t            new_buffersize;  /* default size for memory underlying al_buffer_t */
+     int               max_freechunks;  /* maximum number of cached al_chunk_t objects */
+ } al_memops_t;
+ 
+ struct al_st {
+     LIST(al_chunk_t)  chunks;          /* list header for al_chunk_t objects */
+     size_t            bytes;           /* total cached number of bytes in chunk */
+     al_memops_t       m;               /* assembly line memory operations (see above) */
+ };
+ 
+ struct al_chunk_st {
+     NODE(al_chunk_t)  chunks;          /* list node for al_chunk_t object chaining */
+     al_buffer_t      *buf;             /* (non-exlusively) referenced buffer object */
+     size_t            begin;           /* offset into buf->mem where data starts */
+     size_t            end;             /* offset into buf->mem where data ends */
+     al_label_t        label;           /* tag data with a label, chunks with distinct labels are not coalesced */
+ };
+ 
+ struct al_buffer_st {
+     char             *mem;             /* reference to underlying chunk of data */
+     size_t            size;            /* size of underlying chunk of data */
+     int               usecount;        /* reference count (from al_chunk_t) */
+     void            (*freemem)(char *p, size_t n, void *u); /* callback function to reclaim memory when it is no longer referenced */
+     void             *userdata;          /* arbitrary pointer to pass context data to the callback function */
+ };
+ 
+ struct al_tx_st {
+     al_td_t           dir;             /* traversal direction */
+     al_chunk_t       *cur;             /* current chunk during traveral steps */
+     size_t            skip;            /* number of bytes to skip for traversal */
+     size_t            togo;            /* number of bytes left for traversal */
+     al_label_t        label;           /* label filter or NULL */
+     al_chunk_t        view;            /* synthetic chunk for returning during traversal steps */
+ };
+ 
+ /* number of bytes described by a chunk */
+ #define AL_CHUNK_LEN(alc) \
+     ((alc)->end - (alc)->begin)
+ 
+ /* memory pointer into a chunk, offset must be less than length */
+ #define AL_CHUNK_PTR(alc, off) \
+     ((alc)->buf->mem + (alc)->begin + (off))
+ 
+ /* number of bytes of a span that are stored in a chunk */
+ #define AL_CHUNK_SPAN(alc, off, n) \
+     ((n) > (AL_CHUNK_LEN(alc) - (off)) ? \
+     (AL_CHUNK_LEN(alc) - (off)) : (n))
+ 
+ /* return chunk label */
+ #define AL_CHUNK_LABEL(alc) \
+     ((alc)->label)
+ 
+ /* check wether labels match */
+ #define AL_SAME_LABEL(alc,label) \
+     ((label) == NULL || AL_CHUNK_LABEL(alc) == (label))
+ 
+ /*
+  * number of bytes a chunk can be grown to the end
+  * we must not grow a chunk in a shared buffer since
+  * we do not track other chunks sharing the buffer
+  */
+ #define AL_CHUNK_RESERVE(alc,label) \
+     (  (alc) != NULL \
+      ? (  (alc)->buf->usecount > 1 || !AL_SAME_LABEL(alc,label) \
+         ? 0 \
+         : (alc)->buf->size - (alc)->end) \
+      : 0)
+ 
+ /* grow chunk to the end */
+ #define AL_RESIZE(al, alc, n) \
+     do { (alc)->end += n; (al)->bytes += (n); } while (0)
+ 
+ /*
+  * number of bytes a chunk can be grown to the beginning
+  * we must not grow a chunk in a shared buffer since
+  * we do not track other chunks sharing the buffer
+  *
+  * empty chunks can be aligned with end
+  */
+ #define AL_CHUNK_PRESERVE(alc,label) \
+     ( (alc) != NULL \
+      ? (  (alc)->buf->usecount > 1 || !AL_SAME_LABEL(alc,label) \
+         ? 0 \
+         : (alc)->end <= (alc)->begin ? \
+           (alc)->buf->size \
+           : (alc)->begin) \
+      : 0)
+ 
+ /*
+  * grow chunk to the beginning
+  *
+  * empty chunks can be aligned with end
+  */
+ #define AL_PRESIZE(al, alc, n) \
+     do { \
+         if ((alc)->end <= (alc)->begin) \
+             (alc)->end = (alc)->begin = (alc)->buf->size; \
+         (alc)->begin -= n; (al)->bytes += (n); \
+     } while (0)
+ 
+ /*
+  * callback to release buffer memory allocated by the library
+  */
+ static
+ void freemem(char *p, size_t n, void *u)
+ {
+     void (*f)(void *) = (void (*)(void *))u;
+     f(p);
+ }
+ 
+ /*
+  * allocate backing store and its control structure from heap
+  *
+  * can be freed when usecount drops to zero
+  */
+ static al_rc_t
+ new_buffer(al_t *al, al_buffer_t **bufp)
+ {
+     size_t n = al->m.new_buffersize;
+     al_buffer_t *buf;
+ 
+     if ((buf = (al_buffer_t *)(al->m.malloc)(sizeof(al_buffer_t))) == NULL)
+         return AL_ERR_MEM;
+ 
+     if ((buf->mem = (al->m.balloc)(n)) == NULL) {
+         (al->m.free)(buf);
+         return AL_ERR_MEM;
+     }
+ 
+     buf->freemem  = freemem;
+     buf->userdata = (void *)al->m.bfree;
+     buf->size     = n;
+     buf->usecount = 0;
+ 
+     *bufp = buf;
+     return AL_OK;
+ }
+ 
+ static al_rc_t
+ dispose_buffer(al_t *al, al_buffer_t *buf)
+ {
+     /* must not happen */
+     if (buf->usecount != 0)
+         return AL_ERR_INT;
+ 
+     if (buf->freemem)
+         (buf->freemem)(buf->mem, buf->size, buf->userdata);
+ 
+     (al->m.free)(buf);
+     return AL_OK;
+ }
+ 
+ /*
+  * allocate only control structure for backing store from heap
+  * and attach to existing memory
+  * only the control structure will be freed later
+  */
+ static
+ al_rc_t make_buffer(al_t *al, char *p, size_t n, void (*freemem_cb)(char *, size_t, void *), void *u, al_buffer_t **bufp)
+ {
+     al_buffer_t *buf;
+ 
+     if ((buf = (al_buffer_t *)(al->m.malloc)(sizeof(al_buffer_t))) == NULL)
+         return AL_ERR_MEM;
+ 
+     buf->mem      = p;
+ 
+     buf->freemem  = freemem_cb;
+     buf->userdata = u;
+     buf->size     = n;
+     buf->usecount = 0;
+ 
+     *bufp = buf;
+     return AL_OK;
+ }
+ 
+ /*
+  * allocate chunks from heap and attach to backing store
+  * keep some freed chunks in a freelist to avoid expensive malloc()
+  * and excessive fragmentation
+  * maintain usage count of backing store
+  * free backing store when no longer in use, this also includes
+  * the case where new_chunk fails and the buffer has no other
+  * users
+  */
+ static struct {
+     LIST(al_chunk_t) chunks;
+ } alc_freelist;
+ static int alc_freecount = 0;
+ 
+ static al_rc_t
+ new_chunk(al_t *al, al_buffer_t *buf, al_label_t label, al_chunk_t **alcp)
+ {
+     al_chunk_t *alc;
+ 
+     if (ISEMPTY(&alc_freelist, chunks)) {
+         if ((alc = (al_chunk_t *)(al->m.malloc)(sizeof(al_chunk_t))) == NULL) {
+             if (buf->usecount == 0)
+                 dispose_buffer(al,buf);
+             return AL_ERR_MEM;
+         }
+     } else {
+         /* thl: FIXME i would suggest using REMTAIL() here because dispose_chunk
+          *            puts the latest disposed chunks at the end of the list and
+          *            those latest data should have a closer approximation to the
+          *            CPU in terms of internal cache, external cache, RAM and VM
+          */
+         REMHEAD(&alc_freelist, chunks, alc);
+         --alc_freecount;
+     }
+ 
+     NODEINIT(alc, chunks);
+     alc->buf   = buf;
+     alc->begin = 0;
+     alc->end   = 0;
+     alc->label = label;
+ 
+     buf->usecount++;
+ 
+     *alcp = alc;
+     return AL_OK;
+ }
+ 
+ static al_rc_t
+ split_chunk(al_t *al, al_chunk_t *orig, size_t off, al_chunk_t **alcp)
+ {
+     al_rc_t rc;
+     al_chunk_t *alc;
+     size_t len = AL_CHUNK_LEN(orig);
+ 
+     if (off > len)
+         return AL_ERR_ARG;
+ 
+     rc = new_chunk(al, orig->buf, orig->label, &alc);
+     if (rc != AL_OK)
+         return rc;
+ 
+     alc->begin  = orig->begin;
+     alc->end    = orig->begin+off;
+     orig->begin = alc->end;
+ 
+     *alcp = alc;
+     return AL_OK;
+ }
+ 
+ static void
+ dispose_chunk(al_t *al, al_chunk_t *alc)
+ {
+     alc->buf->usecount--;
+     if (alc->buf->usecount == 0)
+         dispose_buffer(al,alc->buf);
+     alc->buf = NULL;
+     alc->label = NULL;
+ 
+     /* stop freelist from growing infinitely */
+     if (alc_freecount >= al->m.max_freechunks)
+         (al->m.free)(alc);
+     else {
+         ADDTAIL(&alc_freelist, chunks, alc);
+         alc_freecount++;
+     }
+ }
+ 
+ /*
+  *  find chunk that represents a particular offset
+  *  a reference to the chunk is stored in *alcp
+  *  the relative offset into the chunk is stored in *skipp
+  *  return AL_OK and *alcp == NULL if positioned exactly to end of list
+  *  return AL_ERR_EOF when no such chunk can be found
+  */
+ static al_rc_t
+ al_seek(al_t *al, size_t off, al_chunk_t **alcp, size_t *skipp)
+ {
+     al_chunk_t *cur;
+     size_t pos, end;
+     size_t chunksize;
+ 
+     if ((al->bytes / 2) >= off) { /* FIXME poor man's heuristic */
+         /* forward search */
+         pos = 0;
+         FOREACH(al,chunks,cur) {
+             chunksize = AL_CHUNK_LEN(cur);
+             end = pos+chunksize;
+             if (pos <= off && off < end) {
+                 *alcp  = cur;
+                 *skipp = off - pos;
+                 return AL_OK;
+             }
+             if (end > off)
+                 break;
+             pos = end;
+         }
+         /* seek to EOF position is ok */
+         if (pos == off) {
+             *alcp  = NULL;
+             *skipp = 0;
+             return AL_OK;
+         }
+     } else {
+         /* reverse search */
+         pos  = al->bytes;
+         /* seek to EOF position is ok */
+         if (pos == off) {
+             *alcp  = NULL;
+             *skipp = 0;
+             return AL_OK;
+         }
+         FOREACHR(al,chunks,cur) {
+             chunksize = AL_CHUNK_LEN(cur);
+             end  = pos;
+             pos -= chunksize;
+             if (pos <= off && off < end) {
+                 *alcp  = cur;
+                 *skipp = off - pos;
+                 return AL_OK;
+             }
+             if (pos < off)
+                 break;
+         }
+     }
+ 
+     return AL_ERR_EOF;
+ }
+ 
+ #ifdef TEST
+ static void
+ dump(al_t *al)
+ {
+     al_chunk_t *cur;
+     size_t total;
+ 
+     printf("AL: %p\n", al);
+     total = 0;
+     FOREACH(al,chunks,cur) {
+         printf(" C: %p [%p] (%d @ %p + %d < %d (use=%d))\n",
+             cur,
+             cur->label,
+             cur->buf->size,cur->buf->mem,
+             cur->begin,cur->end,
+             cur->buf->usecount);
+         total += AL_CHUNK_LEN(cur);
+     }
+     printf("size = %d == %d\n",al->bytes,total);
+     printf("--\n\n");
+ }
+ #endif
+ 
+ /****************************************************************************/
+ 
+ /*
+  * allocate an empty assembly line
+  * dispose all chunks and all allocated backing store
+  */
+ al_rc_t
+ al_create(al_t **alp)
+ {
+     al_t *al;
+ 
+     /* argument sanity check(s) */
+     if (alp == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     /* allocate and initialize new assembly line object */
+     /* XXX - what malloc ? */
+     if ((al = (al_t *)malloc(sizeof(al_t))) == NULL)
+         return AL_RC(AL_ERR_MEM);
+ 
+     LISTINIT(al,chunks);
+     al->bytes = 0;
+ 
+     /* memory policy */
+     al->m.malloc = malloc;    /* structure allocation */
+     al->m.free   = free;
+     al->m.balloc = malloc;    /* buffer allocation */
+     al->m.bfree  = free;
+ #ifdef TEST
+     al->m.new_buffersize = 42;
+ #else
+     al->m.new_buffersize = 4096;
+ #endif
+     al->m.max_freechunks = 500;
+ 
+     /* pass object to caller */
+     *alp = al;
+ 
+     return AL_OK;
+ }
+ 
+ al_rc_t
+ al_destroy(al_t *al)
+ {
+     al_chunk_t *cur, *pred;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     /* free chunks and backing store */
+     FOREACHD(al,chunks,cur,pred) {
+         REMOVE(al,chunks,cur);
+         dispose_chunk(al,cur);
+     }
+ 
+     /* free object itself */
+     /* XXX - which free() ? */
+     free(al);
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * copy bytes into buffer, FIFO
+  *
+  * stops copy operation when a new buffer cannot be created
+  * but leaves data structure consistent
+  */
+ al_rc_t
+ al_append_bytes(al_t *al, const char *src, size_t n, al_label_t label)
+ {
+     al_rc_t rc;
+     al_chunk_t *cur;
+     al_buffer_t *buf;
+     size_t res, step;
+     char *dst;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL || src == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     cur = TAIL(al,chunks);
+     res = AL_CHUNK_RESERVE(cur,label);
+ 
+     while (n > 0) {
+         if (res == 0) {
+             rc = new_buffer(al, &buf);
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+             rc = new_chunk(al,buf,label,&cur);
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+             res = AL_CHUNK_RESERVE(cur,label);
+             ADDTAIL(al, chunks, cur);
+         }
+         step = n;
+         if (step > res)
+             step = res;
+ 
+         dst = AL_CHUNK_PTR(cur, AL_CHUNK_LEN(cur));
+         memcpy(dst, src, step);
+ 
+         src += step;
+         AL_RESIZE(al, cur, step);
+         n   -= step;
+         res = AL_CHUNK_RESERVE(cur,label);
+     }
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * copy bytes into buffer, LIFO
+  *
+  * stops copy operation when a new buffer cannot be created
+  * but leaves data structure consistent
+  */
+ al_rc_t
+ al_prepend_bytes(al_t *al, const char *src, size_t n, al_label_t label)
+ {
+     al_rc_t rc;
+     al_chunk_t *cur;
+     al_buffer_t *buf;
+     size_t res, step;
+     char *dst;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL || src == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     cur = HEAD(al,chunks);
+     res = AL_CHUNK_PRESERVE(cur,label);
+ 
+     src += n;
+ 
+     while (n > 0) {
+         if (res == 0) {
+             rc = new_buffer(al, &buf);
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+             rc = new_chunk(al,buf,label,&cur);
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+             res = AL_CHUNK_PRESERVE(cur,label);
+             ADDHEAD(al, chunks, cur);
+         }
+         step = n;
+         if (step > res)
+             step = res;
+ 
+         src -= step;
+         AL_PRESIZE(al, cur, step);
+         n   -= step;
+         res = AL_CHUNK_PRESERVE(cur,label);
+ 
+         dst = AL_CHUNK_PTR(cur, 0);
+         memcpy(dst, src, step);
+     }
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * append a caller supplied buffer
+  *
+  * buffer must exist until list is destroyed
+  * XXX - buffer can have multiple refs caused by splice operations
+  * XXX - some list operations modify the buffer
+  *
+  */
+ al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, al_label_t label,
+                          void (*freemem_cb)(char *, size_t, void *), void *u)
+ {
+     al_rc_t rc;
+     al_buffer_t *buf;
+     al_chunk_t  *cur;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL || p == NULL || n <= 0)
+         return AL_RC(AL_ERR_ARG);
+ 
+     rc = make_buffer(al, p, n, freemem_cb, u, &buf);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+     rc = new_chunk(al,buf,label,&cur);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+     ADDTAIL(al, chunks, cur);
+ 
+     /* validate data in buffer */
+     AL_RESIZE(al, cur, n);
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * this is the central function to manipulate assembly line
+  *
+  * cut arbitrary spans from list into a destination buffer (or drop it)
+  * insert (destructive move) content from another list into the cut
+  *
+  * this is analog to perls splice function, except that
+  * -> the output is not stored in the target buffer but is appended
+  * -> the replacement data is moved and not copied.
+  *
+  */
+ al_rc_t
+ al_splice(al_t *al, size_t off, size_t n, al_t *nal, al_t *tal)
+ {
+     al_rc_t rc;
+     al_chunk_t *cur, *start, *end, *next, *ins, *splitbuf;
+     size_t pos, skip, len, step;
+     int doinsert;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     /* optimization: treat an empty list as no insertion at all */
+     doinsert = (nal != NULL) && !ISEMPTY(nal,chunks);
+ 
+     /*
+      * seek to beginning, return EOF when seek position does not exist
+      * EOD must be a valid seek position so that we can append data
+      */
+     rc = al_seek(al, off, &cur, &skip);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     /*
+      * remember insertion point
+      *
+      * caveat: if the first chunk is removed from input the insertion
+      *         point shifts to the next chunk (or EOD -> NULL pointer)
+      */
+     ins = cur;
+ 
+     /*
+      * the inseration point is either behind the list or
+      * within the current chunk
+      *
+      * if it is behind the list:
+      * -> insert operation switches to append mode
+      *
+      * if the insertion point is at the beginning of the current chunk:
+      * -> insertion point moves later if the chunk is removed
+      *
+      * if the inseration point is in the middle of the current chunk:
+      * -> chunk is split into two so that the insertion
+      *    point is at the beginning of the second part
+      *
+      * insertion point cannot be at EOD of the chunk
+      *
+      * splitting at this point preserves all data in case the
+      * allocation of the split buffer fails
+      */
+     if (doinsert) {
+         if (ins != NULL && skip > 0) {
+             rc = split_chunk(al, ins, skip, &splitbuf);
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+             INSERT(al,chunks,ins,splitbuf);
+             skip = 0;
+         }
+     }
+ 
+     /*
+      * as long as there is data to move
+      */
+     pos = off;
+     while (n > 0 && cur != NULL) {
+         next = NEXT(cur, chunks);
+         len  = AL_CHUNK_LEN(cur);
+ 
+         /*
+          * check if partial chunk was selected
+          * if skip > 0 we have to preserve bytes at the beginning
+          * if skip == 0 && n < len-skip we have to preserve bytes at the end
+          */
+         if (skip > 0 || n < len - skip) {
+ 
+             /* compute number of bytes to process */
+             step = AL_CHUNK_SPAN(cur, skip, n);
+ 
+             /* copy data to target */
+             if (tal != NULL) {
+                 /*
+                  * XXX - this operation can fail
+                  */
+                 size_t before = tal->bytes;
+ 
+                 rc = al_append_bytes(tal, AL_CHUNK_PTR(cur, skip),
+                                      step, AL_CHUNK_LABEL(cur));
+                 if (rc != AL_OK)
+                     /* correct step size to actual size */
+                     step = tal->bytes - before;
+ 
+             } else
+                 rc = AL_OK;
+ 
+             /*
+              * cut span from src chunk
+              * if skip == 0, simply shrink the chunk from the beginning
+              * if skip > 0, compute number of bytes to preserve,
+              *              align buffer and shrink chunk from the end
+              */
+             if (skip == 0)
+                 AL_PRESIZE(al, cur, -step);
+             else {
+                 /* align trailing bytes */
+                 if (len > (skip+step)) {
+                     memmove(
+                         AL_CHUNK_PTR(cur, skip),
+                         AL_CHUNK_PTR(cur, skip+step),
+                         len - (skip+step)
+                     );
+                 }
+                 AL_RESIZE(al, cur, -step);
+             }
+ 
+             /*
+              * bail out from failed al_append_bytes operation above
+              *
+              */
+             if (rc != AL_OK)
+                 return AL_RC(rc);
+         }
+         else {
+             /*
+              * the whole chunk has to be moved,
+              *
+              * scan ahead for more such chunks to unlink
+              * and relink a whole chain in a single operation
+              *
+              * move the chunks to the target chain
+              * manual accounting for total size
+              */
+ 
+             /*
+              * when the insertion chunk is removed, we have to adjust
+              * the insertion point
+              *
+              * if the insertion chunk was the last chunk we get a NULL
+              * next pointer and the insertion method switches to append
+              * mode
+              */
+ 
+             step  = len;
+             start = cur;
+             end   = cur;
+ 
+             if (cur == ins)
+                 ins = next;
+ 
+             while (next && step + (len = AL_CHUNK_LEN(next)) <= n) {
+                 step += len;
+                 end  = next;
+                 next = NEXT(next, chunks);
+                 if (end == ins)
+                     ins = next;
+             }
+             REMOVE2(al, chunks, start, end);
+ 
+             al->bytes -= step;
+             if (tal == NULL) {
+                 do {
+                     cur = start;
+                     start = NEXT(cur, chunks);
+                     dispose_chunk(al, cur);
+                 } while (cur != end);
+             } else {
+                 ADDTAIL2(tal, chunks, start, end);
+                 tal->bytes += step;
+             }
+         }
+         n   -= step;
+         pos += step;
+         cur  = next;
+         skip = 0;
+     }
+ 
+     /*
+      * now splice in replacement chunks
+      */
+     if (doinsert) {
+         if (ins != NULL) {
+             /*
+              * complex case where list is inserted
+              *
+              * the original list has already been modified so
+              * that we can simply insert between two chunks
+              */
+             INSERTLIST(al,chunks,ins,nal);
+         } else {
+             /*
+              * simple case where list end is 'replaced'
+              */
+             APPENDLIST(al,chunks,nal);
+         }
+ 
+         al->bytes += nal->bytes;
+         nal->bytes = 0;
+ 
+     }
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  *
+  */
+ al_rc_t
+ al_setlabel(al_t *al, size_t off, size_t n,
+             al_label_t oldlabel, al_label_t newlabel)
+ {
+     al_rc_t rc;
+     al_chunk_t *cur, *splitbuf;
+     size_t skip, len;
+ 
+     /* argument sanity check(s) */
+     if (al == NULL)
+         return AL_RC(AL_ERR_ARG);
+ 
+     /*
+      * seek to beginning, return EOF when seek position does not exist
+      * EOD must be a valid seek position so that we can append data
+      */
+     rc = al_seek(al, off, &cur, &skip);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     /*
+      * seek to EOD, nothing to label
+      */
+     if (cur == NULL)
+         return AL_OK;
+ 
+     /*
+      * if first chunk doesn't need relabeling
+      * then skip it, adjust seek size
+      *
+      * else if offset is not at chunk start
+      * then split chunk at offset, continue
+      * with second half
+      */
+     if (!AL_SAME_LABEL(cur, oldlabel) ||
+         AL_SAME_LABEL(cur, newlabel)) {
+         len = AL_CHUNK_LEN(cur) - skip;
+         n = n < len ? 0 : n - len;
+         cur = NEXT(cur, chunks);
+     } else if (skip > 0) {
+         rc = split_chunk(al, cur, skip, &splitbuf);
+         if (rc != AL_OK)
+             return AL_RC(rc);
+         INSERT(al,chunks,cur,splitbuf);
+     }
+ 
+     /*
+      * for all remaining chunks and bytes
+      *
+      * if chunk doesn't need relabeling
+      * then skip it, adjust size
+      *
+      * else if chunk isn't covered in total
+      * then split chunk at end offset and
+      * process first half
+      */
+     while (n > 0 && cur != NULL) {
+         len = AL_CHUNK_LEN(cur);
+         if (!AL_SAME_LABEL(cur, oldlabel) ||
+             AL_SAME_LABEL(cur, newlabel)) {
+             n = n < len ? 0 : n - len;
+         } else {
+             if (n < len) {
+                 /*
+                  * split last chunk at end offset
+                  */
+                 rc = split_chunk(al, cur, n, &splitbuf);
+                 if (rc != AL_OK)
+                     return AL_RC(rc);
+                 INSERT(al,chunks,cur,splitbuf);
+                 cur = splitbuf;
+                 len = AL_CHUNK_LEN(cur);
+             }
+             AL_CHUNK_LABEL(cur) = newlabel;
+             n   -= len;
+         }
+         cur  = NEXT(cur, chunks);
+     }
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * assembly line traversal requires a context. It needs to be
+  * malloced to keep its inner structure private
+  */
+ al_rc_t
+ al_txalloc(al_t *al, al_tx_t **txp)
+ {
+     al_tx_t *tx;
+ 
+     tx = (al_tx_t*)(al->m.malloc)(sizeof(al_tx_t));
+     if (tx == NULL)
+         return AL_RC(AL_ERR_MEM);
+ 
+     *txp = tx;
+     return AL_OK;
+ }
+ 
+ /*
+  * free traversal context using proper policy function
+  */
+ al_rc_t
+ al_txfree(al_t *al, al_tx_t *tx)
+ {
+     (al->m.free)(tx);
+     return AL_OK;
+ }
+ 
+ /*
+  * initiate assembly line traversal
+  *
+  * - do initial seek, fail if position does not exist
+  * - save traversal parameters
+  */
+ al_rc_t
+ al_traverse(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_tx_t *tx)
+ {
+     al_rc_t rc;
+ 
+     tx->cur = NULL;
+ 
+     rc = al_seek(al, off, &tx->cur, &tx->skip);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     tx->dir   = dir;
+     tx->togo  = n;
+     tx->label = label;
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * assembly line traversal step
+  *
+  * return EOF if at end of assembly line
+  * clip view chunk to traversal bounds
+  * advance chunk cursor according to traversal direction
+  */
+ al_rc_t
+ al_traverse_next(al_t *al, al_tx_t *tx, al_chunk_t **alcp)
+ {
+     size_t step;
+ 
+     do {
+         if (tx->togo <= 0)     /* XXX - togo can be negative from bad input */
+             return AL_ERR_EOF;
+ 
+         if (tx->cur == NULL)   /* premature EOF */
+             return AL_ERR_EOF;
+ 
+         /* compute number of bytes to process */
+         step = AL_CHUNK_SPAN(tx->cur, tx->skip, tx->togo);
+ 
+         /*
+          * synthetic chunk which is NOT maintained in usecount
+          * MUST NOT BE USED for modifications to chunk list
+          * MUST NOT BE USED for modifications to chunk size
+          * ALLOWED is read access to chunk content
+          * ALLOWED is modification in place of chunk content
+          */
+         tx->view        = *(tx->cur);
+         tx->view.begin += tx->skip;
+         tx->view.end    = tx->view.begin + step;
+ 
+         switch (tx->dir) {
+         case AL_FORWARD:
+         case AL_BACKWARD:
+             break;
+         case AL_FORWARD_SPAN:
+         case AL_BACKWARD_SPAN:
+             if (!AL_SAME_LABEL(&tx->view, tx->label)) {
+                 tx->togo = 0;
+                 return AL_ERR_EOF;
+             }
+             break;
+         }
+ 
+         switch (tx->dir) {
+             case AL_FORWARD:
+             case AL_FORWARD_SPAN:
+                 tx->cur   = NEXT(tx->cur,chunks);
+                 tx->togo -= step;
+                 tx->skip  = 0;
+                 break;
+             case AL_BACKWARD:
+             case AL_BACKWARD_SPAN:
+                 tx->cur   = PREV(tx->cur,chunks);
+                 tx->togo -= step;
+                 tx->skip  = 0;
+                 break;
+         }
+     } while (!AL_SAME_LABEL(&tx->view, tx->label));
+ 
+     *alcp = &tx->view;
+     return AL_OK;
+ }
+ 
+ /*
+  * assembly line traversal end
+  *
+  * to free resources allocated/locked during traversal
+  * currently a NOOP
+  */
+ al_rc_t al_traverse_end(al_t *al, al_tx_t *tx, int final)
+ {
+     return AL_OK;
+ }
+ 
+ /*
+  * full assembly line traversal with callback
+  *
+  * traversal is aborted when callback return != AL_OK
+  * reaching EOF (and also aborting with AL_ERR_EOF) is not an error
+  *
+  * traversal context is kept on stack (XXX ?)
+  */
+ al_rc_t
+ al_traverse_cb(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label,
+                al_rc_t (*cb)(al_chunk_t *, void *), void *u)
+ {
+     al_rc_t rc;
+     al_tx_t tx;                /* XXX - private tx structure on stack */
+     al_chunk_t *view;
+ 
+     rc = al_traverse(al, off, n, dir, label, &tx);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
+         rc = cb(view, u);
+         if (rc != AL_OK)
+             break;
+     }
+ 
+     al_traverse_end(al, &tx, 1);
+ 
+     if (rc != AL_ERR_EOF)
+         return AL_RC(rc);
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * full assembly line traversal with data copy to linear buffer
+  *
+  * returns actual number of bytes copied
+  *
+  * Do not copy if destination pointer is NULL, but still count.
+  * This can be used to precalculate the size of the needed linear
+  * buffer with n set to some arbitrary huge value.
+  *
+  * traversal context is kept on stack (XXX ?)
+  */
+ al_rc_t
+ al_flatten(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label,
+            char *dst, size_t *lenp)
+ {
+     al_rc_t rc;
+     al_tx_t tx;                /* XXX - private tx structure on stack */
+     al_chunk_t *view;
+     size_t step, total;
+ 
+     *lenp = 0; /* keep caller on safe side */
+ 
+     rc = al_traverse(al, off, n, dir, label, &tx);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     switch (dir) {
+     case AL_FORWARD:
+     case AL_FORWARD_SPAN:
+         break;
+     case AL_BACKWARD:
+     case AL_BACKWARD_SPAN:
+         dst += n;
+         break;
+     }
+ 
+     total = 0;
+ 
+     if (dst == NULL) {
+         while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK)
+             total += AL_CHUNK_LEN(view);
+     } else {
+         while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
+             step = AL_CHUNK_LEN(view);
+             switch (dir) {
+             case AL_FORWARD:
+             case AL_FORWARD_SPAN:
+                 memmove(dst, AL_CHUNK_PTR(view, 0), step);
+                 dst   += step;
+                 break;
+             case AL_BACKWARD:
+             case AL_BACKWARD_SPAN:
+                 dst   -= step;
+                 memmove(dst, AL_CHUNK_PTR(view, 0), step);
+                 break;
+             }
+             total += step;
+         }
+     }
+     *lenp = total;
+ 
+     al_traverse_end(al, &tx, 1);
+ 
+     if (rc != AL_ERR_EOF)
+         return AL_RC(rc);
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * full assembly line traversal with data copy to target assembly line
+  *
+  * traversal context is kept on stack (XXX ?)
+  */
+ al_rc_t
+ al_copy(al_t *al, size_t off, size_t n, al_label_t label, al_t *tal)
+ {
+     al_rc_t rc;
+     al_tx_t tx;                /* XXX - private tx structure on stack */
+     al_chunk_t *view;
+     size_t step;
+ 
+     rc = al_traverse(al, off, n, AL_FORWARD, label, &tx);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
+         step = AL_CHUNK_LEN(view);
+         al_append_bytes(tal, AL_CHUNK_PTR(view, 0), step, AL_CHUNK_LABEL(view));
+     }
+ 
+     al_traverse_end(al, &tx, 1);
+ 
+     if (rc != AL_ERR_EOF)
+         return AL_RC(rc);
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * traverse assembly line and retrieve first chunk
+  *
+  * traversal context is kept on stack (XXX ?)
+  */
+ al_rc_t
+ al_firstlabel(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label,
+               al_label_t *labelp)
+ {
+     al_rc_t rc;
+     al_tx_t tx;                /* XXX - private tx structure on stack */
+     al_chunk_t *view;
+ 
+     rc = al_traverse(al, off, n, dir, label, &tx);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     if ((rc = al_traverse_next(al, &tx, &view)) == AL_OK)
+         *labelp = AL_CHUNK_LABEL(view);
+ 
+     al_traverse_end(al, &tx, 1);
+ 
+     return rc;
+ }
+ 
+ /*
+  * traverse assembly line forward and search first chunk
+  * that matches label and continue search until end of
+  * span of same label
+  *
+  * return offset to first byte in *offp
+  * return size of span to last byte in *spanp
+  *
+  * traversal context is kept on stack (XXX ?)
+  */
+ al_rc_t
+ al_spanlabel(al_t *al, size_t off, size_t n, al_label_t label,
+              size_t *offp, size_t *spanp)
+ {
+     al_rc_t rc;
+     al_tx_t tx;                /* XXX - private tx structure on stack */
+     al_chunk_t *view;
+     size_t len, total, start;
+     int have_first;
+ 
+     /*
+      * we need to track absolute traversal position,
+      * so we have to see all chunks.. no filtering
+      * allowed
+      */
+     rc = al_traverse(al, off, n, AL_FORWARD, NULL, &tx);
+     if (rc != AL_OK)
+         return AL_RC(rc);
+ 
+     have_first = 0;
+     start      = 0;
+     total      = 0;
+     while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
+         len = AL_CHUNK_LEN(view);
+         if (AL_SAME_LABEL(view, label)) {
+             if (!have_first) {
+                 start      = total;
+                 have_first = 1;
+             }
+         } else if (have_first)
+             break;
+         total += len;
+     }
+ 
+     al_traverse_end(al, &tx, 1);
+ 
+     if (rc != AL_OK && rc != AL_ERR_EOF)
+         return AL_RC(rc);
+ 
+     if (!have_first)
+         return AL_RC(AL_ERR_EOF);
+ 
+     *offp   = off + start;
+     *spanp  = total - start;
+ 
+     return AL_OK;
+ }
+ 
+ /*
+  * relay macros to caller
+  *
+  * al_bytes      - total number of bytes in assembly line
+  * al_chunk_len  - number of bytes in chunk
+  * al_chunk_span - clip interval (off,off+n( against chunk length
+  * al_chunk_label- return chunk label
+  * al_same_label - check if label matches with chunk label
+  * al_chunk_ptr  - return memory pointer to byte within chunk
+  *
+  * off must be a valid offset within (0,len(
+  */
+ 
+ size_t
+ al_bytes(const al_t *al)
+ {
+     return al->bytes;
+ }
+ 
+ size_t
+ al_chunk_len(al_chunk_t *alc)
+ {
+     return AL_CHUNK_LEN(alc);
+ }
+ 
+ size_t
+ al_chunk_span(al_chunk_t *alc, size_t off, size_t n)
+ {
+     return AL_CHUNK_SPAN(alc, off, n);
+ }
+ 
+ al_label_t
+ al_chunk_label(al_chunk_t *alc)
+ {
+     return AL_CHUNK_LABEL(alc);
+ }
+ 
+ int
+ al_same_label(al_chunk_t *alc, al_label_t label)
+ {
+     return AL_SAME_LABEL(alc, label);
+ }
+ 
+ char *
+ al_chunk_ptr(al_chunk_t *alc, size_t off)
+ {
+     return AL_CHUNK_PTR(alc, off);
+ }
+ 
+ /*
+  * convert error code into human readable form
+  */
+ const char *
+ al_error(al_rc_t rc)
+ {
+     const char *mess;
+ 
+     switch (rc) {
+         case AL_OK:       mess = "Everything Ok"; break;
+         case AL_ERR_ARG:  mess = "Invalid Argument"; break;
+         case AL_ERR_MEM:  mess = "Not Enough Memory"; break;
+         case AL_ERR_EOF:  mess = "End Of Data"; break;
+         case AL_ERR_INT:  mess = "Internal Error"; break;
+         default:          mess = "Invalid Result Code"; break;
+     }
+ 
+     return mess;
+ }
+ 


ossp-pkg/al/al.h -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,89 ----
+ /*
+ **  OSSP al -- Assembly Line
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ **
+ **  This file is part of OSSP al, an abstract datatype of a data buffer
+ **  that can assemble, move and truncate data but avoids actual copying.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ **  SUCH DAMAGE.
+ **
+ **  al.h: assembly line public API definition
+ */
+ 
+ #ifndef __AL_H__
+ #define __AL_H__
+ 
+ typedef enum {
+     AL_OK,
+     AL_ERR_ARG,
+     AL_ERR_MEM,
+     AL_ERR_EOF,
+     AL_ERR_INT
+ } al_rc_t;
+ 
+ struct al_st;
+ typedef struct al_st al_t;
+ 
+ struct al_chunk_st;
+ typedef struct al_chunk_st al_chunk_t;
+ 
+ typedef void *al_label_t;
+ 
+ typedef enum {
+     AL_FORWARD,
+     AL_BACKWARD,
+     AL_FORWARD_SPAN,
+     AL_BACKWARD_SPAN
+ } al_td_t;
+ 
+ struct al_tx_st;
+ typedef struct al_tx_st al_tx_t;
+ 
+ al_rc_t al_create       (al_t **alp);
+ al_rc_t al_destroy      (al_t *al);
+ al_rc_t al_append_bytes (al_t *al, const char *src, size_t n, al_label_t label);
+ al_rc_t al_prepend_bytes(al_t *al, const char *src, size_t n, al_label_t label);
+ al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, al_label_t label, void (*freemem)(char *, size_t, void *), void *u);
+ al_rc_t al_txalloc      (al_t *al, al_tx_t **txp);
+ al_rc_t al_txfree       (al_t *al, al_tx_t *tx);
+ al_rc_t al_traverse     (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_tx_t *tx);
+ al_rc_t al_traverse_next(al_t *al, al_tx_t *tx, al_chunk_t **alcp);
+ al_rc_t al_traverse_end (al_t *al, al_tx_t *tx, int final);
+ al_rc_t al_traverse_cb  (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_rc_t (*cb)(al_chunk_t *, void *), void *u);
+ al_rc_t al_copy         (al_t *al, size_t off, size_t n, al_label_t label, al_t *tal);
+ al_rc_t al_splice       (al_t *al, size_t off, size_t n, al_t *nal, al_t *tal);
+ al_rc_t al_setlabel     (al_t *al, size_t off, size_t n, al_label_t oldlabel, al_label_t newlabel);
+ al_rc_t al_flatten      (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, char *dst, size_t *lenp);
+ al_rc_t al_firstlabel   (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_label_t *labelp);
+ al_rc_t al_spanlabel    (al_t *al, size_t off, size_t n, al_label_t label, size_t *offp, size_t *spanp);
+ 
+ size_t     al_bytes      (const al_t *al);
+ size_t     al_chunk_len  (al_chunk_t *alc);
+ al_label_t al_chunk_label(al_chunk_t *alc);
+ int        al_same_label (al_chunk_t *alc, al_label_t label);
+ size_t     al_chunk_span (al_chunk_t *alc, size_t off, size_t n);
+ char      *al_chunk_ptr  (al_chunk_t *alc, size_t off);
+ 
+ const char *al_error      (al_rc_t rc);
+ 
+ #endif /* __AL_H__ */
+ 


ossp-pkg/al/al.pod -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,474 ----
+ ##
+ ##  OSSP al - Assembly Line
+ ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ ##  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ ##
+ ##  This file is part of OSSP al, an abstract datatype of a data buffer
+ ##  that can assemble, move and truncate data but avoids actual copying.
+ ##
+ ##  Permission to use, copy, modify, and distribute this software for
+ ##  any purpose with or without fee is hereby granted, provided that
+ ##  the above copyright notice and this permission notice appear in all
+ ##  copies.
+ ##
+ ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ ##  SUCH DAMAGE.
+ ##
+ ##  al.pod: assembly line library manual page
+ ##
+ 
+ =pod
+ 
+ =head1 NAME
+ 
+ B<OSSP al> - Assembly Line
+ 
+ =head1 VERSION
+ 
+ B<OSSP al AL_VERSION_STR>
+ 
+ =head1 SYNOPSIS
+ 
+ =over 4
+ 
+ =item B<Abstract Data Types>:
+ 
+ al_rc_t,
+ al_t,
+ al_tx_t,
+ al_td_t,
+ al_chunk_t.
+ 
+ =item B<Assembly Line Operations>:
+ 
+ al_create,
+ al_destroy,
+ al_append_bytes,
+ al_prepend_bytes,
+ al_attach_buffer,
+ al_splice,
+ al_setlabel,
+ al_bytes.
+ 
+ =item B<Traversal Operations>:
+ 
+ al_txalloc,
+ al_txfree,
+ al_traverse,
+ al_traverse_next,
+ al_traverse_end,
+ al_traverse_cb.
+ 
+ =item B<Convenience Operations>:
+ 
+ al_flatten,
+ al_copy,
+ al_firstlabel,
+ al_spanlabel.
+ 
+ =item B<Chunk Operations>:
+ 
+ al_chunk_len,
+ al_chunk_span,
+ al_chunk_label,
+ al_same_label,
+ al_chunk_ptr.
+ 
+ =item B<Error Handling>:
+ 
+ al_error.
+ 
+ =back
+ 
+ =head1 DESCRIPTION
+ 
+ B<OSSP al> defines an abstract type of a data buffer that can
+ assemble, move and truncate data but avoids actual copying.
+ 
+ It provides the following key features:
+ 
+ =over 4
+ 
+ =back
+ 
+ =head1 DATA TYPES
+ 
+ B<OSSP al> uses six data types in its API:
+ 
+ =over 4
+ 
+ =item B<al_rc_t> (Return Code Type)
+ 
+ This is an exported enumerated integer type with the following possible
+ values:
+ 
+  AL_OK       Everything Ok
+  AL_ERR_ARG  Invalid Argument
+  AL_ERR_MEM  Not Enough Memory
+  AL_ERR_EOF  End Of Communication
+  AL_ERR_INT  Internal Error
+ 
+ =item B<al_t> (Assembly Line Type)
+ 
+ This is an opaque data type representing a data buffer.
+ Only pointers to this abstract data type are used in the API.
+ 
+ =item B<al_label_t> (Label Type)
+ 
+ This is an opaque pointer type representing a specific data flavour.
+ You can restrict traversal operations to data that was marked with
+ the specific flavour. Usually you would cast a pointer to the
+ object that maintains the data to B<al_label_t>. You may use
+ NULL as a label but on traversal NULL matches any label.
+ 
+ =item B<al_tx_t> (Traversal Context Type)
+ 
+ This is an opaque data type representing the state of a buffer
+ traversal operation. Only pointers to this abstract data type are
+ used in the API.
+ 
+ =item B<al_td_t> (Traversal Direction Type)
+ 
+ This is an exported enumerated integer type with the following possible
+ values:
+ 
+  AL_FORWARD        traverse assembly line from beginning to end
+  AL_BACKWARD       traverse assembly line from end to beginning
+  AL_FORWARD_SPAN   like AL_FORWARD, but stop when label does not match
+  AL_BACKWARD_SPAN  like AL_BACKWARD, but stop when label does not match
+ 
+ =item B<al_chunk_t> (Chunk Type)
+ 
+ This is an opaque data type representing a chunk of a buffer during
+ a traversal operation. Only pointers to this abstract data type are
+ used in the API. The B<al_chunk_t> type is used to generate a pointer
+ and byte count to access the data in the buffer.
+ 
+ =back
+ 
+ =head1 FUNCTIONS
+ 
+ B<OSSP al> provides a bunch of API functions, all modelled after the
+ same prototype: "C<al_rc_t> C<al_>I<name>C<(al_>[C<chunk>]C<_t *,>
+ ...C<)>". This means every function returns C<al_rc_t> to indicate its
+ success (C<AL_OK>) or failure (C<AL_ERR_XXX>) by returning a return code
+ (the corresponding describing text can be determined by passing this
+ return code to C<al_error>). Each function name starts with the common
+ prefix C<al_> and receives a C<al_t> (or C<al_chunk_t>) object on which
+ it operates as its first argument.
+ 
+ =head2 Assembly Line Operations
+ 
+ =over 4
+ 
+ =item al_rc_t B<al_create>(al_t **I<alp>);
+ 
+ Create an assembly line abstraction object. 
+ The object is stored in I<alp> on success.
+ 
+ Example: C<al_t *al; al_create(&al);>
+ 
+ =item al_rc_t B<al_destroy>(al_t *I<al>);
+ 
+ Destroy an assembly line abstraction object.
+ The object I<al> is invalid after this call succeeded.
+ 
+ Example: C<al_destroy(al);>
+ 
+ =item al_rc_t B<al_append_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>, al_label_t I<label>);
+ 
+ Append I<n> bytes from a storage array at I<src> to the assembly line. The
+ bytes are copied, memory is allocated as necessary. The data is tagged
+ with I<label>.
+ 
+ Example: C<al_append_bytes(al, "Goodbye cruel world\n", 20, NULL);>
+ 
+ =item al_rc_t B<al_prepend_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>, al_label_t I<label>);
+ 
+ Prepend I<n> bytes from a storage array at I<src> to the assembly line. The
+ bytes are copied, memory is allocated as necessary.
+ 
+ Example: C<al_prepend_bytes(al, "Hello world\n", 12, NULL);>
+ 
+ =item al_rc_t B<al_attach_buffer>(al_t *I<al>, char *I<p>, size_t I<n>, al_label_t I<label>, void (*I<freemem>)(char *, size_t, void *), void *I<u>);
+ 
+ Attach the storage array starting at I<p> with size I<n> at the end of
+ the assembly line. Its content becomes part of the assembly line
+ and is subject to assembly line operations. The storage array must stay
+ in scope until it is no longer referenced by the assembly line. When
+ this happens the function I<freemem> is called with the original pointer
+ I<p>, size I<n> and an arbitrary pointer I<u>. Passing a NULL pointer
+ for I<freemem> is valid, then no callback takes place, which might be
+ appropriate for static buffers.
+ 
+ Example: C<char store[] = "foo\n"; al_attach_buffer(al, store, sizeof(store), NULL, NULL, NULL);>
+ 
+ =item al_rc_t B<al_splice>(al_t *I<al>, size_t I<off>, size_t I<n>, al_t *I<nal>, al_t *I<tal>);
+ 
+ This is the general data move operation modelled after the perl operator
+ B<splice>.
+ 
+ I<off> and I<n> are byte counts that define a span of bytes within the
+ source assembly line I<al>. These bytes are moved to the target assembly line
+ I<tal> while the content of the new assembly line I<nal> is moved to the source
+ to replace the selected span.
+ 
+ There are two deviations from the Perl operator to avoid copying:
+ 
+ The move to the target assembly line I<tal> appends the data to its end.
+ The move from the new assembly line I<nal> removes the data from its origin.
+ 
+ The target assembly line I<tal> may be B<NULL>, the data bytes that would
+ be moved to the target are then discarded. This avoids creation
+ and destruction of a dummy target.
+ 
+ The new assembly line I<nal> may be B<NULL>, then nothing is inserted into
+ the source. This avoids creation and destruction of an empty assembly line.
+ 
+ Examples:
+ 
+  al_t *source;
+  al_t *insertion;
+  al_t *buffer;
+ 
+  al_create(&source);
+  al_create(&insertion);
+  al_create(&buffer);
+ 
+  al_append_bytes(source, "Hello world\n", 12, NULL);
+  al_append_bytes(insertion, "Goodbye cruel", 13, NULL);
+ 
+  al_splice(source, 0, 5, insertion, buffer);
+ 
+ The buffer now holds the string "Hello".
+ The source now holds the string "Goodbye cruel world\n".
+ The insertion is now empty.
+ 
+  al_append_bytes(insertion, "brave", 5, NULL);
+  al_splice(source, 8, 5, insertion, NULL);
+ 
+ The source now holds the string "Goodbye brave world\n".
+ The insertion is now empty.
+ 
+  al_append_bytes(insertion, "B", 1, NULL);
+  al_splice(source, 0, 8, NULL, buffer);
+  al_splice(source, 0, 1, insertion, NULL);
+  al_append_bytes(insertion, "\n", 1, NULL);
+  al_splice(buffer, al_bytes(buffer)-1, 1, insertion, NULL),
+ 
+ The source now holds the string "Brave world\n".
+ The buffer now holds the string "HelloGoodbye\n".
+ The insertion is empty.
+ 
+ =item al_rc_t B<al_setlabel>(al_t *I<al>, size_t I<off>, size_t I<n>, al_label_t oldlabel, al_label_t newlabel);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes within the
+ source assembly line I<al>. The bytes within that span that match I<oldlabel>
+ are tagged with I<newlabel>, any existing labels for these bytes are
+ overwritten.
+ 
+ =item size_t B<al_bytes>(const al_t *I<al>);
+ 
+ Returns the number of bytes stored in the assembly line.
+ 
+ Example: C<al_t *al; size_t count; count = al_bytes(al);>
+ 
+ =back
+ 
+ =head2 Traversal Operations
+ 
+ =over 4
+ 
+ =item al_rc_t B<al_txalloc>(al_t *I<al>, al_tx_t **txp);
+ 
+ Allocate a traversal context.
+ 
+ Example: C<al_tx_t *tx; al_txalloc(&tx);>
+ 
+ =item al_rc_t B<al_txfree>(al_t *I<al>, al_tx_t *tx);
+ 
+ Free a traversal context.
+ 
+ Example: C<al_tx_t *tx; al_txfree(tx);>
+ 
+ =item al_rc_t B<al_traverse>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_label_t I<label>, al_tx_t *I<tx>);
+ 
+ Start traversing the assembly line I<al> beginning at byte offset I<off>
+ for up to I<n> bytes in direction I<dir>. If I<label> is not NULL then
+ you will see only data that was tagged with I<label>. The state of the
+ traversal is stored in the supplied context I<tx>.
+ 
+ This function fails when the offset is outside the assembly line bounds.
+ 
+ 
+ =item al_rc_t B<al_traverse_next>(al_t *I<al>, al_tx_t *I<tx>, al_chunk_t **I<alcp>);
+ 
+ Complete a traversal step on the assembly line I<al> using the initialized
+ context I<tx>. In each step a chunk descriptor is filled and stored in
+ I<alcp>. All bytes of the chunk are guaranteed to be stored in a flat
+ array and can be accessed through the chunk operations described below.
+ 
+ The function returns AL_ERR_EOF when it passes the end (or beginning
+ in case of backward traversal) of the assembly line.
+ 
+ =item al_rc_t B<al_traverse_end>(al_t *I<al>, al_tx_t *I<tx>, int final);
+ 
+ Clean up internal state of traversal. If I<final> is zero, you may
+ continue the traversal later by calling B<al_traverse_next>. If
+ I<final> is non-zero you need to start a new traversal. It is
+ mandatory that every traversal that was started is finished by
+ a call to B<al_traverse_end> with I<final> set to a non-zero value.
+ 
+ =item al_rc_t B<al_traverse_cb>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_label_t I<label>, al_rc_t (*I<cb>)(al_chunk_t *, void *), void *u);
+ 
+ B<al_traverse_cb> is a wrapper function that does a full assembly line traversal in
+ a single call. In every step a chunk descriptor is passed to the callback
+ function I<cb> together with a user supplied pointer I<u>. When the
+ callback function returns AL_OK the traversal continues, when it returns
+ AL_ERR_EOF the traversal is aborted and AL_OK is returned to the original
+ caller. Any other return code returned by the callback is passed to the
+ original caller verbatim.
+ 
+ =back
+ 
+ =head2 Convenience Operations
+ 
+ =over 4
+ 
+ =item al_rc_t B<al_flatten>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, char *I<dst>, size_t *I<lenp>);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes with the
+ assembly line I<al>. These bytes are copied to the storage array I<dst>
+ which must be sized appropriately.
+ I<off> must be a valid offset, I<n> must be positive but may exceed
+ the size of the assembly line.
+ The actual number of bytes that is copied to the destination is stored
+ in I<lenp>.
+ If I<dst> is NULL then no data is copied but the number of bytes is
+ still counted in I<lenp>. This can be used to precalculate the size
+ of the needed storage array by passing an arbitrary high maximum size
+ as I<n>.
+ If I<dir> denotes a backwards traversal the storage array is filled
+ from its end.
+ 
+ Example:
+ 
+  al_t *al;
+  char buffer[42];
+  size_t actual;
+ 
+  al_flatten(al, 500, 42, AL_FORWARD, buffer, &actual);
+ 
+ =item al_rc_t B<al_copy>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_t *I<tal>);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes within the
+ assembly line I<al>. These bytes are appended to the target assembly line I<tal>,
+ memory is allocated as necessary.
+ I<off> must be a valid offset, I<n> must be positive but may exceed
+ the size of the assembly line.
+ 
+ Example:
+ 
+  al_t *al;
+  al_t *tal;
+ 
+  al_create(&tal);
+  al_flatten(al, 500, 42, tal);
+ 
+ =item al_rc_t B<al_firstlabel>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_label_t *I<labelp>);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes within the
+ assembly line I<al>. The label that was attached to the first byte
+ within the defined span is stored in I<labelp>, otherwise B<al_firstlabel>
+ returns an error.
+ 
+ =item al_rc_t B<al_spanlabel>(al_t *I<al>, size_t I<off>, size_t I<n>, al_label_t *I<label>, size_t *<offp>, size_t *<spanp>);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes within the
+ assembly line I<al>. This span is searched for data tagged with the I<label>.
+ The absolute byte offset of the first byte matching the label and the
+ length of the span of the same label is returned in I<offp> and I<spanp>
+ respectively.
+ 
+ =back
+ 
+ =head2 Chunk Operations
+ 
+ =over 4
+ 
+ =item size_t B<al_chunk_len>(al_chunk_t *I<alc>);
+ 
+ Returns the number of bytes in a chunk.
+ 
+ =item size_t B<al_chunk_span>(al_chunk_t *I<alc>, size_t I<off>, size_t I<n>);
+ 
+ I<off> and I<n> are byte counts that define a span of bytes.
+ B<al_chunk_span> returns the number of bytes that are stored in the chunk.
+ I<off> must be a valid offset, I<n> must be positive but may exceed
+ the size of the chunk.
+ 
+ =item al_label_t B<al_chunk_label>(al_chunk_t *I<alc>);
+ 
+ Return the label that was used to tag the data in I<alc>. This can
+ be NULL.
+ 
+ =item int B<al_same_label>(al_chunk_t *I<alc>, al_label_t *I<label>);
+ 
+ Return true if I<label> matches the label that was used to tag the data
+ in I<alc>. A NULL I<label> matches everything.
+ 
+ =item char *B<al_chunk_ptr>(al_chunk_t *I<alc>, size_t I<off>);
+ 
+ Returns the pointer to the byte at offset I<off> within the chunk I<alc>.
+ I<off> must be positive and must not exceed the size of the chunk.
+ Since all bytes of the chunk are guaranteed to be stored in a flat
+ array the pointer can be used to reference every byte within the chunk.
+ 
+ Example:
+ 
+  al_chunk_t *alc;
+  char *start, *end;
+ 
+  start = al_chunk_ptr(alc, 0);
+  end   = start + al_chunk_len(alc) - 1;
+ 
+ =back
+ 
+ =head2 Error Handling
+ 
+ =over 4
+ 
+ =item const char *B<al_error>(al_rc_t I<rv>);
+ 
+ Retrieve a string that describes the return code I<rv> in english.
+ 
+ =back
+ 
+ =head1 SEE ALSO
+ 
+ =head1 HISTORY
+ 
+ B<OSSP al> was invented in October 2002 by Michael van Elst
+ E<lt>mlelstv@dev.de.cw.netE<gt> under contract with Cable & Wireless
+ Germany E<lt>http://www.cw.com/deE<gt> for use inside the OSSP project
+ E<lt>http://www.ossp.org/E<gt>.
+ 
+ =head1 AUTHORS
+ 
+  Michael van Elst
+  mlelstv@dev.de.cw.net
+ 
+ =cut
+ 


ossp-pkg/al/al_test.c -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,313 ----
+ /*
+ **  OSSP al - Assembly Line
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ **
+ **  This file is part of OSSP al, an abstract datatype of a data buffer
+ **  that can assemble, move and truncate data but avoids actual copying.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ **  SUCH DAMAGE.
+ **
+ **  al_test.c: assembly line library test suite
+ */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <time.h>
+ #include <sys/utsname.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ 
+ #include "ts.h"
+ #include "al.h"
+ 
+ static char label, label2, label3;
+ #define LABEL ((al_label_t)&label)
+ #define LABEL2 ((al_label_t)&label2)
+ #define LABEL3 ((al_label_t)&label3)
+ 
+ #define S(s) s, strlen(s)
+ #define RCHK(name, rc, rc0) \
+     if (rc != rc0) \
+         ts_test_fail(TS_CTX, "%s -> %d[%s] (expected %d[%s])\n", \
+             rc, al_error(al), rc0, al_error(rc0))
+ #define CCHK(name, al) \
+     do { \
+         size_t good, bad; \
+         if (chklen(al, &good, &bad)) { \
+             ts_test_fail(TS_CTX, "%s -> corrupted length %d (expected %d)\n", \
+                 good, bad); \
+         } \
+     } while (0)
+ 
+ static const char *fill(char *p, int n)
+ {
+     static char buf[4 * 80 + 1];
+     int max = sizeof(buf)-5;
+     int k;
+ 
+     k=0;
+     while (n > 0 && k < max) {
+         if (isprint(*p)) {
+             buf[k] = *p;
+             k += 1;
+         } else {
+             sprintf(buf+k,"<%2.2x>",*p);
+             k += 4;
+         }
+         ++p;
+         --n;
+     }
+     buf[k] = '\0';
+ 
+     return (const char *)buf;
+ }
+ 
+ static int checklen(al_t *al, size_t *goodp, size_t *badp)
+ {
+     al_tx_t *tx;
+     al_chunk_t *cur;
+     size_t total, total2;
+ 
+     total = 0;
+ 
+     al_txalloc(al, &tx);
+     al_traverse(al, 0, al_bytes(al), AL_FORWARD, NULL, tx);
+     while (al_traverse_next(al, tx, &cur) == AL_OK)
+         total += al_chunk_len(cur);
+     al_traverse_end(al, tx, 1);
+     al_txfree(al, tx);
+ 
+     total2 = al_bytes(al);
+ 
+     if (total != total2) {
+         *goodp = total;
+         *badp  = total2;
+         return -1;
+     }
+ 
+     return 0;
+ }
+ 
+ 
+ /* test: data copy */
+ TS_TEST(test_al_data)
+ {
+     al_rc_t rc;
+     al_t *al;
+ 
+     rc = al_create(&al);
+     RCHK('al_create',rc,AL_OK);
+     rc = al_append_bytes(al, S("Hello world\n"));
+     RCHK('al_append_bytes',rc,AL_OK);
+     CCHK('al_append_bytes', al);
+     rc = al_destroy(&al);
+     RCHK('al_destroy',rc,AL_OK);
+ }
+ 
+ /* test: splicing */
+ TS_TEST(test_al_splice)
+ {
+     al_rc_t rc;
+     al_t *src, *ins, *dst;
+     int i;
+ 
+     rc = al_create(&src);
+     RCHK('al_create(&src)',rc,AL_OK);
+     rc = al_create(&ins);
+     RCHK('al_create(&ins)',rc,AL_OK);
+     rc = al_create(&dst);
+     RCHK('al_create(&dst)',rc,AL_OK);
+ 
+     for (i=0; i<500; ++i) {
+         rc = al_append_bytes(src, S("Huhu world\n"), LABEL);
+         RCHK('al_append_bytes(src)',rc,AL_OK);
+     }
+     rc = al_append_bytes(src, S("Goodbye world\n"), LABEL);
+     RCHK('al_append_bytes(src)',rc,AL_OK);
+     CCHK('al_append_bytes(src)',src);
+     rc = al_append_bytes(src, S("Goodbye world\n"), LABEL2);
+     RCHK('al_append_bytes(src)',rc,AL_OK);
+     CCHK('al_append_bytes(src)',src);
+     rc = al_prepend_bytes(src, S("Hello world\n"), LABEL2);
+     RCHK('al_prepend_bytes(src)',rc,AL_OK);
+     CCHK('al_prepend_bytes(src)',src);
+     rc = al_prepend_bytes(src, S("Hello world\n"), LABEL);
+     RCHK('al_prepend_bytes(src)',rc,AL_OK);
+     CCHK('al_prepend_bytes(src)',src);
+ 
+     rc = al_prepend_bytes(ins, S("KICK "), LABEL3);
+     RCHK('al_prepend_bytes(ins)',rc,AL_OK);
+     CCHK('al_prepend_bytes(ins)',ins);
+     rc = al_append_bytes(ins, S("ME\n"), LABEL3);
+     RCHK('al_append_bytes(ins)',rc,AL_OK);
+     CCHK('al_append_bytes(ins)',ins);
+ 
+     rc = al_splice(src, 4, 80, ins, dst);
+     RCHK('al_splice',rc,AL_OK);
+     CCHK('al_splice(src)',src);
+     CCHK('al_splice(ins)',ins);
+     CCHK('al_splice(dst)',dst);
+ 
+     rc = al_destroy(dst);
+     RCHK('al_destroy(dst)',rc,AL_OK);
+     rc = al_destroy(ins);
+     RCHK('al_destroy(ins)',rc,AL_OK);
+     rc = al_destroy(src);
+     RCHK('al_destroy(src)',rc,AL_OK);
+ }
+ 
+ /* test: labelling */
+ TS_TEST(test_al_label)
+ {
+     al_rc_t rc;
+     al_t *al;
+ 
+     rc = al_create(&al);
+     RCHK('al_create',rc,AL_OK);
+     rc = al_append_bytes(&al, S("Hello world\n"), LABEL);
+     RCHK('al_create',rc,AL_OK);
+ 
+     rc = al_setlabel(al, 7, 2, NULL, LABEL3);
+     RCHK('al_setlabel',rc,AL_OK);
+     CCHK('al_setlabel',al);
+     rc = al_setlabel(al, 5, 9, NULL, LABEL2);
+     CCHK('al_setlabel',al);
+ 
+     rc = al_destroy(al);
+     RCHK('al_destroy(al)',rc,AL_OK);
+ }
+ 
+ /* test: attach */
+ static char *reclaim_ptr = NULL;
+ static size_t *reclaim_size = 0;
+ static void *reclaim_u = NULL;
+ static int reclaim_count = 0;
+ static void reclaim(char *p, size_t n, void *u)
+ {
+     ++reclaim_count;
+ 
+     if (reclaim_ptr != NULL ||
+         reclaim_size != 0 ||
+         reclaim_u != NULL)
+         return;
+ 
+     reclaim_ptr  = p;
+     reclaim_size = n;
+     reclaim_u    = u;
+ }
+ static const char *reclaim_result(char *p, size_t n, void *u)
+ {
+     if (reclaim_count == 0)
+         return "reclaim never called";
+     if (reclaim_count > 0)
+         return "repeated call";
+ 
+     if (p != reclaim_ptr ||
+         n != reclaim_size ||
+         u != reclaim_u)
+         return "bad data for free";
+ 
+     return NULL;
+ }
+ 
+ TS_TEST(test_al_attach)
+ {
+     al_rc_t rc;
+     al_t *al;
+     char baf[] = "Mittendrin\n";
+     char *context = "CONTEXT";
+     char *mess;
+ 
+     rc = al_create(&al);
+     RCHK('al_create', rc, AL_OK);
+     rc = al_append_bytes(al, S("Hello world\n"), NULL);
+     RCHK('al_append_bytes', rc, AL_OK);
+     CCHK('al_append_bytes', al);
+     rc = al_attach_buffer(al, S(baf), NULL, reclaim, context);
+     RCHK('al_attach_buffer', rc, AL_OK);
+     CCHK('al_attach_buffer', al);
+     rc = al_append_bytes(al, S("Goodbye world\n"), NULL);
+     RCHK('al_append_bytes', rc, AL_OK);
+     CCHK('al_append_bytes', al);
+     rc = al_destroy(&al);
+     RCHK('al_destroy', rc, AL_OK);
+ 
+     mess = reclaim_result(S(baf), context);
+     if (mess != NULL)
+         ts_test_fail(TS_CTX,"buffer reclaim failed: %s\n",mess);
+ }
+ 
+ /* test: exception handling */
+ #ifdef WITH_EX
+ #include "ex.h"
+ TS_TEST(test_sa_ex)
+ {
+     volatile al_t *al;
+     ex_t ex;
+     int caught;
+ 
+     ts_test_check(TS_CTX, "exception handling");
+     caught = 0;
+     ex_try {
+         al = NULL;
+         al_create(&al);
+         al_append_bytes(&al, S("DUMMYDUMMY"), NULL);
+         al_splice(al, 50, 1, NULL, NULL);
+     }
+     ex_cleanup {
+         if (al != NULL) al_destroy(&al);
+     }
+     ex_catch (ex) {
+         if ((sa_rc_t)ex.ex_value != AL_ERR_EOF)
+             ts_test_fail(TS_CTX, "unexpected exception: %d\n", (al_rc_t)ex.ex_value);
+         caught = 1;
+     }
+     if (!caught)
+         ts_test_fail(TS_CTX, "expected exception not caught\n");
+ }
+ #endif
+ 
+ int main(int argc, char *argv[])
+ {
+     ts_suite_t *ts;
+     int n;
+ 
+     ts = ts_suite_new("OSSP al (Assembly Line)");
+     ts_suite_test(ts, test_al_data,   "assembly line data copying");
+     ts_suite_test(ts, test_al_splice, "assembly line splicing");
+     ts_suite_test(ts, test_al_label,  "assembly line labelling");
+     ts_suite_test(ts, test_al_attach, "assembly line buffer attach");
+ #ifdef WITH_EX
+     ts_suite_test(ts, test_al_ex,     "exception handling");
+ #endif
+     n = ts_suite_run(ts);
+     ts_suite_free(ts);
+     return n;
+ }
+ 


ossp-pkg/al/configure.ac -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,55 ----
+ dnl ##
+ dnl ##  OSSP al - Assembly Line
+ dnl ##  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ dnl ##  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ dnl ##  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ dnl ##  Copyright (c) 2002 Michael van Elst <mlelstv@dev.de.cw.net>
+ dnl ##
+ dnl ##  This file is part of OSSP al, an abstract datatype of a data buffer
+ dnl ##  that can assemble, move and truncate data but avoids actual copying.
+ dnl ##
+ dnl ##  Permission to use, copy, modify, and distribute this software for
+ dnl ##  any purpose with or without fee is hereby granted, provided that
+ dnl ##  the above copyright notice and this permission notice appear in all
+ dnl ##  copies.
+ dnl ##
+ dnl ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ dnl ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ dnl ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ dnl ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ dnl ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ dnl ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ dnl ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ dnl ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ dnl ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ dnl ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ dnl ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ dnl ##  SUCH DAMAGE.
+ dnl ##
+ dnl ##  configure.ac: GNU Autoconf source script
+ dnl ##
+ 
+ AC_PREREQ(2.53)
+ AC_INIT
+ AL_VERSION_STR=`./shtool version -l txt -d long VERSION`
+ ./shtool echo -e "Configuring %BOSSP al%b (Assembly Line), version %B${AL_VERSION_STR}%b"
+ AC_SUBST(AL_VERSION_STR)
+ 
+ AC_PROG_MAKE_SET
+ AC_PROG_CC
+ AC_CHECK_DEBUGGING
+ 
+ sinclude(libtool.m4)
+ AC_PROG_LIBTOOL
+ 
+ sinclude(al.ac)
+ AL_CHECK_ALL
+ 
+ AC_CHECK_EXTLIB([OSSP ex], ex, __ex_ctx, ex.h,
+                 [AC_DEFINE(WITH_EX, 1, [Define to 1 if building with OSSP ex])])
+ 
+ AC_CONFIG_HEADERS(config.h)
+ AC_CONFIG_FILES([Makefile al-config])
+ AC_CONFIG_COMMANDS([adjustment], [chmod a+x al-config])
+ AC_OUTPUT
+ 


ossp-pkg/al/devtool -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,47 ----
+ #!/bin/sh
+ ##
+ ##  devtool -- Development Tool
+ ##  Copyright (c) 2001 Ralf S. Engelschall <rse@engelschall.com> 
+ ##
+ 
+ if [ $# -eq 0 ]; then
+     echo "devtool:USAGE: devtool <command> [<arg> ...]" 1>&2
+     exit 1
+ fi
+ 
+ cmd="$1"
+ shift
+ 
+ devtoolfunc="./devtool.func"
+ 
+ if [ ! -f devtool.conf ]; then
+     echo "devtool:ERROR: no devtool.conf in current directory" 1>&2
+     exit 1
+ fi
+ 
+ cmdline=`grep "^%$cmd" devtool.conf`
+ if [ ".$cmdline" = . ]; then
+     echo "devtool:ERROR: command $cmd not found in devtool.conf" 1>&2
+     exit 1
+ fi
+ 
+ if [ ".$TMPDIR" != . ]; then
+     tmpdir="$TMPDIR"
+ elif [ ".$TEMPDIR" != . ]; then
+     tmpdir="$TEMPDIR"
+ else
+     tmpdir="/tmp"
+ fi
+ tmpfile="$tmpdir/rc.$$.tmp"
+ 
+ rm -f $tmpfile
+ touch $tmpfile
+ echo ". $devtoolfunc" >>$tmpfile
+ ( sed <devtool.conf -e "1,/^%common/d" -e '/^%.*/,$d'
+   sed <devtool.conf -e "1,/^%$cmd/d" -e '/^%.*/,$d' ) |\
+ sed -e 's;\([  ]\)@\([a-zA-Z_][a-zA-Z0-9_]*\);\1devtool_\2;' >>$tmpfile
+ 
+ sh $tmpfile "$@"
+ 
+ rm -f $tmpfile >/dev/null 2>&1 || true
+ 


ossp-pkg/al/devtool.conf -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,61 ----
+ ##
+ ##  devtool.conf -- Development Tool Configuration
+ ##
+ 
+ %autogen
+     @autogen shtool   1.6.2 "1.6.*" all
+     @autogen libtool  1.4.3 "1.4*"
+     @autogen autoconf 2.57  "2.5[3-9]*"
+ 
+ %autoclean
+     @autoclean shtool
+     @autoclean libtool
+     @autoclean autoconf
+ 
+ %configure
+     ./configure \
+         --prefix=/tmp/al \
+         --disable-shared \
+         --enable-debug \
+         "$@"
+ 
+ %version
+     ./shtool version -l txt -n "OSSP al" -e VERSION
+     V=`./shtool version -l txt -d long VERSION`
+     sed -e "s/Version .*(.*)/Version $V/g" <README >README.n
+     mv README.n README
+ 
+ %dist
+     rm -f sa-*.tar.gz
+     ./devtool autoclean
+     ./devtool autogen
+     ./configure
+     make clean all man
+     make distclean
+     ./shtool fixperm -v .
+     V=`./shtool version -l txt -d short VERSION`
+     ./shtool tarball -o al-${V}.tar.gz -d al-${V} -u gnu -g al \
+                      -e 'CVS,\.cvsignore,\.[ao]$,^\.,devtool*' -c 'gzip --best' .
+     ls -l al-${V}.tar.gz
+     gunzip <al-${V}.tar.gz | tar tvf - | head -10; echo "[...]"
+     gunzip <al-${V}.tar.gz | tar tvf - | tail -10
+ 
+ %snap
+     rm -f al-*.tar.gz
+     ./devtool autoclean
+     ./devtool autogen
+     ./configure
+     make clean all man
+     make distclean
+     ./shtool fixperm -v .
+     D=`date '+%Y%m%d'`
+     ./shtool tarball -o al-SNAP-${D}.tar.gz -d al-SNAP-${D} -u gnu -g al \
+                      -e 'CVS,\.cvsignore,\.[ao]$,^\.,devtool*' -c 'gzip --best' .
+     ls -l al-SNAP-${D}.tar.gz
+     gunzip <al-SNAP-${D}.tar.gz | tar tvf - | head -10; echo "[...]"
+     gunzip <al-SNAP-${D}.tar.gz | tar tvf - | tail -10
+ 
+ %release
+     echo "+++ copying to ftp://ftp.ossp.org/pkg/lib/al/"
+     scp al-*.tar.gz master.ossp.org:/e/ossp/ftp/pkg/lib/al/
+ 


ossp-pkg/al/devtool.func -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,73 ----
+ ##
+ ##  devtool.func -- Development Tool Functions
+ ##  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com> 
+ ##
+ 
+ devtool_require () {
+     t="$1"; o="$2"; p="$3"; e="$4"; a="$5"
+     v=`($t $o | head -1 | awk "{ print \\\$$p; }") 2>/dev/null`
+     if [ ".$v" = . ]; then
+         echo "devtool:ERROR: unable to determine version of $t" 1>&2
+         exit 1
+     fi
+     case "$v" in
+         $e )
+             ;;
+         $a )
+             echo "devtool:WARNING: $t version $v still accepted, although expected $e." 1>&2
+             ;;
+         * )
+             echo "devtool:ERROR: $t version $e expected, but found $v." 1>&2
+             exit 1
+             ;;
+     esac
+     echo "$v"
+ }
+ 
+ devtool_autogen () {
+     tool=$1
+     shift
+     case $tool in
+         autoconf )
+             autoconf_version=`devtool_require autoconf --version 4 "$1" "$2"`
+             echo "generating (GNU Autoconf $autoconf_version): configure config.h.in"
+             autoconf
+             autoheader 2>&1 | grep -v "is unchanged"
+             rm -rf autom4te.cache >/dev/null 2>&1
+             ;;
+         libtool )
+             libtoolize_version=`devtool_require libtoolize --version 4 "$1" "$2"`
+             echo "generating (GNU Libtool $libtoolize_version): ltmain.sh, libtool.m4, config.guess, config.sub"
+             libtoolize --force --copy >/dev/null 2>&1
+             cp `libtoolize --force --copy --dry-run | grep "add the contents of" |\
+                 sed -e 's;^[^\`]*\`;;' -e "s;'.*;;"` libtool.m4
+             ;;
+         shtool )
+             shtoolize_version=`devtool_require shtoolize -v 3 "$1" "$2"`
+             echo "generating (GNU Shtool $shtoolize_version): shtool"
+             shift
+             shift
+             shtoolize -q "$@"
+             ;;
+     esac
+ }
+ 
+ devtool_autoclean () {
+     tool=$1
+     shift
+     case $tool in
+         autoconf )
+             echo "removing: configure config.h.in"
+             rm -f configure config.h.in
+             ;;
+         libtool )
+             echo "removing: ltmain.sh libtool.m4 config.guess config.sub"
+             rm -f ltmain.sh libtool.m4 config.guess config.sub
+             ;;
+         shtool )
+             echo "removing: shtool"
+             rm -f shtool
+             ;;
+     esac
+ }
+ 


ossp-pkg/al/ts.c -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,468 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a small test suite library which
+ **  can be found at http://www.ossp.org/pkg/ts/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ **  SUCH DAMAGE.
+ **
+ **  ts.c: test suite library
+ */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdarg.h>
+ 
+ #include "config.h"
+ #if defined(HAVE_DMALLOC_H) && defined(WITH_DMALLOC)
+ #include "dmalloc.h"
+ #endif
+ 
+ #include "ts.h"
+ 
+ /* embedded ring data structure library */
+ #define RING_ENTRY(elem) \
+     struct { elem *next; elem *prev; }
+ #define RING_HEAD(elem) \
+     struct { elem *next; elem *prev; }
+ #define RING_SENTINEL(hp, elem, link) \
+     (elem *)((char *)(hp) - ((size_t)(&((elem *)0)->link)))
+ #define RING_FIRST(hp) \
+     (hp)->next
+ #define RING_LAST(hp) \
+     (hp)->prev
+ #define RING_NEXT(ep, link) \
+     (ep)->link.next
+ #define RING_PREV(ep, link) \
+     (ep)->link.prev
+ #define RING_INIT(hp, elem, link) \
+     do { RING_FIRST((hp)) = RING_SENTINEL((hp), elem, link); \
+          RING_LAST((hp))  = RING_SENTINEL((hp), elem, link); } while (0)
+ #define RING_EMPTY(hp, elem, link) \
+     (RING_FIRST((hp)) == RING_SENTINEL((hp), elem, link))
+ #define RING_ELEM_INIT(ep, link) \
+     do { RING_NEXT((ep), link) = (ep); \
+          RING_PREV((ep), link) = (ep); } while (0)
+ #define RING_SPLICE_BEFORE(lep, ep1, epN, link) \
+     do { RING_NEXT((epN), link) = (lep); \
+          RING_PREV((ep1), link) = RING_PREV((lep), link); \
+          RING_NEXT(RING_PREV((lep), link), link) = (ep1); \
+          RING_PREV((lep), link) = (epN); } while (0)
+ #define RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
+     RING_SPLICE_BEFORE(RING_SENTINEL((hp), elem, link), (ep1), (epN), link)
+ #define RING_INSERT_TAIL(hp, nep, elem, link) \
+     RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
+ #define RING_FOREACH(ep, hp, elem, link) \
+     for ((ep)  = RING_FIRST((hp)); \
+          (ep) != RING_SENTINEL((hp), elem, link); \
+          (ep)  = RING_NEXT((ep), link))
+ 
+ /* test suite test log */
+ struct tstl_st;
+ typedef struct tstl_st tstl_t;
+ struct tstl_st {
+     RING_ENTRY(tstl_t) next;
+     char              *text;
+     const char        *file;
+     int                line;
+ };
+ 
+ /* test suite test check */
+ struct tstc_st;
+ typedef struct tstc_st tstc_t;
+ struct tstc_st {
+     RING_ENTRY(tstc_t) next;
+     char              *title;
+     int                failed;
+     const char        *file;
+     int                line;
+     RING_HEAD(tstl_t)  logs;
+ };
+ 
+ /* test suite test */
+ struct ts_test_st {
+     RING_ENTRY(ts_test_t)  next;
+     char              *title;
+     ts_test_cb_t         func;
+     const char        *file;
+     int                line;
+     RING_HEAD(tstc_t)  checks;
+ };
+ 
+ /* test suite */
+ struct ts_suite_st {
+     char              *title;
+     RING_HEAD(ts_test_t)   tests;
+ };
+ 
+ /* minimal output-independent vprintf(3) variant which supports %{c,s,d,%} only */
+ static int ts_suite_mvxprintf(char *buffer, size_t bufsize, const char *format, va_list ap)
+ {
+     /* sufficient integer buffer: <available-bits> x log_10(2) + safety */
+     char ibuf[((sizeof(int)*8)/3)+10]; 
+     char *cp;
+     char c;
+     int d;
+     int n;
+     int bytes;
+ 
+     if (format == NULL)
+         return -1;
+     bytes = 0;
+     while (*format != '\0') {
+         if (*format == '%') {
+             c = *(format+1);
+             if (c == '%') {
+                 /* expand "%%" */
+                 cp = &c;
+                 n = sizeof(char);
+             }
+             else if (c == 'c') {
+                 /* expand "%c" */
+                 c = (char)va_arg(ap, int);
+                 cp = &c;
+                 n = sizeof(char);
+             }
+             else if (c == 's') {
+                 /* expand "%s" */
+                 if ((cp = (char *)va_arg(ap, char *)) == NULL)
+                     cp = "(null)";
+                 n = strlen(cp);
+             }
+             else if (c == 'd') {
+                 /* expand "%d" */
+                 d = (int)va_arg(ap, int);
+ #ifdef HAVE_SNPRINTF
+                 snprintf(ibuf, sizeof(ibuf), "%d", d); /* explicitly secure */
+ #else
+                 sprintf(ibuf, "%d", d);                /* implicitly secure */
+ #endif
+                 cp = ibuf;
+                 n = strlen(cp);
+             }
+             else {
+                 /* any other "%X" */
+                 cp = (char *)format;
+                 n  = 2;
+             }
+             format += 2;
+         }
+         else {
+             /* plain text */
+             cp = (char *)format;
+             if ((format = strchr(cp, '%')) == NULL)
+                 format = strchr(cp, '\0');
+             n = format - cp;
+         }
+         /* perform output operation */
+         if (buffer != NULL) {
+             if (n > bufsize)
+                 return -1;
+             memcpy(buffer, cp, n);
+             buffer  += n;
+             bufsize -= n;
+         }
+         bytes += n;
+     }
+     /* nul-terminate output */
+     if (buffer != NULL) {
+         if (bufsize == 0)
+             return -1;
+         *buffer = '\0';
+     }
+     return bytes;
+ }
+ 
+ /* minimal vasprintf(3) variant which supports %{c,s,d} only */
+ static char *ts_suite_mvasprintf(const char *format, va_list ap)
+ {
+     char *buffer;
+     int n;
+     va_list ap2;
+ 
+     if (format == NULL)
+         return NULL;
+     ap2 = ap;
+     if ((n = ts_suite_mvxprintf(NULL, 0, format, ap)) == -1)
+         return NULL;
+     if ((buffer = (char *)malloc(n+1)) == NULL)
+         return NULL;
+     ts_suite_mvxprintf(buffer, n+1, format, ap2);
+     return buffer;
+ }
+ 
+ /* minimal asprintf(3) variant which supports %{c,s,d} only */
+ static char *ts_suite_masprintf(const char *format, ...)
+ {
+     va_list ap;
+     char *cp;
+ 
+     va_start(ap, format);
+     cp = ts_suite_mvasprintf(format, ap);
+     va_end(ap);
+     return cp;
+ }
+ 
+ /* create test suite */
+ ts_suite_t *ts_suite_new(const char *fmt, ...)
+ {
+     ts_suite_t *ts;
+     va_list ap;
+ 
+     if ((ts = (ts_suite_t *)malloc(sizeof(ts_suite_t))) == NULL)
+         return NULL;
+     va_start(ap, fmt);
+     ts->title = ts_suite_mvasprintf(fmt, ap);
+     RING_INIT(&ts->tests, ts_test_t, next);
+     va_end(ap);
+     return ts;
+ }
+ 
+ /* add test case to test suite */
+ void ts_suite_test(ts_suite_t *ts, ts_test_cb_t func, const char *fmt, ...)
+ {
+     ts_test_t *tst;
+     va_list ap;
+ 
+     if (ts == NULL || func == NULL || fmt == NULL)
+         return;
+     if ((tst = (ts_test_t *)malloc(sizeof(ts_test_t))) == NULL)
+         return;
+     RING_ELEM_INIT(tst, next);
+     va_start(ap, fmt);
+     tst->title = ts_suite_mvasprintf(fmt, ap);
+     va_end(ap);
+     tst->func = func;
+     tst->file = NULL;
+     tst->line = 0;
+     RING_INIT(&tst->checks, tstc_t, next);
+     RING_INSERT_TAIL(&ts->tests, tst, ts_test_t, next);
+     return;
+ }
+ 
+ /* run test suite */
+ int ts_suite_run(ts_suite_t *ts)
+ {
+     ts_test_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+     int total_tests, total_tests_suite_failed;
+     int total_checks, total_checks_failed;
+     int test_checks, test_checks_failed;
+     const char *file;
+     int line;
+     char *cp;
+ 
+     if (ts == NULL)
+         return 0;
+ 
+     /* init total counters */
+     total_tests         = 0;
+     total_tests_suite_failed  = 0;
+     total_checks        = 0;
+     total_checks_failed = 0;
+ 
+     fprintf(stdout, "\n");
+     fprintf(stdout, " Test Suite: %s\n", ts->title);
+     fprintf(stdout, " __________________________________________________________________\n");
+     fprintf(stdout, "\n");
+     fflush(stdout);
+ 
+     /* iterate through all test cases */
+     RING_FOREACH(tst, &ts->tests, ts_test_t, next) {
+         cp = ts_suite_masprintf(" Test: %s ........................................"
+                                 "........................................", tst->title);
+         cp[60] = '\0';
+         fprintf(stdout, "%s", cp);
+         free(cp);
+         fflush(stdout);
+ 
+         /* init test case counters */
+         test_checks        = 0;
+         test_checks_failed = 0;
+ 
+         /* run the test case function */
+         tst->func(tst);
+ 
+         /* iterate through all performed checks to determine status */
+         RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+             test_checks++;
+             if (tstc->failed)
+                 test_checks_failed++;
+         }
+ 
+         if (test_checks_failed > 0) {
+             /* some checks failed, so do detailed reporting of test case */
+             fprintf(stdout, " FAILED\n");
+             fprintf(stdout, "       Ops, %d/%d checks failed! Detailed report follows:\n",
+                     test_checks_failed, test_checks);
+             RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+                 file = (tstc->file != NULL ? tstc->file : tst->file);
+                 line = (tstc->line != 0    ? tstc->line : tst->line);
+                 if (file != NULL)
+                     fprintf(stdout, "       Check: %s [%s:%d]\n", tstc->title, file, line);
+                 else
+                     fprintf(stdout, "       Check: %s\n", tstc->title);
+                 RING_FOREACH(tstl, &tstc->logs, tstl_t, next) {
+                     file = (tstl->file != NULL ? tstl->file : file);
+                     line = (tstl->line != 0    ? tstl->line : line);
+                     if (file != NULL)
+                         fprintf(stdout, "              Log: %s [%s:%d]\n", tstl->text, file, line);
+                     else
+                         fprintf(stdout, "              Log: %s\n", tstl->text);
+                 }
+             }
+         }
+         else {
+             /* test case ran successfully */
+             fprintf(stdout, ".... OK\n");
+         }
+         fflush(stdout);
+ 
+         /* accumulate counters */
+         total_checks += test_checks;
+         total_tests++;
+         if (test_checks_failed > 0) {
+             total_checks_failed += test_checks_failed;
+             total_tests_suite_failed++;
+         }
+     }
+ 
+     /* print test suite summary */
+     fprintf(stdout, " __________________________________________________________________\n");
+     fprintf(stdout, "\n");
+     fprintf(stdout, " Test Summary: %d tests (%d ok, %d failed), %d checks (%d ok, %d failed)\n", 
+             total_tests, (total_tests - total_tests_suite_failed), total_tests_suite_failed, 
+             total_checks, (total_checks - total_checks_failed), total_checks_failed); 
+     if (total_tests_suite_failed > 0)
+         fprintf(stdout, " Test Suite: FAILED\n");
+     else
+         fprintf(stdout, " Test Suite: OK\n");
+     fprintf(stdout, "\n");
+     fflush(stdout);
+ 
+     return total_checks_failed;
+ }
+ 
+ /* destroy test suite */
+ void ts_suite_free(ts_suite_t *ts)
+ {
+     ts_test_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+ 
+     if (ts == NULL)
+         return;
+     RING_FOREACH(tst, &ts->tests, ts_test_t, next) {
+         RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+             RING_FOREACH(tstl, &tstc->logs, tstl_t, next) {
+                 free(tstl->text);
+             }
+             free(tstc->title);
+             free(tstc);
+         }
+         free(tst->title);
+         free(tst);
+     }
+     free(ts->title);
+     free(ts);
+     return;
+ }
+ 
+ /* annotate test case with file name and line number */
+ ts_test_t *ts_test_ctx(ts_test_t *tst, const char *file, int line)
+ {
+     if (tst != NULL && file != NULL) {
+         tst->file = file;
+         tst->line = line;
+     }
+     return tst;
+ }
+ 
+ /* annotate test case with check */
+ void ts_test_check(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstc = (tstc_t *)malloc(sizeof(tstc_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     RING_ELEM_INIT(tstc, next);
+     tstc->title = ts_suite_mvasprintf(fmt, ap);
+     tstc->failed = 0;
+     tstc->file = tst->file;
+     tstc->line = tst->line;
+     RING_INIT(&tstc->logs, tstl_t, next);
+     RING_INSERT_TAIL(&tst->checks, tstc, tstc_t, next);
+     va_end(ap);
+     return;
+ }
+ 
+ /* annotate test case with log message and failure */
+ void ts_test_fail(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     tstl_t *tstl;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     tstl->text = ts_suite_mvasprintf(fmt, ap);
+     tstl->file = tst->file;
+     tstl->line = tst->line;
+     RING_ELEM_INIT(tstl, next);
+     tstc = RING_LAST(&tst->checks);
+     RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
+     tstc->failed = 1;
+     va_end(ap);
+     return;
+ }
+ 
+ /* annotate test case with log message only */
+ void ts_test_log(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     tstl_t *tstl;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     tstl->text = ts_suite_mvasprintf(fmt, ap);
+     tstl->file = tst->file;
+     tstl->line = tst->line;
+     RING_ELEM_INIT(tstl, next);
+     tstc = RING_LAST(&tst->checks);
+     RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
+     va_end(ap);
+     return;
+ }
+ 


ossp-pkg/al/ts.h -> 1.1

*** /dev/null    Sun Apr 28 03:57:20 2024
--- -    Sun Apr 28 03:57:56 2024
***************
*** 0 ****
--- 1,64 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a small test suite library which
+ **  can be found at http://www.ossp.org/pkg/ts/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ **  SUCH DAMAGE.
+ **
+ **  ts.h: test suite library API
+ */
+ 
+ #ifndef _TS_H_
+ #define _TS_H_
+ 
+ /* test suite object type */
+ struct ts_suite_st;
+ typedef struct ts_suite_st ts_suite_t;
+ 
+ /* test object type */
+ struct ts_test_st;
+ typedef struct ts_test_st ts_test_t;
+ 
+ /* test callback function type */
+ typedef void (*ts_test_cb_t)(ts_test_t *);
+ 
+ /* test suite operations */
+ ts_suite_t *ts_suite_new  (const char *fmt, ...);
+ void        ts_suite_test (ts_suite_t *s, ts_test_cb_t func, const char *fmt, ...);
+ int         ts_suite_run  (ts_suite_t *s);
+ void        ts_suite_free (ts_suite_t *s);
+ 
+ /* test operations */
+ ts_test_t  *ts_test_ctx   (ts_test_t *t, const char *file, int line);
+ void        ts_test_check (ts_test_t *t, const char *fmt, ...);
+ void        ts_test_fail  (ts_test_t *t, const char *fmt, ...);
+ void        ts_test_log   (ts_test_t *t, const char *fmt, ...);
+ 
+ /* test suite short-cut macros */
+ #define TS_TEST(name) \
+     static void name(ts_test_t *_t)
+ #define TS_CTX \
+     ts_test_ctx(_t, __FILE__, __LINE__)
+ 
+ #endif /* _TS_H_ */
+ 

CVSTrac 2.0.1