ia64/xen-unstable
changeset 5132:9f22db685802
bitkeeper revision 1.1536 (429399e9qNO_CnmTploLs7q5t-754Q)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into firebug.cl.cam.ac.uk:/local/scratch/cl349/xen-unstable.bk
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into firebug.cl.cam.ac.uk:/local/scratch/cl349/xen-unstable.bk
line diff
1.1 --- a/.rootkeys Tue May 24 21:10:23 2005 +0000 1.2 +++ b/.rootkeys Tue May 24 21:17:29 2005 +0000 1.3 @@ -698,40 +698,6 @@ 42337174PxyzzPk62raDiYCIsfStDg tools/lib 1.4 4273458duzL--nsTfT6e_q6Kfij48g tools/libxc/xc_ptrace_core.c 1.5 41ebbfe9U0b0kI-HgjK7VEY4EvW7_w tools/libxc/xc_sedf.c 1.6 41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c 1.7 -40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile 1.8 -40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c 1.9 -40e03332KYz7o1bn2MG_KPbBlyoIMA tools/libxutil/allocate.h 1.10 -41a216cav5JJbtDQnusfuMa_1x_Xpw tools/libxutil/debug.h 1.11 -40e9808eyjiahG5uF6AMelNVujBzCg tools/libxutil/enum.c 1.12 -40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/libxutil/enum.h 1.13 -4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/libxutil/fd_stream.c 1.14 -4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/libxutil/fd_stream.h 1.15 -40e03332p5Dc_owJQRuN72ymJZddFQ tools/libxutil/file_stream.c 1.16 -40e03332jWfB2viAhLSkq1WK0r_iDQ tools/libxutil/file_stream.h 1.17 -40e03332rUjNMGg11n2rN6V4DCrvOg tools/libxutil/gzip_stream.c 1.18 -40e033321O5Qg22haLoq5lpmk4tooQ tools/libxutil/gzip_stream.h 1.19 -40e9808easXCzzAZQodEfKAhgUXSPA tools/libxutil/hash_table.c 1.20 -40e9808e94BNXIVVKBFHC3rnkvwtJg tools/libxutil/hash_table.h 1.21 -40e03332ihnBGzHykVwZnFmkAppb4g tools/libxutil/iostream.c 1.22 -40e03332UGwbLR4wsw4ft14p0Yw5pg tools/libxutil/iostream.h 1.23 -40e0333245DLDzJemeSVBLuutHtzEQ tools/libxutil/kernel_stream.c 1.24 -40e03332aK0GkgpDdc-PVTkWKTeOBg tools/libxutil/kernel_stream.h 1.25 -40e9808epW9iHcLXuO3QfUfLzB7onw tools/libxutil/lexis.c 1.26 -40e9808egccMhCizayQRGtpBA3L5MQ tools/libxutil/lexis.h 1.27 -41a216caM4z39Fzjb91rv9Ed_4By1A tools/libxutil/socket_stream.c 1.28 -41a216caqinvF1I5FQMHA4HTRz8MSA tools/libxutil/socket_stream.h 1.29 -40e03332KT_tnnoAMbPVAZBB7kSOAQ tools/libxutil/string_stream.c 1.30 -40e03332-VtK6_OZa1vMHXFil8uq6w tools/libxutil/string_stream.h 1.31 -40e9808e5_PLdodqVOSx0b4T_f5aeg tools/libxutil/sxpr.c 1.32 -40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/libxutil/sxpr.h 1.33 -40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/libxutil/sxpr_parser.c 1.34 -40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/libxutil/sxpr_parser.h 1.35 -40e03332Rkvq6nn_UNjzAAK_Tk9v1g tools/libxutil/sys_net.c 1.36 -40e03332lQHvQHw4Rh7VsT1_sui29A tools/libxutil/sys_net.h 1.37 -40e033321smklZd7bDSdWvQCeIshtg tools/libxutil/sys_string.c 1.38 -40e03332h5V611rRWURRLqb1Ekatxg tools/libxutil/sys_string.h 1.39 -41a216cayFe2FQroFuzvNPw1AvNiqQ tools/libxutil/util.c 1.40 -41a216ca7mgVSnCBHPCLkGOIqPS1CQ tools/libxutil/util.h 1.41 3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile 1.42 4225f56d7sa9aEARfjNeCVTMYDAmZA tools/misc/cpuperf/Makefile 1.43 4225f56dS5TGdKojmuBnrV3PzbE6Rg tools/misc/cpuperf/README.txt 1.44 @@ -967,6 +933,40 @@ 41a21888FGQhPR5LJ1GRtOSIIN3QEw tools/vne 1.45 41a21888QPgKrulCfR9SY_pxZKU0KA tools/vnet/examples/vnet97.sxp 1.46 41a21888Gm0UBs1i7HqveT7Yz0u8DQ tools/vnet/examples/vnet98.sxp 1.47 41a21888r4oGPuGv2Lxl-thgV3H54w tools/vnet/examples/vnet99.sxp 1.48 +40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/vnet/libxutil/Makefile 1.49 +40e033325Sjqs-_4TuzeUEprP_gYFg tools/vnet/libxutil/allocate.c 1.50 +40e03332KYz7o1bn2MG_KPbBlyoIMA tools/vnet/libxutil/allocate.h 1.51 +41a216cav5JJbtDQnusfuMa_1x_Xpw tools/vnet/libxutil/debug.h 1.52 +40e9808eyjiahG5uF6AMelNVujBzCg tools/vnet/libxutil/enum.c 1.53 +40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/vnet/libxutil/enum.h 1.54 +4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/vnet/libxutil/fd_stream.c 1.55 +4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/vnet/libxutil/fd_stream.h 1.56 +40e03332p5Dc_owJQRuN72ymJZddFQ tools/vnet/libxutil/file_stream.c 1.57 +40e03332jWfB2viAhLSkq1WK0r_iDQ tools/vnet/libxutil/file_stream.h 1.58 +40e03332rUjNMGg11n2rN6V4DCrvOg tools/vnet/libxutil/gzip_stream.c 1.59 +40e033321O5Qg22haLoq5lpmk4tooQ tools/vnet/libxutil/gzip_stream.h 1.60 +40e9808easXCzzAZQodEfKAhgUXSPA tools/vnet/libxutil/hash_table.c 1.61 +40e9808e94BNXIVVKBFHC3rnkvwtJg tools/vnet/libxutil/hash_table.h 1.62 +40e03332ihnBGzHykVwZnFmkAppb4g tools/vnet/libxutil/iostream.c 1.63 +40e03332UGwbLR4wsw4ft14p0Yw5pg tools/vnet/libxutil/iostream.h 1.64 +40e0333245DLDzJemeSVBLuutHtzEQ tools/vnet/libxutil/kernel_stream.c 1.65 +40e03332aK0GkgpDdc-PVTkWKTeOBg tools/vnet/libxutil/kernel_stream.h 1.66 +40e9808epW9iHcLXuO3QfUfLzB7onw tools/vnet/libxutil/lexis.c 1.67 +40e9808egccMhCizayQRGtpBA3L5MQ tools/vnet/libxutil/lexis.h 1.68 +41a216caM4z39Fzjb91rv9Ed_4By1A tools/vnet/libxutil/socket_stream.c 1.69 +41a216caqinvF1I5FQMHA4HTRz8MSA tools/vnet/libxutil/socket_stream.h 1.70 +40e03332KT_tnnoAMbPVAZBB7kSOAQ tools/vnet/libxutil/string_stream.c 1.71 +40e03332-VtK6_OZa1vMHXFil8uq6w tools/vnet/libxutil/string_stream.h 1.72 +40e9808e5_PLdodqVOSx0b4T_f5aeg tools/vnet/libxutil/sxpr.c 1.73 +40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/vnet/libxutil/sxpr.h 1.74 +40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/vnet/libxutil/sxpr_parser.c 1.75 +40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/vnet/libxutil/sxpr_parser.h 1.76 +40e03332Rkvq6nn_UNjzAAK_Tk9v1g tools/vnet/libxutil/sys_net.c 1.77 +40e03332lQHvQHw4Rh7VsT1_sui29A tools/vnet/libxutil/sys_net.h 1.78 +40e033321smklZd7bDSdWvQCeIshtg tools/vnet/libxutil/sys_string.c 1.79 +40e03332h5V611rRWURRLqb1Ekatxg tools/vnet/libxutil/sys_string.h 1.80 +41a216cayFe2FQroFuzvNPw1AvNiqQ tools/vnet/libxutil/util.c 1.81 +41a216ca7mgVSnCBHPCLkGOIqPS1CQ tools/vnet/libxutil/util.h 1.82 41a21888c9TCRlUwJS9WBjB3e9aWgg tools/vnet/vnet-module/00README 1.83 41a21888K2ItolEkksc1MUqyTDI_Kg tools/vnet/vnet-module/Makefile 1.84 41a21888mJsFJD7bVMm-nrnWnalGBw tools/vnet/vnet-module/Makefile-2.4
2.1 --- a/tools/Makefile Tue May 24 21:10:23 2005 +0000 2.2 +++ b/tools/Makefile Tue May 24 21:17:29 2005 +0000 2.3 @@ -2,7 +2,6 @@ XEN_ROOT = ../ 2.4 include $(XEN_ROOT)/tools/Rules.mk 2.5 2.6 SUBDIRS := 2.7 -SUBDIRS += libxutil 2.8 SUBDIRS += libxc 2.9 SUBDIRS += misc 2.10 SUBDIRS += examples
3.1 --- a/tools/Rules.mk Tue May 24 21:10:23 2005 +0000 3.2 +++ b/tools/Rules.mk Tue May 24 21:17:29 2005 +0000 3.3 @@ -4,7 +4,6 @@ include $(XEN_ROOT)/Config.mk 3.4 3.5 XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc 3.6 XEN_LIBXC = $(XEN_ROOT)/tools/libxc 3.7 -XEN_LIBXUTIL = $(XEN_ROOT)/tools/libxutil 3.8 3.9 ifeq ($(XEN_TARGET_ARCH),x86_32) 3.10 CFLAGS += -m32 -march=i686
4.1 --- a/tools/blktap/Makefile Tue May 24 21:10:23 2005 +0000 4.2 +++ b/tools/blktap/Makefile Tue May 24 21:17:29 2005 +0000 4.3 @@ -47,7 +47,6 @@ CFLAGS += -Wno-unused 4.4 CFLAGS += -g3 4.5 CFLAGS += -fno-strict-aliasing 4.6 CFLAGS += -I $(XEN_LIBXC) 4.7 -CFLAGS += -I $(XEN_LIBXUTIL) 4.8 CFLAGS += $(INCLUDES) -I. 4.9 CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE 4.10 # Get gcc to generate the dependencies for us. 4.11 @@ -97,16 +96,16 @@ libblktap.so: 4.12 libblktap.so.$(MAJOR): 4.13 ln -sf libblktap.so.$(MAJOR).$(MINOR) $@ 4.14 libblktap.so.$(MAJOR).$(MINOR): $(OBJS) 4.15 - $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -lpthread -L../libxutil -lxutil -lz 4.16 + $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -lpthread -lz 4.17 4.18 blkdump: $(LIB) 4.19 - $(CC) $(CFLAGS) -o blkdump -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -l blktap blkdump.c 4.20 + $(CC) $(CFLAGS) -o blkdump -L$(XEN_LIBXC) -L. -l blktap blkdump.c 4.21 4.22 parallax: $(LIB) $(PLX_SRCS) 4.23 - $(CC) $(CFLAGS) -o parallax -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -lblktap -lpthread $(PLX_SRCS) 4.24 + $(CC) $(CFLAGS) -o parallax -L$(XEN_LIBXC) -L. -lblktap -lpthread $(PLX_SRCS) 4.25 4.26 parallax-threaded: $(LIB) $(PLXT_SRCS) 4.27 - $(CC) $(CFLAGS) -o parallax-threaded -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -lpthread -lblktap $(PLXT_SRCS) 4.28 + $(CC) $(CFLAGS) -o parallax-threaded -L$(XEN_LIBXC) -L. -lpthread -lblktap $(PLXT_SRCS) 4.29 4.30 vdi_list: $(LIB) vdi_list.c $(VDI_SRCS) 4.31 $(CC) $(CFLAGS) -g3 -o vdi_list vdi_list.c -lpthread $(VDI_SRCS)
5.1 --- a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in Tue May 24 21:10:23 2005 +0000 5.2 +++ b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in Tue May 24 21:17:29 2005 +0000 5.3 @@ -83,7 +83,7 @@ READLINE_DEP = $$(READLINE_DIR) 5.4 # -I. for config files. 5.5 # -I${srcdir} for our headers. 5.6 # -I$(srcdir)/../regformats for regdef.h. 5.7 -INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR) -I../../../../libxc/ -I../../../../libxutil/ 5.8 +INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR) -I../../../../libxc/ 5.9 5.10 # M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS 5.11 # from the config/ directory.
6.1 --- a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure Tue May 24 21:10:23 2005 +0000 6.2 +++ b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure Tue May 24 21:17:29 2005 +0000 6.3 @@ -3475,7 +3475,7 @@ USE_THREAD_DB= 6.4 6.5 6.6 GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles" 6.7 -GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -L../../../../libxutil/ -lxc -lxutil" 6.8 +GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -lxc" 6.9 6.10 6.11
7.1 --- a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in Tue May 24 21:10:23 2005 +0000 7.2 +++ b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in Tue May 24 21:17:29 2005 +0000 7.3 @@ -107,7 +107,7 @@ USE_THREAD_DB= 7.4 7.5 7.6 GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles" 7.7 -GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -L../../../../libxutil/ -lxc -lxutil" 7.8 +GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -lxc" 7.9 7.10 AC_SUBST(GDBSERVER_DEPFILES) 7.11 AC_SUBST(GDBSERVER_LIBS)
8.1 --- a/tools/ioemu/target-i386-dm/Makefile Tue May 24 21:10:23 2005 +0000 8.2 +++ b/tools/ioemu/target-i386-dm/Makefile Tue May 24 21:17:29 2005 +0000 8.3 @@ -189,7 +189,7 @@ endif 8.4 ######################################################### 8.5 8.6 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 8.7 -LIBS+=-lm -L../../libxc -L../../libxutil -lxc -lxutil 8.8 +LIBS+=-lm -L../../libxc -lxc 8.9 ifndef CONFIG_USER_ONLY 8.10 LIBS+=-lz 8.11 endif
9.1 --- a/tools/libxc/Makefile Tue May 24 21:10:23 2005 +0000 9.2 +++ b/tools/libxc/Makefile Tue May 24 21:17:29 2005 +0000 9.3 @@ -12,9 +12,6 @@ CC = gcc 9.4 XEN_ROOT = ../.. 9.5 include $(XEN_ROOT)/tools/Rules.mk 9.6 9.7 -vpath %c $(XEN_LIBXUTIL) 9.8 -INCLUDES += -I $(XEN_LIBXUTIL) 9.9 - 9.10 SRCS := 9.11 SRCS += xc_sedf.c 9.12 SRCS += xc_bvtsched.c 9.13 @@ -105,6 +102,6 @@ libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(M 9.14 ln -sf $< $@ 9.15 9.16 libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS) 9.17 - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz 9.18 + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -lz 9.19 9.20 -include $(DEPS)
11.1 --- a/tools/libxutil/Makefile Tue May 24 21:10:23 2005 +0000 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,77 +0,0 @@ 11.4 - 11.5 -XEN_ROOT = ../.. 11.6 -INSTALL = install 11.7 -INSTALL_DATA = $(INSTALL) -m0644 11.8 -INSTALL_PROG = $(INSTALL) -m0755 11.9 -INSTALL_DIR = $(INSTALL) -d -m0755 11.10 - 11.11 -include $(XEN_ROOT)/tools/Rules.mk 11.12 - 11.13 -LIB_SRCS := 11.14 -LIB_SRCS += allocate.c 11.15 -LIB_SRCS += enum.c 11.16 -LIB_SRCS += file_stream.c 11.17 -LIB_SRCS += gzip_stream.c 11.18 -LIB_SRCS += hash_table.c 11.19 -LIB_SRCS += iostream.c 11.20 -LIB_SRCS += lexis.c 11.21 -LIB_SRCS += string_stream.c 11.22 -LIB_SRCS += sxpr.c 11.23 -LIB_SRCS += sxpr_parser.c 11.24 -LIB_SRCS += sys_net.c 11.25 -LIB_SRCS += sys_string.c 11.26 -LIB_SRCS += util.c 11.27 - 11.28 -LIB_OBJS := $(LIB_SRCS:.c=.o) 11.29 -PIC_OBJS := $(LIB_SRCS:.c=.opic) 11.30 - 11.31 -CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing 11.32 - 11.33 -# Get gcc to generate the dependencies for us. 11.34 -CFLAGS += -Wp,-MD,.$(@F).d 11.35 -DEPS = .*.d 11.36 - 11.37 -MAJOR := 3.0 11.38 -MINOR := 0 11.39 -LIB := libxutil.so 11.40 -LIB += libxutil.so.$(MAJOR) 11.41 -LIB += libxutil.so.$(MAJOR).$(MINOR) 11.42 -LIB += libxutil.a 11.43 - 11.44 -all: build 11.45 -build: check-for-zlib 11.46 - $(MAKE) $(LIB) 11.47 - 11.48 -libxutil.so: libxutil.so.$(MAJOR) 11.49 - ln -sf $^ $@ 11.50 - 11.51 -libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) 11.52 - ln -sf $^ $@ 11.53 - 11.54 -libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) 11.55 - $(CC) $(CFLAGS) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ 11.56 - 11.57 -libxutil.a: $(LIB_OBJS) 11.58 - $(AR) rc $@ $^ 11.59 - 11.60 -check-for-zlib: 11.61 - @if [ ! -e /usr/include/zlib.h ]; then \ 11.62 - echo "***********************************************************"; \ 11.63 - echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \ 11.64 - echo "***********************************************************"; \ 11.65 - false; \ 11.66 - fi 11.67 - 11.68 -install: build 11.69 - [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) 11.70 - $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) 11.71 - $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/$(LIBDIR) 11.72 - ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so.$(MAJOR) 11.73 - ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so 11.74 - 11.75 -clean: 11.76 - $(RM) *.a *.so* *.o *.opic *.rpm 11.77 - $(RM) *~ 11.78 - $(RM) $(DEPS) 11.79 - 11.80 --include $(DEPS)
12.1 --- a/tools/libxutil/allocate.c Tue May 24 21:10:23 2005 +0000 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,116 +0,0 @@ 12.4 -/* 12.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 12.6 - * 12.7 - * This library is free software; you can redistribute it and/or modify 12.8 - * it under the terms of the GNU Lesser General Public License as published by 12.9 - * the Free Software Foundation; either version 2.1 of the License, or 12.10 - * (at your option) any later version. 12.11 - * 12.12 - * This library is distributed in the hope that it will be useful, 12.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.15 - * GNU Lesser General Public License for more details. 12.16 - * 12.17 - * You should have received a copy of the GNU Lesser General Public License 12.18 - * along with this library; if not, write to the Free Software 12.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12.20 - */ 12.21 - 12.22 -#include "allocate.h" 12.23 - 12.24 -/** @file 12.25 - * Support for allocating memory. 12.26 - * Usable from user code or kernel code (with __KERNEL__ defined). 12.27 - * In user code will use GC if USE_GC is defined. 12.28 - */ 12.29 - 12.30 -#ifdef __KERNEL__ 12.31 -/*----------------------------------------------------------------------------*/ 12.32 -# include <linux/config.h> 12.33 -# include <linux/slab.h> 12.34 -# include <linux/string.h> 12.35 -# include <linux/types.h> 12.36 - 12.37 -# define DEFAULT_TYPE 0 12.38 -# define MALLOC(n, type) kmalloc(n, type) 12.39 -# define FREE(ptr) kfree(ptr) 12.40 - 12.41 -/*----------------------------------------------------------------------------*/ 12.42 -#else /* ! __KERNEL__ */ 12.43 - 12.44 -# include <stdlib.h> 12.45 -# include <string.h> 12.46 - 12.47 -# define DEFAULT_TYPE 0 12.48 - 12.49 -#ifdef USE_GC 12.50 -# include "gc.h" 12.51 -# define MALLOC(n, typ) GC_malloc(n) 12.52 -# define FREE(ptr) (ptr=NULL) 12.53 -//typedef void *GC_PTR; 12.54 -//GC_PTR (*GC_oom_fn)(size_t n); 12.55 -#else 12.56 -# define MALLOC(n, type) malloc(n) 12.57 -# define FREE(ptr) free(ptr) 12.58 -#endif 12.59 - 12.60 -/*----------------------------------------------------------------------------*/ 12.61 -#endif 12.62 - 12.63 -/** Function to call when memory cannot be allocated. */ 12.64 -AllocateFailedFn *allocate_failed_fn = NULL; 12.65 - 12.66 -/** Allocate memory and zero it. 12.67 - * The type is only relevant when calling from kernel code, 12.68 - * from user code it is ignored. 12.69 - * In kernel code the values accepted by kmalloc can be used: 12.70 - * GFP_USER, GFP_ATOMIC, GFP_KERNEL. 12.71 - * 12.72 - * @param size number of bytes to allocate 12.73 - * @param type memory type to allocate (kernel only) 12.74 - * @return pointer to the allocated memory or zero 12.75 - * if malloc failed 12.76 - */ 12.77 -void *allocate_type(int size, int type){ 12.78 - void *p = MALLOC(size, type); 12.79 - if(p){ 12.80 - memzero(p, size); 12.81 - } else if(allocate_failed_fn){ 12.82 - allocate_failed_fn(size, type); 12.83 - } 12.84 - return p; 12.85 -} 12.86 - 12.87 -/** Allocate memory and zero it. 12.88 - * 12.89 - * @param size number of bytes to allocate 12.90 - * @return pointer to the allocated memory or zero 12.91 - * if malloc failed 12.92 - */ 12.93 -void *allocate(int size){ 12.94 - return allocate_type(size, DEFAULT_TYPE); 12.95 -} 12.96 - 12.97 -/** Free memory allocated by allocate(). 12.98 - * No-op if 'p' is null. 12.99 - * 12.100 - * @param p memory to free 12.101 - */ 12.102 -void deallocate(void *p){ 12.103 - if(p){ 12.104 - FREE(p); 12.105 - } 12.106 -} 12.107 - 12.108 -/** Set bytes to zero. 12.109 - * No-op if 'p' is null. 12.110 - * 12.111 - * @param p memory to zero 12.112 - * @param size number of bytes to zero 12.113 - */ 12.114 -void memzero(void *p, int size){ 12.115 - if(p){ 12.116 - memset(p, 0, (size_t)size); 12.117 - } 12.118 -} 12.119 -
13.1 --- a/tools/libxutil/allocate.h Tue May 24 21:10:23 2005 +0000 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,45 +0,0 @@ 13.4 -/* 13.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 13.6 - * 13.7 - * This library is free software; you can redistribute it and/or modify 13.8 - * it under the terms of the GNU Lesser General Public License as published by 13.9 - * the Free Software Foundation; either version 2.1 of the License, or 13.10 - * (at your option) any later version. 13.11 - * 13.12 - * This library is distributed in the hope that it will be useful, 13.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.15 - * GNU Lesser General Public License for more details. 13.16 - * 13.17 - * You should have received a copy of the GNU Lesser General Public License 13.18 - * along with this library; if not, write to the Free Software 13.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 13.20 - */ 13.21 - 13.22 -#ifndef _XUTIL_ALLOCATE_H_ 13.23 -#define _XUTIL_ALLOCATE_H_ 13.24 - 13.25 -/** Allocate memory for a given type, and cast. */ 13.26 -#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype)) 13.27 - 13.28 -/** Allocate memory for a given type, and cast. */ 13.29 -#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype)) 13.30 - 13.31 -extern void *allocate_type(int size, int type); 13.32 -extern void *allocate(int size); 13.33 -extern void deallocate(void *); 13.34 -extern void memzero(void *p, int size); 13.35 - 13.36 -typedef void AllocateFailedFn(int size, int type); 13.37 -extern AllocateFailedFn *allocate_failed_fn; 13.38 - 13.39 -#endif /* _XUTIL_ALLOCATE_H_ */ 13.40 - 13.41 - 13.42 - 13.43 - 13.44 - 13.45 - 13.46 - 13.47 - 13.48 -
14.1 --- a/tools/libxutil/debug.h Tue May 24 21:10:23 2005 +0000 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,72 +0,0 @@ 14.4 -/* 14.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 14.6 - * 14.7 - * This library is free software; you can redistribute it and/or modify 14.8 - * it under the terms of the GNU Lesser General Public License as published by 14.9 - * the Free Software Foundation; either version 2.1 of the License, or 14.10 - * (at your option) any later version. 14.11 - * 14.12 - * This library is distributed in the hope that it will be useful, 14.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.15 - * GNU Lesser General Public License for more details. 14.16 - * 14.17 - * You should have received a copy of the GNU Lesser General Public License 14.18 - * along with this library; if not, write to the Free Software 14.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 14.20 - */ 14.21 -#ifndef _XUTIL_DEBUG_H_ 14.22 -#define _XUTIL_DEBUG_H_ 14.23 - 14.24 -#ifndef MODULE_NAME 14.25 -#define MODULE_NAME "" 14.26 -#endif 14.27 - 14.28 -#ifdef __KERNEL__ 14.29 -#include <linux/config.h> 14.30 -#include <linux/kernel.h> 14.31 - 14.32 -#ifdef DEBUG 14.33 - 14.34 -#define dprintf(fmt, args...) printk(KERN_DEBUG "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 14.35 -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 14.36 -#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 14.37 -#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 14.38 - 14.39 -#else 14.40 - 14.41 -#define dprintf(fmt, args...) do {} while(0) 14.42 -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args) 14.43 -#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME fmt, ##args) 14.44 -#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME fmt, ##args) 14.45 - 14.46 -#endif 14.47 - 14.48 -#else 14.49 - 14.50 -#include <stdio.h> 14.51 - 14.52 -#ifdef DEBUG 14.53 - 14.54 -#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 14.55 -#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 14.56 -#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 14.57 -#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 14.58 - 14.59 -#else 14.60 - 14.61 -#define dprintf(fmt, args...) do {} while(0) 14.62 -#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args) 14.63 -#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args) 14.64 -#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args) 14.65 - 14.66 -#endif 14.67 - 14.68 -#endif 14.69 - 14.70 -/** Print format for an IP address. 14.71 - * See NIPQUAD(), HIPQUAD() 14.72 - */ 14.73 -#define IPFMT "%u.%u.%u.%u" 14.74 - 14.75 -#endif /* ! _XUTIL_DEBUG_H_ */
15.1 --- a/tools/libxutil/enum.c Tue May 24 21:10:23 2005 +0000 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,61 +0,0 @@ 15.4 -/* 15.5 - * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com> 15.6 - * 15.7 - * This library is free software; you can redistribute it and/or modify 15.8 - * it under the terms of the GNU Lesser General Public License as 15.9 - * published by the Free Software Foundation; either version 2.1 of the 15.10 - * License, or (at your option) any later version. This library is 15.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 15.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.13 - * FITNESS FOR A PARTICULAR PURPOSE. 15.14 - * See the GNU Lesser General Public License for more details. 15.15 - * 15.16 - * You should have received a copy of the GNU Lesser General Public License 15.17 - * along with this library; if not, write to the Free Software Foundation, 15.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15.19 - */ 15.20 - 15.21 -#ifdef __KERNEL__ 15.22 -#include <linux/errno.h> 15.23 -#else 15.24 -#include <errno.h> 15.25 -#endif 15.26 - 15.27 -#include "sys_string.h" 15.28 -#include "enum.h" 15.29 - 15.30 -/** Map an enum name to its value using a table. 15.31 - * 15.32 - * @param name enum name 15.33 - * @param defs enum definitions 15.34 - * @return enum value or -1 if not known 15.35 - */ 15.36 -int enum_name_to_val(char *name, EnumDef *defs){ 15.37 - int val = -1; 15.38 - for(; defs->name; defs++){ 15.39 - if(!strcmp(defs->name, name)){ 15.40 - val = defs->val; 15.41 - break; 15.42 - } 15.43 - } 15.44 - return val; 15.45 -} 15.46 - 15.47 -/** Map an enum value to its name using a table. 15.48 - * 15.49 - * @param val enum value 15.50 - * @param defs enum definitions 15.51 - * @param defs_n number of definitions 15.52 - * @return enum name or NULL if not known 15.53 - */ 15.54 -char *enum_val_to_name(int val, EnumDef *defs){ 15.55 - char *name = NULL; 15.56 - for(; defs->name; defs++){ 15.57 - if(val == defs->val){ 15.58 - name = defs->name; 15.59 - break; 15.60 - } 15.61 - } 15.62 - return name; 15.63 -} 15.64 -
16.1 --- a/tools/libxutil/enum.h Tue May 24 21:10:23 2005 +0000 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,30 +0,0 @@ 16.4 -/* 16.5 - * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com> 16.6 - * 16.7 - * This library is free software; you can redistribute it and/or modify 16.8 - * it under the terms of the GNU Lesser General Public License as 16.9 - * published by the Free Software Foundation; either version 2.1 of the 16.10 - * License, or (at your option) any later version. This library is 16.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 16.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.13 - * FITNESS FOR A PARTICULAR PURPOSE. 16.14 - * See the GNU Lesser General Public License for more details. 16.15 - * 16.16 - * You should have received a copy of the GNU Lesser General Public License 16.17 - * along with this library; if not, write to the Free Software Foundation, 16.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16.19 - */ 16.20 - 16.21 -#ifndef _XUTIL_ENUM_H_ 16.22 -#define _XUTIL_ENUM_H_ 16.23 - 16.24 -/** Mapping of an enum value to a name. */ 16.25 -typedef struct EnumDef { 16.26 - int val; 16.27 - char *name; 16.28 -} EnumDef; 16.29 - 16.30 -extern int enum_name_to_val(char *name, EnumDef *defs); 16.31 -extern char *enum_val_to_name(int val, EnumDef *defs); 16.32 - 16.33 -#endif /* _XUTIL_ENUM_H_ */
17.1 --- a/tools/libxutil/fd_stream.c Tue May 24 21:10:23 2005 +0000 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,184 +0,0 @@ 17.4 -/* 17.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 17.6 - * 17.7 - * This library is free software; you can redistribute it and/or modify 17.8 - * it under the terms of the GNU Lesser General Public License as published by 17.9 - * the Free Software Foundation; either version 2.1 of the License, or 17.10 - * (at your option) any later version. 17.11 - * 17.12 - * This library is distributed in the hope that it will be useful, 17.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 17.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.15 - * GNU Lesser General Public License for more details. 17.16 - * 17.17 - * You should have received a copy of the GNU Lesser General Public License 17.18 - * along with this library; if not, write to the Free Software 17.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17.20 - */ 17.21 - 17.22 -/** @file 17.23 - * An IOStream implementation using fds. 17.24 - */ 17.25 -#ifndef __KERNEL__ 17.26 - 17.27 -#include <stdio.h> 17.28 -#include <stdlib.h> 17.29 -#include <string.h> 17.30 -#include <unistd.h> 17.31 -#include <errno.h> 17.32 -#include "allocate.h" 17.33 -#include "fd_stream.h" 17.34 - 17.35 -#define MODULE_NAME "fd_stream" 17.36 -#define DEBUG 1 17.37 -//#undef DEBUG 17.38 -#include "debug.h" 17.39 - 17.40 -static int fd_read(IOStream *s, void *buf, size_t n); 17.41 -static int fd_write(IOStream *s, const void *buf, size_t n); 17.42 -static int fd_error(IOStream *s); 17.43 -static int fd_close(IOStream *s); 17.44 -static void fd_free(IOStream *s); 17.45 -static int fd_flush(IOStream *s); 17.46 - 17.47 -/** Methods used by a fd IOStream. */ 17.48 -static const IOMethods fd_methods = { 17.49 - read: fd_read, 17.50 - write: fd_write, 17.51 - error: fd_error, 17.52 - close: fd_close, 17.53 - free: fd_free, 17.54 - flush: fd_flush, 17.55 -}; 17.56 - 17.57 -/** Get the fd data. 17.58 - * 17.59 - * @param io fd stream 17.60 - * @return data 17.61 - */ 17.62 -static inline FDData * fd_data(IOStream *io){ 17.63 - return (FDData *)io->data; 17.64 -} 17.65 - 17.66 -/** Test if a stream is a fd stream. 17.67 - * 17.68 - * @param io stream 17.69 - * @return 0 if a fd stream, -EINVAL if not 17.70 - */ 17.71 -int fd_stream_check(IOStream *io){ 17.72 - return (io && io->methods == &fd_methods ? 0 : -EINVAL); 17.73 -} 17.74 - 17.75 -/** Get the data for a fd stream. 17.76 - * 17.77 - * @param io stream 17.78 - * @param data return value for the data 17.79 - * @return 0 if a fd stream, -EINVAL if not 17.80 - */ 17.81 -int fd_stream_data(IOStream *io, FDData **data){ 17.82 - int err = fd_stream_check(io); 17.83 - if(err){ 17.84 - *data = NULL; 17.85 - } else { 17.86 - *data = fd_data(io); 17.87 - } 17.88 - return err; 17.89 -} 17.90 - 17.91 - 17.92 -/** Write to the underlying fd. 17.93 - * 17.94 - * @param stream input 17.95 - * @param buf where to put input 17.96 - * @param n number of bytes to write 17.97 - * @return number of bytes written 17.98 - */ 17.99 -static int fd_write(IOStream *s, const void *buf, size_t n){ 17.100 - FDData *data = fd_data(s); 17.101 - int k; 17.102 - k = write(data->fd, buf, n); 17.103 - return k; 17.104 -} 17.105 - 17.106 -/** Read from the underlying stream; 17.107 - * 17.108 - * @param stream input 17.109 - * @param buf where to put input 17.110 - * @param n number of bytes to read 17.111 - * @return number of bytes read 17.112 - */ 17.113 -static int fd_read(IOStream *s, void *buf, size_t n){ 17.114 - FDData *data = fd_data(s); 17.115 - int k; 17.116 - k = read(data->fd, buf, n); 17.117 - //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k); 17.118 - return k; 17.119 -} 17.120 - 17.121 -/** Flush the fd (no-op). 17.122 - * 17.123 - * @param s fd stream 17.124 - * @return 0 on success, error code otherwise 17.125 - */ 17.126 -static int fd_flush(IOStream *s){ 17.127 - return 0; 17.128 -} 17.129 - 17.130 -/** Check if a fd stream has an error (no-op). 17.131 - * 17.132 - * @param s fd stream 17.133 - * @return 1 if has an error, 0 otherwise 17.134 - */ 17.135 -static int fd_error(IOStream *s){ 17.136 - return 0; 17.137 -} 17.138 - 17.139 -/** Close a fd stream. 17.140 - * 17.141 - * @param s fd stream to close 17.142 - * @return result of the close 17.143 - */ 17.144 -static int fd_close(IOStream *s){ 17.145 - FDData *data = fd_data(s); 17.146 - return close(data->fd); 17.147 -} 17.148 - 17.149 -/** Free a fd stream. 17.150 - * 17.151 - * @param s fd stream 17.152 - */ 17.153 -static void fd_free(IOStream *s){ 17.154 - FDData *data = fd_data(s); 17.155 - deallocate(data); 17.156 -} 17.157 - 17.158 -/** Create an IOStream for a fd. 17.159 - * 17.160 - * @param fd fd to wtap 17.161 - * @return new IOStream using fd for i/o 17.162 - */ 17.163 -IOStream *fd_stream_new(int fd){ 17.164 - int err = -ENOMEM; 17.165 - IOStream *io = NULL; 17.166 - FDData *data = NULL; 17.167 - 17.168 - io = ALLOCATE(IOStream); 17.169 - if(!io) goto exit; 17.170 - io->methods = &fd_methods; 17.171 - data = ALLOCATE(FDData); 17.172 - if(!data) goto exit; 17.173 - io->data = data; 17.174 - data->fd = fd; 17.175 - err = 0; 17.176 - exit: 17.177 - if(err){ 17.178 - if(io){ 17.179 - if(data) deallocate(data); 17.180 - deallocate(io); 17.181 - io = NULL; 17.182 - } 17.183 - } 17.184 - return io; 17.185 -} 17.186 - 17.187 -#endif
18.1 --- a/tools/libxutil/fd_stream.h Tue May 24 21:10:23 2005 +0000 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,36 +0,0 @@ 18.4 -/* 18.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 18.6 - * 18.7 - * This library is free software; you can redistribute it and/or modify 18.8 - * it under the terms of the GNU Lesser General Public License as published by 18.9 - * the Free Software Foundation; either version 2.1 of the License, or 18.10 - * (at your option) any later version. 18.11 - * 18.12 - * This library is distributed in the hope that it will be useful, 18.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 18.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18.15 - * GNU Lesser General Public License for more details. 18.16 - * 18.17 - * You should have received a copy of the GNU Lesser General Public License 18.18 - * along with this library; if not, write to the Free Software 18.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18.20 - */ 18.21 - 18.22 -#ifndef _XMC_FD_STREAM_H_ 18.23 -#define _XMC_FD_STREAM_H_ 18.24 - 18.25 -#ifndef __KERNEL__ 18.26 -#include "iostream.h" 18.27 - 18.28 -/** Data associated with a fd stream. */ 18.29 -typedef struct FDData { 18.30 - /** The socket file descriptor. */ 18.31 - int fd; 18.32 -} FDData; 18.33 - 18.34 -extern IOStream *fd_stream_new(int fd); 18.35 -extern int fd_stream_data(IOStream *io, FDData **data); 18.36 -extern int fd_stream_check(IOStream *io); 18.37 - 18.38 -#endif 18.39 -#endif /* !_XMC_FD_STREAM_H_ */
19.1 --- a/tools/libxutil/file_stream.c Tue May 24 21:10:23 2005 +0000 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,220 +0,0 @@ 19.4 -/* 19.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 19.6 - * 19.7 - * This library is free software; you can redistribute it and/or modify 19.8 - * it under the terms of the GNU Lesser General Public License as published by 19.9 - * the Free Software Foundation; either version 2.1 of the License, or 19.10 - * (at your option) any later version. 19.11 - * 19.12 - * This library is distributed in the hope that it will be useful, 19.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 19.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19.15 - * GNU Lesser General Public License for more details. 19.16 - * 19.17 - * You should have received a copy of the GNU Lesser General Public License 19.18 - * along with this library; if not, write to the Free Software 19.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19.20 - */ 19.21 - 19.22 -/** @file 19.23 - * An IOStream implementation using FILE*. 19.24 - */ 19.25 -#ifndef __KERNEL__ 19.26 -#include <stdio.h> 19.27 -#include <stdlib.h> 19.28 -#include "allocate.h" 19.29 -#include "file_stream.h" 19.30 - 19.31 -static int file_read(IOStream *s, void *buf, size_t n); 19.32 -static int file_write(IOStream *s, const void *buf, size_t n); 19.33 -static int file_error(IOStream *s); 19.34 -static int file_close(IOStream *s); 19.35 -static void file_free(IOStream *s); 19.36 -static int file_flush(IOStream *s); 19.37 - 19.38 -/** Methods used by a FILE* IOStream. */ 19.39 -static const IOMethods file_methods = { 19.40 - read: file_read, 19.41 - write: file_write, 19.42 - error: file_error, 19.43 - close: file_close, 19.44 - free: file_free, 19.45 - flush: file_flush, 19.46 -}; 19.47 - 19.48 -/** IOStream for stdin. */ 19.49 -static IOStream _iostdin = { 19.50 - methods: &file_methods, 19.51 - data: (void*)1, 19.52 - nofree: 1, 19.53 -}; 19.54 - 19.55 -/** IOStream for stdout. */ 19.56 -static IOStream _iostdout = { 19.57 - methods: &file_methods, 19.58 - data: (void*)2, 19.59 - nofree: 1, 19.60 -}; 19.61 - 19.62 -/** IOStream for stderr. */ 19.63 -static IOStream _iostderr = { 19.64 - methods: &file_methods, 19.65 - data: (void*)3, 19.66 - nofree: 1, 19.67 -}; 19.68 - 19.69 -/** IOStream for stdin. */ 19.70 -IOStream *iostdin = &_iostdin; 19.71 - 19.72 -/** IOStream for stdout. */ 19.73 -IOStream *iostdout = &_iostdout; 19.74 - 19.75 -/** IOStream for stderr. */ 19.76 -IOStream *iostderr = &_iostderr; 19.77 - 19.78 -/* Get the underlying FILE*. 19.79 - * 19.80 - * @param s file stream 19.81 - * @return the stream s wraps 19.82 - */ 19.83 -static inline FILE *get_file(IOStream *s){ 19.84 - FILE *data = NULL; 19.85 - switch((long)s->data){ 19.86 - case 1: 19.87 - data = stdin; 19.88 - break; 19.89 - case 2: 19.90 - data = stdout; 19.91 - break; 19.92 - case 3: 19.93 - data = stderr; 19.94 - break; 19.95 - default: 19.96 - data = (FILE*)s->data; 19.97 - break; 19.98 - } 19.99 - return data; 19.100 -} 19.101 - 19.102 -/** Control buffering on the underlying stream, like setvbuf(). 19.103 - * 19.104 - * @param io file stream 19.105 - * @param buf buffer 19.106 - * @param mode buffering mode (see man setvbuf()) 19.107 - * @param size buffer size 19.108 - * @return 0 on success, non-zero otherwise 19.109 - */ 19.110 -int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){ 19.111 - return setvbuf(get_file(io), buf, mode, size); 19.112 -} 19.113 - 19.114 -/** Write to the underlying stream using fwrite(); 19.115 - * 19.116 - * @param stream input 19.117 - * @param buf where to put input 19.118 - * @param n number of bytes to write 19.119 - * @return number of bytes written 19.120 - */ 19.121 -static int file_write(IOStream *s, const void *buf, size_t n){ 19.122 - return fwrite(buf, 1, n, get_file(s)); 19.123 -} 19.124 - 19.125 -/** Read from the underlying stream using fread(); 19.126 - * 19.127 - * @param stream input 19.128 - * @param buf where to put input 19.129 - * @param n number of bytes to read 19.130 - * @return number of bytes read 19.131 - */ 19.132 -static int file_read(IOStream *s, void *buf, size_t n){ 19.133 - return fread(buf, 1, n, get_file(s)); 19.134 -} 19.135 - 19.136 -/** Fush the underlying stream using fflush(). 19.137 - * 19.138 - * @param s file stream 19.139 - * @return 0 on success, error code otherwise 19.140 - */ 19.141 -static int file_flush(IOStream *s){ 19.142 - return fflush(get_file(s)); 19.143 -} 19.144 - 19.145 -/** Check if a stream has an error. 19.146 - * 19.147 - * @param s file stream 19.148 - * @return 1 if has an error, 0 otherwise 19.149 - */ 19.150 -static int file_error(IOStream *s){ 19.151 - return ferror(get_file(s)); 19.152 -} 19.153 - 19.154 -/** Close a file stream. 19.155 - * 19.156 - * @param s file stream to close 19.157 - * @return result of the close 19.158 - */ 19.159 -static int file_close(IOStream *s){ 19.160 - int result = 0; 19.161 - result = fclose(get_file(s)); 19.162 - return result; 19.163 -} 19.164 - 19.165 -/** Free a file stream. 19.166 - * 19.167 - * @param s file stream 19.168 - */ 19.169 -static void file_free(IOStream *s){ 19.170 - // Nothing extra to do - close did it all. 19.171 -} 19.172 - 19.173 -/** Create an IOStream for a stream. 19.174 - * 19.175 - * @param f stream to wrap 19.176 - * @return new IOStream using f for i/o 19.177 - */ 19.178 -IOStream *file_stream_new(FILE *f){ 19.179 - IOStream *io = ALLOCATE(IOStream); 19.180 - if(io){ 19.181 - io->methods = &file_methods; 19.182 - io->data = (void*)f; 19.183 - } 19.184 - return io; 19.185 -} 19.186 - 19.187 -/** IOStream version of fopen(). 19.188 - * 19.189 - * @param file name of the file to open 19.190 - * @param flags giving the mode to open in (as for fopen()) 19.191 - * @return new stream for the open file, or 0 if failed 19.192 - */ 19.193 -IOStream *file_stream_fopen(const char *file, const char *flags){ 19.194 - IOStream *io = 0; 19.195 - FILE *fin = fopen(file, flags); 19.196 - if(fin){ 19.197 - io = file_stream_new(fin); 19.198 - if(!io){ 19.199 - fclose(fin); 19.200 - } 19.201 - } 19.202 - return io; 19.203 -} 19.204 - 19.205 -/** IOStream version of fdopen(). 19.206 - * 19.207 - * @param fd file descriptor 19.208 - * @param flags giving the mode to open in (as for fdopen()) 19.209 - * @return new stream for the open file, or 0 if failed. Always takes 19.210 - * ownership of fd. 19.211 - */ 19.212 -IOStream *file_stream_fdopen(int fd, const char *flags){ 19.213 - IOStream *io = 0; 19.214 - FILE *fin = fdopen(fd, flags); 19.215 - if(fin){ 19.216 - io = file_stream_new(fin); 19.217 - if(!io){ 19.218 - fclose(fin); 19.219 - } 19.220 - } 19.221 - return io; 19.222 -} 19.223 -#endif
20.1 --- a/tools/libxutil/file_stream.h Tue May 24 21:10:23 2005 +0000 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,35 +0,0 @@ 20.4 -/* 20.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 20.6 - * 20.7 - * This library is free software; you can redistribute it and/or modify 20.8 - * it under the terms of the GNU Lesser General Public License as published by 20.9 - * the Free Software Foundation; either version 2.1 of the License, or 20.10 - * (at your option) any later version. 20.11 - * 20.12 - * This library is distributed in the hope that it will be useful, 20.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 20.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20.15 - * GNU Lesser General Public License for more details. 20.16 - * 20.17 - * You should have received a copy of the GNU Lesser General Public License 20.18 - * along with this library; if not, write to the Free Software 20.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20.20 - */ 20.21 - 20.22 -#ifndef _XUTIL_FILE_STREAM_H_ 20.23 -#define _XUTIL_FILE_STREAM_H_ 20.24 - 20.25 -#ifndef __KERNEL__ 20.26 -#include "iostream.h" 20.27 -#include <stdio.h> 20.28 - 20.29 -extern IOStream *file_stream_new(FILE *f); 20.30 -extern IOStream *file_stream_fopen(const char *file, const char *flags); 20.31 -extern IOStream *file_stream_fdopen(int fd, const char *flags); 20.32 -extern IOStream get_stream_stdout(void); 20.33 -extern IOStream get_stream_stderr(void); 20.34 -extern IOStream get_stream_stdin(void); 20.35 - 20.36 -extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size); 20.37 -#endif 20.38 -#endif /* !_XUTIL_FILE_STREAM_H_ */
21.1 --- a/tools/libxutil/gzip_stream.c Tue May 24 21:10:23 2005 +0000 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,174 +0,0 @@ 21.4 -/* 21.5 - * Copyright (C) 2003 Hewlett-Packard Company. 21.6 - * 21.7 - * This library is free software; you can redistribute it and/or modify 21.8 - * it under the terms of the GNU Lesser General Public License as published by 21.9 - * the Free Software Foundation; either version 2.1 of the License, or 21.10 - * (at your option) any later version. 21.11 - * 21.12 - * This library is distributed in the hope that it will be useful, 21.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 21.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.15 - * GNU Lesser General Public License for more details. 21.16 - * 21.17 - * You should have received a copy of the GNU Lesser General Public License 21.18 - * along with this library; if not, write to the Free Software 21.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21.20 - */ 21.21 - 21.22 -/** @file 21.23 - * An IOStream implementation using zlib gzFile to provide 21.24 - * compression and decompression. 21.25 - */ 21.26 -#ifndef __KERNEL__ 21.27 - 21.28 -#include <stdio.h> 21.29 -#include <stdlib.h> 21.30 - 21.31 -#include "zlib.h" 21.32 - 21.33 -#include "allocate.h" 21.34 -#include "gzip_stream.h" 21.35 - 21.36 -static int gzip_read(IOStream *s, void *buf, size_t n); 21.37 -static int gzip_write(IOStream *s, const void *buf, size_t n); 21.38 -static int gzip_error(IOStream *s); 21.39 -static int gzip_close(IOStream *s); 21.40 -static void gzip_free(IOStream *s); 21.41 -static int gzip_flush(IOStream *s); 21.42 - 21.43 -/** Methods used by a gzFile* IOStream. */ 21.44 -static const IOMethods gzip_methods = { 21.45 - read: gzip_read, 21.46 - write: gzip_write, 21.47 - error: gzip_error, 21.48 - close: gzip_close, 21.49 - free: gzip_free, 21.50 - flush: gzip_flush, 21.51 -}; 21.52 - 21.53 -/** Get the underlying gzFile*. 21.54 - * 21.55 - * @param s gzip stream 21.56 - * @return the stream s wraps 21.57 - */ 21.58 -static inline gzFile get_gzfile(IOStream *s){ 21.59 - return (gzFile)s->data; 21.60 -} 21.61 - 21.62 -/** Write to the underlying stream. 21.63 - * 21.64 - * @param stream destination 21.65 - * @param buf data 21.66 - * @param n number of bytes to write 21.67 - * @return number of bytes written 21.68 - */ 21.69 -static int gzip_write(IOStream *s, const void *buf, size_t n){ 21.70 - return gzwrite(get_gzfile(s), (void*)buf, n); 21.71 -} 21.72 - 21.73 -/** Read from the underlying stream. 21.74 - * 21.75 - * @param stream input 21.76 - * @param buf where to put input 21.77 - * @param n number of bytes to read 21.78 - * @return number of bytes read 21.79 - */ 21.80 -static int gzip_read(IOStream *s, void *buf, size_t n){ 21.81 - return gzread(get_gzfile(s), buf, n); 21.82 -} 21.83 - 21.84 -/** Flush the underlying stream. 21.85 - * 21.86 - * @param s gzip stream 21.87 - * @return 0 on success, error code otherwise 21.88 - */ 21.89 -static int gzip_flush(IOStream *s){ 21.90 - //return gzflush(get_gzfile(s), Z_NO_FLUSH); 21.91 - return gzflush(get_gzfile(s), Z_SYNC_FLUSH); 21.92 - //return gzflush(get_gzfile(s), Z_FULL_FLUSH); 21.93 -} 21.94 - 21.95 -/** Check if a stream has an error. 21.96 - * 21.97 - * @param s gzip stream 21.98 - * @return 1 if has an error, 0 otherwise 21.99 - */ 21.100 -static int gzip_error(IOStream *s){ 21.101 - int err; 21.102 - gzFile *gz = get_gzfile(s); 21.103 - gzerror(gz, &err); 21.104 - return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err); 21.105 -} 21.106 - 21.107 -/** Close a gzip stream. 21.108 - * 21.109 - * @param s gzip stream to close 21.110 - * @return result of the close 21.111 - */ 21.112 -static int gzip_close(IOStream *s){ 21.113 - int result = 0; 21.114 - result = gzclose(get_gzfile(s)); 21.115 - return result; 21.116 -} 21.117 - 21.118 -/** Free a gzip stream. 21.119 - * 21.120 - * @param s gzip stream 21.121 - */ 21.122 -static void gzip_free(IOStream *s){ 21.123 - // Nothing to do - close did it all. 21.124 -} 21.125 - 21.126 -/** Create an IOStream for a gzip stream. 21.127 - * 21.128 - * @param f stream to wrap 21.129 - * @return new IOStream using f for i/o 21.130 - */ 21.131 -IOStream *gzip_stream_new(gzFile *f){ 21.132 - IOStream *io = ALLOCATE(IOStream); 21.133 - if(io){ 21.134 - io->methods = &gzip_methods; 21.135 - io->data = (void*)f; 21.136 - } 21.137 - return io; 21.138 -} 21.139 - 21.140 -/** IOStream version of fopen(). 21.141 - * 21.142 - * @param file name of the file to open 21.143 - * @param flags giving the mode to open in (as for fopen()) 21.144 - * @return new stream for the open file, or NULL if failed 21.145 - */ 21.146 -IOStream *gzip_stream_fopen(const char *file, const char *flags){ 21.147 - IOStream *io = NULL; 21.148 - gzFile *fgz; 21.149 - fgz = gzopen(file, flags); 21.150 - if(fgz){ 21.151 - io = gzip_stream_new(fgz); 21.152 - if(!io){ 21.153 - gzclose(fgz); 21.154 - } 21.155 - } 21.156 - return io; 21.157 -} 21.158 - 21.159 -/** IOStream version of fdopen(). 21.160 - * 21.161 - * @param fd file descriptor 21.162 - * @param flags giving the mode to open in (as for fdopen()) 21.163 - * @return new stream for the open file, or NULL if failed. Always takes 21.164 - * ownership of fd. 21.165 - */ 21.166 -IOStream *gzip_stream_fdopen(int fd, const char *flags){ 21.167 - IOStream *io = NULL; 21.168 - gzFile *fgz; 21.169 - fgz = gzdopen(fd, flags); 21.170 - if(fgz){ 21.171 - io = gzip_stream_new(fgz); 21.172 - if(!io) 21.173 - gzclose(fgz); 21.174 - } 21.175 - return io; 21.176 -} 21.177 -#endif
22.1 --- a/tools/libxutil/gzip_stream.h Tue May 24 21:10:23 2005 +0000 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,30 +0,0 @@ 22.4 -/* 22.5 - * Copyright (C) 2003 Hewlett-Packard Company. 22.6 - * 22.7 - * This library is free software; you can redistribute it and/or modify 22.8 - * it under the terms of the GNU Lesser General Public License as published by 22.9 - * the Free Software Foundation; either version 2.1 of the License, or 22.10 - * (at your option) any later version. 22.11 - * 22.12 - * This library is distributed in the hope that it will be useful, 22.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 22.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22.15 - * GNU Lesser General Public License for more details. 22.16 - * 22.17 - * You should have received a copy of the GNU Lesser General Public License 22.18 - * along with this library; if not, write to the Free Software 22.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22.20 - */ 22.21 - 22.22 -#ifndef _XUTIL_GZIP_STREAM_H_ 22.23 -#define _XUTIL_GZIP_STREAM_H_ 22.24 - 22.25 -#ifndef __KERNEL__ 22.26 -#include "iostream.h" 22.27 -#include "zlib.h" 22.28 - 22.29 -extern IOStream *gzip_stream_new(gzFile *f); 22.30 -extern IOStream *gzip_stream_fopen(const char *file, const char *flags); 22.31 -extern IOStream *gzip_stream_fdopen(int fd, const char *flags); 22.32 -#endif 22.33 -#endif /* !_XUTIL_GZIP_STREAM_H_ */
23.1 --- a/tools/libxutil/hash_table.c Tue May 24 21:10:23 2005 +0000 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,640 +0,0 @@ 23.4 -/* 23.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 23.6 - * 23.7 - * This library is free software; you can redistribute it and/or modify 23.8 - * it under the terms of the GNU Lesser General Public License as published by 23.9 - * the Free Software Foundation; either version 2.1 of the License, or 23.10 - * (at your option) any later version. 23.11 - * 23.12 - * This library is distributed in the hope that it will be useful, 23.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 23.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.15 - * GNU Lesser General Public License for more details. 23.16 - * 23.17 - * You should have received a copy of the GNU Lesser General Public License 23.18 - * along with this library; if not, write to the Free Software 23.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23.20 - */ 23.21 - 23.22 -#ifdef __KERNEL__ 23.23 -# include <linux/config.h> 23.24 -# include <linux/module.h> 23.25 -# include <linux/kernel.h> 23.26 -# include <linux/errno.h> 23.27 -#else 23.28 -# include <errno.h> 23.29 -# include <stddef.h> 23.30 -#endif 23.31 - 23.32 -//#include <limits.h> 23.33 - 23.34 -#include "allocate.h" 23.35 -#include "hash_table.h" 23.36 - 23.37 -/** @file 23.38 - * Base support for hashtables. 23.39 - * 23.40 - * Hash codes are reduced modulo the number of buckets to index tables, 23.41 - * so there is no need for hash functions to limit the range of hashcodes. 23.42 - * In fact it is assumed that hashcodes do not change when the number of 23.43 - * buckets in the table changes. 23.44 - */ 23.45 - 23.46 -/*==========================================================================*/ 23.47 -/** Number of bits in half a word. */ 23.48 -//#if __WORDSIZE == 64 23.49 -//#define HALF_WORD_BITS 32 23.50 -//#else 23.51 -#define HALF_WORD_BITS 16 23.52 -//#endif 23.53 - 23.54 -/** Mask for lo half of a word. On 32-bit this is 23.55 - * (1<<16) - 1 = 65535 = 0xffff 23.56 - * It's 4294967295 = 0xffffffff on 64-bit. 23.57 - */ 23.58 -#define LO_HALF_MASK ((1 << HALF_WORD_BITS) - 1) 23.59 - 23.60 -/** Get the lo half of a word. */ 23.61 -#define LO_HALF(x) ((x) & LO_HALF_MASK) 23.62 - 23.63 -/** Get the hi half of a word. */ 23.64 -#define HI_HALF(x) ((x) >> HALF_WORD_BITS) 23.65 - 23.66 -/** Do a full hash on both inputs, using DES-style non-linear scrambling. 23.67 - * Both inputs are replaced with the results of the hash. 23.68 - * 23.69 - * @param pleft input/output word 23.70 - * @param pright input/output word 23.71 - */ 23.72 -void pseudo_des(unsigned long *pleft, unsigned long *pright){ 23.73 - // Bit-rich mixing constant. 23.74 - static const unsigned long a_mixer[] = { 23.75 - 0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L, }; 23.76 - 23.77 - // Bit-rich mixing constant. 23.78 - static const unsigned long b_mixer[] = { 23.79 - 0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L, }; 23.80 - 23.81 - // Number of iterations - must be 2 or 4. 23.82 - static const int ncycle = 4; 23.83 - //static const int ncycle = 2; 23.84 - 23.85 - unsigned long left = *pleft, right = *pright; 23.86 - unsigned long v, v_hi, v_lo; 23.87 - int i; 23.88 - 23.89 - for(i=0; i<ncycle; i++){ 23.90 - // Flip some bits in right to get v. 23.91 - v = right; 23.92 - v ^= a_mixer[i]; 23.93 - // Get lo and hi halves of v. 23.94 - v_lo = LO_HALF(v); 23.95 - v_hi = HI_HALF(v); 23.96 - // Non-linear mix of the halves of v. 23.97 - v = ((v_lo * v_lo) + ~(v_hi * v_hi)); 23.98 - // Swap the halves of v. 23.99 - v = (HI_HALF(v) | (LO_HALF(v) << HALF_WORD_BITS)); 23.100 - // Flip some bits. 23.101 - v ^= b_mixer[i]; 23.102 - // More non-linear mixing. 23.103 - v += (v_lo * v_hi); 23.104 - v ^= left; 23.105 - left = right; 23.106 - right = v; 23.107 - } 23.108 - *pleft = left; 23.109 - *pright = right; 23.110 -} 23.111 - 23.112 -/** Hash a string. 23.113 - * 23.114 - * @param s input to hash 23.115 - * @return hashcode 23.116 - */ 23.117 -Hashcode hash_string(char *s){ 23.118 - Hashcode h = 0; 23.119 - if(s){ 23.120 - for( ; *s; s++){ 23.121 - h = hash_2ul(h, *s); 23.122 - } 23.123 - } 23.124 - return h; 23.125 -} 23.126 - 23.127 -/** Get the bucket for a hashcode in a hash table. 23.128 - * 23.129 - * @param table to get bucket from 23.130 - * @param hashcode to get bucket for 23.131 - * @return bucket 23.132 - */ 23.133 -inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){ 23.134 - return table->buckets + (hashcode % table->buckets_n); 23.135 -} 23.136 - 23.137 -/** Initialize a hash table. 23.138 - * Can be safely called more than once. 23.139 - * 23.140 - * @param table to initialize 23.141 - */ 23.142 -void HashTable_init(HashTable *table){ 23.143 - int i; 23.144 - 23.145 - if(!table->init_done){ 23.146 - table->init_done = 1; 23.147 - table->next_id = 0; 23.148 - for(i=0; i<table->buckets_n; i++){ 23.149 - HTBucket *bucket = get_bucket(table, i); 23.150 - bucket->head = 0; 23.151 - bucket->count = 0; 23.152 - } 23.153 - table->entry_count = 0; 23.154 - } 23.155 -} 23.156 - 23.157 -/** Allocate a new hashtable. 23.158 - * If the number of buckets is not positive the default is used. 23.159 - * The number of buckets should usually be prime. 23.160 - * 23.161 - * @param buckets_n number of buckets 23.162 - * @return new hashtable or null 23.163 - */ 23.164 -HashTable *HashTable_new(int buckets_n){ 23.165 - HashTable *z = ALLOCATE(HashTable); 23.166 - if(!z) goto exit; 23.167 - if(buckets_n <= 0){ 23.168 - buckets_n = HT_BUCKETS_N; 23.169 - } 23.170 - z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); 23.171 - if(!z->buckets){ 23.172 - deallocate(z); 23.173 - z = 0; 23.174 - goto exit; 23.175 - } 23.176 - z->buckets_n = buckets_n; 23.177 - HashTable_init(z); 23.178 - exit: 23.179 - return z; 23.180 -} 23.181 - 23.182 -/** Free a hashtable. 23.183 - * Any entries are removed and freed. 23.184 - * 23.185 - * @param h hashtable (ignored if null) 23.186 - */ 23.187 -void HashTable_free(HashTable *h){ 23.188 - if(h){ 23.189 - HashTable_clear(h); 23.190 - deallocate(h->buckets); 23.191 - deallocate(h); 23.192 - } 23.193 -} 23.194 - 23.195 -/** Push an entry on the list in the bucket for a given hashcode. 23.196 - * 23.197 - * @param table to add entry to 23.198 - * @param hashcode for the entry 23.199 - * @param entry to add 23.200 - */ 23.201 -static inline void push_on_bucket(HashTable *table, Hashcode hashcode, 23.202 - HTEntry *entry){ 23.203 - HTBucket *bucket; 23.204 - HTEntry *old_head; 23.205 - 23.206 - bucket = get_bucket(table, hashcode); 23.207 - old_head = bucket->head; 23.208 - bucket->count++; 23.209 - bucket->head = entry; 23.210 - entry->next = old_head; 23.211 -} 23.212 - 23.213 -/** Change the number of buckets in a hashtable. 23.214 - * No-op if the number of buckets is not positive. 23.215 - * Existing entries are reallocated to buckets based on their hashcodes. 23.216 - * The table is unmodified if the number of buckets cannot be changed. 23.217 - * 23.218 - * @param table hashtable 23.219 - * @param buckets_n new number of buckets 23.220 - * @return 0 on success, error code otherwise 23.221 - */ 23.222 -int HashTable_set_buckets_n(HashTable *table, int buckets_n){ 23.223 - int err = 0; 23.224 - HTBucket *old_buckets = table->buckets; 23.225 - int old_buckets_n = table->buckets_n; 23.226 - int i; 23.227 - 23.228 - if(buckets_n <= 0){ 23.229 - err = -EINVAL; 23.230 - goto exit; 23.231 - } 23.232 - table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); 23.233 - if(!table->buckets){ 23.234 - err = -ENOMEM; 23.235 - table->buckets = old_buckets; 23.236 - goto exit; 23.237 - } 23.238 - table->buckets_n = buckets_n; 23.239 - for(i=0; i<old_buckets_n; i++){ 23.240 - HTBucket *bucket = old_buckets + i; 23.241 - HTEntry *entry, *next; 23.242 - for(entry = bucket->head; entry; entry = next){ 23.243 - next = entry->next; 23.244 - push_on_bucket(table, entry->hashcode, entry); 23.245 - } 23.246 - } 23.247 - deallocate(old_buckets); 23.248 - exit: 23.249 - return err; 23.250 -} 23.251 - 23.252 -/** Adjust the number of buckets so the table is neither too full nor too empty. 23.253 - * The table is unmodified if adjusting fails. 23.254 - * 23.255 - * @param table hash table 23.256 - * @param buckets_min minimum number of buckets (use default if 0 or negative) 23.257 - * @return 0 on success, error code otherwise 23.258 - */ 23.259 -int HashTable_adjust(HashTable *table, int buckets_min){ 23.260 - int buckets_n = 0; 23.261 - int err = 0; 23.262 - if(buckets_min <= 0) buckets_min = HT_BUCKETS_N; 23.263 - if(table->entry_count >= table->buckets_n){ 23.264 - // The table is dense - expand it. 23.265 - buckets_n = 2 * table->buckets_n; 23.266 - } else if((table->buckets_n > buckets_min) && 23.267 - (4 * table->entry_count < table->buckets_n)){ 23.268 - // The table is more than minimum size and sparse - shrink it. 23.269 - buckets_n = 2 * table->entry_count; 23.270 - if(buckets_n < buckets_min) buckets_n = buckets_min; 23.271 - } 23.272 - if(buckets_n){ 23.273 - err = HashTable_set_buckets_n(table, buckets_n); 23.274 - } 23.275 - return err; 23.276 -} 23.277 - 23.278 -/** Allocate a new entry for a given value. 23.279 - * 23.280 - * @param value to put in the entry 23.281 - * @return entry, or 0 on failure 23.282 - */ 23.283 -HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){ 23.284 - HTEntry *z = ALLOCATE(HTEntry); 23.285 - if(z){ 23.286 - z->hashcode = hashcode; 23.287 - z->key = key; 23.288 - z->value = value; 23.289 - } 23.290 - return z; 23.291 -} 23.292 - 23.293 -/** Free an entry. 23.294 - * 23.295 - * @param z entry to free 23.296 - */ 23.297 -inline void HTEntry_free(HTEntry *z){ 23.298 - if(z){ 23.299 - deallocate(z); 23.300 - } 23.301 -} 23.302 - 23.303 -/** Free an entry in a hashtable. 23.304 - * The table's entry_free_fn is used is defined, otherwise 23.305 - * the HTEntry itself is freed. 23.306 - * 23.307 - * @param table hashtable 23.308 - * @param entry to free 23.309 - */ 23.310 -inline void HashTable_free_entry(HashTable *table, HTEntry *entry){ 23.311 - if(!entry)return; 23.312 - if(table && table->entry_free_fn){ 23.313 - table->entry_free_fn(table, entry); 23.314 - } else { 23.315 - HTEntry_free(entry); 23.316 - } 23.317 -} 23.318 - 23.319 -/** Get the first entry satisfying a test from the bucket for the 23.320 - * given hashcode. 23.321 - * 23.322 - * @param table to look in 23.323 - * @param hashcode indicates the bucket 23.324 - * @param test_fn test to apply to elements 23.325 - * @param arg first argument to calls to test_fn 23.326 - * @return entry found, or 0 23.327 - */ 23.328 -inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, 23.329 - TableTestFn *test_fn, TableArg arg){ 23.330 - HTBucket *bucket; 23.331 - HTEntry *entry = 0; 23.332 - HTEntry *next; 23.333 - 23.334 - bucket = get_bucket(table, hashcode); 23.335 - for(entry = bucket->head; entry; entry = next){ 23.336 - next = entry->next; 23.337 - if(test_fn(arg, table, entry)){ 23.338 - break; 23.339 - } 23.340 - } 23.341 - return entry; 23.342 -} 23.343 - 23.344 -/** Test hashtable keys for equality. 23.345 - * Uses the table's key_equal_fn if defined, otherwise pointer equality. 23.346 - * 23.347 - * @param key1 key to compare 23.348 - * @param key2 key to compare 23.349 - * @return 1 if equal, 0 otherwise 23.350 - */ 23.351 -inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){ 23.352 - return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1==key2); 23.353 -} 23.354 - 23.355 -/** Compute the hashcode of a hashtable key. 23.356 - * The table's key_hash_fn is used if defined, otherwise the address of 23.357 - * the key is hashed. 23.358 - * 23.359 - * @param table hashtable 23.360 - * @param key to hash 23.361 - * @return hashcode 23.362 - */ 23.363 -inline Hashcode HashTable_key_hash(HashTable *table, void *key){ 23.364 - return (table->key_hash_fn ? table->key_hash_fn(key) : hash_ul((unsigned long)key)); 23.365 -} 23.366 - 23.367 -/** Test if an entry has a given key. 23.368 - * 23.369 - * @param arg containing key to test for 23.370 - * @param table the entry is in 23.371 - * @param entry to test 23.372 - * @return 1 if the entry has the key, 0 otherwise 23.373 - */ 23.374 -static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){ 23.375 - return HashTable_key_equal(table, arg.ptr, entry->key); 23.376 -} 23.377 - 23.378 -/** Get an entry with a given key. 23.379 - * 23.380 - * @param table to search 23.381 - * @param key to look for 23.382 - * @return entry if found, null otherwise 23.383 - */ 23.384 -#if 0 23.385 -inline HTEntry * HashTable_get_entry(HashTable *table, void *key){ 23.386 - TableArg arg = { ptr: key }; 23.387 - return HashTable_find_entry(table, HashTable_key_hash(table, key), has_key, arg); 23.388 -} 23.389 -#else 23.390 -inline HTEntry * HashTable_get_entry(HashTable *table, void *key){ 23.391 - Hashcode hashcode; 23.392 - HTBucket *bucket; 23.393 - HTEntry *entry = 0; 23.394 - HTEntry *next; 23.395 - 23.396 - hashcode = HashTable_key_hash(table, key); 23.397 - bucket = get_bucket(table, hashcode); 23.398 - for(entry = bucket->head; entry; entry = next){ 23.399 - next = entry->next; 23.400 - if(HashTable_key_equal(table, key, entry->key)){ 23.401 - break; 23.402 - } 23.403 - } 23.404 - return entry; 23.405 -} 23.406 -#endif 23.407 - 23.408 -/** Get the value of an entry with a given key. 23.409 - * 23.410 - * @param table to search 23.411 - * @param key to look for 23.412 - * @return value if an entry was found, null otherwise 23.413 - */ 23.414 -inline void * HashTable_get(HashTable *table, void *key){ 23.415 - HTEntry *entry = HashTable_get_entry(table, key); 23.416 - return (entry ? entry->value : 0); 23.417 -} 23.418 - 23.419 -/** Print the buckets in a table. 23.420 - * 23.421 - * @param table to print 23.422 - */ 23.423 -void show_buckets(HashTable *table, IOStream *io){ 23.424 - int i,j ; 23.425 - IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n); 23.426 - for(i=0; i<table->buckets_n; i++){ 23.427 - if(0 || table->buckets[i].count>0){ 23.428 - IOStream_print(io, "bucket %3d %3d %10p ", i, 23.429 - table->buckets[i].count, 23.430 - table->buckets[i].head); 23.431 - for(j = table->buckets[i].count; j>0; j--){ 23.432 - IOStream_print(io, "+"); 23.433 - } 23.434 - IOStream_print(io, "\n"); 23.435 - } 23.436 - } 23.437 - HashTable_print(table, io); 23.438 -} 23.439 - 23.440 -/** Print an entry in a table. 23.441 - * 23.442 - * @param entry to print 23.443 - * @param arg a pointer to an IOStream to print to 23.444 - * @return 0 23.445 - */ 23.446 -static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){ 23.447 - IOStream *io = (IOStream*)arg.ptr; 23.448 - IOStream_print(io, " b=%4lx h=%08lx i=%08lx |-> e=%8p k=%8p v=%8p\n", 23.449 - entry->hashcode % table->buckets_n, 23.450 - entry->hashcode, 23.451 - entry->index, 23.452 - entry, entry->key, entry->value); 23.453 - return 0; 23.454 -} 23.455 - 23.456 -/** Print a hash table. 23.457 - * 23.458 - * @param table to print 23.459 - */ 23.460 -void HashTable_print(HashTable *table, IOStream *io){ 23.461 - IOStream_print(io, "{\n"); 23.462 - HashTable_map(table, print_entry, (TableArg){ ptr: io }); 23.463 - IOStream_print(io, "}\n"); 23.464 -} 23.465 -/*==========================================================================*/ 23.466 - 23.467 -/** Get the next entry id to use for a table. 23.468 - * 23.469 - * @param table hash table 23.470 - * @return non-zero entry id 23.471 - */ 23.472 -static inline unsigned long get_next_id(HashTable *table){ 23.473 - unsigned long id; 23.474 - 23.475 - if(table->next_id == 0){ 23.476 - table->next_id = 1; 23.477 - } 23.478 - id = table->next_id++; 23.479 - return id; 23.480 -} 23.481 - 23.482 -/** Add an entry to the bucket for the 23.483 - * given hashcode. 23.484 - * 23.485 - * @param table to insert in 23.486 - * @param hashcode indicates the bucket 23.487 - * @param key to add an entry for 23.488 - * @param value to add an entry for 23.489 - * @return entry on success, 0 on failure 23.490 - */ 23.491 -inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){ 23.492 - HTEntry *entry = HTEntry_new(hashcode, key, value); 23.493 - if(entry){ 23.494 - entry->index = get_next_id(table); 23.495 - push_on_bucket(table, hashcode, entry); 23.496 - table->entry_count++; 23.497 - } 23.498 - return entry; 23.499 -} 23.500 - 23.501 -/** Move the front entry for a bucket to the correct point in the bucket order as 23.502 - * defined by the order function. If this is called every time a new entry is added 23.503 - * the bucket will be maintained in sorted order. 23.504 - * 23.505 - * @param table to modify 23.506 - * @param hashcode indicates the bucket 23.507 - * @param order entry comparison function 23.508 - * @return 0 if an entry was moved, 1 if not 23.509 - */ 23.510 -int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){ 23.511 - HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL; 23.512 - HTBucket *bucket; 23.513 - int err = 1; 23.514 - 23.515 - bucket = get_bucket(table, hashcode); 23.516 - new_entry = bucket->head; 23.517 - if(!new_entry || !new_entry->next) goto exit; 23.518 - for(entry = new_entry->next; entry; prev = entry, entry = entry->next){ 23.519 - if(order(new_entry, entry) <= 0) break; 23.520 - } 23.521 - if(prev){ 23.522 - err = 0; 23.523 - bucket->head = new_entry->next; 23.524 - new_entry->next = entry; 23.525 - prev->next = new_entry; 23.526 - } 23.527 - exit: 23.528 - return err; 23.529 -} 23.530 - 23.531 -/** Add an entry to a hashtable. 23.532 - * The entry is added to the bucket for its key's hashcode. 23.533 - * 23.534 - * @param table to insert in 23.535 - * @param key to add an entry for 23.536 - * @param value to add an entry for 23.537 - * @return entry on success, 0 on failure 23.538 - */ 23.539 -inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){ 23.540 - return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value); 23.541 -} 23.542 - 23.543 - 23.544 -/** Remove entries satisfying a test from the bucket for the 23.545 - * given hashcode. 23.546 - * 23.547 - * @param table to remove from 23.548 - * @param hashcode indicates the bucket 23.549 - * @param test_fn test to apply to elements 23.550 - * @param arg first argument to calls to test_fn 23.551 - * @return number of entries removed 23.552 - */ 23.553 -inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode, 23.554 - TableTestFn *test_fn, TableArg arg){ 23.555 - HTBucket *bucket; 23.556 - HTEntry *entry, *prev = 0, *next; 23.557 - int removed_count = 0; 23.558 - 23.559 - bucket = get_bucket(table, hashcode); 23.560 - for(entry = bucket->head; entry; entry = next){ 23.561 - next = entry->next; 23.562 - if(test_fn(arg, table, entry)){ 23.563 - if(prev){ 23.564 - prev->next = next; 23.565 - } else { 23.566 - bucket->head = next; 23.567 - } 23.568 - bucket->count--; 23.569 - table->entry_count--; 23.570 - removed_count++; 23.571 - HashTable_free_entry(table, entry); 23.572 - entry = 0; 23.573 - } 23.574 - prev = entry; 23.575 - } 23.576 - return removed_count; 23.577 -} 23.578 - 23.579 -/** Remove entries with a given key. 23.580 - * 23.581 - * @param table to remove from 23.582 - * @param key of entries to remove 23.583 - * @return number of entries removed 23.584 - */ 23.585 -inline int HashTable_remove(HashTable *table, void *key){ 23.586 -#if 1 23.587 - Hashcode hashcode; 23.588 - HTBucket *bucket; 23.589 - HTEntry *entry, *prev = 0, *next; 23.590 - int removed_count = 0; 23.591 - 23.592 - hashcode = HashTable_key_hash(table, key); 23.593 - bucket = get_bucket(table, hashcode); 23.594 - for(entry = bucket->head; entry; entry = next){ 23.595 - next = entry->next; 23.596 - if(HashTable_key_equal(table, key, entry->key)){ 23.597 - if(prev){ 23.598 - prev->next = next; 23.599 - } else { 23.600 - bucket->head = next; 23.601 - } 23.602 - bucket->count--; 23.603 - table->entry_count--; 23.604 - removed_count++; 23.605 - HashTable_free_entry(table, entry); 23.606 - entry = 0; 23.607 - } 23.608 - prev = entry; 23.609 - } 23.610 - return removed_count; 23.611 -#else 23.612 - return HashTable_remove_entry(table, HashTable_key_hash(table, key), 23.613 - has_key, (TableArg){ ptr: key}); 23.614 -#endif 23.615 -} 23.616 - 23.617 -/** Remove (and free) all the entries in a bucket. 23.618 - * 23.619 - * @param bucket to clear 23.620 - */ 23.621 -static inline void bucket_clear(HashTable *table, HTBucket *bucket){ 23.622 - HTEntry *entry, *next; 23.623 - 23.624 - for(entry = bucket->head; entry; entry = next){ 23.625 - next = entry->next; 23.626 - HashTable_free_entry(table, entry); 23.627 - } 23.628 - bucket->head = 0; 23.629 - table->entry_count -= bucket->count; 23.630 - bucket->count = 0; 23.631 -} 23.632 - 23.633 -/** Remove (and free) all the entries in a table. 23.634 - * 23.635 - * @param table to clear 23.636 - */ 23.637 -void HashTable_clear(HashTable *table){ 23.638 - int i, n = table->buckets_n; 23.639 - 23.640 - for(i=0; i<n; i++){ 23.641 - bucket_clear(table, table->buckets + i); 23.642 - } 23.643 -}
24.1 --- a/tools/libxutil/hash_table.h Tue May 24 21:10:23 2005 +0000 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,294 +0,0 @@ 24.4 -/* 24.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 24.6 - * 24.7 - * This library is free software; you can redistribute it and/or modify 24.8 - * it under the terms of the GNU Lesser General Public License as published by 24.9 - * the Free Software Foundation; either version 2.1 of the License, or 24.10 - * (at your option) any later version. 24.11 - * 24.12 - * This library is distributed in the hope that it will be useful, 24.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 24.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.15 - * GNU Lesser General Public License for more details. 24.16 - * 24.17 - * You should have received a copy of the GNU Lesser General Public License 24.18 - * along with this library; if not, write to the Free Software 24.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24.20 - */ 24.21 - 24.22 -#ifndef _XUTIL_HASH_TABLE_H_ 24.23 -#define _XUTIL_HASH_TABLE_H_ 24.24 - 24.25 -#include "iostream.h" 24.26 - 24.27 -typedef unsigned long Hashcode; 24.28 - 24.29 -/** Type used to pass parameters to table functions. */ 24.30 -typedef union TableArg { 24.31 - unsigned long ul; 24.32 - void *ptr; 24.33 -} TableArg; 24.34 - 24.35 -/** An entry in a bucket list. */ 24.36 -typedef struct HTEntry { 24.37 - /** Hashcode of the entry's key. */ 24.38 - Hashcode hashcode; 24.39 - /** Identifier for this entry in the table. */ 24.40 - int index; 24.41 - /** The key for this entry. */ 24.42 - void *key; 24.43 - /** The value in this entry. */ 24.44 - void *value; 24.45 - /** The next entry in the list. */ 24.46 - struct HTEntry *next; 24.47 -} HTEntry; 24.48 - 24.49 -/** A bucket in a rule table. */ 24.50 -typedef struct HTBucket { 24.51 - /** Number of entries in the bucket. */ 24.52 - int count; 24.53 - /** First entry in the bucket (may be null). */ 24.54 - HTEntry *head; 24.55 -} HTBucket; 24.56 - 24.57 -/** Default number of buckets in a hash table. 24.58 - * You want enough buckets so the lists in the buckets will typically be short. 24.59 - * It's a good idea if this is prime, since that will help to spread hashcodes 24.60 - * around the table. 24.61 - */ 24.62 -//#define HT_BUCKETS_N 1 24.63 -//#define HT_BUCKETS_N 3 24.64 -//#define HT_BUCKETS_N 7 24.65 -//#define HT_BUCKETS_N 17 24.66 -//#define HT_BUCKETS_N 97 24.67 -//#define HT_BUCKETS_N 211 24.68 -//#define HT_BUCKETS_N 401 24.69 -#define HT_BUCKETS_N 1021 24.70 - 24.71 -typedef struct HashTable HashTable; 24.72 - 24.73 -/** Type for a function used to select table entries. */ 24.74 -typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry); 24.75 - 24.76 -/** Type for a function to map over table entries. */ 24.77 -typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry); 24.78 - 24.79 -/** Type for a function to free table entries. */ 24.80 -typedef void TableFreeFn(HashTable *table, HTEntry *entry); 24.81 - 24.82 -/** Type for a function to hash table keys. */ 24.83 -typedef Hashcode TableHashFn(void *key); 24.84 - 24.85 -/** Type for a function to test table keys for equality. */ 24.86 -typedef int TableEqualFn(void *key1, void *key2); 24.87 - 24.88 -/** Type for a function to order table entries. */ 24.89 -typedef int TableOrderFn(HTEntry *e1, HTEntry *e2); 24.90 - 24.91 -/** General hash table. 24.92 - * A hash table with a list in each bucket. 24.93 - * Functions can be supplied for freeing entries, hashing keys, and comparing keys. 24.94 - * These all default to 0, when default behaviour treating keys as integers is used. 24.95 - */ 24.96 -struct HashTable { 24.97 - /** Flag indicating whether the table has been initialised. */ 24.98 - int init_done; 24.99 - /** Next value for the id field in inserted rules. */ 24.100 - unsigned long next_id; 24.101 - /** Number of buckets in the bucket array. */ 24.102 - int buckets_n; 24.103 - /** Array of buckets, each with its own list. */ 24.104 - HTBucket *buckets; 24.105 - /** Number of entries in the table. */ 24.106 - int entry_count; 24.107 - /** Function to free keys and values in entries. */ 24.108 - TableFreeFn *entry_free_fn; 24.109 - /** Function to hash keys. */ 24.110 - TableHashFn *key_hash_fn; 24.111 - /** Function to compare keys for equality. */ 24.112 - TableEqualFn *key_equal_fn; 24.113 - /** Place for the user of the table to hang extra data. */ 24.114 - void *user_data; 24.115 -}; 24.116 - 24.117 -extern HashTable *HashTable_new(int bucket_n); 24.118 -extern void HashTable_free(HashTable *table); 24.119 -extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value); 24.120 -extern void HTEntry_free(HTEntry *entry); 24.121 -extern int HashTable_set_bucket_n(HashTable *table, int bucket_n); 24.122 -extern void HashTable_clear(HashTable *table); 24.123 -extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value); 24.124 -extern HTEntry * HashTable_get_entry(HashTable *table, void *key); 24.125 -extern HTEntry * HashTable_add(HashTable *table, void *key, void *value); 24.126 -extern void * HashTable_get(HashTable *table, void *key); 24.127 -extern int HashTable_remove(HashTable *table, void *key); 24.128 -extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, 24.129 - TableTestFn *test_fn, TableArg arg); 24.130 -extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode, 24.131 - TableTestFn *test_fn, TableArg arg); 24.132 -//extern int HashTable_map(HashTable *table, TableMapFn *map_fn, TableArg arg); 24.133 -extern void HashTable_print(HashTable *table, IOStream *out); 24.134 -extern int HashTable_set_buckets_n(HashTable *table, int buckets_n); 24.135 -extern int HashTable_adjust(HashTable *table, int buckets_min); 24.136 -extern void pseudo_des(unsigned long *pleft, unsigned long *pright); 24.137 -extern Hashcode hash_string(char *s); 24.138 - 24.139 -extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order); 24.140 - 24.141 -/** Control whether to use hashing based on DES or simple 24.142 - * hashing. DES hashing is `more random' but much more expensive. 24.143 - */ 24.144 -#define HASH_PSEUDO_DES 0 24.145 - 24.146 -/** Hash a long using a quick and dirty linear congruential random number generator. 24.147 - * See `Numerical Recipes in C', Chapter 7, "An Even Quicker Generator". 24.148 - * 24.149 - * @param a value to hash 24.150 - * @return hashed input 24.151 - */ 24.152 -static inline unsigned long lcrng_hash(unsigned long a){ 24.153 - return (1664525L * a + 1013904223L); 24.154 -} 24.155 - 24.156 -/** Hash an unsigned long. 24.157 - * 24.158 - * @param a input to hash 24.159 - * @return hashcode 24.160 - */ 24.161 -static inline Hashcode hash_ul(unsigned long a){ 24.162 -#if HASH_PSEUDO_DES 24.163 - unsigned long left = a; 24.164 - unsigned long right = 0L; 24.165 - pseudo_des(&left, &right); 24.166 - return right; 24.167 -#else 24.168 - a = lcrng_hash(a); 24.169 - a = lcrng_hash(a); 24.170 - return a; 24.171 -#endif 24.172 -} 24.173 - 24.174 -/** Hash two unsigned longs together. 24.175 - * 24.176 - * @param a input to hash 24.177 - * @param b input to hash 24.178 - * @return hashcode 24.179 - */ 24.180 -static inline Hashcode hash_2ul(unsigned long a, unsigned long b){ 24.181 -#if HASH_PSEUDO_DES 24.182 - unsigned long left = a; 24.183 - unsigned long right = b; 24.184 - pseudo_des(&left, &right); 24.185 - return right; 24.186 -#else 24.187 - a = lcrng_hash(a); 24.188 - a ^= b; 24.189 - a = lcrng_hash(a); 24.190 - return a; 24.191 -#endif 24.192 -} 24.193 - 24.194 -/** Hash a hashcode and an unsigned long together. 24.195 - * 24.196 - * @param a input hashcode 24.197 - * @param b input to hash 24.198 - * @return hashcode 24.199 - */ 24.200 -static inline Hashcode hash_hul(Hashcode a, unsigned long b){ 24.201 -#if HASH_PSEUDO_DES 24.202 - unsigned long left = a; 24.203 - unsigned long right = b; 24.204 - pseudo_des(&left, &right); 24.205 - return right; 24.206 -#else 24.207 - a ^= b; 24.208 - a = lcrng_hash(a); 24.209 - return a; 24.210 -#endif 24.211 -} 24.212 - 24.213 -/** Macro to declare variables for HashTable_for_each() to use. 24.214 - * 24.215 - * @param entry variable that is set to entries in the table 24.216 - */ 24.217 -#define HashTable_for_decl(entry) \ 24.218 - HashTable *_var_table; \ 24.219 - HTBucket *_var_bucket; \ 24.220 - HTBucket *_var_end; \ 24.221 - HTEntry *_var_next; \ 24.222 - HTEntry *entry 24.223 - 24.224 -/** Macro to iterate over the entries in a hashtable. 24.225 - * Must be in a scope where HashTable_for_decl() has been used to declare 24.226 - * variables for it to use. 24.227 - * The variable 'entry' is iterated over entries in the table. 24.228 - * The code produced is syntactically a loop, so it must be followed by 24.229 - * a loop body, typically some statements in braces: 24.230 - * HashTable_for_each(entry, table){ ...loop body... } 24.231 - * 24.232 - * HashTable_for_each() and HashTable_for_decl() cannot be used for nested 24.233 - * loops as variables will clash. 24.234 - * 24.235 - * @note The simplest way to code a direct loop over the entries in a hashtable 24.236 - * is to use a loop over the buckets, with a nested loop over the entries 24.237 - * in a bucket. Using this approach in a macro means the macro contains 24.238 - * an opening brace, and calls to it must be followed by 2 braces! 24.239 - * To avoid this the code has been restructured so that it is a for loop. 24.240 - * So that statements could be used in the test expression of the for loop, 24.241 - * we have used the gcc statement expression extension ({ ... }). 24.242 - * 24.243 - * @param entry variable to iterate over the entries 24.244 - * @param table to iterate over (non-null) 24.245 - */ 24.246 -#define HashTable_for_each(entry, table) \ 24.247 - _var_table = table; \ 24.248 - _var_bucket = _var_table->buckets; \ 24.249 - _var_end = _var_bucket + _var_table->buckets_n; \ 24.250 - for(entry=0, _var_next=0; \ 24.251 - ({ if(_var_next){ \ 24.252 - entry = _var_next; \ 24.253 - _var_next = entry->next; \ 24.254 - } else { \ 24.255 - while(_var_bucket < _var_end){ \ 24.256 - entry = _var_bucket->head; \ 24.257 - _var_bucket++; \ 24.258 - if(entry){ \ 24.259 - _var_next = entry->next; \ 24.260 - break; \ 24.261 - } \ 24.262 - } \ 24.263 - }; \ 24.264 - entry; }); \ 24.265 - entry = _var_next ) 24.266 - 24.267 -/** Map a function over the entries in a table. 24.268 - * Mapping stops when the function returns a non-zero value. 24.269 - * Uses the gcc statement expression extension ({ ... }). 24.270 - * 24.271 - * @param table to map over 24.272 - * @param fn function to apply to entries 24.273 - * @param arg first argument to call the function with 24.274 - * @return 0 if fn always returned 0, first non-zero value otherwise 24.275 - */ 24.276 -#define HashTable_map(table, fn, arg) \ 24.277 - ({ HashTable_for_decl(_var_entry); \ 24.278 - TableArg _var_arg = arg; \ 24.279 - int _var_value = 0; \ 24.280 - HashTable_for_each(_var_entry, table){ \ 24.281 - if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \ 24.282 - } \ 24.283 - _var_value; }) 24.284 - 24.285 -/** Cast x to the type for a key or value in a hash table. 24.286 - * This avoids compiler warnings when using short integers 24.287 - * as keys or values (especially on 64-bit platforms). 24.288 - */ 24.289 -#define HKEY(x) ((void*)(unsigned long)(x)) 24.290 - 24.291 -/** Cast x from the type for a key or value in a hash table. 24.292 - * to an unsigned long. This avoids compiler warnings when using 24.293 - * short integers as keys or values (especially on 64-bit platforms). 24.294 - */ 24.295 -#define HVAL(x) ((unsigned long)(x)) 24.296 - 24.297 -#endif /* !_XUTIL_HASH_TABLE_H_ */
25.1 --- a/tools/libxutil/iostream.c Tue May 24 21:10:23 2005 +0000 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,55 +0,0 @@ 25.4 -/* 25.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 25.6 - * 25.7 - * This library is free software; you can redistribute it and/or modify 25.8 - * it under the terms of the GNU Lesser General Public License as published by 25.9 - * the Free Software Foundation; either version 2.1 of the License, or 25.10 - * (at your option) any later version. 25.11 - * 25.12 - * This library is distributed in the hope that it will be useful, 25.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 25.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.15 - * GNU Lesser General Public License for more details. 25.16 - * 25.17 - * You should have received a copy of the GNU Lesser General Public License 25.18 - * along with this library; if not, write to the Free Software 25.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25.20 - */ 25.21 - 25.22 -#include "iostream.h" 25.23 -#include "sys_string.h" 25.24 - 25.25 -/** Print on a stream, like vfprintf(). 25.26 - * 25.27 - * @param stream to print to 25.28 - * @param format for the print (as fprintf()) 25.29 - * @param args arguments to print 25.30 - * @return result code from the print 25.31 - */ 25.32 -int IOStream_vprint(IOStream *stream, const char *format, va_list args){ 25.33 - char buffer[1024]; 25.34 - int k = sizeof(buffer), n; 25.35 - 25.36 - n = vsnprintf(buffer, k, (char*)format, args); 25.37 - if(n < 0 || n > k ){ 25.38 - n = k; 25.39 - } 25.40 - n = IOStream_write(stream, buffer, n); 25.41 - return n; 25.42 -} 25.43 - 25.44 -/** Print on a stream, like fprintf(). 25.45 - * 25.46 - * @param stream to print to 25.47 - * @param format for the print (as fprintf()) 25.48 - * @return result code from the print 25.49 - */ 25.50 -int IOStream_print(IOStream *stream, const char *format, ...){ 25.51 - va_list args; 25.52 - int result = -1; 25.53 - 25.54 - va_start(args, format); 25.55 - result = IOStream_vprint(stream, format, args); 25.56 - va_end(args); 25.57 - return result; 25.58 -}
26.1 --- a/tools/libxutil/iostream.h Tue May 24 21:10:23 2005 +0000 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,269 +0,0 @@ 26.4 -/* 26.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 26.6 - * 26.7 - * This library is free software; you can redistribute it and/or modify 26.8 - * it under the terms of the GNU Lesser General Public License as published by 26.9 - * the Free Software Foundation; either version 2.1 of the License, or 26.10 - * (at your option) any later version. 26.11 - * 26.12 - * This library is distributed in the hope that it will be useful, 26.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 26.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26.15 - * GNU Lesser General Public License for more details. 26.16 - * 26.17 - * You should have received a copy of the GNU Lesser General Public License 26.18 - * along with this library; if not, write to the Free Software 26.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26.20 - */ 26.21 - 26.22 -#ifndef _XUTIL_IOSTREAM_H_ 26.23 -#define _XUTIL_IOSTREAM_H_ 26.24 - 26.25 -#include <stdarg.h> 26.26 - 26.27 -#ifdef __KERNEL__ 26.28 -#include <linux/config.h> 26.29 -#include <linux/types.h> 26.30 -#include <linux/errno.h> 26.31 -#else 26.32 -#include <errno.h> 26.33 -#include <stdint.h> 26.34 -#include <stddef.h> 26.35 -#endif 26.36 - 26.37 -#include "allocate.h" 26.38 - 26.39 -/** End of input return value (for getc). */ 26.40 -#define IOSTREAM_EOF -1 26.41 - 26.42 -/** An input/output abstraction. 26.43 - */ 26.44 -typedef struct IOStream IOStream; 26.45 - 26.46 -/** Record of the functions to use for operations on an 26.47 - * IOStream implementation. 26.48 - */ 26.49 -typedef struct IOMethods { 26.50 - /** Read function. Called with the user data, buffer to read into 26.51 - * and number of bytes to read. Must return number of bytes read 26.52 - * on success, less than zero on error. 26.53 - */ 26.54 - int (*read)(IOStream *stream, void *buf, size_t n); 26.55 - 26.56 - /** Write function. Called with user data, buffer to write and 26.57 - * number of bytes to write. Must return number of bytes written on 26.58 - * success, less than zero otherwise. 26.59 - */ 26.60 - int (*write)(IOStream *stream, const void *buf, size_t n); 26.61 - 26.62 - int (*flush)(IOStream *s); 26.63 - 26.64 - int (*error)(IOStream *s); 26.65 - 26.66 - int (*close)(IOStream *s); 26.67 - 26.68 - void (*free)(IOStream *s); 26.69 - 26.70 - void (*lock)(IOStream *s); 26.71 - void (*unlock)(IOStream *s); 26.72 - 26.73 -} IOMethods; 26.74 - 26.75 -/** Abstract i/o object. 26.76 - */ 26.77 -struct IOStream { 26.78 - /** Methods to use to implement operations. */ 26.79 - const IOMethods *methods; 26.80 - /** Private state for the implementation. */ 26.81 - const void *data; 26.82 - /** Flag indicating whether the stream is closed. */ 26.83 - int closed; 26.84 - /** Number of bytes written. */ 26.85 - int written; 26.86 - /** Number of bytes read. */ 26.87 - int read; 26.88 - /** Flag indicating whether not to free when closed. */ 26.89 - int nofree; 26.90 -}; 26.91 - 26.92 - 26.93 -/** IOStream version of stdin. */ 26.94 -extern IOStream *iostdin; 26.95 - 26.96 -/** IOStream version of stdout, */ 26.97 -extern IOStream *iostdout; 26.98 - 26.99 -/** IOStream version of stderr. */ 26.100 -extern IOStream *iostderr; 26.101 - 26.102 -extern int IOStream_print(IOStream *io, const char *format, ...); 26.103 -extern int IOStream_vprint(IOStream *io, const char *format, va_list args); 26.104 - 26.105 -/** Read from a stream. 26.106 - * 26.107 - * @param stream input 26.108 - * @param buf where to put input 26.109 - * @param n number of bytes to read 26.110 - * @return if ok, number of bytes read, otherwise negative error code 26.111 - */ 26.112 -static inline int IOStream_read(IOStream *stream, void *buf, size_t n){ 26.113 - int result; 26.114 - if(stream->closed){ 26.115 - result = -EIO; 26.116 - goto exit; 26.117 - } 26.118 - if(!stream->methods || !stream->methods->read){ 26.119 - result = -EINVAL; 26.120 - goto exit; 26.121 - } 26.122 - result = (stream->methods->read)(stream, buf, n); 26.123 - if(result > 0){ 26.124 - stream->read += result; 26.125 - } 26.126 - exit: 26.127 - return result; 26.128 -} 26.129 - 26.130 -/** Write to a stream. 26.131 - * 26.132 - * @param stream input 26.133 - * @param buf where to put input 26.134 - * @param n number of bytes to write 26.135 - * @return if ok, number of bytes written, otherwise negative error code 26.136 - */ 26.137 -static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){ 26.138 - int result; 26.139 - if(stream->closed){ 26.140 - result = -EIO; 26.141 - goto exit; 26.142 - } 26.143 - if(!stream->methods || !stream->methods->write){ 26.144 - result = -EINVAL; 26.145 - goto exit; 26.146 - } 26.147 - result = (stream->methods->write)(stream, buf, n); 26.148 - if(result > 0){ 26.149 - stream->written += result; 26.150 - } 26.151 - exit: 26.152 - return result; 26.153 -} 26.154 - 26.155 -/** Flush the stream. 26.156 - * 26.157 - * @param stream stream 26.158 - * @return 0 on success, negative error code otherwise 26.159 - */ 26.160 -static inline int IOStream_flush(IOStream *stream){ 26.161 - int result = 0; 26.162 - if(stream->closed){ 26.163 - result = -EIO; 26.164 - } else if(stream->methods->flush){ 26.165 - result = (stream->methods->flush)(stream); 26.166 - } 26.167 - return result; 26.168 -} 26.169 - 26.170 -/** Check whether the stream has an error. 26.171 - * 26.172 - * @param stream to check 26.173 - * @return 1 for error, 0 otherwise 26.174 - */ 26.175 -static inline int IOStream_error(IOStream *stream){ 26.176 - int err = 0; 26.177 - if(stream->methods && stream->methods->error){ 26.178 - err = (stream->methods->error)(stream); 26.179 - } 26.180 - return err; 26.181 -} 26.182 - 26.183 -/** Close the stream. 26.184 - * 26.185 - * @param stream to close 26.186 - * @return 0 on success, negative error code otherwise 26.187 - */ 26.188 -static inline int IOStream_close(IOStream *stream){ 26.189 - int err = 0; 26.190 - if(!stream || stream->closed){ 26.191 - err = -EIO; 26.192 - goto exit; 26.193 - } 26.194 - if(stream->methods && stream->methods->close){ 26.195 - err = (stream->methods->close)(stream); 26.196 - stream->closed = 1; 26.197 - } 26.198 - if(stream->nofree) goto exit; 26.199 - if(stream->methods && stream->methods->free){ 26.200 - (stream->methods->free)(stream); 26.201 - } 26.202 - *stream = (IOStream){}; 26.203 - deallocate(stream); 26.204 - exit: 26.205 - return err; 26.206 -} 26.207 - 26.208 -/** Test if the stream has been closed. 26.209 - * 26.210 - * @param stream to check 26.211 - * @return 1 if closed, 0 otherwise 26.212 - */ 26.213 -static inline int IOStream_is_closed(IOStream *stream){ 26.214 - return stream->closed; 26.215 -} 26.216 - 26.217 -/** Print a character to a stream, like fputc(). 26.218 - * 26.219 - * @param stream to print to 26.220 - * @param c character to print 26.221 - * @return result code from the print 26.222 - */ 26.223 -static inline int IOStream_putc(IOStream *stream, int c){ 26.224 - int err; 26.225 - unsigned char b = (unsigned char)c; 26.226 - err = IOStream_write(stream, &b, 1); 26.227 - if(err < 1){ 26.228 - err = IOSTREAM_EOF; 26.229 - } else { 26.230 - err = b; 26.231 - } 26.232 - return err; 26.233 -} 26.234 - 26.235 -/** Read from a stream, like fgetc(). 26.236 - * 26.237 - * @param stream to read from 26.238 - * @return IOSTREAM_EOF on error, character read otherwise 26.239 - */ 26.240 -static inline int IOStream_getc(IOStream *stream){ 26.241 - int err, rc; 26.242 - unsigned char b; 26.243 - 26.244 - err = IOStream_read(stream, &b, 1); 26.245 - if(err < 1){ 26.246 - rc = IOSTREAM_EOF; 26.247 - } else { 26.248 - rc = b; 26.249 - } 26.250 - return rc; 26.251 -} 26.252 - 26.253 -/** Get number of bytes read. 26.254 - * 26.255 - * @param stream to get from 26.256 - * @return number of bytes read 26.257 - */ 26.258 -static inline int IOStream_get_read(IOStream *stream){ 26.259 - return stream->read; 26.260 -} 26.261 - 26.262 -/** Get number of bytes written. 26.263 - * 26.264 - * @param stream to get from 26.265 - * @return number of bytes written 26.266 - */ 26.267 -static inline int IOStream_get_written(IOStream *stream){ 26.268 - return stream->written; 26.269 -} 26.270 - 26.271 - 26.272 -#endif /* ! _XUTIL_IOSTREAM_H_ */
27.1 --- a/tools/libxutil/kernel_stream.c Tue May 24 21:10:23 2005 +0000 27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3 @@ -1,178 +0,0 @@ 27.4 -/* 27.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 27.6 - * 27.7 - * This library is free software; you can redistribute it and/or modify 27.8 - * it under the terms of the GNU Lesser General Public License as published by 27.9 - * the Free Software Foundation; either version 2.1 of the License, or 27.10 - * (at your option) any later version. 27.11 - * 27.12 - * This library is distributed in the hope that it will be useful, 27.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 27.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27.15 - * GNU Lesser General Public License for more details. 27.16 - * 27.17 - * You should have received a copy of the GNU Lesser General Public License 27.18 - * along with this library; if not, write to the Free Software 27.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27.20 - */ 27.21 - 27.22 -/** @file 27.23 - * An IOStream implementation using printk() for output. 27.24 - * Input is not implemented. 27.25 - */ 27.26 -#ifdef __KERNEL__ 27.27 - 27.28 -#include <linux/config.h> 27.29 -#include <linux/module.h> 27.30 -#include <linux/kernel.h> 27.31 -#include <linux/types.h> 27.32 -#include <linux/errno.h> 27.33 -#include <linux/slab.h> 27.34 -#include <linux/spinlock.h> 27.35 - 27.36 -#include "kernel_stream.h" 27.37 -#include "allocate.h" 27.38 - 27.39 -/** Number of characters in the output buffer. 27.40 - * The kernel uses 1024 for printk, so that should suffice. 27.41 - */ 27.42 -#define BUF_N 1024 27.43 - 27.44 -/** State for a kernel stream. */ 27.45 -typedef struct KernelData { 27.46 - /** Stream lock. We need a lock to serialize access to the stream. */ 27.47 - spinlock_t lock; 27.48 - /** Saved flags for locking. */ 27.49 - unsigned long flags; 27.50 - /** Size of the output buffer. */ 27.51 - int buf_n; 27.52 - /** Output buffer. */ 27.53 - char buf[BUF_N]; 27.54 -} KernelData; 27.55 - 27.56 -static int kernel_write(IOStream *s, const void *msg, size_t n); 27.57 -static void kernel_free(IOStream *s); 27.58 -static void kernel_stream_lock(IOStream *s); 27.59 -static void kernel_stream_unlock(IOStream *s); 27.60 - 27.61 -/** Methods for a kernel stream. Output only. */ 27.62 -static const IOMethods kernel_methods = { 27.63 - write: kernel_write, 27.64 - free: kernel_free, 27.65 - lock: kernel_stream_lock, 27.66 - unlock: kernel_stream_unlock, 27.67 -}; 27.68 - 27.69 -/** Shared state for kernel streams. 27.70 - * All implementations write using printk, so we can use 27.71 - * shared state and avoid allocating it. 27.72 - */ 27.73 -static const KernelData kernel_data = { 27.74 - lock: SPIN_LOCK_UNLOCKED, 27.75 - flags: 0, 27.76 - buf_n: BUF_N, 27.77 -}; 27.78 - 27.79 -/** Stream for kernel printk. */ 27.80 -static IOStream iokernel = { 27.81 - methods: &kernel_methods, 27.82 - data: &kernel_data, 27.83 - nofree: 1, 27.84 -}; 27.85 - 27.86 -/** Stream for kernel printk. */ 27.87 -IOStream *iostdout = &iokernel; 27.88 - 27.89 -/** Stream for kernel printk. */ 27.90 -IOStream *iostdin = &iokernel; 27.91 - 27.92 -/** Stream for kernel printk. */ 27.93 -IOStream *iostderr = &iokernel; 27.94 - 27.95 -/** Get an output-only stream implementation using 27.96 - * printk(). The stream uses static storage, and must not be freed. 27.97 - * 27.98 - * @return kernel stream 27.99 - */ 27.100 -IOStream get_stream_kernel(void){ 27.101 - return iokernel; 27.102 -} 27.103 - 27.104 -/** Obtain the lock on the stream state. 27.105 - * 27.106 - * @param kdata stream state 27.107 - */ 27.108 -static inline void KernelData_lock(KernelData *kdata){ 27.109 - spin_lock_irqsave(&kdata->lock, kdata->flags); 27.110 -} 27.111 - 27.112 -/** Release the lock on the stream state. 27.113 - * 27.114 - * @param kdata stream state 27.115 - */ 27.116 -static inline void KernelData_unlock(KernelData *kdata){ 27.117 - spin_unlock_irqrestore(&kdata->lock, kdata->flags); 27.118 -} 27.119 - 27.120 -/** Get the stream state. 27.121 - * 27.122 - * @param s kernel stream 27.123 - * @return stream state 27.124 - */ 27.125 -static inline KernelData *get_kernel_data(IOStream *s){ 27.126 - return (KernelData*)s->data; 27.127 -} 27.128 - 27.129 -/** Obtain the lock on the stream state. 27.130 - * 27.131 - * @param s stream 27.132 - */ 27.133 -void kernel_stream_lock(IOStream *s){ 27.134 - KernelData_lock(get_kernel_data(s)); 27.135 -} 27.136 - 27.137 -/** Release the lock on the stream state. 27.138 - * 27.139 - * @param s stream 27.140 - */ 27.141 -void kernel_stream_unlock(IOStream *s){ 27.142 - KernelData_unlock(get_kernel_data(s)); 27.143 -} 27.144 - 27.145 -/** Write to a kernel stream. 27.146 - * 27.147 - * @param stream kernel stream 27.148 - * @param format print format 27.149 - * @param args print arguments 27.150 - * @return result of the print 27.151 - */ 27.152 -static int kernel_write(IOStream *stream, const void *buf, size_t n){ 27.153 - KernelData *kdata = get_kernel_data(stream); 27.154 - int k; 27.155 - k = kdata->buf_n - 1; 27.156 - if(n < k) k = n; 27.157 - memcpy(kdata->buf, buf, k); 27.158 - kdata->buf[k] = '\0'; 27.159 - printk(kdata->buf); 27.160 - return k; 27.161 -} 27.162 - 27.163 -/** Free a kernel stream. 27.164 - * Frees the internal state of the stream. 27.165 - * Do not call this unless the stream was dynamically allocated. 27.166 - * Do not call this on a stream returned from get_stream_kernel(). 27.167 - * 27.168 - * @param io stream to free 27.169 - */ 27.170 -static void kernel_free(IOStream *io){ 27.171 - KernelData *kdata; 27.172 - if(io == &iokernel) return; 27.173 - kdata = get_kernel_data(io); 27.174 - memset(kdata, 0, sizeof(*kdata)); 27.175 - deallocate(kdata); 27.176 -} 27.177 -#endif /* __KERNEL__ */ 27.178 - 27.179 - 27.180 - 27.181 -
28.1 --- a/tools/libxutil/kernel_stream.h Tue May 24 21:10:23 2005 +0000 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,29 +0,0 @@ 28.4 -/* 28.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 28.6 - * 28.7 - * This library is free software; you can redistribute it and/or modify 28.8 - * it under the terms of the GNU Lesser General Public License as published by 28.9 - * the Free Software Foundation; either version 2.1 of the License, or 28.10 - * (at your option) any later version. 28.11 - * 28.12 - * This library is distributed in the hope that it will be useful, 28.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 28.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.15 - * GNU Lesser General Public License for more details. 28.16 - * 28.17 - * You should have received a copy of the GNU Lesser General Public License 28.18 - * along with this library; if not, write to the Free Software 28.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28.20 - */ 28.21 - 28.22 -#ifndef _XUTIL_KERNEL_STREAM_H_ 28.23 -#define _XUTIL_KERNEL_STREAM_H_ 28.24 - 28.25 -#ifdef __KERNEL__ 28.26 -#include "iostream.h" 28.27 - 28.28 -extern IOStream get_stream_kernel(void); 28.29 -#define get_stream_stdout get_stream_kernel 28.30 - 28.31 -#endif /* __KERNEL__ */ 28.32 -#endif /* !_XUTIL_KERNEL_STREAM_H_ */
29.1 --- a/tools/libxutil/lexis.c Tue May 24 21:10:23 2005 +0000 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,94 +0,0 @@ 29.4 -/* 29.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 29.6 - * 29.7 - * This library is free software; you can redistribute it and/or modify 29.8 - * it under the terms of the GNU Lesser General Public License as 29.9 - * published by the Free Software Foundation; either version 2.1 of the 29.10 - * License, or (at your option) any later version. This library is 29.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 29.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.13 - * FITNESS FOR A PARTICULAR PURPOSE. 29.14 - * See the GNU Lesser General Public License for more details. 29.15 - * 29.16 - * You should have received a copy of the GNU Lesser General Public License 29.17 - * along with this library; if not, write to the Free Software Foundation, 29.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29.19 - */ 29.20 - 29.21 -/** @file 29.22 - * Lexical analysis. 29.23 - */ 29.24 - 29.25 -#include "sys_string.h" 29.26 -#include "lexis.h" 29.27 -#include <errno.h> 29.28 - 29.29 -/** Check if a value lies in a (closed) range. 29.30 - * 29.31 - * @param x value to test 29.32 - * @param lo low end of the range 29.33 - * @param hi high end of the range 29.34 - * @return 1 if x is in the interval [lo, hi], 0 otherwise 29.35 - */ 29.36 -inline static int in_range(int x, int lo, int hi){ 29.37 - return (lo <= x) && (x <= hi); 29.38 -} 29.39 - 29.40 -/** Determine if a string is an (unsigned) decimal number. 29.41 - * 29.42 - * @param s pointer to characters to test 29.43 - * @param n length of string 29.44 - * @return 1 if s is a decimal number, 0 otherwise. 29.45 - */ 29.46 -int is_decimal_number(const char *s, int n){ 29.47 - int i; 29.48 - if(n <= 0)return 0; 29.49 - for(i = 0; i < n; i++){ 29.50 - if(!in_decimal_digit_class(s[i])) return 0; 29.51 - } 29.52 - return 1; 29.53 -} 29.54 - 29.55 -/** Determine if a string is a hex number. 29.56 - * Hex numbers are 0, or start with 0x or 0X followed 29.57 - * by a non-zero number of hex digits (0-9,a-f,A-F). 29.58 - * 29.59 - * @param s pointer to characters to test 29.60 - * @param n length of string 29.61 - * @return 1 if s is a hex number, 0 otherwise. 29.62 - */ 29.63 -int is_hex_number(const char *s, int n){ 29.64 - int i; 29.65 - if(n <= 0) return 0; 29.66 - if(n == 1){ 29.67 - return s[0]=='0'; 29.68 - } 29.69 - if(n <= 3) return 0; 29.70 - if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0; 29.71 - for(i = 2; i < n; i++){ 29.72 - if(!in_hex_digit_class(s[i])) return 0; 29.73 - } 29.74 - return 1; 29.75 -} 29.76 - 29.77 -/** Test if a string matches a keyword. 29.78 - * The comparison is case-insensitive. 29.79 - * The comparison fails if either argument is null. 29.80 - * 29.81 - * @param s string 29.82 - * @param k keyword 29.83 - * @return 1 if they match, 0 otherwise 29.84 - */ 29.85 -int is_keyword(const char *s, const char *k){ 29.86 - return s && k && !strcasecmp(s, k); 29.87 -} 29.88 - 29.89 -/** Test if a string matches a character. 29.90 - * 29.91 - * @param s string 29.92 - * @param c character (non-null) 29.93 - * @return 1 if s contains exactly c, 0 otherwise 29.94 - */ 29.95 -int is_keychar(const char *s, char c){ 29.96 - return c && (s[0] == c) && !s[1]; 29.97 -}
30.1 --- a/tools/libxutil/lexis.h Tue May 24 21:10:23 2005 +0000 30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 30.3 @@ -1,128 +0,0 @@ 30.4 -/* 30.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 30.6 - * 30.7 - * This library is free software; you can redistribute it and/or modify 30.8 - * it under the terms of the GNU Lesser General Public License as 30.9 - * published by the Free Software Foundation; either version 2.1 of the 30.10 - * License, or (at your option) any later version. This library is 30.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 30.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.13 - * FITNESS FOR A PARTICULAR PURPOSE. 30.14 - * See the GNU Lesser General Public License for more details. 30.15 - * 30.16 - * You should have received a copy of the GNU Lesser General Public License 30.17 - * along with this library; if not, write to the Free Software Foundation, 30.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30.19 - */ 30.20 - 30.21 -#ifndef _XUTIL_LEXIS_H_ 30.22 -#define _XUTIL_LEXIS_H_ 30.23 - 30.24 -#include "sys_string.h" 30.25 - 30.26 -#ifdef __KERNEL__ 30.27 -# include <linux/ctype.h> 30.28 -#else 30.29 -# include <ctype.h> 30.30 -#endif 30.31 - 30.32 -/** @file 30.33 - * Lexical analysis. 30.34 - */ 30.35 - 30.36 -/** Class of characters treated as space. */ 30.37 -#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 }) 30.38 - 30.39 -/** Class of separator characters. */ 30.40 -#define sep_class "{}()<>[]!;\"'" 30.41 - 30.42 -#define comment_class "#" 30.43 - 30.44 -/** Determine if a character is in a given class. 30.45 - * 30.46 - * @param c character to test 30.47 - * @param s null-terminated string of characters in the class 30.48 - * @return 1 if c is in the class, 0 otherwise. 30.49 - */ 30.50 -static inline int in_class(int c, const char *s){ 30.51 - return s && (strchr(s, c) != 0); 30.52 -} 30.53 - 30.54 -/** Determine if a character is in the space class. 30.55 - * 30.56 - * @param c character to test 30.57 - * @return 1 if c is in the class, 0 otherwise. 30.58 - */ 30.59 -static inline int in_space_class(int c){ 30.60 - return in_class(c, space_class); 30.61 -} 30.62 - 30.63 -static inline int in_comment_class(int c){ 30.64 - return in_class(c, comment_class); 30.65 -} 30.66 - 30.67 -/** Determine if a character is in the separator class. 30.68 - * Separator characters terminate tokens, and do not need space 30.69 - * to separate them. 30.70 - * 30.71 - * @param c character to test 30.72 - * @return 1 if c is in the class, 0 otherwise. 30.73 - */ 30.74 -static inline int in_sep_class(int c){ 30.75 - return in_class(c, sep_class); 30.76 -} 30.77 - 30.78 -/** Determine if a character is in the alpha class. 30.79 - * 30.80 - * @param c character to test 30.81 - * @return 1 if c is in the class, 0 otherwise. 30.82 - */ 30.83 -static inline int in_alpha_class(int c){ 30.84 - return isalpha(c); 30.85 -} 30.86 - 30.87 -/** Determine if a character is in the octal digit class. 30.88 - * 30.89 - * @param c character to test 30.90 - * @return 1 if c is in the class, 0 otherwise. 30.91 - */ 30.92 -static inline int in_octal_digit_class(int c){ 30.93 - return '0' <= c && c <= '7'; 30.94 -} 30.95 - 30.96 -/** Determine if a character is in the decimal digit class. 30.97 - * 30.98 - * @param c character to test 30.99 - * @return 1 if c is in the class, 0 otherwise. 30.100 - */ 30.101 -static inline int in_decimal_digit_class(int c){ 30.102 - return isdigit(c); 30.103 -} 30.104 - 30.105 -/** Determine if a character is in the hex digit class. 30.106 - * 30.107 - * @param c character to test 30.108 - * @return 1 if c is in the class, 0 otherwise. 30.109 - */ 30.110 -static inline int in_hex_digit_class(int c){ 30.111 - return isdigit(c) || in_class(c, "abcdefABCDEF"); 30.112 -} 30.113 - 30.114 - 30.115 -static inline int in_string_quote_class(int c){ 30.116 - return in_class(c, "'\""); 30.117 -} 30.118 - 30.119 -static inline int in_printable_class(int c){ 30.120 - return ('A' <= c && c <= 'Z') 30.121 - || ('a' <= c && c <= 'z') 30.122 - || ('0' <= c && c <= '9') 30.123 - || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~"); 30.124 -} 30.125 - 30.126 -extern int is_decimal_number(const char *s, int n); 30.127 -extern int is_hex_number(const char *s, int n); 30.128 -extern int is_keyword(const char *s, const char *k); 30.129 -extern int is_keychar(const char *s, char c); 30.130 - 30.131 -#endif /* !_XUTIL_LEXIS_H_ */
31.1 --- a/tools/libxutil/socket_stream.c Tue May 24 21:10:23 2005 +0000 31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 31.3 @@ -1,230 +0,0 @@ 31.4 -/* 31.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 31.6 - * 31.7 - * This library is free software; you can redistribute it and/or modify 31.8 - * it under the terms of the GNU Lesser General Public License as published by 31.9 - * the Free Software Foundation; either version 2.1 of the License, or 31.10 - * (at your option) any later version. 31.11 - * 31.12 - * This library is distributed in the hope that it will be useful, 31.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 31.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31.15 - * GNU Lesser General Public License for more details. 31.16 - * 31.17 - * You should have received a copy of the GNU Lesser General Public License 31.18 - * along with this library; if not, write to the Free Software 31.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 31.20 - */ 31.21 - 31.22 -/** @file 31.23 - * An IOStream implementation using sockets. 31.24 - */ 31.25 -#ifndef __KERNEL__ 31.26 - 31.27 -#include <stdio.h> 31.28 -#include <stdlib.h> 31.29 -#include <string.h> 31.30 -#include <unistd.h> 31.31 -#include <errno.h> 31.32 -#include "allocate.h" 31.33 -#include "socket_stream.h" 31.34 - 31.35 -#define MODULE_NAME "sock" 31.36 -#define DEBUG 0 31.37 -//#undef DEBUG 31.38 -#include "debug.h" 31.39 - 31.40 -static int socket_read(IOStream *s, void *buf, size_t n); 31.41 -static int socket_write(IOStream *s, const void *buf, size_t n); 31.42 -static int socket_error(IOStream *s); 31.43 -static int socket_close(IOStream *s); 31.44 -static void socket_free(IOStream *s); 31.45 -static int socket_flush(IOStream *s); 31.46 - 31.47 -/** Methods used by a socket IOStream. */ 31.48 -static const IOMethods socket_methods = { 31.49 - read: socket_read, 31.50 - write: socket_write, 31.51 - error: socket_error, 31.52 - close: socket_close, 31.53 - free: socket_free, 31.54 - flush: socket_flush, 31.55 -}; 31.56 - 31.57 -/** Get the socket data. 31.58 - * 31.59 - * @param io socket stream 31.60 - * @return data 31.61 - */ 31.62 -static inline SocketData * socket_data(IOStream *io){ 31.63 - return (SocketData *)io->data; 31.64 -} 31.65 - 31.66 -/** Test if a stream is a socket stream. 31.67 - * 31.68 - * @param io stream 31.69 - * @return 0 if a socket stream, -EINVAL if not 31.70 - */ 31.71 -int socket_stream_check(IOStream *io){ 31.72 - return (io && io->methods == &socket_methods ? 0 : -EINVAL); 31.73 -} 31.74 - 31.75 -/** Get the data for a socket stream. 31.76 - * 31.77 - * @param io stream 31.78 - * @param data return value for the data 31.79 - * @return 0 if a socket stream, -EINVAL if not 31.80 - */ 31.81 -int socket_stream_data(IOStream *io, SocketData **data){ 31.82 - int err = socket_stream_check(io); 31.83 - if(err){ 31.84 - *data = NULL; 31.85 - } else { 31.86 - *data = socket_data(io); 31.87 - } 31.88 - return err; 31.89 -} 31.90 - 31.91 -/** Set the destination address for a socket stream. 31.92 - * 31.93 - * @param io stream 31.94 - * @param addr address 31.95 - * @return 0 if a socket stream, -EINVAL if not 31.96 - */ 31.97 -int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){ 31.98 - int err = 0; 31.99 - SocketData *data = NULL; 31.100 - err = socket_stream_data(io, &data); 31.101 - if(!err){ 31.102 - data->daddr = *addr; 31.103 - } 31.104 - return err; 31.105 -} 31.106 - 31.107 -/** Set the send flags for a socket stream. 31.108 - * 31.109 - * @param io stream 31.110 - * @param flags flags 31.111 - * @return 0 if a socket stream, -EINVAL if not 31.112 - */ 31.113 -int socket_stream_set_flags(IOStream *io, int flags){ 31.114 - int err = 0; 31.115 - SocketData *data = NULL; 31.116 - err = socket_stream_data(io, &data); 31.117 - if(!err){ 31.118 - data->flags = flags; 31.119 - } 31.120 - return err; 31.121 -} 31.122 - 31.123 -/** Write to the underlying socket using sendto. 31.124 - * 31.125 - * @param stream input 31.126 - * @param buf where to put input 31.127 - * @param n number of bytes to write 31.128 - * @return number of bytes written 31.129 - */ 31.130 -static int socket_write(IOStream *s, const void *buf, size_t n){ 31.131 - SocketData *data = socket_data(s); 31.132 - struct sockaddr *daddr = (struct sockaddr *)&data->daddr; 31.133 - socklen_t daddr_n = sizeof(data->daddr); 31.134 - int k; 31.135 - dprintf("> sock=%d addr=%s:%d n=%d\n", 31.136 - data->fd, inet_ntoa(data->daddr.sin_addr), ntohs(data->daddr.sin_port), n); 31.137 - if(0){ 31.138 - struct sockaddr_in self = {}; 31.139 - socklen_t self_n; 31.140 - getsockname(data->fd, (struct sockaddr *)&self, &self_n); 31.141 - dprintf("> sockname sock=%d %s:%d\n", 31.142 - data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port)); 31.143 - } 31.144 - k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n); 31.145 - dprintf("> sendto=%d\n", k); 31.146 - return k; 31.147 -} 31.148 - 31.149 -/** Read from the underlying stream using recv(); 31.150 - * 31.151 - * @param stream input 31.152 - * @param buf where to put input 31.153 - * @param n number of bytes to read 31.154 - * @return number of bytes read 31.155 - */ 31.156 -static int socket_read(IOStream *s, void *buf, size_t n){ 31.157 - SocketData *data = socket_data(s); 31.158 - int k; 31.159 - struct sockaddr *saddr = (struct sockaddr *)&data->saddr; 31.160 - socklen_t saddr_n = sizeof(data->saddr); 31.161 - k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n); 31.162 - return k; 31.163 -} 31.164 - 31.165 -/** Flush the socket (no-op). 31.166 - * 31.167 - * @param s socket stream 31.168 - * @return 0 on success, error code otherwise 31.169 - */ 31.170 -static int socket_flush(IOStream *s){ 31.171 - return 0; 31.172 -} 31.173 - 31.174 -/** Check if a socket stream has an error (no-op). 31.175 - * 31.176 - * @param s socket stream 31.177 - * @return 1 if has an error, 0 otherwise 31.178 - */ 31.179 -static int socket_error(IOStream *s){ 31.180 - // Read SOL_SOCKET/SO_ERROR ? 31.181 - return 0; 31.182 -} 31.183 - 31.184 -/** Close a socket stream. 31.185 - * 31.186 - * @param s socket stream to close 31.187 - * @return result of the close 31.188 - */ 31.189 -static int socket_close(IOStream *s){ 31.190 - SocketData *data = socket_data(s); 31.191 - return close(data->fd); 31.192 -} 31.193 - 31.194 -/** Free a socket stream. 31.195 - * 31.196 - * @param s socket stream 31.197 - */ 31.198 -static void socket_free(IOStream *s){ 31.199 - SocketData *data = socket_data(s); 31.200 - deallocate(data); 31.201 -} 31.202 - 31.203 -/** Create an IOStream for a socket. 31.204 - * 31.205 - * @param fd socket to wtap 31.206 - * @return new IOStream using fd for i/o 31.207 - */ 31.208 -IOStream *socket_stream_new(int fd){ 31.209 - int err = -ENOMEM; 31.210 - IOStream *io = NULL; 31.211 - SocketData *data = NULL; 31.212 - 31.213 - io = ALLOCATE(IOStream); 31.214 - if(!io) goto exit; 31.215 - io->methods = &socket_methods; 31.216 - data = ALLOCATE(SocketData); 31.217 - if(!data) goto exit; 31.218 - io->data = data; 31.219 - data->fd = fd; 31.220 - data->buf_n = sizeof(data->buf); 31.221 - err = 0; 31.222 - exit: 31.223 - if(err){ 31.224 - if(io){ 31.225 - if(data) deallocate(data); 31.226 - deallocate(io); 31.227 - io = NULL; 31.228 - } 31.229 - } 31.230 - return io; 31.231 -} 31.232 - 31.233 -#endif
32.1 --- a/tools/libxutil/socket_stream.h Tue May 24 21:10:23 2005 +0000 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,53 +0,0 @@ 32.4 -/* 32.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 32.6 - * 32.7 - * This library is free software; you can redistribute it and/or modify 32.8 - * it under the terms of the GNU Lesser General Public License as published by 32.9 - * the Free Software Foundation; either version 2.1 of the License, or 32.10 - * (at your option) any later version. 32.11 - * 32.12 - * This library is distributed in the hope that it will be useful, 32.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 32.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32.15 - * GNU Lesser General Public License for more details. 32.16 - * 32.17 - * You should have received a copy of the GNU Lesser General Public License 32.18 - * along with this library; if not, write to the Free Software 32.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32.20 - */ 32.21 - 32.22 -#ifndef _XEN_LIB_SOCKET_STREAM_H_ 32.23 -#define _XEN_LIB_SOCKET_STREAM_H_ 32.24 - 32.25 -#ifndef __KERNEL__ 32.26 -#include "iostream.h" 32.27 -#include <stdio.h> 32.28 - 32.29 -#include <sys/socket.h> 32.30 -#include <netinet/in.h> 32.31 -#include <arpa/inet.h> 32.32 - 32.33 -/** Data associated with a socket stream. */ 32.34 -typedef struct SocketData { 32.35 - /** The socket file descriptor. */ 32.36 - int fd; 32.37 - /** Source address from last read (recvfrom). */ 32.38 - struct sockaddr_in saddr; 32.39 - /** Destination address for writes (sendto). */ 32.40 - struct sockaddr_in daddr; 32.41 - /** Write flags (sendto). */ 32.42 - int flags; 32.43 - /** Buffer size. */ 32.44 - int buf_n; 32.45 - /** Buffer for formatted printing. */ 32.46 - char buf[1024]; 32.47 -} SocketData; 32.48 - 32.49 -extern IOStream *socket_stream_new(int fd); 32.50 -extern int socket_stream_data(IOStream *io, SocketData **data); 32.51 -extern int socket_stream_check(IOStream *io); 32.52 -extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr); 32.53 -extern int socket_stream_set_flags(IOStream *io, int flags); 32.54 - 32.55 -#endif 32.56 -#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */
33.1 --- a/tools/libxutil/string_stream.c Tue May 24 21:10:23 2005 +0000 33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 33.3 @@ -1,162 +0,0 @@ 33.4 -/* 33.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 33.6 - * 33.7 - * This library is free software; you can redistribute it and/or modify 33.8 - * it under the terms of the GNU Lesser General Public License as published by 33.9 - * the Free Software Foundation; either version 2.1 of the License, or 33.10 - * (at your option) any later version. 33.11 - * 33.12 - * This library is distributed in the hope that it will be useful, 33.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 33.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33.15 - * GNU Lesser General Public License for more details. 33.16 - * 33.17 - * You should have received a copy of the GNU Lesser General Public License 33.18 - * along with this library; if not, write to the Free Software 33.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 33.20 - */ 33.21 - 33.22 -/** @file 33.23 - * IOStream subtype for input and output to strings. 33.24 - * Usable from user or kernel code (with __KERNEL__ defined). 33.25 - */ 33.26 - 33.27 -#include "sys_string.h" 33.28 -#include "string_stream.h" 33.29 -#include "allocate.h" 33.30 - 33.31 -static int string_error(IOStream *io); 33.32 -static int string_close(IOStream *io); 33.33 -static void string_free(IOStream *io); 33.34 -static int string_write(IOStream *io, const void *msg, size_t n); 33.35 -static int string_read(IOStream *io, void *buf, size_t n); 33.36 - 33.37 -/** Methods for a string stream. */ 33.38 -static IOMethods string_methods = { 33.39 - read: string_read, 33.40 - write: string_write, 33.41 - error: string_error, 33.42 - close: string_close, 33.43 - free: string_free, 33.44 -}; 33.45 - 33.46 -/** Get the string stream state. 33.47 - * 33.48 - * @param io string stream 33.49 - * @return state 33.50 - */ 33.51 -static inline StringData *get_string_data(IOStream *io){ 33.52 - return (StringData*)io->data; 33.53 -} 33.54 - 33.55 -static int string_write(IOStream *io, const void *msg, size_t n){ 33.56 - StringData *data = get_string_data(io); 33.57 - int k; 33.58 - 33.59 - k = data->end - data->out; 33.60 - if(n > k) n = k; 33.61 - memcpy(data->out, msg, n); 33.62 - data->out += n; 33.63 - return n; 33.64 -} 33.65 - 33.66 -static int string_read(IOStream *io, void *buf, size_t n){ 33.67 - StringData *data = get_string_data(io); 33.68 - int k; 33.69 - 33.70 - k = data->end - data->in; 33.71 - if(n > k) n = k; 33.72 - memcpy(buf, data->in, k); 33.73 - data->in += n; 33.74 - return n; 33.75 -} 33.76 - 33.77 -/** Test if a string stream has an error. 33.78 - * 33.79 - * @param io string stream 33.80 - * @return 0 if ok, error code otherwise 33.81 - */ 33.82 -static int string_error(IOStream *io){ 33.83 - StringData *data = get_string_data(io); 33.84 - return data->out == NULL; 33.85 -} 33.86 - 33.87 -/** Close a string stream. 33.88 - * 33.89 - * @param io string stream 33.90 - * @return 0 33.91 - */ 33.92 -static int string_close(IOStream *io){ 33.93 - StringData *data = get_string_data(io); 33.94 - data->in = NULL; 33.95 - data->out = NULL; 33.96 - return 0; 33.97 -} 33.98 - 33.99 -/** Free a string stream. 33.100 - * The stream state is freed, but the underlying string is not. 33.101 - * 33.102 - * @param io string stream 33.103 - */ 33.104 -static void string_free(IOStream *io){ 33.105 - StringData *data = get_string_data(io); 33.106 - memzero(data, sizeof(*data)); 33.107 - deallocate(data); 33.108 -} 33.109 - 33.110 -/** Get the methods to use for a string stream. 33.111 - * 33.112 - * @return methods 33.113 - */ 33.114 -IOMethods *string_stream_get_methods(void){ 33.115 - return &string_methods; 33.116 -} 33.117 - 33.118 -/** Initialise a string stream, usually from static data. 33.119 - * If the stream and StringData should be freed when 33.120 - * the stream is closed, unset io->nofree. 33.121 - * The string is not freed on close. 33.122 - * 33.123 - * @param io address of IOStream to fill in 33.124 - * @param data address of StringData to fill in 33.125 - * @param s string to use 33.126 - * @param n length of the string 33.127 - */ 33.128 -void string_stream_init(IOStream *io, StringData *data, char *s, int n){ 33.129 - if(data && io){ 33.130 - memzero(data, sizeof(*data)); 33.131 - data->string = (char*)s; 33.132 - data->in = data->string; 33.133 - data->out = data->string; 33.134 - data->size = n; 33.135 - data->end = data->string + n; 33.136 - memzero(io, sizeof(*io)); 33.137 - io->methods = &string_methods; 33.138 - io->data = data; 33.139 - io->nofree = 1; 33.140 - } 33.141 -} 33.142 - 33.143 -/** Allocate and initialise a string stream. 33.144 - * The stream is freed on close, but the string is not. 33.145 - * 33.146 - * @param s string to use 33.147 - * @param n length of the string 33.148 - * @return new stream (free using IOStream_free) 33.149 - */ 33.150 -IOStream *string_stream_new(char *s, int n){ 33.151 - int ok = 0; 33.152 - StringData *data = ALLOCATE(StringData); 33.153 - IOStream *io = ALLOCATE(IOStream); 33.154 - if(data && io){ 33.155 - ok = 1; 33.156 - string_stream_init(io, data, s, n); 33.157 - io->nofree = 0; 33.158 - } 33.159 - if(!ok){ 33.160 - deallocate(data); 33.161 - deallocate(io); 33.162 - io = NULL; 33.163 - } 33.164 - return io; 33.165 -}
34.1 --- a/tools/libxutil/string_stream.h Tue May 24 21:10:23 2005 +0000 34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3 @@ -1,45 +0,0 @@ 34.4 -/* 34.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 34.6 - * 34.7 - * This library is free software; you can redistribute it and/or modify 34.8 - * it under the terms of the GNU Lesser General Public License as published by 34.9 - * the Free Software Foundation; either version 2.1 of the License, or 34.10 - * (at your option) any later version. 34.11 - * 34.12 - * This library is distributed in the hope that it will be useful, 34.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 34.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34.15 - * GNU Lesser General Public License for more details. 34.16 - * 34.17 - * You should have received a copy of the GNU Lesser General Public License 34.18 - * along with this library; if not, write to the Free Software 34.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34.20 - */ 34.21 - 34.22 -#ifndef _XUTIL_STRING_STREAM_H_ 34.23 -#define _XUTIL_STRING_STREAM_H_ 34.24 - 34.25 -#include "iostream.h" 34.26 - 34.27 -/** Internal state for a string stream. 34.28 - * Exposed here so that string streams can be statically created, using 34.29 - * string_stream_init(). 34.30 - */ 34.31 -typedef struct { 34.32 - /** The string used for input and ouput. */ 34.33 - char *string; 34.34 - /** Output pointer. */ 34.35 - char *out; 34.36 - /** Input pointer. */ 34.37 - char *in; 34.38 - /** Length of string. */ 34.39 - int size; 34.40 - /** End marker. */ 34.41 - char *end; 34.42 -} StringData; 34.43 - 34.44 -extern IOMethods *string_stream_get_methods(void); 34.45 -extern IOStream *string_stream_new(char *s, int n); 34.46 -extern void string_stream_init(IOStream *stream, StringData *data, char *s, int n); 34.47 - 34.48 -#endif /* !_XUTIL_STRING_STREAM_H_ */
35.1 --- a/tools/libxutil/sxpr.c Tue May 24 21:10:23 2005 +0000 35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 35.3 @@ -1,1230 +0,0 @@ 35.4 -/* 35.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 35.6 - * 35.7 - * This library is free software; you can redistribute it and/or modify 35.8 - * it under the terms of the GNU Lesser General Public License as 35.9 - * published by the Free Software Foundation; either version 2.1 of the 35.10 - * License, or (at your option) any later version. This library is 35.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 35.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 35.13 - * FITNESS FOR A PARTICULAR PURPOSE. 35.14 - * See the GNU Lesser General Public License for more details. 35.15 - * 35.16 - * You should have received a copy of the GNU Lesser General Public License 35.17 - * along with this library; if not, write to the Free Software Foundation, 35.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 35.19 - */ 35.20 - 35.21 -#include <stdarg.h> 35.22 -#include "sys_string.h" 35.23 -#include "lexis.h" 35.24 -#include "sys_net.h" 35.25 -#include "hash_table.h" 35.26 -#include "sxpr.h" 35.27 - 35.28 -#ifdef __KERNEL__ 35.29 -#include <linux/errno.h> 35.30 -#else 35.31 -#include <errno.h> 35.32 -#endif 35.33 - 35.34 -#ifdef __KERNEL__ 35.35 -#include <linux/random.h> 35.36 - 35.37 -int rand(void){ 35.38 - int v; 35.39 - get_random_bytes(&v, sizeof(v)); 35.40 - return v; 35.41 -} 35.42 - 35.43 -#else 35.44 -#include <stdlib.h> 35.45 -#endif 35.46 - 35.47 -#undef free 35.48 - 35.49 -/** @file 35.50 - * General representation of sxprs. 35.51 - * Includes print, equal, and free functions for the sxpr types. 35.52 - * 35.53 - * Zero memory containing an Sxpr will have the value ONONE - this is intentional. 35.54 - * When a function returning an sxpr cannot allocate memory we return ONOMEM. 35.55 - * 35.56 - */ 35.57 - 35.58 -static int atom_print(IOStream *io, Sxpr obj, unsigned flags); 35.59 -static int atom_equal(Sxpr x, Sxpr y); 35.60 -static void atom_free(Sxpr obj); 35.61 -static Sxpr atom_copy(Sxpr obj); 35.62 - 35.63 -static int string_print(IOStream *io, Sxpr obj, unsigned flags); 35.64 -static int string_equal(Sxpr x, Sxpr y); 35.65 -static void string_free(Sxpr obj); 35.66 -static Sxpr string_copy(Sxpr obj); 35.67 - 35.68 -static int cons_print(IOStream *io, Sxpr obj, unsigned flags); 35.69 -static int cons_equal(Sxpr x, Sxpr y); 35.70 -static void cons_free(Sxpr obj); 35.71 -static Sxpr cons_copy(Sxpr obj); 35.72 - 35.73 -static int null_print(IOStream *io, Sxpr obj, unsigned flags); 35.74 -static int none_print(IOStream *io, Sxpr obj, unsigned flags); 35.75 -static int int_print(IOStream *io, Sxpr obj, unsigned flags); 35.76 -static int bool_print(IOStream *io, Sxpr obj, unsigned flags); 35.77 -static int err_print(IOStream *io, Sxpr obj, unsigned flags); 35.78 -static int nomem_print(IOStream *io, Sxpr obj, unsigned flags); 35.79 - 35.80 -/** Type definitions. */ 35.81 -static SxprType types[1024] = { 35.82 - [T_NONE] { .type= T_NONE, .name= "none", .print= none_print }, 35.83 - [T_NULL] { .type= T_NULL, .name= "null", .print= null_print }, 35.84 - [T_UINT] { .type= T_UINT, .name= "int", .print= int_print, }, 35.85 - [T_BOOL] { .type= T_BOOL, .name= "bool", .print= bool_print, }, 35.86 - [T_ERR] { .type= T_ERR, .name= "err", .print= err_print, }, 35.87 - [T_NOMEM] { .type= T_ERR, .name= "nomem", .print= nomem_print, }, 35.88 - [T_ATOM] { .type= T_ATOM, .name= "atom", .print= atom_print, 35.89 - .pointer= TRUE, 35.90 - .free= atom_free, 35.91 - .equal= atom_equal, 35.92 - .copy= atom_copy, 35.93 - }, 35.94 - [T_STRING] { .type= T_STRING, .name= "string", .print= string_print, 35.95 - .pointer= TRUE, 35.96 - .free= string_free, 35.97 - .equal= string_equal, 35.98 - .copy= string_copy, 35.99 - }, 35.100 - [T_CONS] { .type= T_CONS, .name= "cons", .print= cons_print, 35.101 - .pointer= TRUE, 35.102 - .free= cons_free, 35.103 - .equal= cons_equal, 35.104 - .copy= cons_copy, 35.105 - }, 35.106 -}; 35.107 - 35.108 -/** Number of entries in the types array. */ 35.109 -static int type_sup = sizeof(types)/sizeof(types[0]); 35.110 - 35.111 -/** Define a type. 35.112 - * The tydef must have a non-zero type code. 35.113 - * It is an error if the type code is out of range or already defined. 35.114 - * 35.115 - * @param tydef type definition 35.116 - * @return 0 on success, error code otherwise 35.117 - */ 35.118 -int def_sxpr_type(SxprType *tydef){ 35.119 - int err = 0; 35.120 - int ty = tydef->type; 35.121 - if(ty < 0 || ty >= type_sup){ 35.122 - err = -EINVAL; 35.123 - goto exit; 35.124 - } 35.125 - if(types[ty].type){ 35.126 - err = -EEXIST; 35.127 - goto exit; 35.128 - } 35.129 - types[ty] = *tydef; 35.130 - exit: 35.131 - return err; 35.132 - 35.133 -} 35.134 - 35.135 -/** Get the type definition for a given type code. 35.136 - * 35.137 - * @param ty type code 35.138 - * @return type definition or null 35.139 - */ 35.140 -SxprType *get_sxpr_type(int ty){ 35.141 - if(0 <= ty && ty < type_sup){ 35.142 - return types+ty; 35.143 - } 35.144 - return NULL; 35.145 -} 35.146 - 35.147 -/** The default print function. 35.148 - * 35.149 - * @param io stream to print to 35.150 - * @param x sxpr to print 35.151 - * @param flags print flags 35.152 - * @return number of bytes written on success 35.153 - */ 35.154 -int default_print(IOStream *io, Sxpr x, unsigned flags){ 35.155 - return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x)); 35.156 -} 35.157 - 35.158 -/** The default equal function. 35.159 - * Uses eq(). 35.160 - * 35.161 - * @param x sxpr to compare 35.162 - * @param y sxpr to compare 35.163 - * @return 1 if equal, 0 otherwise 35.164 - */ 35.165 -int default_equal(Sxpr x, Sxpr y){ 35.166 - return eq(x, y); 35.167 -} 35.168 - 35.169 -/** General sxpr print function. 35.170 - * Prints an sxpr on a stream using the print function for the sxpr type. 35.171 - * Printing is controlled by flags from the PrintFlags enum. 35.172 - * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr 35.173 - * (for debugging). 35.174 - * 35.175 - * @param io stream to print to 35.176 - * @param x sxpr to print 35.177 - * @param flags print flags 35.178 - * @return number of bytes written 35.179 - */ 35.180 -int objprint(IOStream *io, Sxpr x, unsigned flags){ 35.181 - SxprType *def = get_sxpr_type(get_type(x)); 35.182 - ObjPrintFn *print_fn = (def && def->print ? def->print : default_print); 35.183 - int k = 0; 35.184 - if(!io) return k; 35.185 - if(flags & PRINT_TYPE){ 35.186 - k += IOStream_print(io, "%s:", def->name); 35.187 - } 35.188 - if(def->pointer && (flags & PRINT_ADDR)){ 35.189 - k += IOStream_print(io, "<%p>", get_ptr(x)); 35.190 - } 35.191 - k += print_fn(io, x, flags); 35.192 - return k; 35.193 -} 35.194 - 35.195 -Sxpr objcopy(Sxpr x){ 35.196 - SxprType *def = get_sxpr_type(get_type(x)); 35.197 - ObjCopyFn *copy_fn = (def ? def->copy : NULL); 35.198 - Sxpr v; 35.199 - if(copy_fn){ 35.200 - v = copy_fn(x); 35.201 - } else if(def->pointer){ 35.202 - v = ONOMEM; 35.203 - } else { 35.204 - v = x; 35.205 - } 35.206 - return v; 35.207 -} 35.208 - 35.209 -/** General sxpr free function. 35.210 - * Frees an sxpr using the free function for its type. 35.211 - * Free functions must recursively free any subsxprs. 35.212 - * If no function is defined then the default is to 35.213 - * free sxprs whose type has pointer true. 35.214 - * Sxprs must not be used after freeing. 35.215 - * 35.216 - * @param x sxpr to free 35.217 - */ 35.218 -void objfree(Sxpr x){ 35.219 - SxprType *def = get_sxpr_type(get_type(x)); 35.220 - 35.221 - if(def){ 35.222 - if(def->free){ 35.223 - def->free(x); 35.224 - } else if (def->pointer){ 35.225 - hfree(x); 35.226 - } 35.227 - } 35.228 -} 35.229 - 35.230 -/** General sxpr equality function. 35.231 - * Compares x and y using the equal function for x. 35.232 - * Uses default_equal() if x has no equal function. 35.233 - * 35.234 - * @param x sxpr to compare 35.235 - * @param y sxpr to compare 35.236 - * @return 1 if equal, 0 otherwise 35.237 - */ 35.238 -int objequal(Sxpr x, Sxpr y){ 35.239 - SxprType *def = get_sxpr_type(get_type(x)); 35.240 - ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal); 35.241 - return equal_fn(x, y); 35.242 -} 35.243 - 35.244 -/** Search for a key in an alist. 35.245 - * An alist is a list of conses, where the cars 35.246 - * of the conses are the keys. Compares keys using equality. 35.247 - * 35.248 - * @param k key 35.249 - * @param l alist to search 35.250 - * @return first element of l with car k, or ONULL 35.251 - */ 35.252 -Sxpr assoc(Sxpr k, Sxpr l){ 35.253 - for( ; CONSP(l) ; l = CDR(l)){ 35.254 - Sxpr x = CAR(l); 35.255 - if(CONSP(x) && objequal(k, CAR(x))){ 35.256 - return x; 35.257 - } 35.258 - } 35.259 - return ONULL; 35.260 -} 35.261 - 35.262 -/** Search for a key in an alist. 35.263 - * An alist is a list of conses, where the cars 35.264 - * of the conses are the keys. Compares keys using eq. 35.265 - * 35.266 - * @param k key 35.267 - * @param l alist to search 35.268 - * @return first element of l with car k, or ONULL 35.269 - */ 35.270 -Sxpr assocq(Sxpr k, Sxpr l){ 35.271 - for( ; CONSP(l); l = CDR(l)){ 35.272 - Sxpr x = CAR(l); 35.273 - if(CONSP(x) && eq(k, CAR(x))){ 35.274 - return x; 35.275 - } 35.276 - } 35.277 - return ONULL; 35.278 -} 35.279 - 35.280 -/** Add a new key and value to an alist. 35.281 - * 35.282 - * @param k key 35.283 - * @param l value 35.284 - * @param l alist 35.285 - * @return l with the new cell added to the front 35.286 - */ 35.287 -Sxpr acons(Sxpr k, Sxpr v, Sxpr l){ 35.288 - Sxpr x, y; 35.289 - x = cons_new(k, v); 35.290 - if(NOMEMP(x)) return x; 35.291 - y = cons_new(x, l); 35.292 - if(NOMEMP(y)) cons_free_cells(x); 35.293 - return y; 35.294 -} 35.295 - 35.296 -/** Test if a list contains an element. 35.297 - * Uses sxpr equality. 35.298 - * 35.299 - * @param l list 35.300 - * @param x element to look for 35.301 - * @return a tail of l with x as car, or ONULL 35.302 - */ 35.303 -Sxpr cons_member(Sxpr l, Sxpr x){ 35.304 - for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){} 35.305 - return l; 35.306 -} 35.307 - 35.308 -/** Test if a list contains an element satisfying a test. 35.309 - * The test function is called with v and an element of the list. 35.310 - * 35.311 - * @param l list 35.312 - * @param test_fn test function to use 35.313 - * @param v value for first argument to the test 35.314 - * @return a tail of l with car satisfying the test, or 0 35.315 - */ 35.316 -Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){ 35.317 - for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ } 35.318 - return l; 35.319 -} 35.320 - 35.321 -/** Test if the elements of list 't' are a subset of the elements 35.322 - * of list 's'. Element order is not significant. 35.323 - * 35.324 - * @param s element list to check subset of 35.325 - * @param t element list to check if is a subset 35.326 - * @return 1 if is a subset, 0 otherwise 35.327 - */ 35.328 -int cons_subset(Sxpr s, Sxpr t){ 35.329 - for( ; CONSP(t); t = CDR(t)){ 35.330 - if(!CONSP(cons_member(s, CAR(t)))){ 35.331 - return 0; 35.332 - } 35.333 - } 35.334 - return 1; 35.335 -} 35.336 - 35.337 -/** Test if two lists have equal sets of elements. 35.338 - * Element order is not significant. 35.339 - * 35.340 - * @param s list to check 35.341 - * @param t list to check 35.342 - * @return 1 if equal, 0 otherwise 35.343 - */ 35.344 -int cons_set_equal(Sxpr s, Sxpr t){ 35.345 - return cons_subset(s, t) && cons_subset(t, s); 35.346 -} 35.347 - 35.348 -#ifdef USE_GC 35.349 -/*============================================================================*/ 35.350 -/* The functions inside this ifdef are only safe if GC is used. 35.351 - * Otherwise they may leak memory. 35.352 - */ 35.353 - 35.354 -/** Remove an element from a list (GC only). 35.355 - * Uses sxpr equality and removes all instances, even 35.356 - * if there are more than one. 35.357 - * 35.358 - * @param l list to remove elements from 35.359 - * @param x element to remove 35.360 - * @return modified input list 35.361 - */ 35.362 -Sxpr cons_remove(Sxpr l, Sxpr x){ 35.363 - return cons_remove_if(l, eq, x); 35.364 -} 35.365 - 35.366 -/** Remove elements satisfying a test (GC only). 35.367 - * The test function is called with v and an element of the set. 35.368 - * 35.369 - * @param l list to remove elements from 35.370 - * @param test_fn function to use to decide if an element should be removed 35.371 - * @return modified input list 35.372 - */ 35.373 -Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){ 35.374 - Sxpr prev = ONULL, elt, next; 35.375 - 35.376 - for(elt = l; CONSP(elt); elt = next){ 35.377 - next = CDR(elt); 35.378 - if(test_fn(v, CAR(elt))){ 35.379 - if(NULLP(prev)){ 35.380 - l = next; 35.381 - } else { 35.382 - CDR(prev) = next; 35.383 - } 35.384 - } 35.385 - } 35.386 - return l; 35.387 -} 35.388 - 35.389 -/** Set the value for a key in an alist (GC only). 35.390 - * If the key is present, changes the value, otherwise 35.391 - * adds a new cell. 35.392 - * 35.393 - * @param k key 35.394 - * @param v value 35.395 - * @param l alist 35.396 - * @return modified or extended list 35.397 - */ 35.398 -Sxpr setf(Sxpr k, Sxpr v, Sxpr l){ 35.399 - Sxpr e = assoc(k, l); 35.400 - if(NULLP(e)){ 35.401 - l = acons(k, v, l); 35.402 - } else { 35.403 - CAR(CDR(e)) = v; 35.404 - } 35.405 - return l; 35.406 -} 35.407 -/*============================================================================*/ 35.408 -#endif /* USE_GC */ 35.409 - 35.410 -/** Create a new atom with the given name. 35.411 - * Makes an integer sxpr if the name can be parsed as an int. 35.412 - * 35.413 - * @param name the name 35.414 - * @return new atom 35.415 - */ 35.416 -Sxpr atom_new(char *name){ 35.417 - Sxpr n, obj = ONOMEM; 35.418 - long v; 35.419 - 35.420 - if(convert_atol(name, &v) == 0){ 35.421 - obj = OINT(v); 35.422 - } else { 35.423 - n = string_new(name); 35.424 - if(NOMEMP(n)) goto exit; 35.425 - obj = HALLOC(ObjAtom, T_ATOM); 35.426 - if(NOMEMP(obj)){ 35.427 - string_free(n); 35.428 - goto exit; 35.429 - } 35.430 - OBJ_ATOM(obj)->name = n; 35.431 - } 35.432 - exit: 35.433 - return obj; 35.434 -} 35.435 - 35.436 -/** Free an atom. 35.437 - * 35.438 - * @param obj to free 35.439 - */ 35.440 -void atom_free(Sxpr obj){ 35.441 - // Interned atoms are shared, so do not free. 35.442 - if(OBJ_ATOM(obj)->interned) return; 35.443 - objfree(OBJ_ATOM(obj)->name); 35.444 - hfree(obj); 35.445 -} 35.446 - 35.447 -/** Copy an atom. 35.448 - * 35.449 - * @param obj to copy 35.450 - */ 35.451 -Sxpr atom_copy(Sxpr obj){ 35.452 - Sxpr v; 35.453 - if(OBJ_ATOM(obj)->interned){ 35.454 - v = obj; 35.455 - } else { 35.456 - v = atom_new(atom_name(obj)); 35.457 - } 35.458 - return v; 35.459 -} 35.460 - 35.461 -/** Print an atom. Prints the atom name. 35.462 - * 35.463 - * @param io stream to print to 35.464 - * @param obj to print 35.465 - * @param flags print flags 35.466 - * @return number of bytes printed 35.467 - */ 35.468 -int atom_print(IOStream *io, Sxpr obj, unsigned flags){ 35.469 - return objprint(io, OBJ_ATOM(obj)->name, flags); 35.470 -} 35.471 - 35.472 -/** Atom equality. 35.473 - * 35.474 - * @param x to compare 35.475 - * @param y to compare 35.476 - * @return 1 if equal, 0 otherwise 35.477 - */ 35.478 -int atom_equal(Sxpr x, Sxpr y){ 35.479 - int ok; 35.480 - ok = eq(x, y); 35.481 - if(ok) goto exit; 35.482 - ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name); 35.483 - if(ok) goto exit; 35.484 - ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y); 35.485 - exit: 35.486 - return ok; 35.487 -} 35.488 - 35.489 -/** Get the name of an atom. 35.490 - * 35.491 - * @param obj atom 35.492 - * @return name 35.493 - */ 35.494 -char * atom_name(Sxpr obj){ 35.495 - return string_string(OBJ_ATOM(obj)->name); 35.496 -} 35.497 - 35.498 -int atom_length(Sxpr obj){ 35.499 - return string_length(OBJ_ATOM(obj)->name); 35.500 -} 35.501 - 35.502 -/** Get the C string from a string sxpr. 35.503 - * 35.504 - * @param obj string sxpr 35.505 - * @return string 35.506 - */ 35.507 -char * string_string(Sxpr obj){ 35.508 - return OBJ_STRING(obj)->data; 35.509 -} 35.510 - 35.511 -/** Get the length of a string. 35.512 - * 35.513 - * @param obj string 35.514 - * @return length 35.515 - */ 35.516 -int string_length(Sxpr obj){ 35.517 - return OBJ_STRING(obj)->len; 35.518 -} 35.519 - 35.520 -/** Create a new string. The input string is copied, 35.521 - * and must be null-terminated. 35.522 - * 35.523 - * @param s characters to put in the string 35.524 - * @return new sxpr 35.525 - */ 35.526 -Sxpr string_new(char *s){ 35.527 - int n = (s ? strlen(s) : 0); 35.528 - return string_new_n(s, n); 35.529 -} 35.530 - 35.531 -/** Create a new string. The input string is copied, 35.532 - * and need not be null-terminated. 35.533 - * 35.534 - * @param s characters to put in the string (may be null) 35.535 - * @param n string length 35.536 - * @return new sxpr 35.537 - */ 35.538 -Sxpr string_new_n(char *s, int n){ 35.539 - Sxpr obj; 35.540 - obj = halloc(sizeof(ObjString) + n + 1, T_STRING); 35.541 - if(!NOMEMP(obj)){ 35.542 - char *str = OBJ_STRING(obj)->data; 35.543 - OBJ_STRING(obj)->len = n; 35.544 - if(s){ 35.545 - memcpy(str, s, n); 35.546 - str[n] = '\0'; 35.547 - } else { 35.548 - memset(str, 0, n + 1); 35.549 - } 35.550 - } 35.551 - return obj; 35.552 -} 35.553 - 35.554 -/** Free a string. 35.555 - * 35.556 - * @param obj to free 35.557 - */ 35.558 -void string_free(Sxpr obj){ 35.559 - hfree(obj); 35.560 -} 35.561 - 35.562 -/** Copy a string. 35.563 - * 35.564 - * @param obj to copy 35.565 - */ 35.566 -Sxpr string_copy(Sxpr obj){ 35.567 - return string_new_n(string_string(obj), string_length(obj)); 35.568 -} 35.569 - 35.570 -/** Determine if a string needs escapes when printed 35.571 - * using the given flags. 35.572 - * 35.573 - * @param str string to check 35.574 - * @param n string length 35.575 - * @param flags print flags 35.576 - * @return 1 if needs escapes, 0 otherwise 35.577 - */ 35.578 -int needs_escapes(char *str, int n, unsigned flags){ 35.579 - char *c; 35.580 - int i; 35.581 - int val = 0; 35.582 - 35.583 - if(str){ 35.584 - for(i=0, c=str; i<n; i++, c++){ 35.585 - if(in_alpha_class(*c)) continue; 35.586 - if(in_decimal_digit_class(*c)) continue; 35.587 - if(in_class(*c, "/._+:@~-")) continue; 35.588 - val = 1; 35.589 - break; 35.590 - } 35.591 - } 35.592 - return val; 35.593 -} 35.594 - 35.595 -char randchar(void){ 35.596 - int r; 35.597 - char c; 35.598 - for( ; ; ){ 35.599 - r = rand(); 35.600 - c = (r >> 16) & 0xff; 35.601 - if('a' <= c && c <= 'z') break; 35.602 - } 35.603 - return c; 35.604 -} 35.605 - 35.606 -int string_contains(char *s, int s_n, char *k, int k_n){ 35.607 - int i, n = s_n - k_n; 35.608 - for(i=0; i < n; i++){ 35.609 - if(!memcmp(s+i, k, k_n)) return 1; 35.610 - } 35.611 - return 0; 35.612 -} 35.613 - 35.614 -int string_delim(char *s, int s_n, char *d, int d_n){ 35.615 - int i; 35.616 - if(d_n < 4) return -1; 35.617 - memset(d, 0, d_n+1); 35.618 - for(i=0; i<3; i++){ 35.619 - d[i] = randchar(); 35.620 - } 35.621 - for( ; i < d_n; i++){ 35.622 - if(!string_contains(s, s_n, d, i)){ 35.623 - return i; 35.624 - } 35.625 - d[i] = randchar(); 35.626 - } 35.627 - return -1; 35.628 -} 35.629 - 35.630 -/** Print the bytes in a string as-is. 35.631 - * 35.632 - * @param io stream 35.633 - * @param str string 35.634 - * @param n length 35.635 - * @return bytes written or error code 35.636 - */ 35.637 -int _string_print_raw(IOStream *io, char *str, int n){ 35.638 - int k = 0; 35.639 - k = IOStream_write(io, str, n); 35.640 - return k; 35.641 -} 35.642 - 35.643 -/** Print a string in counted data format. 35.644 - * 35.645 - * @param io stream 35.646 - * @param str string 35.647 - * @param n length 35.648 - * @return bytes written or error code 35.649 - */ 35.650 -int _string_print_counted(IOStream *io, char *str, int n){ 35.651 - int k = 0; 35.652 - k += IOStream_print(io, "%c%c%d%c", 35.653 - c_data_open, c_data_count, n, c_data_count); 35.654 - k += IOStream_write(io, str, n); 35.655 - return k; 35.656 -} 35.657 - 35.658 -/** Print a string in quoted data format. 35.659 - * 35.660 - * @param io stream 35.661 - * @param str string 35.662 - * @param n length 35.663 - * @return bytes written or error code 35.664 - */ 35.665 -int _string_print_quoted(IOStream *io, char *str, int n){ 35.666 - int k = 0; 35.667 - char d[10]; 35.668 - int d_n; 35.669 - d_n = string_delim(str, n, d, sizeof(d) - 1); 35.670 - k += IOStream_print(io, "%c%c%s%c", 35.671 - c_data_open, c_data_quote, d, c_data_quote); 35.672 - k += IOStream_write(io, str, n); 35.673 - k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote); 35.674 - return k; 35.675 -} 35.676 - 35.677 -/** Print a string as a quoted string. 35.678 - * 35.679 - * @param io stream 35.680 - * @param str string 35.681 - * @param n length 35.682 - * @return bytes written or error code 35.683 - */ 35.684 -int _string_print_string(IOStream *io, char *str, int n){ 35.685 - int k = 0; 35.686 - 35.687 - k += IOStream_print(io, "\""); 35.688 - if(str){ 35.689 - char *s, *t; 35.690 - for(s = str, t = str + n; s < t; s++){ 35.691 - if(*s < ' ' || *s >= 127 ){ 35.692 - switch(*s){ 35.693 - case '\a': k += IOStream_print(io, "\\a"); break; 35.694 - case '\b': k += IOStream_print(io, "\\b"); break; 35.695 - case '\f': k += IOStream_print(io, "\\f"); break; 35.696 - case '\n': k += IOStream_print(io, "\\n"); break; 35.697 - case '\r': k += IOStream_print(io, "\\r"); break; 35.698 - case '\t': k += IOStream_print(io, "\\t"); break; 35.699 - case '\v': k += IOStream_print(io, "\\v"); break; 35.700 - default: 35.701 - // Octal escape; 35.702 - k += IOStream_print(io, "\\%o", *s); 35.703 - break; 35.704 - } 35.705 - } else if(*s == c_double_quote || 35.706 - *s == c_single_quote || 35.707 - *s == c_escape){ 35.708 - k += IOStream_print(io, "\\%c", *s); 35.709 - } else { 35.710 - k+= IOStream_print(io, "%c", *s); 35.711 - } 35.712 - } 35.713 - } 35.714 - k += IOStream_print(io, "\""); 35.715 - return k; 35.716 -} 35.717 - 35.718 -/** Print a string to a stream, with escapes if necessary. 35.719 - * 35.720 - * @param io stream to print to 35.721 - * @param str string 35.722 - * @param n string length 35.723 - * @param flags print flags 35.724 - * @return number of bytes written 35.725 - */ 35.726 -int _string_print(IOStream *io, char *str, int n, unsigned flags){ 35.727 - int k = 0; 35.728 - if((flags & PRINT_COUNTED)){ 35.729 - k = _string_print_counted(io, str, n); 35.730 - } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){ 35.731 - k = _string_print_raw(io, str, n); 35.732 - } else if(n > 50){ 35.733 - k = _string_print_quoted(io, str, n); 35.734 - } else { 35.735 - k = _string_print_string(io, str, n); 35.736 - } 35.737 - return k; 35.738 -} 35.739 - 35.740 -/** Print a string to a stream, with escapes if necessary. 35.741 - * 35.742 - * @param io stream to print to 35.743 - * @param obj string 35.744 - * @param flags print flags 35.745 - * @return number of bytes written 35.746 - */ 35.747 -int string_print(IOStream *io, Sxpr obj, unsigned flags){ 35.748 - return _string_print(io, 35.749 - OBJ_STRING(obj)->data, 35.750 - OBJ_STRING(obj)->len, 35.751 - flags); 35.752 -} 35.753 - 35.754 -int string_eq(char *s, int s_n, char *t, int t_n){ 35.755 - return (s_n == t_n) && (memcmp(s, t, s_n) == 0); 35.756 -} 35.757 - 35.758 -/** Compare an sxpr with a string for equality. 35.759 - * 35.760 - * @param x string to compare with 35.761 - * @param y sxpr to compare 35.762 - * @return 1 if equal, 0 otherwise 35.763 - */ 35.764 -int string_equal(Sxpr x, Sxpr y){ 35.765 - int ok = 0; 35.766 - ok = eq(x,y); 35.767 - if(ok) goto exit; 35.768 - ok = has_type(y, T_STRING) && 35.769 - string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, 35.770 - OBJ_STRING(y)->data, OBJ_STRING(y)->len); 35.771 - if(ok) goto exit; 35.772 - ok = has_type(y, T_ATOM) && 35.773 - string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, 35.774 - atom_name(y), atom_length(y)); 35.775 - exit: 35.776 - return ok; 35.777 -} 35.778 - 35.779 -/** Create a new cons cell. 35.780 - * The cell is ONOMEM if either argument is. 35.781 - * 35.782 - * @param car sxpr for the car 35.783 - * @param cdr sxpr for the cdr 35.784 - * @return new cons 35.785 - */ 35.786 -Sxpr cons_new(Sxpr car, Sxpr cdr){ 35.787 - Sxpr obj; 35.788 - if(NOMEMP(car) || NOMEMP(cdr)){ 35.789 - obj = ONOMEM; 35.790 - } else { 35.791 - obj = HALLOC(ObjCons, T_CONS); 35.792 - if(!NOMEMP(obj)){ 35.793 - ObjCons *z = OBJ_CONS(obj); 35.794 - z->car = car; 35.795 - z->cdr = cdr; 35.796 - } 35.797 - } 35.798 - return obj; 35.799 -} 35.800 - 35.801 -/** Push a new element onto a list. 35.802 - * 35.803 - * @param list list to add to 35.804 - * @param elt element to add 35.805 - * @return 0 if successful, error code otherwise 35.806 - */ 35.807 -int cons_push(Sxpr *list, Sxpr elt){ 35.808 - Sxpr l; 35.809 - l = cons_new(elt, *list); 35.810 - if(NOMEMP(l)) return -ENOMEM; 35.811 - *list = l; 35.812 - return 0; 35.813 -} 35.814 - 35.815 -/** Free a cons. Recursively frees the car and cdr. 35.816 - * 35.817 - * @param obj to free 35.818 - */ 35.819 -void cons_free(Sxpr obj){ 35.820 - Sxpr next; 35.821 - for(; CONSP(obj); obj = next){ 35.822 - next = CDR(obj); 35.823 - objfree(CAR(obj)); 35.824 - hfree(obj); 35.825 - } 35.826 - if(!NULLP(obj)){ 35.827 - objfree(obj); 35.828 - } 35.829 -} 35.830 - 35.831 -/** Copy a cons. Recursively copies the car and cdr. 35.832 - * 35.833 - * @param obj to copy 35.834 - */ 35.835 -Sxpr cons_copy(Sxpr obj){ 35.836 - Sxpr v = ONULL; 35.837 - Sxpr l = ONULL, x = ONONE; 35.838 - for(l = obj; CONSP(l); l = CDR(l)){ 35.839 - x = objcopy(CAR(l)); 35.840 - if(NOMEMP(x)) goto exit; 35.841 - x = cons_new(x, v); 35.842 - if(NOMEMP(x)) goto exit; 35.843 - v = x; 35.844 - } 35.845 - v = nrev(v); 35.846 - exit: 35.847 - if(NOMEMP(x)){ 35.848 - objfree(v); 35.849 - v = ONOMEM; 35.850 - } 35.851 - return v; 35.852 -} 35.853 - 35.854 -/** Free a cons and its cdr cells, but not the car sxprs. 35.855 - * Does nothing if called on something that is not a cons. 35.856 - * 35.857 - * @param obj to free 35.858 - */ 35.859 -void cons_free_cells(Sxpr obj){ 35.860 - Sxpr next; 35.861 - for(; CONSP(obj); obj = next){ 35.862 - next = CDR(obj); 35.863 - hfree(obj); 35.864 - } 35.865 -} 35.866 - 35.867 -/** Print a cons. 35.868 - * Prints the cons in list format if the cdrs are conses. 35.869 - * uses pair (dot) format if the last cdr is not a cons (or null). 35.870 - * 35.871 - * @param io stream to print to 35.872 - * @param obj to print 35.873 - * @param flags print flags 35.874 - * @return number of bytes written 35.875 - */ 35.876 -int cons_print(IOStream *io, Sxpr obj, unsigned flags){ 35.877 - int first = 1; 35.878 - int k = 0; 35.879 - k += IOStream_print(io, "("); 35.880 - for( ; CONSP(obj) ; obj = CDR(obj)){ 35.881 - if(first){ 35.882 - first = 0; 35.883 - } else { 35.884 - k += IOStream_print(io, " "); 35.885 - } 35.886 - k += objprint(io, CAR(obj), flags); 35.887 - } 35.888 - if(!NULLP(obj)){ 35.889 - k += IOStream_print(io, " . "); 35.890 - k += objprint(io, obj, flags); 35.891 - } 35.892 - k += IOStream_print(io, ")"); 35.893 - return (IOStream_error(io) ? -1 : k); 35.894 -} 35.895 - 35.896 -/** Compare a cons with another sxpr for equality. 35.897 - * If y is a cons, compares the cars and cdrs recursively. 35.898 - * 35.899 - * @param x cons to compare 35.900 - * @param y sxpr to compare 35.901 - * @return 1 if equal, 0 otherwise 35.902 - */ 35.903 -int cons_equal(Sxpr x, Sxpr y){ 35.904 - return CONSP(y) && 35.905 - objequal(CAR(x), CAR(y)) && 35.906 - objequal(CDR(x), CDR(y)); 35.907 -} 35.908 - 35.909 -/** Return the length of a cons list. 35.910 - * 35.911 - * @param obj list 35.912 - * @return length 35.913 - */ 35.914 -int cons_length(Sxpr obj){ 35.915 - int count = 0; 35.916 - for( ; CONSP(obj); obj = CDR(obj)){ 35.917 - count++; 35.918 - } 35.919 - return count; 35.920 -} 35.921 - 35.922 -/** Destructively reverse a cons list in-place. 35.923 - * If the argument is not a cons it is returned unchanged. 35.924 - * 35.925 - * @param l to reverse 35.926 - * @return reversed list 35.927 - */ 35.928 -Sxpr nrev(Sxpr l){ 35.929 - if(CONSP(l)){ 35.930 - // Iterate down the cells in the list making the cdr of 35.931 - // each cell point to the previous cell. The last cell 35.932 - // is the head of the reversed list. 35.933 - Sxpr prev = ONULL; 35.934 - Sxpr cell = l; 35.935 - Sxpr next; 35.936 - 35.937 - while(1){ 35.938 - next = CDR(cell); 35.939 - CDR(cell) = prev; 35.940 - if(!CONSP(next)) break; 35.941 - prev = cell; 35.942 - cell = next; 35.943 - } 35.944 - l = cell; 35.945 - } 35.946 - return l; 35.947 -} 35.948 - 35.949 -/** Print the null sxpr. 35.950 - * 35.951 - * @param io stream to print to 35.952 - * @param obj to print 35.953 - * @param flags print flags 35.954 - * @return number of bytes written 35.955 - */ 35.956 -static int null_print(IOStream *io, Sxpr obj, unsigned flags){ 35.957 - return IOStream_print(io, "()"); 35.958 -} 35.959 - 35.960 -/** Print the `unspecified' sxpr none. 35.961 - * 35.962 - * @param io stream to print to 35.963 - * @param obj to print 35.964 - * @param flags print flags 35.965 - * @return number of bytes written 35.966 - */ 35.967 -static int none_print(IOStream *io, Sxpr obj, unsigned flags){ 35.968 - return IOStream_print(io, "<none>"); 35.969 -} 35.970 - 35.971 -/** Print an integer. 35.972 - * 35.973 - * @param io stream to print to 35.974 - * @param obj to print 35.975 - * @param flags print flags 35.976 - * @return number of bytes written 35.977 - */ 35.978 -static int int_print(IOStream *io, Sxpr obj, unsigned flags){ 35.979 - return IOStream_print(io, "%d", OBJ_INT(obj)); 35.980 -} 35.981 - 35.982 -/** Print a boolean. 35.983 - * 35.984 - * @param io stream to print to 35.985 - * @param obj to print 35.986 - * @param flags print flags 35.987 - * @return number of bytes written 35.988 - */ 35.989 -static int bool_print(IOStream *io, Sxpr obj, unsigned flags){ 35.990 - return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false)); 35.991 -} 35.992 - 35.993 -/** Print an error. 35.994 - * 35.995 - * @param io stream to print to 35.996 - * @param obj to print 35.997 - * @param flags print flags 35.998 - * @return number of bytes written 35.999 - */ 35.1000 -static int err_print(IOStream *io, Sxpr obj, unsigned flags){ 35.1001 - int err = OBJ_INT(obj); 35.1002 - if(err < 0) err = -err; 35.1003 - return IOStream_print(io, "[error:%d:%s]", err, strerror(err)); 35.1004 -} 35.1005 - 35.1006 -/** Print the 'nomem' sxpr. 35.1007 - * 35.1008 - * @param io stream to print to 35.1009 - * @param obj to print 35.1010 - * @param flags print flags 35.1011 - * @return number of bytes written 35.1012 - */ 35.1013 -static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){ 35.1014 - return IOStream_print(io, "[ENOMEM]"); 35.1015 -} 35.1016 - 35.1017 -int sxprp(Sxpr obj, Sxpr name){ 35.1018 - return CONSP(obj) && objequal(CAR(obj), name); 35.1019 -} 35.1020 - 35.1021 -/** Get the name of an element. 35.1022 - * 35.1023 - * @param obj element 35.1024 - * @return name 35.1025 - */ 35.1026 -Sxpr sxpr_name(Sxpr obj){ 35.1027 - Sxpr val = ONONE; 35.1028 - if(CONSP(obj)){ 35.1029 - val = CAR(obj); 35.1030 - } else if(STRINGP(obj) || ATOMP(obj)){ 35.1031 - val = obj; 35.1032 - } 35.1033 - return val; 35.1034 -} 35.1035 - 35.1036 -int sxpr_is(Sxpr obj, char *s){ 35.1037 - if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s)); 35.1038 - if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s)); 35.1039 - return 0; 35.1040 -} 35.1041 - 35.1042 -int sxpr_elementp(Sxpr obj, Sxpr name){ 35.1043 - int ok = 0; 35.1044 - ok = CONSP(obj) && objequal(CAR(obj), name); 35.1045 - return ok; 35.1046 -} 35.1047 - 35.1048 -/** Get the attributes of an sxpr. 35.1049 - * 35.1050 - * @param obj sxpr 35.1051 - * @return attributes 35.1052 - */ 35.1053 -Sxpr sxpr_attributes(Sxpr obj){ 35.1054 - Sxpr val = ONULL; 35.1055 - if(CONSP(obj)){ 35.1056 - obj = CDR(obj); 35.1057 - if(CONSP(obj)){ 35.1058 - obj = CAR(obj); 35.1059 - if(sxprp(obj, intern("@"))){ 35.1060 - val = CDR(obj); 35.1061 - } 35.1062 - } 35.1063 - } 35.1064 - return val; 35.1065 -} 35.1066 - 35.1067 -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){ 35.1068 - Sxpr val = ONONE; 35.1069 - val = assoc(sxpr_attributes(obj), key); 35.1070 - if(CONSP(val) && CONSP(CDR(val))){ 35.1071 - val = CADR(def); 35.1072 - } else { 35.1073 - val = def; 35.1074 - } 35.1075 - return val; 35.1076 -} 35.1077 - 35.1078 -/** Get the children of an sxpr. 35.1079 - * 35.1080 - * @param obj sxpr 35.1081 - * @return children 35.1082 - */ 35.1083 -Sxpr sxpr_children(Sxpr obj){ 35.1084 - Sxpr val = ONULL; 35.1085 - if(CONSP(obj)){ 35.1086 - val = CDR(obj); 35.1087 - if(CONSP(val) && sxprp(CAR(val), intern("@"))){ 35.1088 - val = CDR(val); 35.1089 - } 35.1090 - } 35.1091 - return val; 35.1092 -} 35.1093 - 35.1094 -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){ 35.1095 - Sxpr val = ONONE; 35.1096 - Sxpr l; 35.1097 - for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){ 35.1098 - if(sxprp(CAR(l), name)){ 35.1099 - val = CAR(l); 35.1100 - break; 35.1101 - } 35.1102 - } 35.1103 - if(NONEP(val)) val = def; 35.1104 - return val; 35.1105 -} 35.1106 - 35.1107 -Sxpr sxpr_child0(Sxpr obj, Sxpr def){ 35.1108 - Sxpr val = ONONE; 35.1109 - Sxpr l = sxpr_children(obj); 35.1110 - if(CONSP(l)){ 35.1111 - val = CAR(l); 35.1112 - } else { 35.1113 - val = def; 35.1114 - } 35.1115 - return val; 35.1116 -} 35.1117 - 35.1118 -Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def){ 35.1119 - Sxpr val = def; 35.1120 - Sxpr l; 35.1121 - int i; 35.1122 - for (i = 0, l = sxpr_children(obj); CONSP(l); i++, l = CDR(l)){ 35.1123 - if(i == n){ 35.1124 - val = CAR(l); 35.1125 - break; 35.1126 - } 35.1127 - } 35.1128 - return val; 35.1129 -} 35.1130 - 35.1131 -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){ 35.1132 - Sxpr val = ONONE; 35.1133 - val = sxpr_child(obj, name, ONONE); 35.1134 - if(NONEP(val)){ 35.1135 - val = def; 35.1136 - } else { 35.1137 - val = sxpr_child0(val, def); 35.1138 - } 35.1139 - return val; 35.1140 -} 35.1141 - 35.1142 -/** Table of interned symbols. Indexed by symbol name. */ 35.1143 -static HashTable *symbols = NULL; 35.1144 - 35.1145 -/** Hash function for entries in the symbol table. 35.1146 - * 35.1147 - * @param key to hash 35.1148 - * @return hashcode 35.1149 - */ 35.1150 -static Hashcode sym_hash_fn(void *key){ 35.1151 - return hash_string((char*)key); 35.1152 -} 35.1153 - 35.1154 -/** Key equality function for the symbol table. 35.1155 - * 35.1156 - * @param x to compare 35.1157 - * @param y to compare 35.1158 - * @return 1 if equal, 0 otherwise 35.1159 - */ 35.1160 -static int sym_equal_fn(void *x, void *y){ 35.1161 - return !strcmp((char*)x, (char*)y); 35.1162 -} 35.1163 - 35.1164 -/** Entry free function for the symbol table. 35.1165 - * 35.1166 - * @param table the entry is in 35.1167 - * @param entry being freed 35.1168 - */ 35.1169 -static void sym_free_fn(HashTable *table, HTEntry *entry){ 35.1170 - if(entry){ 35.1171 - objfree(((ObjAtom*)entry->value)->name); 35.1172 - HTEntry_free(entry); 35.1173 - } 35.1174 -} 35.1175 - 35.1176 -/** Initialize the symbol table. 35.1177 - * 35.1178 - * @return 0 on sucess, error code otherwise 35.1179 - */ 35.1180 -static int init_symbols(void){ 35.1181 - symbols = HashTable_new(100); 35.1182 - if(symbols){ 35.1183 - symbols->key_hash_fn = sym_hash_fn; 35.1184 - symbols->key_equal_fn = sym_equal_fn; 35.1185 - symbols->entry_free_fn = sym_free_fn; 35.1186 - return 0; 35.1187 - } 35.1188 - return -1; 35.1189 -} 35.1190 - 35.1191 -/** Cleanup the symbol table. Frees the table and all its symbols. 35.1192 - */ 35.1193 -void cleanup_symbols(void){ 35.1194 - HashTable_free(symbols); 35.1195 - symbols = NULL; 35.1196 -} 35.1197 - 35.1198 -/** Get the interned symbol with the given name. 35.1199 - * No new symbol is created. 35.1200 - * 35.1201 - * @return symbol or null 35.1202 - */ 35.1203 -Sxpr get_symbol(char *sym){ 35.1204 - HTEntry *entry; 35.1205 - if(!symbols){ 35.1206 - if(init_symbols()) return ONOMEM; 35.1207 - return ONULL; 35.1208 - } 35.1209 - entry = HashTable_get_entry(symbols, sym); 35.1210 - if(entry){ 35.1211 - return OBJP(T_ATOM, entry->value); 35.1212 - } else { 35.1213 - return ONULL; 35.1214 - } 35.1215 -} 35.1216 - 35.1217 -/** Get the interned symbol with the given name. 35.1218 - * Creates a new symbol if necessary. 35.1219 - * 35.1220 - * @return symbol 35.1221 - */ 35.1222 -Sxpr intern(char *sym){ 35.1223 - Sxpr symbol = get_symbol(sym); 35.1224 - if(NULLP(symbol)){ 35.1225 - if(!symbols) return ONOMEM; 35.1226 - symbol = atom_new(sym); 35.1227 - if(!NOMEMP(symbol)){ 35.1228 - OBJ_ATOM(symbol)->interned = TRUE; 35.1229 - HashTable_add(symbols, atom_name(symbol), get_ptr(symbol)); 35.1230 - } 35.1231 - } 35.1232 - return symbol; 35.1233 -}
36.1 --- a/tools/libxutil/sxpr.h Tue May 24 21:10:23 2005 +0000 36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 36.3 @@ -1,437 +0,0 @@ 36.4 -/* 36.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 36.6 - * 36.7 - * This library is free software; you can redistribute it and/or modify 36.8 - * it under the terms of the GNU Lesser General Public License as 36.9 - * published by the Free Software Foundation; either version 2.1 of the 36.10 - * License, or (at your option) any later version. This library is 36.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 36.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.13 - * FITNESS FOR A PARTICULAR PURPOSE. 36.14 - * See the GNU Lesser General Public License for more details. 36.15 - * 36.16 - * You should have received a copy of the GNU Lesser General Public License 36.17 - * along with this library; if not, write to the Free Software Foundation, 36.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 36.19 - */ 36.20 -#ifndef _XUTIL_SXPR_H_ 36.21 -#define _XUTIL_SXPR_H_ 36.22 - 36.23 -#ifdef __KERNEL__ 36.24 -#include <linux/config.h> 36.25 -#include <linux/types.h> 36.26 -#else 36.27 -#include <stdint.h> 36.28 -#endif 36.29 - 36.30 -#include "hash_table.h" 36.31 -#include "iostream.h" 36.32 -#include "allocate.h" 36.33 - 36.34 -/** @file 36.35 - * Definitions for rules and sxprs. 36.36 - */ 36.37 - 36.38 -#ifndef NULL 36.39 -#define NULL 0 36.40 -#endif 36.41 - 36.42 -#ifndef TRUE 36.43 -#define TRUE 1 36.44 -#endif 36.45 - 36.46 -#ifndef FALSE 36.47 -#define FALSE 0 36.48 -#endif 36.49 - 36.50 -/** Sxpr type. */ 36.51 -typedef int16_t TypeCode; 36.52 - 36.53 -/** A typed sxpr handle.*/ 36.54 -typedef struct Sxpr { 36.55 - /** Sxpr type. */ 36.56 - TypeCode type; 36.57 - union { 36.58 - /** Sxpr value. */ 36.59 - unsigned long ul; 36.60 - /** Pointer. */ 36.61 - void *ptr; 36.62 - } v; 36.63 -} Sxpr; 36.64 - 36.65 -/** Get the integer value from an sxpr. 36.66 - * 36.67 - * @param obj sxpr 36.68 - * @return value 36.69 - */ 36.70 -static inline unsigned long get_ul(Sxpr obj){ 36.71 - return obj.v.ul; 36.72 -} 36.73 - 36.74 -/** Get the pointer value from an sxpr. 36.75 - * 36.76 - * @param obj sxpr 36.77 - * @return value 36.78 - */ 36.79 -static inline void * get_ptr(Sxpr obj){ 36.80 - return obj.v.ptr; 36.81 -} 36.82 - 36.83 -/** Create an sxpr containing a pointer. 36.84 - * 36.85 - * @param ty typecode 36.86 - * @param val pointer 36.87 - * @return sxpr 36.88 - */ 36.89 -static inline Sxpr obj_ptr(TypeCode ty, void *val){ 36.90 - return (Sxpr){ .type= ty, .v= { .ptr= val } }; 36.91 -} 36.92 - 36.93 -/** Create an sxpr containing an integer. 36.94 - * 36.95 - * @param ty typecode 36.96 - * @param val integer 36.97 - * @return sxpr 36.98 - */ 36.99 -static inline Sxpr obj_ul(TypeCode ty, unsigned long val){ 36.100 - return (Sxpr){ .type= ty, .v= { .ul= val } }; 36.101 -} 36.102 - 36.103 -/** Get the type of an sxpr. 36.104 - * 36.105 - * @param obj sxpr 36.106 - * @return type 36.107 - */ 36.108 -static inline TypeCode get_type(Sxpr obj){ 36.109 - return obj.type; 36.110 -} 36.111 - 36.112 -/** Check the type of an sxpr. 36.113 - * 36.114 - * @param obj sxpr 36.115 - * @param type to check 36.116 - * @return 1 if has the type, 0 otherwise 36.117 - */ 36.118 -static inline int has_type(Sxpr obj, TypeCode type){ 36.119 - return get_type(obj) == type; 36.120 -} 36.121 - 36.122 -/** Compare sxprs for literal equality of type and value. 36.123 - * 36.124 - * @param x sxpr to compare 36.125 - * @param y sxpr to compare 36.126 - * @return 1 if equal, 0 otherwise 36.127 - */ 36.128 -static inline int eq(Sxpr x, Sxpr y){ 36.129 - return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y))); 36.130 -} 36.131 - 36.132 -/** The 'unspecified' sxpr. */ 36.133 -#define T_NONE ((TypeCode)0) 36.134 -/** The empty list. */ 36.135 -#define T_NULL ((TypeCode)1) 36.136 -/** Unsigned integer. */ 36.137 -#define T_UINT ((TypeCode)2) 36.138 -/** A string. */ 36.139 -#define T_STRING ((TypeCode)3) 36.140 -/** An atom. */ 36.141 -#define T_ATOM ((TypeCode)4) 36.142 -/** A boolean. */ 36.143 -#define T_BOOL ((TypeCode)5) 36.144 - 36.145 -/** A cons (pair or list). */ 36.146 -#define T_CONS ((TypeCode)10) 36.147 - 36.148 -/** An error. */ 36.149 -#define T_ERR ((TypeCode)40) 36.150 -/** Sxpr type to indicate out of memory. */ 36.151 -#define T_NOMEM ((TypeCode)41) 36.152 - 36.153 -typedef struct ObjString { 36.154 - int len; 36.155 - char data[]; 36.156 -} ObjString; 36.157 - 36.158 -/** An atom. */ 36.159 -typedef struct ObjAtom { 36.160 - Sxpr name; 36.161 - Hashcode hashcode; 36.162 - int interned; 36.163 -} ObjAtom; 36.164 - 36.165 -/** A cons (pair). */ 36.166 -typedef struct ObjCons { 36.167 - Sxpr car; 36.168 - Sxpr cdr; 36.169 -} ObjCons; 36.170 - 36.171 -/** Flags for sxpr printing. */ 36.172 -enum PrintFlags { 36.173 - PRINT_RAW = 0x001, 36.174 - PRINT_TYPE = 0x002, 36.175 - PRINT_PRETTY = 0x004, 36.176 - PRINT_COUNTED = 0x008, 36.177 - PRINT_ADDR = 0x010, 36.178 -}; 36.179 - 36.180 -extern int _string_print(IOStream *io, char *str, int n, unsigned flags); 36.181 -extern int _string_print_raw(IOStream *io, char *str, int n); 36.182 -extern int _string_print_counted(IOStream *io, char *str, int n); 36.183 -extern int _string_print_quoted(IOStream *io, char *str, int n); 36.184 -extern int _string_print_string(IOStream *io, char *str, int n); 36.185 - 36.186 -/** An integer sxpr. 36.187 - * 36.188 - * @param ty type 36.189 - * @param val integer value 36.190 - */ 36.191 -#define OBJI(ty, val) obj_ul(ty, val) 36.192 - 36.193 -/** Make an integer sxpr. 36.194 - * @param x value 36.195 - */ 36.196 -#define OINT(x) OBJI(T_UINT, x) 36.197 - 36.198 -/** Make an error sxpr. 36.199 - * 36.200 - * @param x value 36.201 - */ 36.202 -#define OERR(x) OBJI(T_ERR, x) 36.203 - 36.204 -/** Out of memory constant. */ 36.205 -#define ONOMEM OBJI(T_NOMEM, 0) 36.206 - 36.207 -/** The `unspecified' constant. */ 36.208 -#define ONONE OBJI(T_NONE, 0) 36.209 - 36.210 -/** Empty list constant. */ 36.211 -#define ONULL OBJI(T_NULL, 0) 36.212 - 36.213 -/** False constant. */ 36.214 -#define OFALSE OBJI(T_BOOL, 0) 36.215 - 36.216 -/** True constant. */ 36.217 -#define OTRUE OBJI(T_BOOL, 1) 36.218 - 36.219 -/** A pointer sxpr. 36.220 - * If the pointer is non-null, returns an sxpr containing it. 36.221 - * If the pointer is null, returns ONOMEM. 36.222 - * 36.223 - * @param ty type 36.224 - * @param val pointer 36.225 - */ 36.226 -static inline Sxpr OBJP(int ty, void *val){ 36.227 - return (val ? obj_ptr(ty, val) : ONOMEM); 36.228 -} 36.229 - 36.230 -/** Make an integer sxpr containing a pointer. 36.231 - * 36.232 - * @param val pointer 36.233 - */ 36.234 -#define PTR(val) OBJP(T_UINT, (void*)(val)) 36.235 - 36.236 -/** Allocate some memory and return an sxpr containing it. 36.237 - * Returns ONOMEM if allocation failed. 36.238 - * 36.239 - * @param n number of bytes to allocate 36.240 - * @param ty typecode 36.241 - * @return sxpr 36.242 - */ 36.243 -#define halloc(_n, _ty) OBJP(_ty, allocate(_n)) 36.244 - 36.245 -/** Allocate an sxpr containing a pointer to the given type. 36.246 - * 36.247 - * @param _ctype type (uses sizeof to determine how many bytes to allocate) 36.248 - * @param _tycode typecode 36.249 - * @return sxpr, ONOMEM if allocation failed 36.250 - */ 36.251 -#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode) 36.252 - 36.253 -/* Recognizers for the various sxpr types. */ 36.254 -#define ATOMP(obj) has_type(obj, T_ATOM) 36.255 -#define BOOLP(obj) has_type(obj, T_BOOL) 36.256 -#define CONSP(obj) has_type(obj, T_CONS) 36.257 -#define ERRP(obj) has_type(obj, T_ERR) 36.258 -#define INTP(obj) has_type(obj, T_UINT) 36.259 -#define NOMEMP(obj) has_type(obj, T_NOMEM) 36.260 -#define NONEP(obj) has_type(obj, T_NONE) 36.261 -#define NULLP(obj) has_type(obj, T_NULL) 36.262 -#define STRINGP(obj) has_type(obj, T_STRING) 36.263 - 36.264 -#define TRUEP(obj) get_ul(obj) 36.265 - 36.266 -/** Convert an sxpr to an unsigned integer. */ 36.267 -#define OBJ_UINT(x) get_ul(x) 36.268 -/** Convert an sxpr to an integer. */ 36.269 -#define OBJ_INT(x) (int)get_ul(x) 36.270 - 36.271 -/* Conversions of sxprs to their values. 36.272 - * No checking is done. 36.273 - */ 36.274 -#define OBJ_STRING(x) ((ObjString*)get_ptr(x)) 36.275 -#define OBJ_CONS(x) ((ObjCons*)get_ptr(x)) 36.276 -#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x)) 36.277 -#define OBJ_SET(x) ((ObjSet*)get_ptr(x)) 36.278 -#define CAR(x) (OBJ_CONS(x)->car) 36.279 -#define CDR(x) (OBJ_CONS(x)->cdr) 36.280 - 36.281 -#define CAAR(x) (CAR(CAR(x))) 36.282 -#define CADR(x) (CAR(CDR(x))) 36.283 -#define CDAR(x) (CDR(CAR(x))) 36.284 -#define CDDR(x) (CDR(CDR(x))) 36.285 - 36.286 -/** Checked version of CAR 36.287 - * 36.288 - * @param x sxpr 36.289 - * @return CAR if a cons, x otherwise 36.290 - */ 36.291 -static inline Sxpr car(Sxpr x){ 36.292 - return (CONSP(x) ? CAR(x) : x); 36.293 -} 36.294 - 36.295 -/** Checked version of CDR. 36.296 - * 36.297 - * @param x sxpr 36.298 - * @return CDR if a cons, null otherwise 36.299 - */ 36.300 -static inline Sxpr cdr(Sxpr x){ 36.301 - return (CONSP(x) ? CDR(x) : ONULL); 36.302 -} 36.303 - 36.304 -typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags); 36.305 -typedef int ObjEqualFn(Sxpr obj, Sxpr other); 36.306 -typedef void ObjFreeFn(Sxpr obj); 36.307 -typedef Sxpr ObjCopyFn(Sxpr obj); 36.308 - 36.309 -/** An sxpr type definition. */ 36.310 -typedef struct SxprType { 36.311 - TypeCode type; 36.312 - char *name; 36.313 - int pointer; 36.314 - ObjPrintFn *print; 36.315 - ObjEqualFn *equal; 36.316 - ObjFreeFn *free; 36.317 - ObjCopyFn *copy; 36.318 -} SxprType; 36.319 - 36.320 - 36.321 -extern int def_sxpr_type(SxprType *tydef); 36.322 -extern SxprType *get_sxpr_type(int ty); 36.323 - 36.324 -/** Free the pointer in an sxpr. 36.325 - * 36.326 - * @param x sxpr containing a pointer 36.327 - */ 36.328 -static inline void hfree(Sxpr x){ 36.329 - deallocate(get_ptr(x)); 36.330 -} 36.331 - 36.332 -extern int objprint(IOStream *io, Sxpr x, unsigned flags); 36.333 -extern int objequal(Sxpr x, Sxpr y); 36.334 -extern void objfree(Sxpr x); 36.335 -extern Sxpr objcopy(Sxpr x); 36.336 - 36.337 -extern void cons_free_cells(Sxpr obj); 36.338 -extern Sxpr intern(char *s); 36.339 - 36.340 -extern Sxpr assoc(Sxpr k, Sxpr l); 36.341 -extern Sxpr assocq(Sxpr k, Sxpr l); 36.342 -extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l); 36.343 -extern Sxpr nrev(Sxpr l); 36.344 -extern Sxpr cons_member(Sxpr l, Sxpr x); 36.345 -extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v); 36.346 -extern int cons_subset(Sxpr s, Sxpr t); 36.347 -extern int cons_set_equal(Sxpr s, Sxpr t); 36.348 - 36.349 -#ifdef USE_GC 36.350 -extern Sxpr cons_remove(Sxpr l, Sxpr x); 36.351 -extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v); 36.352 -#endif 36.353 - 36.354 -extern Sxpr atom_new(char *name); 36.355 -extern char * atom_name(Sxpr obj); 36.356 -extern int atom_length(Sxpr obj); 36.357 - 36.358 -extern Sxpr string_new(char *s); 36.359 -extern Sxpr string_new_n(char *s, int n); 36.360 -extern char * string_string(Sxpr obj); 36.361 -extern int string_length(Sxpr obj); 36.362 - 36.363 -extern Sxpr cons_new(Sxpr car, Sxpr cdr); 36.364 -extern int cons_push(Sxpr *list, Sxpr elt); 36.365 -extern int cons_length(Sxpr obj); 36.366 - 36.367 -Sxpr sxpr_name(Sxpr obj); 36.368 -int sxpr_is(Sxpr obj, char *s); 36.369 -int sxpr_elementp(Sxpr obj, Sxpr name); 36.370 -Sxpr sxpr_attributes(Sxpr obj); 36.371 -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def); 36.372 -Sxpr sxpr_children(Sxpr obj); 36.373 -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def); 36.374 -Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def); 36.375 -Sxpr sxpr_child0(Sxpr obj, Sxpr def); 36.376 -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def); 36.377 - 36.378 -/** Create a new atom. 36.379 - * 36.380 - * @param s atom name 36.381 - * @return new atom 36.382 - */ 36.383 -static inline Sxpr mkatom(char *s){ 36.384 - return atom_new(s); 36.385 -} 36.386 - 36.387 -/** Create a new string sxpr. 36.388 - * 36.389 - * @param s string bytes (copied) 36.390 - * @return new string 36.391 - */ 36.392 -static inline Sxpr mkstring(char *s){ 36.393 - return string_new(s); 36.394 -} 36.395 - 36.396 -/** Create an integer sxpr. 36.397 - * 36.398 - * @param i value 36.399 - * @return sxpr 36.400 - */ 36.401 -static inline Sxpr mkint(int i){ 36.402 - return OBJI(T_UINT, i); 36.403 -} 36.404 - 36.405 -/** Create a boolean sxpr. 36.406 - * 36.407 - * @param b value 36.408 - * @return sxpr 36.409 - */ 36.410 -static inline Sxpr mkbool(int b){ 36.411 - return OBJI(T_BOOL, (b ? 1 : 0)); 36.412 -} 36.413 - 36.414 -/* Constants used in parsing and printing. */ 36.415 -#define k_list_open "(" 36.416 -#define c_list_open '(' 36.417 -#define k_list_close ")" 36.418 -#define c_list_close ')' 36.419 -#define k_true "true" 36.420 -#define k_false "false" 36.421 - 36.422 -#define c_escape '\\' 36.423 -#define c_single_quote '\'' 36.424 -#define c_double_quote '"' 36.425 -#define c_string_open c_double_quote 36.426 -#define c_string_close c_double_quote 36.427 - 36.428 -#define c_data_open '<' 36.429 -#define c_data_quote '<' 36.430 -#define c_data_count '*' 36.431 -//#define c_data_open '[' 36.432 -//#define c_data_close ']' 36.433 -//#define c_binary '*' 36.434 - 36.435 -#define c_var '$' 36.436 -#define c_eval '!' 36.437 -#define c_concat_open '{' 36.438 -#define c_concat_close '}' 36.439 - 36.440 -#endif /* ! _XUTIL_SXPR_H_ */
37.1 --- a/tools/libxutil/sxpr_parser.c Tue May 24 21:10:23 2005 +0000 37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 37.3 @@ -1,991 +0,0 @@ 37.4 -/* 37.5 - * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com> 37.6 - * 37.7 - * This library is free software; you can redistribute it and/or modify 37.8 - * it under the terms of the GNU Lesser General Public License as 37.9 - * published by the Free Software Foundation; either version 2.1 of the 37.10 - * License, or (at your option) any later version. This library is 37.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 37.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 37.13 - * FITNESS FOR A PARTICULAR PURPOSE. 37.14 - * See the GNU Lesser General Public License for more details. 37.15 - * 37.16 - * You should have received a copy of the GNU Lesser General Public License 37.17 - * along with this library; if not, write to the Free Software Foundation, 37.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 37.19 - */ 37.20 - 37.21 -#ifdef __KERNEL__ 37.22 -# include <linux/config.h> 37.23 -# include <linux/module.h> 37.24 -# include <linux/kernel.h> 37.25 -# include <linux/string.h> 37.26 -# include <linux/errno.h> 37.27 -#else 37.28 -# include <stdlib.h> 37.29 -# include <errno.h> 37.30 -#endif 37.31 - 37.32 -#include "sys_net.h" 37.33 - 37.34 -#include "iostream.h" 37.35 -#include "lexis.h" 37.36 -#include "sxpr_parser.h" 37.37 -#include "sys_string.h" 37.38 -#include "enum.h" 37.39 - 37.40 -/** @file 37.41 - * Sxpr parsing. 37.42 - * 37.43 - * So that the parser does not leak memory, all sxprs constructed by 37.44 - * the parser must be freed on error. On successful parse the sxpr 37.45 - * returned becomes the responsibility of the caller. 37.46 - * 37.47 - * @author Mike Wray <mike.wray@hpl.hp.com> 37.48 - */ 37.49 - 37.50 -#ifdef DEBUG 37.51 -#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args) 37.52 -#else 37.53 -#define dprintf(fmt, args...) do{ }while(0) 37.54 -#endif 37.55 - 37.56 -#undef printf 37.57 -#define printf(fmt, args...) IOStream_print(iostdout, fmt, ##args) 37.58 - 37.59 -static int state_start(Parser *p, char c); 37.60 -static int begin_start(Parser *p, char c); 37.61 - 37.62 -#if 0 37.63 -/** Print a parse error. 37.64 - * 37.65 - * @param in parser 37.66 - * @param msg format followed by printf arguments 37.67 - */ 37.68 -static void eprintf(Parser *in, char *msg, ...){ 37.69 - va_list args; 37.70 - if(in->error_out){ 37.71 - va_start(args, msg); 37.72 - IOStream_vprint(in->error_out, msg, args); 37.73 - va_end(args); 37.74 - } 37.75 -} 37.76 - 37.77 -/** Print a parse warning. 37.78 - * 37.79 - * @param in parser 37.80 - * @param msg format followed by printf arguments 37.81 - */ 37.82 -static void wprintf(Parser *in, char *msg, ...){ 37.83 - va_list args; 37.84 - if(in->error_out){ 37.85 - va_start(args, msg); 37.86 - IOStream_vprint(in->error_out, msg, args); 37.87 - va_end(args); 37.88 - } 37.89 -} 37.90 -#endif 37.91 - 37.92 - 37.93 -/*============================================================================*/ 37.94 - 37.95 -/** Record defining the message for a parse error. */ 37.96 -typedef struct { 37.97 - ParseErrorId id; 37.98 - char *message; 37.99 -} ParseError; 37.100 - 37.101 -/** Format for printing parse error messages. */ 37.102 -#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s" 37.103 - 37.104 -/** Message catalog for the parse error codes. */ 37.105 -static ParseError catalog[] = { 37.106 - { PARSE_ERR_UNSPECIFIED, "unspecified error" }, 37.107 - { PARSE_ERR_NOMEM, "out of memory" }, 37.108 - { PARSE_ERR_UNEXPECTED_EOF, "unexpected end of input" }, 37.109 - { PARSE_ERR_TOKEN_TOO_LONG, "token too long" }, 37.110 - { PARSE_ERR_INVALID_SYNTAX, "syntax error" }, 37.111 - { PARSE_ERR_INVALID_ESCAPE, "invalid escape" }, 37.112 - { 0, NULL } 37.113 -}; 37.114 - 37.115 -/** Number of entries in the message catalog. */ 37.116 -const static int catalog_n = sizeof(catalog)/sizeof(ParseError); 37.117 - 37.118 -/** Set the parser error stream. 37.119 - * Parse errors are reported on the the error stream if it is non-null. 37.120 - * 37.121 - * @param z parser 37.122 - * @param error_out error stream 37.123 - */ 37.124 -void Parser_set_error_stream(Parser *z, IOStream *error_out){ 37.125 - z->error_out = error_out; 37.126 -} 37.127 - 37.128 -/** Get the parser error message for an error code. 37.129 - * 37.130 - * @param id error code 37.131 - * @return error message (empty string if the code is unknown) 37.132 - */ 37.133 -static char *get_message(ParseErrorId id){ 37.134 - int i; 37.135 - for(i = 0; i < catalog_n; i++){ 37.136 - if(id == catalog[i].id){ 37.137 - return catalog[i].message; 37.138 - } 37.139 - } 37.140 - return ""; 37.141 -} 37.142 - 37.143 -#if 0 37.144 -/** Get the line number. 37.145 - * 37.146 - * @param in parser 37.147 - */ 37.148 -static int get_line(Parser *in){ 37.149 - return in->line_no; 37.150 -} 37.151 - 37.152 -/** Get the column number. 37.153 - * 37.154 - * @param in parser 37.155 - */ 37.156 -static int get_column(Parser *in){ 37.157 - return in->char_no; 37.158 -} 37.159 -#endif 37.160 - 37.161 -/** Get the line number the current token started on. 37.162 - * 37.163 - * @param in parser 37.164 - */ 37.165 -static int get_tok_line(Parser *in){ 37.166 - return in->tok_begin_line; 37.167 -} 37.168 - 37.169 -/** Get the column number the current token started on. 37.170 - * 37.171 - * @param in parser 37.172 - */ 37.173 -static int get_tok_column(Parser *in){ 37.174 - return in->tok_begin_char; 37.175 -} 37.176 - 37.177 -/** Return the current token. 37.178 - * The return value points at the internal buffer, so 37.179 - * it must not be modified (or freed). Use copy_token() if you need a copy. 37.180 - * 37.181 - * @param p parser 37.182 - * @return token 37.183 - */ 37.184 -char *peek_token(Parser *p){ 37.185 - return p->tok; 37.186 -} 37.187 - 37.188 -int token_len(Parser *p){ 37.189 - return p->tok_end - p->tok; 37.190 -} 37.191 - 37.192 -/** Return a copy of the current token. 37.193 - * The returned value should be freed when finished with. 37.194 - * 37.195 - * @param p parser 37.196 - * @return copy of token 37.197 - */ 37.198 -char *copy_token(Parser *p){ 37.199 - int n = token_len(p); 37.200 - char *buf = allocate(n + 1); 37.201 - if(buf){ 37.202 - memcpy(buf, peek_token(p), n); 37.203 - buf[n] = '\0'; 37.204 - } 37.205 - return buf; 37.206 -} 37.207 - 37.208 -void new_token(Parser *p){ 37.209 - memset(p->buf, 0, p->buf_end - p->buf); 37.210 - p->tok = p->buf; 37.211 - p->tok_end = p->tok; 37.212 - p->tok_begin_line = p->line_no; 37.213 - p->tok_begin_char = p->char_no; 37.214 -} 37.215 - 37.216 -/** Report a parse error. 37.217 - * Does nothing if the error stream is null or there is no error. 37.218 - * 37.219 - * @param in parser 37.220 - */ 37.221 -static void report_error(Parser *in){ 37.222 - if(in->error_out && in->err){ 37.223 - char *msg = get_message(in->err); 37.224 - char *tok = peek_token(in); 37.225 - IOStream_print(in->error_out, PARSE_ERR_FMT, 37.226 - get_tok_line(in), get_tok_column(in), msg); 37.227 - if(tok && tok[0]){ 37.228 - IOStream_print(in->error_out, " '%s'", tok); 37.229 - } 37.230 - IOStream_print(in->error_out, "\n"); 37.231 - } 37.232 -} 37.233 - 37.234 -/** Get the error message for the current parse error code. 37.235 - * Does nothing if there is no error. 37.236 - * 37.237 - * @param in parser 37.238 - * @param buf where to place the message 37.239 - * @param n maximum number of characters to place in buf 37.240 - * @return current error code (zero for no error) 37.241 - */ 37.242 -int Parser_error_message(Parser *in, char *buf, int n){ 37.243 - if(in->err){ 37.244 - char *msg = get_message(in->err); 37.245 - snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), 37.246 - get_tok_column(in), msg); 37.247 - } 37.248 - return in->err; 37.249 -} 37.250 - 37.251 -/** Flag a parse error. All subsequent reads will fail. 37.252 - * Does not change the parser error code if it is already set. 37.253 - * 37.254 - * @param in parser 37.255 - * @param id error code 37.256 - */ 37.257 -int Parser_error_id(Parser *in, ParseErrorId id){ 37.258 - if(!in->err){ 37.259 - in->err = id; 37.260 - report_error(in); 37.261 - } 37.262 - return -EINVAL; 37.263 -} 37.264 - 37.265 -/** Flag an unspecified parse error. 37.266 - * 37.267 - * @param in parser 37.268 - */ 37.269 -int Parser_error(Parser *in){ 37.270 - return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX); 37.271 -} 37.272 - 37.273 -/** Test if the parser's error flag is set. 37.274 - * 37.275 - * @param in parser 37.276 - * @return 1 if set, 0 otherwise 37.277 - */ 37.278 -int Parser_has_error(Parser *in){ 37.279 - return (in->err > 0); 37.280 -} 37.281 - 37.282 -/** Test if the parser is at end of input. 37.283 - * 37.284 - * @param in parser 37.285 - * @return 1 if at EOF, 0 otherwise 37.286 - */ 37.287 -int Parser_at_eof(Parser *p){ 37.288 - return p->eof; 37.289 -} 37.290 - 37.291 -void ParserState_free(ParserState *z){ 37.292 - if(!z) return; 37.293 - objfree(z->val); 37.294 - deallocate(z); 37.295 -} 37.296 - 37.297 -int ParserState_new(ParserStateFn *fn, char *name, 37.298 - ParserState *parent, ParserState **val){ 37.299 - int err = -ENOMEM; 37.300 - ParserState *z; 37.301 - z = ALLOCATE(ParserState); 37.302 - if(!z) goto exit; 37.303 - z->name = name; 37.304 - z->fn = fn; 37.305 - z->parent = parent; 37.306 - z->val = ONULL; 37.307 - err = 0; 37.308 - exit: 37.309 - *val = (err ? NULL : z); 37.310 - return err; 37.311 -} 37.312 - 37.313 -void Parser_pop(Parser *p){ 37.314 - ParserState *s = p->state; 37.315 - if(!s) return; 37.316 - p->state = s->parent; 37.317 - if (p->start_state == s) { 37.318 - p->start_state = NULL; 37.319 - } 37.320 - ParserState_free(s); 37.321 -} 37.322 - 37.323 -/** Free a parser. 37.324 - * No-op if the parser is null. 37.325 - * 37.326 - * @param z parser 37.327 - */ 37.328 -void Parser_free(Parser *z){ 37.329 - if(!z) return; 37.330 - // Hmmm. Need to free states, but careful about double free of values. 37.331 - while(z->state){ 37.332 - objfree(z->state->val); 37.333 - Parser_pop(z); 37.334 - } 37.335 - if(z->buf) deallocate(z->buf); 37.336 - objfree(z->val); 37.337 - z->val = ONONE; 37.338 - deallocate(z); 37.339 -} 37.340 - 37.341 -int Parser_push(Parser *p, ParserStateFn *fn, char *name){ 37.342 - return ParserState_new(fn, name, p->state, &p->state); 37.343 -} 37.344 - 37.345 -int Parser_return(Parser *p){ 37.346 - int err = 0; 37.347 - Sxpr val = ONONE; 37.348 - if(!p->state){ 37.349 - err = -EINVAL; 37.350 - goto exit; 37.351 - } 37.352 - val = p->state->val; 37.353 - p->state->val = ONONE; 37.354 - Parser_pop(p); 37.355 - if(p->state){ 37.356 - err = cons_push(&p->state->val, val); 37.357 - } else { 37.358 - val = nrev(val); 37.359 - p->val = val; 37.360 - } 37.361 - exit: 37.362 - if(err){ 37.363 - objfree(val); 37.364 - } 37.365 - return err; 37.366 -} 37.367 - 37.368 -/** Reset the fields of a parser to initial values. 37.369 - * 37.370 - * @param z parser 37.371 - */ 37.372 -static void reset(Parser *z){ 37.373 - // leave flags 37.374 - // leave error_out 37.375 - while(z->state){ 37.376 - Parser_pop(z); 37.377 - } 37.378 - z->val = ONONE; 37.379 - z->eof = 0; 37.380 - z->err = 0; 37.381 - z->line_no = 1; 37.382 - z->char_no = 0; 37.383 - memset(z->buf, 0, z->buf_end - z->buf); 37.384 - z->tok = z->buf; 37.385 - z->tok_end = z->tok; 37.386 - z->tok_begin_line = 0; 37.387 - z->tok_begin_char = 0; 37.388 - z->start_state = NULL; 37.389 -} 37.390 - 37.391 -/** Create a new parser. The error stream defaults to null. 37.392 - */ 37.393 -Parser * Parser_new(void){ 37.394 - Parser *z = ALLOCATE(Parser); 37.395 - int n = PARSER_BUF_SIZE; 37.396 - int err = -ENOMEM; 37.397 - 37.398 - if(!z) goto exit; 37.399 - z->buf = allocate(n); 37.400 - if(!z->buf) goto exit; 37.401 - err = 0; 37.402 - z->buf_end = z->buf + n; 37.403 - z->begin = begin_start; 37.404 - reset(z); 37.405 - exit: 37.406 - if(err){ 37.407 - Parser_free(z); 37.408 - z = NULL; 37.409 - } 37.410 - return z; 37.411 -} 37.412 - 37.413 -/** Get the next character. 37.414 - * Records the character read in the parser, 37.415 - * and sets the line and character counts. 37.416 - * 37.417 - * @param p parser 37.418 - * @return error flag: 0 on success, non-zero on error 37.419 - */ 37.420 -static int input_char(Parser *p, char c){ 37.421 - int err = 0; 37.422 - if(c=='\n'){ 37.423 - p->line_no++; 37.424 - p->char_no = 0; 37.425 - } else { 37.426 - p->char_no++; 37.427 - } 37.428 - return err; 37.429 -} 37.430 - 37.431 -int save_char(Parser *p, char c){ 37.432 - int err = 0; 37.433 - if(p->tok_end >= p->buf_end){ 37.434 - int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT; 37.435 - char *buf = allocate(buf_n); 37.436 - if(!buf){ 37.437 - err = -ENOMEM; 37.438 - goto exit; 37.439 - } 37.440 - memcpy(buf, p->buf, p->tok_end - p->buf); 37.441 - p->buf_end = buf + buf_n; 37.442 - p->tok = buf + (p->tok - p->buf); 37.443 - p->tok_end = buf + (p->tok_end - p->buf); 37.444 - deallocate(p->buf); 37.445 - p->buf = buf; 37.446 - } 37.447 - *p->tok_end++ = c; 37.448 - exit: 37.449 - return err; 37.450 -} 37.451 - 37.452 -/** Determine if a character is a separator. 37.453 - * 37.454 - * @param p parser 37.455 - * @param c character to test 37.456 - * @return 1 if a separator, 0 otherwise 37.457 - */ 37.458 -static int is_separator(Parser *p, char c){ 37.459 - return in_sep_class(c); 37.460 -} 37.461 - 37.462 -int Parser_set_value(Parser *p, Sxpr obj){ 37.463 - int err = 0; 37.464 - if(NOMEMP(obj)){ 37.465 - err = -ENOMEM; 37.466 - } else { 37.467 - p->state->val = obj; 37.468 - } 37.469 - return err; 37.470 -} 37.471 - 37.472 -int Parser_intern(Parser *p){ 37.473 - Sxpr obj = intern(peek_token(p)); 37.474 - return Parser_set_value(p, obj); 37.475 -} 37.476 - 37.477 -int Parser_atom(Parser *p){ 37.478 - Sxpr obj = atom_new(peek_token(p)); 37.479 - return Parser_set_value(p, obj); 37.480 -} 37.481 - 37.482 -int Parser_string(Parser *p){ 37.483 - Sxpr obj = string_new_n(peek_token(p), token_len(p)); 37.484 - return Parser_set_value(p, obj); 37.485 -} 37.486 - 37.487 -int Parser_data(Parser *p){ 37.488 - Sxpr obj = string_new_n(peek_token(p), token_len(p)); 37.489 - return Parser_set_value(p, obj); 37.490 -} 37.491 - 37.492 -int Parser_uint(Parser *p){ 37.493 - unsigned int x = htonl(*(unsigned int *)peek_token(p)); 37.494 - return Parser_set_value(p, OINT(x)); 37.495 -} 37.496 - 37.497 -static int get_escape(char c, char *d){ 37.498 - int err = 0; 37.499 - switch(c){ 37.500 - case 'a': *d = '\a'; break; 37.501 - case 'b': *d = '\b'; break; 37.502 - case 'f': *d = '\f'; break; 37.503 - case 'n': *d = '\n'; break; 37.504 - case 'r': *d = '\r'; break; 37.505 - case 't': *d = '\t'; break; 37.506 - case 'v': *d = '\v'; break; 37.507 - case c_escape: *d = c_escape; break; 37.508 - case c_single_quote: *d = c_single_quote; break; 37.509 - case c_double_quote: *d = c_double_quote; break; 37.510 - default: 37.511 - err = -EINVAL; 37.512 - } 37.513 - return err; 37.514 -} 37.515 - 37.516 -int Parser_ready(Parser *p){ 37.517 - return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val)); 37.518 -} 37.519 - 37.520 -Sxpr Parser_get_val(Parser *p){ 37.521 - Sxpr v = ONONE; 37.522 - if(CONSP(p->val)){ 37.523 - } else if (p->start_state && CONSP(p->start_state->val)){ 37.524 - p->val = p->start_state->val; 37.525 - p->val = nrev(p->val); 37.526 - p->start_state->val = ONULL; 37.527 - } else { 37.528 - goto exit; 37.529 - } 37.530 - Sxpr w = p->val; 37.531 - v = CAR(w); 37.532 - p->val = CDR(w); 37.533 - hfree(w); 37.534 - exit: 37.535 - return v; 37.536 -} 37.537 - 37.538 -Sxpr Parser_get_all(Parser *p){ 37.539 - Sxpr v = ONULL; 37.540 - if(CONSP(p->val)){ 37.541 - v = p->val; 37.542 - p->val = ONONE; 37.543 - } else if(p->start_state && CONSP(p->start_state->val)){ 37.544 - v = p->start_state->val; 37.545 - p->start_state->val = ONULL; 37.546 - v = nrev(v); 37.547 - } 37.548 - return v; 37.549 -} 37.550 - 37.551 -static int state_comment(Parser *p, char c){ 37.552 - int err = 0; 37.553 - if(c == '\n' || Parser_at_eof(p)){ 37.554 - Parser_pop(p); 37.555 - } else { 37.556 - err = input_char(p, c); 37.557 - } 37.558 - return err; 37.559 -} 37.560 - 37.561 -static int begin_comment(Parser *p, char c){ 37.562 - int err = 0; 37.563 - err = Parser_push(p, state_comment, "comment"); 37.564 - if(err) goto exit; 37.565 - err = input_char(p, c); 37.566 - exit: 37.567 - return err; 37.568 -} 37.569 - 37.570 -static int end_string(Parser *p){ 37.571 - int err = 0; 37.572 - err = Parser_string(p); 37.573 - if(err) goto exit; 37.574 - err = Parser_return(p); 37.575 - exit: 37.576 - return err; 37.577 -} 37.578 - 37.579 -static int octaldone(Parser *p){ 37.580 - int err = 0; 37.581 - char d = (char)(p->state->ival & 0xff); 37.582 - Parser_pop(p); 37.583 - err = Parser_input_char(p, d); 37.584 - return err; 37.585 -} 37.586 - 37.587 -static int octaldigit(Parser *p, int d){ 37.588 - int err = 0; 37.589 - p->state->ival *= 8; 37.590 - p->state->ival += d; 37.591 - p->state->count++; 37.592 - if(err) goto exit; 37.593 - if(p->state->ival < 0 || p->state->ival > 0xff){ 37.594 - err = Parser_error(p); 37.595 - goto exit; 37.596 - } 37.597 - if(p->state->count == 3){ 37.598 - err = octaldone(p); 37.599 - } 37.600 - exit: 37.601 - return err; 37.602 -} 37.603 - 37.604 -static int state_octal(Parser *p, char c){ 37.605 - int err = 0; 37.606 - if(Parser_at_eof(p)){ 37.607 - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 37.608 - goto exit; 37.609 - } else if('0' <= c && c <= '7'){ 37.610 - err = octaldigit(p, c - '0'); 37.611 - } else { 37.612 - err = octaldone(p); 37.613 - if(err) goto exit; 37.614 - Parser_input_char(p, c); 37.615 - } 37.616 - exit: 37.617 - return err; 37.618 -} 37.619 - 37.620 -static int hexdone(Parser *p){ 37.621 - int err = 0; 37.622 - char d = (char)(p->state->ival & 0xff); 37.623 - Parser_pop(p); 37.624 - err = Parser_input_char(p, d); 37.625 - return err; 37.626 -} 37.627 - 37.628 -static int hexdigit(Parser *p, int d){ 37.629 - int err = 0; 37.630 - p->state->ival *= 16; 37.631 - p->state->ival += d; 37.632 - p->state->count++; 37.633 - if(err) goto exit; 37.634 - if(p->state->ival < 0 || p->state->ival > 0xff){ 37.635 - err = Parser_error(p); 37.636 - goto exit; 37.637 - } 37.638 - if(p->state->count == 2){ 37.639 - err = hexdone(p); 37.640 - } 37.641 - exit: 37.642 - return err; 37.643 -} 37.644 - 37.645 -static int state_hex(Parser *p, char c){ 37.646 - int err = 0; 37.647 - if(Parser_at_eof(p)){ 37.648 - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 37.649 - goto exit; 37.650 - } else if('0' <= c && c <= '9'){ 37.651 - err = hexdigit(p, c - '0'); 37.652 - } else if('A' <= c && c <= 'F'){ 37.653 - err = hexdigit(p, c - 'A' + 10); 37.654 - } else if('a' <= c && c <= 'f'){ 37.655 - err = hexdigit(p, c - 'a' + 10); 37.656 - } else if(p->state->count){ 37.657 - err = hexdone(p); 37.658 - if(err) goto exit; 37.659 - Parser_input_char(p, c); 37.660 - } 37.661 - exit: 37.662 - return err; 37.663 -} 37.664 - 37.665 -static int state_escape(Parser *p, char c){ 37.666 - int err = 0; 37.667 - char d; 37.668 - if(Parser_at_eof(p)){ 37.669 - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 37.670 - goto exit; 37.671 - } 37.672 - if(get_escape(c, &d) == 0){ 37.673 - err = save_char(p, d); 37.674 - if(err) goto exit; 37.675 - Parser_pop(p); 37.676 - } else if(c == 'x'){ 37.677 - p->state->fn = state_hex; 37.678 - p->state->ival = 0; 37.679 - p->state->count = 0; 37.680 - } else { 37.681 - p->state->fn = state_octal; 37.682 - p->state->ival = 0; 37.683 - p->state->count = 0; 37.684 - err = Parser_input_char(p, c); 37.685 - } 37.686 - exit: 37.687 - return err; 37.688 -} 37.689 - 37.690 -static int state_string(Parser *p, char c){ 37.691 - int err = 0; 37.692 - if(Parser_at_eof(p)){ 37.693 - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 37.694 - } else if(c == p->state->delim){ 37.695 - err = end_string(p); 37.696 - } else if(c == '\\'){ 37.697 - err = Parser_push(p, state_escape, "escape"); 37.698 - } else { 37.699 - err = save_char(p, c); 37.700 - } 37.701 - return err; 37.702 -} 37.703 - 37.704 -static int begin_string(Parser *p, char c){ 37.705 - int err = 0; 37.706 - err = Parser_push(p, state_string, "string"); 37.707 - if(err) goto exit; 37.708 - new_token(p); 37.709 - p->state->delim = c; 37.710 - exit: 37.711 - return err; 37.712 -} 37.713 - 37.714 -static int end_atom(Parser *p){ 37.715 - int err = 0; 37.716 - err = Parser_atom(p); 37.717 - if(err) goto exit; 37.718 - err = Parser_return(p); 37.719 - exit: 37.720 - return err; 37.721 -} 37.722 - 37.723 -static int state_atom(Parser *p, char c){ 37.724 - int err = 0; 37.725 - if(Parser_at_eof(p)){ 37.726 - err = end_atom(p); 37.727 - } else if(is_separator(p, c) || 37.728 - in_space_class(c) || 37.729 - in_comment_class(c)){ 37.730 - err = end_atom(p); 37.731 - if(err) goto exit; 37.732 - err = Parser_input_char(p, c); 37.733 - } else { 37.734 - err = save_char(p, c); 37.735 - } 37.736 - exit: 37.737 - return err; 37.738 -} 37.739 - 37.740 -static int begin_atom(Parser *p, char c){ 37.741 - int err = 0; 37.742 - err = Parser_push(p, state_atom, "atom"); 37.743 - if(err) goto exit; 37.744 - new_token(p); 37.745 - err = save_char(p, c); 37.746 - exit: 37.747 - return err; 37.748 -} 37.749 - 37.750 -static int end_data(Parser *p){ 37.751 - int err = 0; 37.752 - err = Parser_data(p); 37.753 - if(err) goto exit; 37.754 - err = Parser_return(p); 37.755 - exit: 37.756 - return err; 37.757 -} 37.758 - 37.759 -static int counted_data(Parser *p, char c){ 37.760 - int err = 0; 37.761 - err = save_char(p, c); 37.762 - if(err) goto exit; 37.763 - if(token_len(p) == p->state->count){ 37.764 - err = end_data(p); 37.765 - } 37.766 - exit: 37.767 - return err; 37.768 -} 37.769 - 37.770 -static int counted_data_count(Parser *p, char c){ 37.771 - int err = 0; 37.772 - if(c == p->state->delim){ 37.773 - new_token(p); 37.774 - p->state->count = p->state->ival; 37.775 - p->state->fn = counted_data; 37.776 - } else if('0' <= c && c <= '9'){ 37.777 - p->state->ival *= 10; 37.778 - p->state->ival += c - '0'; 37.779 - } else { 37.780 - err = -EINVAL; 37.781 - } 37.782 - return err; 37.783 -} 37.784 - 37.785 -static int quoted_data(Parser *p, char c){ 37.786 - int err = 0; 37.787 - int count = p->state->count; 37.788 - err = save_char(p, c); 37.789 - if(err) goto exit; 37.790 - // Check that buf is longer than delim and 37.791 - // ends with delim. If so, trim delim off and return. 37.792 - if((token_len(p) >= count) && 37.793 - !memcmp(p->tok_end - count, p->buf, count)){ 37.794 - p->tok_end -= count; 37.795 - end_data(p); 37.796 - } 37.797 - exit: 37.798 - return err; 37.799 -} 37.800 - 37.801 -static int quoted_data_delim(Parser *p, char c){ 37.802 - // Saves the delim in the token buffer. 37.803 - int err = 0; 37.804 - err = save_char(p, c); 37.805 - if(err) goto exit; 37.806 - if(c == p->state->delim){ 37.807 - p->state->fn = quoted_data; 37.808 - p->state->count = token_len(p); 37.809 - // Advance the token pointer past the delim. 37.810 - p->tok = p->tok_end; 37.811 - } 37.812 - exit: 37.813 - return err; 37.814 -} 37.815 - 37.816 -static int state_data(Parser *p, char c){ 37.817 - // Quoted data: 37.818 - // <<delim< anything not containing delimiter<delim< 37.819 - // Where 'delim' is anything not containing '<'. 37.820 - // Counted data: 37.821 - // <*nnn..* N bytes 37.822 - // Where nnn... is N in decimal ( 37.823 - int err = 0; 37.824 - switch(c){ 37.825 - case c_data_count: 37.826 - p->state->delim = c; 37.827 - p->state->fn = counted_data_count; 37.828 - p->state->ival = 0; 37.829 - new_token(p); 37.830 - break; 37.831 - case c_data_quote: 37.832 - p->state->delim = c; 37.833 - p->state->fn = quoted_data_delim; 37.834 - new_token(p); 37.835 - err = save_char(p, c); 37.836 - break; 37.837 - default: 37.838 - err = Parser_error(p); 37.839 - break; 37.840 - } 37.841 - return err; 37.842 -} 37.843 - 37.844 -static int begin_data(Parser *p, char c){ 37.845 - int err = 0; 37.846 - err = Parser_push(p, state_data, "data"); 37.847 - if(err) goto exit; 37.848 - new_token(p); 37.849 - exit: 37.850 - return err; 37.851 -} 37.852 - 37.853 -static int state_list(Parser *p, char c){ 37.854 - int err = 0; 37.855 - dprintf(">\n"); 37.856 - if(Parser_at_eof(p)){ 37.857 - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 37.858 - } else if(c == c_list_close){ 37.859 - p->state->val = nrev(p->state->val); 37.860 - err = Parser_return(p); 37.861 - } else { 37.862 - err = state_start(p, c); 37.863 - } 37.864 - dprintf("< err=%d\n", err); 37.865 - return err; 37.866 - 37.867 -} 37.868 - 37.869 -static int begin_list(Parser *p, char c){ 37.870 - return Parser_push(p, state_list, "list"); 37.871 -} 37.872 - 37.873 -static int state_start(Parser *p, char c){ 37.874 - int err = 0; 37.875 - dprintf(">\n"); 37.876 - if(Parser_at_eof(p)){ 37.877 - err = Parser_return(p); 37.878 - } else if(in_space_class(c)){ 37.879 - //skip 37.880 - } else if(in_comment_class(c)){ 37.881 - begin_comment(p, c); 37.882 - } else if(c == c_list_open){ 37.883 - begin_list(p, c); 37.884 - } else if(c == c_list_close){ 37.885 - err = Parser_error(p); 37.886 - } else if(in_string_quote_class(c)){ 37.887 - begin_string(p, c); 37.888 - } else if(c == c_data_open){ 37.889 - begin_data(p, c); 37.890 - } else if(in_printable_class(c)){ 37.891 - begin_atom(p, c); 37.892 - } else if(c == 0x04){ 37.893 - //ctrl-D, EOT: end-of-text. 37.894 - Parser_input_eof(p); 37.895 - } else { 37.896 - err = Parser_error(p); 37.897 - } 37.898 - dprintf("< err=%d\n", err); 37.899 - return err; 37.900 -} 37.901 - 37.902 -int begin_start(Parser *p, char c){ 37.903 - int err = 0; 37.904 - dprintf(">\n"); 37.905 - err = Parser_push(p, state_start, "start"); 37.906 - if(err) goto exit; 37.907 - p->start_state = p->state; 37.908 - exit: 37.909 - dprintf("< err=%d\n", err); 37.910 - return err; 37.911 -} 37.912 - 37.913 -int Parser_input_char(Parser *p, char c){ 37.914 - int err = 0; 37.915 - if(Parser_at_eof(p)){ 37.916 - //skip; 37.917 - } else { 37.918 - input_char(p, c); 37.919 - } 37.920 - if(!p->state){ 37.921 - err = p->begin(p, c); 37.922 - if(err) goto exit; 37.923 - } 37.924 - err = p->state->fn(p, c); 37.925 - exit: 37.926 - return err; 37.927 -} 37.928 - 37.929 -int Parser_input_eof(Parser *p){ 37.930 - int err = 0; 37.931 - p->eof = 1; 37.932 - err = Parser_input_char(p, IOSTREAM_EOF); 37.933 - return err; 37.934 -} 37.935 - 37.936 -int Parser_input(Parser *p, char *buf, int buf_n){ 37.937 - int err = 0; 37.938 - int i = 0; 37.939 - dprintf("> |%s|\n", buf); 37.940 - if(buf_n <= 0){ 37.941 - err = Parser_input_eof(p); 37.942 - goto exit; 37.943 - } 37.944 - for(i = 0; i < buf_n; i++){ 37.945 - err = Parser_input_char(p, buf[i]); 37.946 - if(err) goto exit; 37.947 - } 37.948 - exit: 37.949 - err = (err < 0 ? err : buf_n); 37.950 - dprintf("< err=%d\n", err); 37.951 - return err; 37.952 -} 37.953 - 37.954 -#ifdef SXPR_PARSER_MAIN 37.955 -/* Stuff for standalone testing. */ 37.956 - 37.957 -#include "file_stream.h" 37.958 -//#include "string_stream.h" 37.959 - 37.960 -/** Main program for testing. 37.961 - * Parses input and prints it. 37.962 - * 37.963 - * @param argc number of arguments 37.964 - * @param argv arguments 37.965 - * @return error code 37.966 - */ 37.967 -int main(int argc, char *argv[]){ 37.968 - Parser *pin; 37.969 - int err = 0; 37.970 - char buf[1024]; 37.971 - int k; 37.972 - Sxpr obj; 37.973 - int i = 0; 37.974 - 37.975 - pin = Parser_new(); 37.976 - Parser_set_error_stream(pin, iostdout); 37.977 - dprintf("> parse...\n"); 37.978 - while(1){ 37.979 - k = fread(buf, 1, 100, stdin); 37.980 - if(k>=0){ 37.981 - buf[k+1] = '\0'; 37.982 - } 37.983 - err = Parser_input(pin, buf, k); 37.984 - while(Parser_ready(pin)){ 37.985 - obj = Parser_get_val(pin); 37.986 - printf("obj %d\n", i++); 37.987 - objprint(iostdout, obj, 0); printf("\n"); 37.988 - } 37.989 - if(k <= 0) break; 37.990 - } 37.991 - dprintf("> err=%d\n", err); 37.992 - return 0; 37.993 -} 37.994 -#endif
38.1 --- a/tools/libxutil/sxpr_parser.h Tue May 24 21:10:23 2005 +0000 38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 38.3 @@ -1,154 +0,0 @@ 38.4 -/* 38.5 - * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com> 38.6 - * 38.7 - * This library is free software; you can redistribute it and/or modify 38.8 - * it under the terms of the GNU Lesser General Public License as 38.9 - * published by the Free Software Foundation; either version 2.1 of the 38.10 - * License, or (at your option) any later version. This library is 38.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 38.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 38.13 - * FITNESS FOR A PARTICULAR PURPOSE. 38.14 - * See the GNU Lesser General Public License for more details. 38.15 - * 38.16 - * You should have received a copy of the GNU Lesser General Public License 38.17 - * along with this library; if not, write to the Free Software Foundation, 38.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 38.19 - */ 38.20 - 38.21 -#ifndef _XUTIL_SXPR_PARSER_H_ 38.22 -#define _XUTIL_SXPR_PARSER_H_ 38.23 - 38.24 -#include "sxpr.h" 38.25 -#include "iostream.h" 38.26 - 38.27 -/** @file 38.28 - * Sxpr parsing definitions. 38.29 - */ 38.30 - 38.31 -/** Initial size of a parser input buffer. 38.32 - */ 38.33 -#define PARSER_BUF_SIZE 512 38.34 - 38.35 -/** Input buffer size increment (when it's full). 38.36 - */ 38.37 -#define PARSER_BUF_INCREMENT 512 38.38 - 38.39 -struct Parser; 38.40 -typedef int ParserStateFn(struct Parser *, char c); 38.41 - 38.42 -typedef struct ParserState { 38.43 - struct ParserState *parent; 38.44 - Sxpr val; 38.45 - int ival; 38.46 - int count; 38.47 - char delim; 38.48 - ParserStateFn *fn; 38.49 - char *name; 38.50 -} ParserState; 38.51 - 38.52 -typedef struct Parser { 38.53 - /** Initial state function. */ 38.54 - ParserStateFn *begin; 38.55 - /** Parse value. */ 38.56 - Sxpr val; 38.57 - /** Error reporting stream (null for no reports). */ 38.58 - IOStream *error_out; 38.59 - /** End-of-file flag, */ 38.60 - int eof; 38.61 - /** Error flag. Non-zero if there has been a read error. */ 38.62 - int err; 38.63 - /** Line number on input (from 1). */ 38.64 - int line_no; 38.65 - /** Column number of input (reset on new line). */ 38.66 - int char_no; 38.67 - /** Buffer for reading tokens. */ 38.68 - char *buf; 38.69 - char *buf_end; 38.70 - char *tok; 38.71 - char *tok_end; 38.72 - /** Line the last token started on. */ 38.73 - int tok_begin_line; 38.74 - /** Character number the last token started on. */ 38.75 - int tok_begin_char; 38.76 - /** Parsing flags. */ 38.77 - int flags; 38.78 - ParserState *state; 38.79 - ParserState *start_state; 38.80 -} Parser; 38.81 - 38.82 -/** Parser error codes. */ 38.83 -typedef enum { 38.84 - PARSE_ERR_NONE=0, 38.85 - PARSE_ERR_UNSPECIFIED, 38.86 - PARSE_ERR_NOMEM, 38.87 - PARSE_ERR_UNEXPECTED_EOF, 38.88 - PARSE_ERR_TOKEN_TOO_LONG, 38.89 - PARSE_ERR_INVALID_SYNTAX, 38.90 - PARSE_ERR_INVALID_ESCAPE, 38.91 -} ParseErrorId; 38.92 - 38.93 - 38.94 -/** Parser flags. */ 38.95 -//enum { 38.96 -//}; 38.97 - 38.98 -/** Raise some parser flags. 38.99 - * 38.100 - * @param in parser 38.101 - * @param flags flags mask 38.102 - */ 38.103 -inline static void Parser_flags_raise(Parser *in, int flags){ 38.104 - in->flags |= flags; 38.105 -} 38.106 - 38.107 -/** Lower some parser flags. 38.108 - * 38.109 - * @param in parser 38.110 - * @param flags flags mask 38.111 - */ 38.112 -inline static void Parser_flags_lower(Parser *in, int flags){ 38.113 - in->flags &= ~flags; 38.114 -} 38.115 - 38.116 -/** Clear all parser flags. 38.117 - * 38.118 - * @param in parser 38.119 - */ 38.120 -inline static void Parser_flags_clear(Parser *in){ 38.121 - in->flags = 0; 38.122 -} 38.123 - 38.124 -extern void Parser_free(Parser *z); 38.125 -extern Parser * Parser_new(void); 38.126 -extern int Parser_input(Parser *p, char *buf, int buf_n); 38.127 -extern int Parser_input_eof(Parser *p); 38.128 -extern int Parser_input_char(Parser *p, char c); 38.129 -extern void Parser_set_error_stream(Parser *z, IOStream *error_out); 38.130 - 38.131 -extern int Parser_error_message(Parser *in, char *buf, int n); 38.132 -extern int Parser_has_error(Parser *in); 38.133 -extern int Parser_at_eof(Parser *in); 38.134 - 38.135 -extern int Parser_ready(Parser *p); 38.136 -extern Sxpr Parser_get_val(Parser *p); 38.137 -extern Sxpr Parser_get_all(Parser *p); 38.138 - 38.139 -/* Internal parser api. */ 38.140 -void Parser_pop(Parser *p); 38.141 -int Parser_push(Parser *p, ParserStateFn *fn, char *name); 38.142 -int Parser_return(Parser *p); 38.143 -int Parser_at_eof(Parser *p); 38.144 -int Parser_error(Parser *in); 38.145 -int Parser_set_value(Parser *p, Sxpr val); 38.146 -int Parser_intern(Parser *p); 38.147 -int Parser_string(Parser *p); 38.148 -int Parser_data(Parser *p); 38.149 -int Parser_uint(Parser *p); 38.150 - 38.151 -char *peek_token(Parser *p); 38.152 -char *copy_token(Parser *p); 38.153 -void new_token(Parser *p); 38.154 -int save_char(Parser *p, char c); 38.155 -int token_len(Parser *p); 38.156 - 38.157 -#endif /* ! _XUTIL_SXPR_PARSER_H_ */
39.1 --- a/tools/libxutil/sys_net.c Tue May 24 21:10:23 2005 +0000 39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 39.3 @@ -1,319 +0,0 @@ 39.4 -/* 39.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 39.6 - * 39.7 - * This library is free software; you can redistribute it and/or modify 39.8 - * it under the terms of the GNU Lesser General Public License as 39.9 - * published by the Free Software Foundation; either version 2.1 of the 39.10 - * License, or (at your option) any later version. This library is 39.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 39.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 39.13 - * FITNESS FOR A PARTICULAR PURPOSE. 39.14 - * See the GNU Lesser General Public License for more details. 39.15 - * 39.16 - * You should have received a copy of the GNU Lesser General Public License 39.17 - * along with this library; if not, write to the Free Software Foundation, 39.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 39.19 - */ 39.20 - 39.21 -#include "sys_net.h" 39.22 -#include "sys_string.h" 39.23 - 39.24 -#ifdef __KERNEL__ 39.25 -# include <linux/errno.h> 39.26 -#else 39.27 -# include <errno.h> 39.28 -#endif 39.29 - 39.30 -/** @file 39.31 - * All network data are kept in network order and only converted to 39.32 - * host order for display. Network data includes IP addresses, port numbers and 39.33 - * network masks. 39.34 - */ 39.35 - 39.36 -/** Maximum value for a port. */ 39.37 -#define PORT_MAX 0xffff 39.38 - 39.39 -/** Convert a number of bits to a network mask 39.40 - * for IP addresses. The number of bits must 39.41 - * be in the range 1-31. 39.42 - * 39.43 - * @param n number of bits to set in the mask 39.44 - * @return value with n high bits set (in network order) 39.45 - */ 39.46 -unsigned long bits_to_mask(int n){ 39.47 - unsigned long mask = (n ? (1 << 31) : 0); 39.48 - int i; 39.49 - for(i=1; i<n; i++){ 39.50 - mask |= (mask >> 1); 39.51 - } 39.52 - return htonl(mask); 39.53 -} 39.54 - 39.55 -/** Convert a network mask to a number of bits. 39.56 - * 39.57 - * @param mask network mask in network order 39.58 - * @return number of bits in mask 39.59 - */ 39.60 -int mask_to_bits(unsigned long mask){ 39.61 - // Start with n set to the number of bits in the mask. Then reduce n by 39.62 - // the number of low zero bits in the mask. 39.63 - int n = 32; 39.64 - for(mask = ntohl(mask); 39.65 - (mask & 1)==0 && n>0; 39.66 - mask >>= 1){ 39.67 - n--; 39.68 - } 39.69 - return n; 39.70 -} 39.71 - 39.72 -/** Get the index of the first occurrence of a character in a string. 39.73 - * Stops at end of string or after n characters. 39.74 - * 39.75 - * @param s input string 39.76 - * @param n maximum number of charactes to search 39.77 - * @param c character to look for 39.78 - * @return index of first occurrence, -1 if not found 39.79 - */ 39.80 -inline static int indexof(const char *s, int n, char c){ 39.81 - int i; 39.82 - for(i=0; i<n && *s; i++, s++){ 39.83 - if(*s == c) return i; 39.84 - } 39.85 - return -1; 39.86 -} 39.87 - 39.88 -/** Convert an IPv4 address in dot notation into an unsigned long (in network order). 39.89 - * 39.90 - * @param s input string 39.91 - * @param address where to put the address 39.92 - * @return 0 on success, negative on error 39.93 - */ 39.94 -int get_inet_addr(const char *s, unsigned long *address){ 39.95 - // Number of bits in a byte. 39.96 - const int BYTE_BITS = 8; 39.97 - // Number of bytes in a word. 39.98 - const int WORD_BYTES = 4; 39.99 - // Max value for a component of an address. 39.100 - const int ADDR_MAX = 255; 39.101 - // Separator for components of an address. 39.102 - const char dot = '.'; 39.103 - 39.104 - int n; 39.105 - unsigned long addr = 0; 39.106 - unsigned long v; 39.107 - int i; 39.108 - int err = -EINVAL; 39.109 - // Bit shift for the current byte. 39.110 - int shift = BYTE_BITS * (WORD_BYTES - 1); 39.111 - char buf[64]; 39.112 - 39.113 - n = strlen(s); 39.114 - if(n >= sizeof(buf)){ 39.115 - goto exit; 39.116 - } 39.117 - for(i=0; i < WORD_BYTES; i++){ 39.118 - int idx = indexof(s, n, dot); 39.119 - idx = (idx < 0 ? strlen(s) : idx); 39.120 - strncpy(buf, s, idx); buf[idx]='\0'; 39.121 - if(convert_atoul(buf, &v)){ 39.122 - goto exit; 39.123 - } 39.124 - if(v < 0 || v > ADDR_MAX){ 39.125 - goto exit; 39.126 - } 39.127 - addr |= (v << shift); 39.128 - if(idx == n) break; 39.129 - shift -= BYTE_BITS; 39.130 - s += idx+1; 39.131 - } 39.132 - err = 0; 39.133 - exit: 39.134 - addr = htonl(addr); 39.135 - *address = (err ? 0 : addr); 39.136 - return err; 39.137 -} 39.138 - 39.139 -#ifdef __KERNEL__ 39.140 -/** Convert an address in network order to IPv4 dot notation. 39.141 - * The return value is a static buffer which is overwritten on each call. 39.142 - * 39.143 - * @param inaddr address (in network order) 39.144 - * @return address in dot notation 39.145 - */ 39.146 -char *inet_ntoa(struct in_addr inaddr){ 39.147 - static char address[16] = {}; 39.148 - uint32_t addr = ntohl(inaddr.s_addr); 39.149 - snprintf(address, sizeof(address), "%d.%d.%d.%d", 39.150 - (unsigned)((addr >> 24) & 0xff), 39.151 - (unsigned)((addr >> 16) & 0xff), 39.152 - (unsigned)((addr >> 8) & 0xff), 39.153 - (unsigned)((addr ) & 0xff)); 39.154 - return address; 39.155 -} 39.156 - 39.157 - 39.158 -/** Convert a string in IPv4 dot notation to an int in network order. 39.159 - * 39.160 - * @param address address in dot notation 39.161 - * @param inp result of conversion (in network order) 39.162 - * @return 0 on success, error code on error 39.163 - */ 39.164 -int inet_aton(const char *address, struct in_addr *inp){ 39.165 - int err = 0; 39.166 - unsigned long addr; 39.167 - 39.168 - err = get_inet_addr(address, &addr); 39.169 - if(err) goto exit; 39.170 - inp->s_addr = addr; 39.171 - exit: 39.172 - return err; 39.173 -} 39.174 -#endif 39.175 - 39.176 -/** Convert a hostname or IPv4 address string to an address in network order. 39.177 - * 39.178 - * @param name input hostname or address string 39.179 - * @param address where to put the address 39.180 - * @return 0 if address found OK, nonzero otherwise 39.181 - */ 39.182 -int get_host_address(const char *name, unsigned long *address){ 39.183 -#ifdef __KERNEL__ 39.184 - return get_inet_addr(name, address); 39.185 -#else 39.186 - struct hostent *host = gethostbyname(name); 39.187 - if(!host){ 39.188 - return -EINVAL; 39.189 - } 39.190 - *address = ((struct in_addr *)(host->h_addr))->s_addr; 39.191 - return 0; 39.192 -#endif 39.193 -} 39.194 - 39.195 -/** Convert a service name to a port (in network order). 39.196 - * 39.197 - * @param name service name 39.198 - * @param port where to put the port 39.199 - * @return 0 if service port found OK, negative otherwise 39.200 - */ 39.201 -int get_service_port(const char *name, unsigned long *port){ 39.202 -#ifdef __KERNEL__ 39.203 - return -ENOSYS; 39.204 -#else 39.205 - struct servent *service; 39.206 - service = getservbyname(name, 0); 39.207 - if(!service){ 39.208 - return -EINVAL; 39.209 - } 39.210 - *port = service->s_port; 39.211 - return 0; 39.212 -#endif 39.213 -} 39.214 - 39.215 -/** Convert a port number (in network order) to a service name. 39.216 - * 39.217 - * @param port the port number 39.218 - * @return service name if found OK, NULL otherwise 39.219 - */ 39.220 -char *get_port_service(unsigned long port){ 39.221 -#ifdef __KERNEL__ 39.222 - return NULL; 39.223 -#else 39.224 - struct servent *service = getservbyport(port, 0); 39.225 - return (service ? service->s_name : NULL); 39.226 -#endif 39.227 -} 39.228 - 39.229 -/** Convert a decimal integer or service name to a port (in network order). 39.230 - * 39.231 - * @param s input to convert 39.232 - * @param port where to put the port 39.233 - * @return 0 if port found OK, -1 otherwise 39.234 - */ 39.235 -int convert_service_to_port(const char *s, unsigned long *port){ 39.236 - int err = 0; 39.237 - unsigned long value; 39.238 - if(convert_atoul(s, &value) == 0){ 39.239 - int ok = (0 <= value) && (value <= PORT_MAX); 39.240 - if(ok){ 39.241 - value = htons((unsigned short)value); 39.242 - } else { 39.243 - err = -EINVAL; 39.244 - } 39.245 - } else { 39.246 - err = get_service_port(s, &value); 39.247 - } 39.248 - *port = (err ? 0: value); 39.249 - return err; 39.250 -} 39.251 - 39.252 -#define MAC_ELEMENT_N 6 // Number of elements in a MAC address. 39.253 -#define MAC_DIGIT_N 2 // Number of digits in an element in a MAC address. 39.254 -#define MAC_LENGTH 17 //((MAC_ELEMENT_N * MAC_DIGIT_N) + MAC_ELEMENT_N - 1) 39.255 - 39.256 -/** Convert a mac address from a string of the form 39.257 - * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars). 39.258 - * Each X denotes a hex digit: 0..9, a..f, A..F. 39.259 - * Also supports using '-' as the separator instead of ':'. 39.260 - * 39.261 - * @param mac_in string to convert 39.262 - * @param mac destination for the value 39.263 - * @return 0 on success, -1 on error 39.264 - */ 39.265 -int mac_aton(const char *mac_in, unsigned char *mac){ 39.266 - int err = 0; 39.267 - int i, j; 39.268 - const char *p; 39.269 - char sep = 0; 39.270 - unsigned char d; 39.271 - if(!mac_in || strlen(mac_in) != MAC_LENGTH){ 39.272 - err = -1; 39.273 - goto exit; 39.274 - } 39.275 - for(i = 0, p = mac_in; i < MAC_ELEMENT_N; i++){ 39.276 - d = 0; 39.277 - if(i){ 39.278 - if(!sep){ 39.279 - if(*p == ':' || *p == '-') sep = *p; 39.280 - } 39.281 - if(sep && *p == sep){ 39.282 - p++; 39.283 - } else { 39.284 - err = -1; 39.285 - goto exit; 39.286 - } 39.287 - } 39.288 - for(j = 0; j < MAC_DIGIT_N; j++, p++){ 39.289 - if(j) d <<= 4; 39.290 - if(*p >= '0' && *p <= '9'){ 39.291 - d += (*p - '0'); 39.292 - } else if(*p >= 'A' && *p <= 'F'){ 39.293 - d += (*p - 'A') + 10; 39.294 - } else if(*p >= 'a' && *p <= 'f'){ 39.295 - d += (*p - 'a') + 10; 39.296 - } else { 39.297 - err = -1; 39.298 - goto exit; 39.299 - } 39.300 - } 39.301 - mac[i] = d; 39.302 - } 39.303 - exit: 39.304 - return err; 39.305 -} 39.306 - 39.307 -/** Convert a MAC address from numerical form to a string. 39.308 - * 39.309 - * @param mac address to convert 39.310 - * @return static string value 39.311 - */ 39.312 -char *mac_ntoa(const unsigned char *mac){ 39.313 - static char buf[MAC_LENGTH + 1]; 39.314 - int buf_n = sizeof(buf); 39.315 - 39.316 - memset(buf, 0, buf_n); 39.317 - snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x", 39.318 - mac[0], mac[1], mac[2], 39.319 - mac[3], mac[4], mac[5]); 39.320 - buf[buf_n - 1] = '\0'; 39.321 - return buf; 39.322 -}
40.1 --- a/tools/libxutil/sys_net.h Tue May 24 21:10:23 2005 +0000 40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 40.3 @@ -1,78 +0,0 @@ 40.4 -/* 40.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 40.6 - * 40.7 - * This library is free software; you can redistribute it and/or modify 40.8 - * it under the terms of the GNU Lesser General Public License as published by 40.9 - * the Free Software Foundation; either version 2.1 of the License, or 40.10 - * (at your option) any later version. 40.11 - * 40.12 - * This library is distributed in the hope that it will be useful, 40.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 40.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40.15 - * GNU Lesser General Public License for more details. 40.16 - * 40.17 - * You should have received a copy of the GNU Lesser General Public License 40.18 - * along with this library; if not, write to the Free Software 40.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 40.20 - */ 40.21 - 40.22 -#ifndef _XUTIL_SYS_NET_H_ 40.23 -#define _XUTIL_SYS_NET_H_ 40.24 -/** @file 40.25 - * 40.26 - * Replacement for standard network includes. 40.27 - * Works in user or kernel code. 40.28 - */ 40.29 - 40.30 -extern int get_inet_addr(const char *s, unsigned long *address); 40.31 -extern unsigned long bits_to_mask(int n); 40.32 -extern int mask_to_bits(unsigned long mask); 40.33 -extern int get_host_address(const char *name, unsigned long *address); 40.34 -extern int get_service_port(const char *name, unsigned long *port); 40.35 -extern char *get_port_service(unsigned long port); 40.36 -extern int convert_service_to_port(const char *s, unsigned long *port); 40.37 - 40.38 -#ifdef __KERNEL__ 40.39 -#include <linux/kernel.h> 40.40 -#include <linux/types.h> 40.41 -#include <linux/errno.h> 40.42 -#include <linux/slab.h> 40.43 -#include <asm/byteorder.h> 40.44 - 40.45 -#ifndef htonl 40.46 -#define htonl(x) __constant_htonl(x) 40.47 -#endif 40.48 - 40.49 -#ifndef ntohl 40.50 -#define ntohl(x) __constant_ntohl(x) 40.51 -#endif 40.52 - 40.53 -#ifndef htons 40.54 -#define htons(x) __constant_htons(x) 40.55 -#endif 40.56 - 40.57 -#ifndef ntohs 40.58 -#define ntohs(x) __constant_ntohs(x) 40.59 -#endif 40.60 - 40.61 -#include <linux/in.h> 40.62 -extern char *inet_ntoa(struct in_addr inaddr); 40.63 -extern int inet_aton(const char *address, struct in_addr *inp); 40.64 - 40.65 -#else 40.66 - 40.67 -#include <limits.h> 40.68 -#include <sys/socket.h> 40.69 -#include <netinet/in.h> 40.70 -#include <netdb.h> 40.71 -#include <arpa/inet.h> 40.72 - 40.73 -#endif 40.74 - 40.75 -extern char *mac_ntoa(const unsigned char *macaddr); 40.76 -extern int mac_aton(const char *addr, unsigned char *macaddr); 40.77 - 40.78 -#endif /* !_XUTIL_SYS_NET_H_ */ 40.79 - 40.80 - 40.81 -
41.1 --- a/tools/libxutil/sys_string.c Tue May 24 21:10:23 2005 +0000 41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 41.3 @@ -1,193 +0,0 @@ 41.4 -/* 41.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 41.6 - * 41.7 - * This library is free software; you can redistribute it and/or modify 41.8 - * it under the terms of the GNU Lesser General Public License as published by 41.9 - * the Free Software Foundation; either version 2.1 of the License, or 41.10 - * (at your option) any later version. 41.11 - * 41.12 - * This library is distributed in the hope that it will be useful, 41.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 41.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 41.15 - * GNU Lesser General Public License for more details. 41.16 - * 41.17 - * You should have received a copy of the GNU Lesser General Public License 41.18 - * along with this library; if not, write to the Free Software 41.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 41.20 - */ 41.21 - 41.22 -#ifdef __KERNEL__ 41.23 -# include <linux/config.h> 41.24 -# include <linux/module.h> 41.25 -# include <linux/kernel.h> 41.26 -# include <linux/errno.h> 41.27 -#else 41.28 -# include <errno.h> 41.29 -#endif 41.30 - 41.31 -#include "allocate.h" 41.32 -#include "sys_string.h" 41.33 - 41.34 -/** Set the base to use for converting a string to a number. Base is 41.35 - * hex if starts with 0x, otherwise decimal. 41.36 - * 41.37 - * @param s input string 41.38 - * @param base where to put the base 41.39 - * @return rest of s to parse as a number 41.40 - */ 41.41 -inline static const char * convert_set_base(const char *s, int *base){ 41.42 - *base = 10; 41.43 - if(s){ 41.44 - if(*s=='0'){ 41.45 - s++; 41.46 - if(*s=='x' || *s=='X'){ 41.47 - *base = 16; 41.48 - s++; 41.49 - } 41.50 - } 41.51 - } 41.52 - return s; 41.53 -} 41.54 - 41.55 -/** Set the sign to use for converting a string to a number. 41.56 - * Value is 1 for positive, -1 for negative. 41.57 - * 41.58 - * @param s input string 41.59 - * @param sign where to put the sign 41.60 - * @return rest of s to parse as a number 41.61 - */ 41.62 -inline static const char * convert_set_sign(const char *s, int *sign){ 41.63 - *sign = 1; 41.64 - if(s){ 41.65 - if(*s == '+'){ 41.66 - *sign = 1; 41.67 - s++; 41.68 - } else if (*s == '-'){ 41.69 - *sign = -1; 41.70 - s++; 41.71 - } 41.72 - } 41.73 - return s; 41.74 -} 41.75 - 41.76 -/** Get the numerical value of a digit in the given base. 41.77 - * 41.78 - * @param c digit character 41.79 - * @param base to use 41.80 - * @return numerical value of digit in range 0..base-1 or 41.81 - * -1 if not in range for the base 41.82 - */ 41.83 -inline static int convert_get_digit(char c, int base){ 41.84 - int d; 41.85 - 41.86 - if('0'<=c && c<='9'){ 41.87 - d = c - '0'; 41.88 - } else if('a'<=c && c<='f'){ 41.89 - d = c - 'a' + 10; 41.90 - } else if('A'<=c && c<='F'){ 41.91 - d = c - 'A' + 10; 41.92 - } else { 41.93 - d = -1; 41.94 - } 41.95 - return (d < base ? d : -1); 41.96 -} 41.97 - 41.98 -/** Convert a string to an unsigned long by parsing it as a number. 41.99 - * Will accept hex or decimal in usual C syntax. 41.100 - * 41.101 - * @param str input string 41.102 - * @param val where to put the result 41.103 - * @return 0 if converted OK, negative otherwise 41.104 - */ 41.105 -int convert_atoul(const char *str, unsigned long *val){ 41.106 - int err = 0; 41.107 - unsigned long v = 0; 41.108 - int base; 41.109 - const char *s = str; 41.110 - 41.111 - if(!s) { 41.112 - err = -EINVAL; 41.113 - goto exit; 41.114 - } 41.115 - s = convert_set_base(s, &base); 41.116 - for( ; !err && *s; s++){ 41.117 - int digit = convert_get_digit(*s, base); 41.118 - if(digit<0){ 41.119 - err = -EINVAL; 41.120 - goto exit; 41.121 - } 41.122 - v *= base; 41.123 - v += digit; 41.124 - } 41.125 - exit: 41.126 - *val = (err ? 0 : v); 41.127 - return err; 41.128 -} 41.129 - 41.130 -/** Convert a string to a long by parsing it as a number. 41.131 - * Will accept hex or decimal in usual C syntax. 41.132 - * 41.133 - * @param str input string 41.134 - * @param val where to put the result 41.135 - * @return 0 if converted OK, negative otherwise 41.136 - */ 41.137 -int convert_atol(const char *str, long *val){ 41.138 - int err = 0; 41.139 - unsigned long v = 0; 41.140 - int base, sign = 1; 41.141 - const char *s = str; 41.142 - 41.143 - if(!s) { 41.144 - err = -EINVAL; 41.145 - goto exit; 41.146 - } 41.147 - s = convert_set_sign(s, &sign); 41.148 - s = convert_set_base(s, &base); 41.149 - for( ; !err && *s; s++){ 41.150 - int digit = convert_get_digit(*s, base); 41.151 - if(digit<0){ 41.152 - err = -EINVAL; 41.153 - goto exit; 41.154 - } 41.155 - v *= base; 41.156 - v += digit; 41.157 - } 41.158 - if(sign < 0) v = -v; 41.159 - exit: 41.160 - *val = (err ? 0 : v); 41.161 - return err; 41.162 -} 41.163 - 41.164 -/** Combine a directory path with a relative path to produce 41.165 - * a new path. 41.166 - * 41.167 - * @param s directory path 41.168 - * @param t relative path 41.169 - * @return new combined path s/t 41.170 - */ 41.171 -int path_concat(char *s, char *t, char **val){ 41.172 - int err = 0; 41.173 - int sn, tn, vn; 41.174 - char *v; 41.175 - sn = strlen(s); 41.176 - if(sn > 0 && s[sn-1] == '/'){ 41.177 - sn--; 41.178 - } 41.179 - tn = strlen(t); 41.180 - if(tn > 0 && t[0] == '/'){ 41.181 - tn--; 41.182 - } 41.183 - vn = sn+tn+1; 41.184 - v = (char*)allocate(vn+1); 41.185 - if(!v){ 41.186 - err = -ENOMEM; 41.187 - goto exit; 41.188 - } 41.189 - strncpy(v, s, sn); 41.190 - v[sn] = '/'; 41.191 - strncpy(v+sn+1, t, tn); 41.192 - v[vn] = '\0'; 41.193 - exit: 41.194 - *val = (err ? NULL : v); 41.195 - return err; 41.196 -}
42.1 --- a/tools/libxutil/sys_string.h Tue May 24 21:10:23 2005 +0000 42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 42.3 @@ -1,92 +0,0 @@ 42.4 -/* 42.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 42.6 - * 42.7 - * This library is free software; you can redistribute it and/or modify 42.8 - * it under the terms of the GNU Lesser General Public License as published by 42.9 - * the Free Software Foundation; either version 2.1 of the License, or 42.10 - * (at your option) any later version. 42.11 - * 42.12 - * This library is distributed in the hope that it will be useful, 42.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 42.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42.15 - * GNU Lesser General Public License for more details. 42.16 - * 42.17 - * You should have received a copy of the GNU Lesser General Public License 42.18 - * along with this library; if not, write to the Free Software 42.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 42.20 - */ 42.21 - 42.22 -#ifndef _XUTIL_SYS_STRING_H_ 42.23 -#define _XUTIL_SYS_STRING_H_ 42.24 -/** @file 42.25 - * Replacement for standard string includes. 42.26 - * Works in user or kernel code. 42.27 - */ 42.28 -/*============================================================================*/ 42.29 -#ifdef __KERNEL__ 42.30 - 42.31 -#include <linux/config.h> 42.32 -#include <linux/kernel.h> 42.33 -#include <linux/string.h> 42.34 -#include <linux/types.h> 42.35 -#include <stdarg.h> 42.36 -#include "allocate.h" 42.37 - 42.38 -#if 0 42.39 -static inline int tolower(int c){ 42.40 - return (c>='A' && c<='Z' ? (c-'A')+'a' : c); 42.41 -} 42.42 -#endif 42.43 - 42.44 -static inline int isalpha(int c){ 42.45 - return (c>='A' && c<='Z') || (c>='a' && c<='z'); 42.46 -} 42.47 - 42.48 -static inline int isdigit(int c){ 42.49 - return (c>='0' && c<='9'); 42.50 -} 42.51 - 42.52 -#if 0 42.53 -static inline int strcasecmp(const char *s1, const char *s2){ 42.54 - int c1, c2; 42.55 - 42.56 - do { 42.57 - c1 = tolower(*s1++); 42.58 - c2 = tolower(*s2++); 42.59 - } while (c1 && c1 == c2); 42.60 - return c1 - c2; 42.61 -} 42.62 -#endif 42.63 - 42.64 -static inline char * strdup(const char *s){ 42.65 - int n = (s ? 1+strlen(s) : 0); 42.66 - char *copy = (n ? allocate(n) : NULL); 42.67 - if(copy){ 42.68 - strcpy(copy, s); 42.69 - } 42.70 - return copy; 42.71 -} 42.72 - 42.73 -/*============================================================================*/ 42.74 -#else 42.75 -#include <string.h> 42.76 -#include <stdio.h> 42.77 - 42.78 -#ifndef _GNU_SOURCE 42.79 -static inline size_t strnlen(const char *s, size_t n){ 42.80 - int k = 0; 42.81 - if(s){ 42.82 - for(k=0; *s && k<n; s++, k++){} 42.83 - } 42.84 - return k; 42.85 -} 42.86 -#endif 42.87 - 42.88 -#endif 42.89 -/*============================================================================*/ 42.90 - 42.91 -extern int convert_atoul(const char *s, unsigned long *v); 42.92 -extern int convert_atol(const char *s, long *v); 42.93 -extern int path_concat(char *s, char *t, char **val); 42.94 - 42.95 -#endif /* !_XUTIL_SYS_STRING_H_ */
43.1 --- a/tools/libxutil/util.c Tue May 24 21:10:23 2005 +0000 43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 43.3 @@ -1,106 +0,0 @@ 43.4 -/* 43.5 - * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>. 43.6 - * 43.7 - * This library is free software; you can redistribute it and/or modify 43.8 - * it under the terms of the GNU Lesser General Public License as 43.9 - * published by the Free Software Foundation; either version 2.1 of the 43.10 - * License, or (at your option) any later version. This library is 43.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 43.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.13 - * FITNESS FOR A PARTICULAR PURPOSE. 43.14 - * See the GNU Lesser General Public License for more details. 43.15 - * 43.16 - * You should have received a copy of the GNU Lesser General Public License 43.17 - * along with this library; if not, write to the Free Software Foundation, 43.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 43.19 - */ 43.20 - 43.21 -#include "sys_net.h" 43.22 -#include "sys_string.h" 43.23 - 43.24 -#ifndef __KERNEL__ 43.25 -# include <grp.h> 43.26 -# include <pwd.h> 43.27 -#endif 43.28 - 43.29 -#include "util.h" 43.30 - 43.31 - 43.32 -/** @file Various utility functions. 43.33 - */ 43.34 - 43.35 -/** Print an address (in network order) as an IPv4 address string 43.36 - * in dot notation. 43.37 - * 43.38 - * @param io where to print address 43.39 - * @param address to print (in network order) 43.40 - * @return bytes printed 43.41 - */ 43.42 -int print_address(IOStream *io, unsigned long address){ 43.43 -#ifdef __KERNEL__ 43.44 - address = ntohl(address); 43.45 - return IOStream_print(io, "%u.%u.%u.%u", 43.46 - (unsigned)((address >> 24) & 0xff), 43.47 - (unsigned)((address >> 16) & 0xff), 43.48 - (unsigned)((address >> 8) & 0xff), 43.49 - (unsigned)((address ) & 0xff)); 43.50 -#else 43.51 - struct in_addr inaddr = { s_addr: address }; 43.52 - return IOStream_print(io, inet_ntoa(inaddr)); 43.53 -#endif 43.54 -} 43.55 - 43.56 -/** Get the protocol number for a protocol. 43.57 - * 43.58 - * @param name protocol name 43.59 - * @param protocol where to put the protocol number 43.60 - * @return 0 if OK, error otherwise 43.61 - */ 43.62 -int get_protocol_number(char *name, unsigned long *protocol){ 43.63 -#ifdef __KERNEL__ 43.64 - return -1; 43.65 -#else 43.66 - struct protoent *proto = getprotobyname(name); 43.67 - if(!proto){ 43.68 - return -1; 43.69 - } 43.70 - *protocol = proto->p_proto; 43.71 - return 0; 43.72 -#endif 43.73 -} 43.74 - 43.75 -/** Get the protocol name for a protocol number. 43.76 - * 43.77 - * @param protocol number 43.78 - * @return name or null 43.79 - */ 43.80 -char *get_protocol_name(unsigned long protocol){ 43.81 -#ifdef __KERNEL__ 43.82 - return 0; 43.83 -#else 43.84 - struct protoent *proto = getprotobynumber(protocol); 43.85 - if(!proto){ 43.86 - return 0; 43.87 - } 43.88 - return proto->p_name; 43.89 -#endif 43.90 -} 43.91 - 43.92 -/** Get the host name for an address. 43.93 - * 43.94 - * @param addr address 43.95 - * @return host name or null 43.96 - */ 43.97 -char *get_host_name(unsigned long addr){ 43.98 -#ifdef __KERNEL__ 43.99 - return 0; 43.100 -#else 43.101 - struct in_addr inaddr; 43.102 - struct hostent *host = 0; 43.103 - 43.104 - inaddr.s_addr = addr; 43.105 - host = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET); 43.106 - if(!host) return NULL; 43.107 - return host->h_name; 43.108 -#endif 43.109 -}
44.1 --- a/tools/libxutil/util.h Tue May 24 21:10:23 2005 +0000 44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 44.3 @@ -1,28 +0,0 @@ 44.4 -/* 44.5 - * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>. 44.6 - * 44.7 - * This library is free software; you can redistribute it and/or modify 44.8 - * it under the terms of the GNU Lesser General Public License as 44.9 - * published by the Free Software Foundation; either version 2.1 of the 44.10 - * License, or (at your option) any later version. This library is 44.11 - * distributed in the hope that it will be useful, but WITHOUT ANY 44.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or 44.13 - * FITNESS FOR A PARTICULAR PURPOSE. 44.14 - * See the GNU Lesser General Public License for more details. 44.15 - * 44.16 - * You should have received a copy of the GNU Lesser General Public License 44.17 - * along with this library; if not, write to the Free Software Foundation, 44.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 44.19 - */ 44.20 - 44.21 -#ifndef _XEN_LIB_UTIL_H_ 44.22 -#define _XEN_LIB_UTIL_H_ 44.23 - 44.24 -#include "iostream.h" 44.25 - 44.26 -extern int print_address(IOStream *io, unsigned long address); 44.27 -extern int get_protocol_number(char *name, unsigned long *protocol); 44.28 -extern char *get_protocol_name(unsigned long protocol); 44.29 -extern char *get_host_name(unsigned long addr); 44.30 - 44.31 -#endif /* ! _XEN_LIB_UTIL_H_ */
45.1 --- a/tools/misc/Makefile Tue May 24 21:10:23 2005 +0000 45.2 +++ b/tools/misc/Makefile Tue May 24 21:17:29 2005 +0000 45.3 @@ -45,4 +45,4 @@ clean: 45.4 $(CC) -c $(CFLAGS) -o $@ $< 45.5 45.6 $(TARGETS): %: %.o Makefile 45.7 - $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil 45.8 + $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc
46.1 --- a/tools/misc/cpuperf/Makefile Tue May 24 21:10:23 2005 +0000 46.2 +++ b/tools/misc/cpuperf/Makefile Tue May 24 21:17:29 2005 +0000 46.3 @@ -38,7 +38,7 @@ clean: 46.4 $(CC) $(CFLAGS) -o $@ $< 46.5 46.6 cpuperf-xen: cpuperf.c $(HDRS) Makefile 46.7 - $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil -DXENO -o $@ $< 46.8 + $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -DXENO -o $@ $< 46.9 46.10 cpuperf-perfcntr: cpuperf.c $(HDRS) Makefile 46.11 $(CC) $(CFLAGS) -DPERFCNTR -o $@ $<
47.1 --- a/tools/python/setup.py Tue May 24 21:10:23 2005 +0000 47.2 +++ b/tools/python/setup.py Tue May 24 21:17:29 2005 +0000 47.3 @@ -9,15 +9,13 @@ extra_compile_args = [ "-fno-strict-ali 47.4 47.5 include_dirs = [ XEN_ROOT + "/tools/python/xen/lowlevel/xu", 47.6 XEN_ROOT + "/tools/libxc", 47.7 - XEN_ROOT + "/tools/libxutil", 47.8 XEN_ROOT + "/tools/xcs", 47.9 ] 47.10 47.11 library_dirs = [ XEN_ROOT + "/tools/libxc", 47.12 - XEN_ROOT + "/tools/libxutil", 47.13 ] 47.14 47.15 -libraries = [ "xc", "xutil" ] 47.16 +libraries = [ "xc" ] 47.17 47.18 xc = Extension("xc", 47.19 extra_compile_args = extra_compile_args,
48.1 --- a/tools/python/xen/lowlevel/xc/xc.c Tue May 24 21:10:23 2005 +0000 48.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Tue May 24 21:17:29 2005 +0000 48.3 @@ -15,7 +15,6 @@ 48.4 #include <netdb.h> 48.5 #include <arpa/inet.h> 48.6 #include "xc_private.h" 48.7 -#include "gzip_stream.h" 48.8 #include "linux_boot_params.h" 48.9 48.10 /* Needed for Python versions earlier than 2.3. */
49.1 --- a/tools/vnet/Makefile Tue May 24 21:10:23 2005 +0000 49.2 +++ b/tools/vnet/Makefile Tue May 24 21:17:29 2005 +0000 49.3 @@ -7,11 +7,11 @@ export prefix?=$(shell cd ../../dist/ins 49.4 49.5 .PHONY: all compile 49.6 .PHONY: gc-install gc-clean gc-prstine 49.7 -.PHONY: vnetd vnet-module install dist clean pristine 49.8 +.PHONY: libxutil vnetd vnet-module install dist clean pristine 49.9 49.10 all: compile 49.11 49.12 -compile: vnetd vnet-module 49.13 +compile: libxutil vnetd vnet-module 49.14 #compile: vnet-module 49.15 49.16 gc.tar.gz: 49.17 @@ -32,6 +32,9 @@ gc-clean: 49.18 gc-pristine: 49.19 -rm -rf gc?.? gc 49.20 49.21 +libxutil: 49.22 + $(MAKE) -C libxutil 49.23 + 49.24 vnetd: gc-install 49.25 $(MAKE) -C vnetd 49.26 49.27 @@ -39,13 +42,15 @@ vnet-module: 49.28 $(MAKE) -C vnet-module 49.29 49.30 install: compile 49.31 + $(MAKE) -C libxutil install 49.32 $(MAKE) -C vnetd install 49.33 $(MAKE) -C vnet-module install 49.34 $(MAKE) -C examples install 49.35 49.36 clean: 49.37 + -$(MAKE) -C libxutil clean 49.38 -$(MAKE) -C vnetd clean 49.39 -$(MAKE) -C vnet-module clean 49.40 -rm -rf gc?.? gc 49.41 - 49.42 + 49.43 pristine: clean gc-pristine
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/tools/vnet/libxutil/Makefile Tue May 24 21:17:29 2005 +0000 50.3 @@ -0,0 +1,77 @@ 50.4 + 50.5 +XEN_ROOT = ../../.. 50.6 +INSTALL = install 50.7 +INSTALL_DATA = $(INSTALL) -m0644 50.8 +INSTALL_PROG = $(INSTALL) -m0755 50.9 +INSTALL_DIR = $(INSTALL) -d -m0755 50.10 + 50.11 +include $(XEN_ROOT)/tools/Rules.mk 50.12 + 50.13 +LIB_SRCS := 50.14 +LIB_SRCS += allocate.c 50.15 +LIB_SRCS += enum.c 50.16 +LIB_SRCS += file_stream.c 50.17 +LIB_SRCS += gzip_stream.c 50.18 +LIB_SRCS += hash_table.c 50.19 +LIB_SRCS += iostream.c 50.20 +LIB_SRCS += lexis.c 50.21 +LIB_SRCS += string_stream.c 50.22 +LIB_SRCS += sxpr.c 50.23 +LIB_SRCS += sxpr_parser.c 50.24 +LIB_SRCS += sys_net.c 50.25 +LIB_SRCS += sys_string.c 50.26 +LIB_SRCS += util.c 50.27 + 50.28 +LIB_OBJS := $(LIB_SRCS:.c=.o) 50.29 +PIC_OBJS := $(LIB_SRCS:.c=.opic) 50.30 + 50.31 +CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing 50.32 + 50.33 +# Get gcc to generate the dependencies for us. 50.34 +CFLAGS += -Wp,-MD,.$(@F).d 50.35 +DEPS = .*.d 50.36 + 50.37 +MAJOR := 3.0 50.38 +MINOR := 0 50.39 +LIB := libxutil.so 50.40 +LIB += libxutil.so.$(MAJOR) 50.41 +LIB += libxutil.so.$(MAJOR).$(MINOR) 50.42 +LIB += libxutil.a 50.43 + 50.44 +all: build 50.45 +build: check-for-zlib 50.46 + $(MAKE) $(LIB) 50.47 + 50.48 +libxutil.so: libxutil.so.$(MAJOR) 50.49 + ln -sf $^ $@ 50.50 + 50.51 +libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) 50.52 + ln -sf $^ $@ 50.53 + 50.54 +libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) 50.55 + $(CC) $(CFLAGS) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ 50.56 + 50.57 +libxutil.a: $(LIB_OBJS) 50.58 + $(AR) rc $@ $^ 50.59 + 50.60 +check-for-zlib: 50.61 + @if [ ! -e /usr/include/zlib.h ]; then \ 50.62 + echo "***********************************************************"; \ 50.63 + echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \ 50.64 + echo "***********************************************************"; \ 50.65 + false; \ 50.66 + fi 50.67 + 50.68 +install: build 50.69 + [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) 50.70 + $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) 50.71 + $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/$(LIBDIR) 50.72 + ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so.$(MAJOR) 50.73 + ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so 50.74 + 50.75 +clean: 50.76 + $(RM) *.a *.so* *.o *.opic *.rpm 50.77 + $(RM) *~ 50.78 + $(RM) $(DEPS) 50.79 + 50.80 +-include $(DEPS)
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/tools/vnet/libxutil/allocate.c Tue May 24 21:17:29 2005 +0000 51.3 @@ -0,0 +1,116 @@ 51.4 +/* 51.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 51.6 + * 51.7 + * This library is free software; you can redistribute it and/or modify 51.8 + * it under the terms of the GNU Lesser General Public License as published by 51.9 + * the Free Software Foundation; either version 2.1 of the License, or 51.10 + * (at your option) any later version. 51.11 + * 51.12 + * This library is distributed in the hope that it will be useful, 51.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 51.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51.15 + * GNU Lesser General Public License for more details. 51.16 + * 51.17 + * You should have received a copy of the GNU Lesser General Public License 51.18 + * along with this library; if not, write to the Free Software 51.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51.20 + */ 51.21 + 51.22 +#include "allocate.h" 51.23 + 51.24 +/** @file 51.25 + * Support for allocating memory. 51.26 + * Usable from user code or kernel code (with __KERNEL__ defined). 51.27 + * In user code will use GC if USE_GC is defined. 51.28 + */ 51.29 + 51.30 +#ifdef __KERNEL__ 51.31 +/*----------------------------------------------------------------------------*/ 51.32 +# include <linux/config.h> 51.33 +# include <linux/slab.h> 51.34 +# include <linux/string.h> 51.35 +# include <linux/types.h> 51.36 + 51.37 +# define DEFAULT_TYPE 0 51.38 +# define MALLOC(n, type) kmalloc(n, type) 51.39 +# define FREE(ptr) kfree(ptr) 51.40 + 51.41 +/*----------------------------------------------------------------------------*/ 51.42 +#else /* ! __KERNEL__ */ 51.43 + 51.44 +# include <stdlib.h> 51.45 +# include <string.h> 51.46 + 51.47 +# define DEFAULT_TYPE 0 51.48 + 51.49 +#ifdef USE_GC 51.50 +# include "gc.h" 51.51 +# define MALLOC(n, typ) GC_malloc(n) 51.52 +# define FREE(ptr) (ptr=NULL) 51.53 +//typedef void *GC_PTR; 51.54 +//GC_PTR (*GC_oom_fn)(size_t n); 51.55 +#else 51.56 +# define MALLOC(n, type) malloc(n) 51.57 +# define FREE(ptr) free(ptr) 51.58 +#endif 51.59 + 51.60 +/*----------------------------------------------------------------------------*/ 51.61 +#endif 51.62 + 51.63 +/** Function to call when memory cannot be allocated. */ 51.64 +AllocateFailedFn *allocate_failed_fn = NULL; 51.65 + 51.66 +/** Allocate memory and zero it. 51.67 + * The type is only relevant when calling from kernel code, 51.68 + * from user code it is ignored. 51.69 + * In kernel code the values accepted by kmalloc can be used: 51.70 + * GFP_USER, GFP_ATOMIC, GFP_KERNEL. 51.71 + * 51.72 + * @param size number of bytes to allocate 51.73 + * @param type memory type to allocate (kernel only) 51.74 + * @return pointer to the allocated memory or zero 51.75 + * if malloc failed 51.76 + */ 51.77 +void *allocate_type(int size, int type){ 51.78 + void *p = MALLOC(size, type); 51.79 + if(p){ 51.80 + memzero(p, size); 51.81 + } else if(allocate_failed_fn){ 51.82 + allocate_failed_fn(size, type); 51.83 + } 51.84 + return p; 51.85 +} 51.86 + 51.87 +/** Allocate memory and zero it. 51.88 + * 51.89 + * @param size number of bytes to allocate 51.90 + * @return pointer to the allocated memory or zero 51.91 + * if malloc failed 51.92 + */ 51.93 +void *allocate(int size){ 51.94 + return allocate_type(size, DEFAULT_TYPE); 51.95 +} 51.96 + 51.97 +/** Free memory allocated by allocate(). 51.98 + * No-op if 'p' is null. 51.99 + * 51.100 + * @param p memory to free 51.101 + */ 51.102 +void deallocate(void *p){ 51.103 + if(p){ 51.104 + FREE(p); 51.105 + } 51.106 +} 51.107 + 51.108 +/** Set bytes to zero. 51.109 + * No-op if 'p' is null. 51.110 + * 51.111 + * @param p memory to zero 51.112 + * @param size number of bytes to zero 51.113 + */ 51.114 +void memzero(void *p, int size){ 51.115 + if(p){ 51.116 + memset(p, 0, (size_t)size); 51.117 + } 51.118 +} 51.119 +
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/tools/vnet/libxutil/allocate.h Tue May 24 21:17:29 2005 +0000 52.3 @@ -0,0 +1,45 @@ 52.4 +/* 52.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 52.6 + * 52.7 + * This library is free software; you can redistribute it and/or modify 52.8 + * it under the terms of the GNU Lesser General Public License as published by 52.9 + * the Free Software Foundation; either version 2.1 of the License, or 52.10 + * (at your option) any later version. 52.11 + * 52.12 + * This library is distributed in the hope that it will be useful, 52.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 52.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52.15 + * GNU Lesser General Public License for more details. 52.16 + * 52.17 + * You should have received a copy of the GNU Lesser General Public License 52.18 + * along with this library; if not, write to the Free Software 52.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52.20 + */ 52.21 + 52.22 +#ifndef _XUTIL_ALLOCATE_H_ 52.23 +#define _XUTIL_ALLOCATE_H_ 52.24 + 52.25 +/** Allocate memory for a given type, and cast. */ 52.26 +#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype)) 52.27 + 52.28 +/** Allocate memory for a given type, and cast. */ 52.29 +#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype)) 52.30 + 52.31 +extern void *allocate_type(int size, int type); 52.32 +extern void *allocate(int size); 52.33 +extern void deallocate(void *); 52.34 +extern void memzero(void *p, int size); 52.35 + 52.36 +typedef void AllocateFailedFn(int size, int type); 52.37 +extern AllocateFailedFn *allocate_failed_fn; 52.38 + 52.39 +#endif /* _XUTIL_ALLOCATE_H_ */ 52.40 + 52.41 + 52.42 + 52.43 + 52.44 + 52.45 + 52.46 + 52.47 + 52.48 +
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/tools/vnet/libxutil/debug.h Tue May 24 21:17:29 2005 +0000 53.3 @@ -0,0 +1,72 @@ 53.4 +/* 53.5 + * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 53.6 + * 53.7 + * This library is free software; you can redistribute it and/or modify 53.8 + * it under the terms of the GNU Lesser General Public License as published by 53.9 + * the Free Software Foundation; either version 2.1 of the License, or 53.10 + * (at your option) any later version. 53.11 + * 53.12 + * This library is distributed in the hope that it will be useful, 53.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 53.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 53.15 + * GNU Lesser General Public License for more details. 53.16 + * 53.17 + * You should have received a copy of the GNU Lesser General Public License 53.18 + * along with this library; if not, write to the Free Software 53.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 53.20 + */ 53.21 +#ifndef _XUTIL_DEBUG_H_ 53.22 +#define _XUTIL_DEBUG_H_ 53.23 + 53.24 +#ifndef MODULE_NAME 53.25 +#define MODULE_NAME "" 53.26 +#endif 53.27 + 53.28 +#ifdef __KERNEL__ 53.29 +#include <linux/config.h> 53.30 +#include <linux/kernel.h> 53.31 + 53.32 +#ifdef DEBUG 53.33 + 53.34 +#define dprintf(fmt, args...) printk(KERN_DEBUG "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 53.35 +#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 53.36 +#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 53.37 +#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) 53.38 + 53.39 +#else 53.40 + 53.41 +#define dprintf(fmt, args...) do {} while(0) 53.42 +#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args) 53.43 +#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME fmt, ##args) 53.44 +#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME fmt, ##args) 53.45 + 53.46 +#endif 53.47 + 53.48 +#else 53.49 + 53.50 +#include <stdio.h> 53.51 + 53.52 +#ifdef DEBUG 53.53 + 53.54 +#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 53.55 +#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 53.56 +#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 53.57 +#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 53.58 + 53.59 +#else 53.60 + 53.61 +#define dprintf(fmt, args...) do {} while(0) 53.62 +#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args) 53.63 +#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args) 53.64 +#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args) 53.65 + 53.66 +#endif 53.67 + 53.68 +#endif 53.69 + 53.70 +/** Print format for an IP address. 53.71 + * See NIPQUAD(), HIPQUAD() 53.72 + */ 53.73 +#define IPFMT "%u.%u.%u.%u" 53.74 + 53.75 +#endif /* ! _XUTIL_DEBUG_H_ */
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/tools/vnet/libxutil/enum.c Tue May 24 21:17:29 2005 +0000 54.3 @@ -0,0 +1,61 @@ 54.4 +/* 54.5 + * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com> 54.6 + * 54.7 + * This library is free software; you can redistribute it and/or modify 54.8 + * it under the terms of the GNU Lesser General Public License as 54.9 + * published by the Free Software Foundation; either version 2.1 of the 54.10 + * License, or (at your option) any later version. This library is 54.11 + * distributed in the hope that it will be useful, but WITHOUT ANY 54.12 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or 54.13 + * FITNESS FOR A PARTICULAR PURPOSE. 54.14 + * See the GNU Lesser General Public License for more details. 54.15 + * 54.16 + * You should have received a copy of the GNU Lesser General Public License 54.17 + * along with this library; if not, write to the Free Software Foundation, 54.18 + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 54.19 + */ 54.20 + 54.21 +#ifdef __KERNEL__ 54.22 +#include <linux/errno.h> 54.23 +#else 54.24 +#include <errno.h> 54.25 +#endif 54.26 + 54.27 +#include "sys_string.h" 54.28 +#include "enum.h" 54.29 + 54.30 +/** Map an enum name to its value using a table. 54.31 + * 54.32 + * @param name enum name 54.33 + * @param defs enum definitions 54.34 + * @return enum value or -1 if not known 54.35 + */ 54.36 +int enum_name_to_val(char *name, EnumDef *defs){ 54.37 + int val = -1; 54.38 + for(; defs->name; defs++){ 54.39 + if(!strcmp(defs->name, name)){ 54.40 + val = defs->val; 54.41 + break; 54.42 + } 54.43 + } 54.44 + return val; 54.45 +} 54.46 + 54.47 +/** Map an enum value to its name using a table. 54.48 + * 54.49 + * @param val enum value 54.50 + * @param defs enum definitions 54.51 + * @param defs_n number of definitions 54.52 + * @return enum name or NULL if not known 54.53 + */ 54.54 +char *enum_val_to_name(int val, EnumDef *defs){ 54.55 + char *name = NULL; 54.56 + for(; defs->name; defs++){ 54.57 + if(val == defs->val){ 54.58 + name = defs->name; 54.59 + break; 54.60 + } 54.61 + } 54.62 + return name; 54.63 +} 54.64 +
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/tools/vnet/libxutil/enum.h Tue May 24 21:17:29 2005 +0000 55.3 @@ -0,0 +1,30 @@ 55.4 +/* 55.5 + * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com> 55.6 + * 55.7 + * This library is free software; you can redistribute it and/or modify 55.8 + * it under the terms of the GNU Lesser General Public License as 55.9 + * published by the Free Software Foundation; either version 2.1 of the 55.10 + * License, or (at your option) any later version. This library is 55.11 + * distributed in the hope that it will be useful, but WITHOUT ANY 55.12 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or 55.13 + * FITNESS FOR A PARTICULAR PURPOSE. 55.14 + * See the GNU Lesser General Public License for more details. 55.15 + * 55.16 + * You should have received a copy of the GNU Lesser General Public License 55.17 + * along with this library; if not, write to the Free Software Foundation, 55.18 + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 55.19 + */ 55.20 + 55.21 +#ifndef _XUTIL_ENUM_H_ 55.22 +#define _XUTIL_ENUM_H_ 55.23 + 55.24 +/** Mapping of an enum value to a name. */ 55.25 +typedef struct EnumDef { 55.26 + int val; 55.27 + char *name; 55.28 +} EnumDef; 55.29 + 55.30 +extern int enum_name_to_val(char *name, EnumDef *defs); 55.31 +extern char *enum_val_to_name(int val, EnumDef *defs); 55.32 + 55.33 +#endif /* _XUTIL_ENUM_H_ */
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/tools/vnet/libxutil/fd_stream.c Tue May 24 21:17:29 2005 +0000 56.3 @@ -0,0 +1,184 @@ 56.4 +/* 56.5 + * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 56.6 + * 56.7 + * This library is free software; you can redistribute it and/or modify 56.8 + * it under the terms of the GNU Lesser General Public License as published by 56.9 + * the Free Software Foundation; either version 2.1 of the License, or 56.10 + * (at your option) any later version. 56.11 + * 56.12 + * This library is distributed in the hope that it will be useful, 56.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 56.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 56.15 + * GNU Lesser General Public License for more details. 56.16 + * 56.17 + * You should have received a copy of the GNU Lesser General Public License 56.18 + * along with this library; if not, write to the Free Software 56.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 56.20 + */ 56.21 + 56.22 +/** @file 56.23 + * An IOStream implementation using fds. 56.24 + */ 56.25 +#ifndef __KERNEL__ 56.26 + 56.27 +#include <stdio.h> 56.28 +#include <stdlib.h> 56.29 +#include <string.h> 56.30 +#include <unistd.h> 56.31 +#include <errno.h> 56.32 +#include "allocate.h" 56.33 +#include "fd_stream.h" 56.34 + 56.35 +#define MODULE_NAME "fd_stream" 56.36 +#define DEBUG 1 56.37 +//#undef DEBUG 56.38 +#include "debug.h" 56.39 + 56.40 +static int fd_read(IOStream *s, void *buf, size_t n); 56.41 +static int fd_write(IOStream *s, const void *buf, size_t n); 56.42 +static int fd_error(IOStream *s); 56.43 +static int fd_close(IOStream *s); 56.44 +static void fd_free(IOStream *s); 56.45 +static int fd_flush(IOStream *s); 56.46 + 56.47 +/** Methods used by a fd IOStream. */ 56.48 +static const IOMethods fd_methods = { 56.49 + read: fd_read, 56.50 + write: fd_write, 56.51 + error: fd_error, 56.52 + close: fd_close, 56.53 + free: fd_free, 56.54 + flush: fd_flush, 56.55 +}; 56.56 + 56.57 +/** Get the fd data. 56.58 + * 56.59 + * @param io fd stream 56.60 + * @return data 56.61 + */ 56.62 +static inline FDData * fd_data(IOStream *io){ 56.63 + return (FDData *)io->data; 56.64 +} 56.65 + 56.66 +/** Test if a stream is a fd stream. 56.67 + * 56.68 + * @param io stream 56.69 + * @return 0 if a fd stream, -EINVAL if not 56.70 + */ 56.71 +int fd_stream_check(IOStream *io){ 56.72 + return (io && io->methods == &fd_methods ? 0 : -EINVAL); 56.73 +} 56.74 + 56.75 +/** Get the data for a fd stream. 56.76 + * 56.77 + * @param io stream 56.78 + * @param data return value for the data 56.79 + * @return 0 if a fd stream, -EINVAL if not 56.80 + */ 56.81 +int fd_stream_data(IOStream *io, FDData **data){ 56.82 + int err = fd_stream_check(io); 56.83 + if(err){ 56.84 + *data = NULL; 56.85 + } else { 56.86 + *data = fd_data(io); 56.87 + } 56.88 + return err; 56.89 +} 56.90 + 56.91 + 56.92 +/** Write to the underlying fd. 56.93 + * 56.94 + * @param stream input 56.95 + * @param buf where to put input 56.96 + * @param n number of bytes to write 56.97 + * @return number of bytes written 56.98 + */ 56.99 +static int fd_write(IOStream *s, const void *buf, size_t n){ 56.100 + FDData *data = fd_data(s); 56.101 + int k; 56.102 + k = write(data->fd, buf, n); 56.103 + return k; 56.104 +} 56.105 + 56.106 +/** Read from the underlying stream; 56.107 + * 56.108 + * @param stream input 56.109 + * @param buf where to put input 56.110 + * @param n number of bytes to read 56.111 + * @return number of bytes read 56.112 + */ 56.113 +static int fd_read(IOStream *s, void *buf, size_t n){ 56.114 + FDData *data = fd_data(s); 56.115 + int k; 56.116 + k = read(data->fd, buf, n); 56.117 + //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k); 56.118 + return k; 56.119 +} 56.120 + 56.121 +/** Flush the fd (no-op). 56.122 + * 56.123 + * @param s fd stream 56.124 + * @return 0 on success, error code otherwise 56.125 + */ 56.126 +static int fd_flush(IOStream *s){ 56.127 + return 0; 56.128 +} 56.129 + 56.130 +/** Check if a fd stream has an error (no-op). 56.131 + * 56.132 + * @param s fd stream 56.133 + * @return 1 if has an error, 0 otherwise 56.134 + */ 56.135 +static int fd_error(IOStream *s){ 56.136 + return 0; 56.137 +} 56.138 + 56.139 +/** Close a fd stream. 56.140 + * 56.141 + * @param s fd stream to close 56.142 + * @return result of the close 56.143 + */ 56.144 +static int fd_close(IOStream *s){ 56.145 + FDData *data = fd_data(s); 56.146 + return close(data->fd); 56.147 +} 56.148 + 56.149 +/** Free a fd stream. 56.150 + * 56.151 + * @param s fd stream 56.152 + */ 56.153 +static void fd_free(IOStream *s){ 56.154 + FDData *data = fd_data(s); 56.155 + deallocate(data); 56.156 +} 56.157 + 56.158 +/** Create an IOStream for a fd. 56.159 + * 56.160 + * @param fd fd to wtap 56.161 + * @return new IOStream using fd for i/o 56.162 + */ 56.163 +IOStream *fd_stream_new(int fd){ 56.164 + int err = -ENOMEM; 56.165 + IOStream *io = NULL; 56.166 + FDData *data = NULL; 56.167 + 56.168 + io = ALLOCATE(IOStream); 56.169 + if(!io) goto exit; 56.170 + io->methods = &fd_methods; 56.171 + data = ALLOCATE(FDData); 56.172 + if(!data) goto exit; 56.173 + io->data = data; 56.174 + data->fd = fd; 56.175 + err = 0; 56.176 + exit: 56.177 + if(err){ 56.178 + if(io){ 56.179 + if(data) deallocate(data); 56.180 + deallocate(io); 56.181 + io = NULL; 56.182 + } 56.183 + } 56.184 + return io; 56.185 +} 56.186 + 56.187 +#endif
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/tools/vnet/libxutil/fd_stream.h Tue May 24 21:17:29 2005 +0000 57.3 @@ -0,0 +1,36 @@ 57.4 +/* 57.5 + * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 57.6 + * 57.7 + * This library is free software; you can redistribute it and/or modify 57.8 + * it under the terms of the GNU Lesser General Public License as published by 57.9 + * the Free Software Foundation; either version 2.1 of the License, or 57.10 + * (at your option) any later version. 57.11 + * 57.12 + * This library is distributed in the hope that it will be useful, 57.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 57.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 57.15 + * GNU Lesser General Public License for more details. 57.16 + * 57.17 + * You should have received a copy of the GNU Lesser General Public License 57.18 + * along with this library; if not, write to the Free Software 57.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 57.20 + */ 57.21 + 57.22 +#ifndef _XMC_FD_STREAM_H_ 57.23 +#define _XMC_FD_STREAM_H_ 57.24 + 57.25 +#ifndef __KERNEL__ 57.26 +#include "iostream.h" 57.27 + 57.28 +/** Data associated with a fd stream. */ 57.29 +typedef struct FDData { 57.30 + /** The socket file descriptor. */ 57.31 + int fd; 57.32 +} FDData; 57.33 + 57.34 +extern IOStream *fd_stream_new(int fd); 57.35 +extern int fd_stream_data(IOStream *io, FDData **data); 57.36 +extern int fd_stream_check(IOStream *io); 57.37 + 57.38 +#endif 57.39 +#endif /* !_XMC_FD_STREAM_H_ */
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/tools/vnet/libxutil/file_stream.c Tue May 24 21:17:29 2005 +0000 58.3 @@ -0,0 +1,220 @@ 58.4 +/* 58.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 58.6 + * 58.7 + * This library is free software; you can redistribute it and/or modify 58.8 + * it under the terms of the GNU Lesser General Public License as published by 58.9 + * the Free Software Foundation; either version 2.1 of the License, or 58.10 + * (at your option) any later version. 58.11 + * 58.12 + * This library is distributed in the hope that it will be useful, 58.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 58.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 58.15 + * GNU Lesser General Public License for more details. 58.16 + * 58.17 + * You should have received a copy of the GNU Lesser General Public License 58.18 + * along with this library; if not, write to the Free Software 58.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 58.20 + */ 58.21 + 58.22 +/** @file 58.23 + * An IOStream implementation using FILE*. 58.24 + */ 58.25 +#ifndef __KERNEL__ 58.26 +#include <stdio.h> 58.27 +#include <stdlib.h> 58.28 +#include "allocate.h" 58.29 +#include "file_stream.h" 58.30 + 58.31 +static int file_read(IOStream *s, void *buf, size_t n); 58.32 +static int file_write(IOStream *s, const void *buf, size_t n); 58.33 +static int file_error(IOStream *s); 58.34 +static int file_close(IOStream *s); 58.35 +static void file_free(IOStream *s); 58.36 +static int file_flush(IOStream *s); 58.37 + 58.38 +/** Methods used by a FILE* IOStream. */ 58.39 +static const IOMethods file_methods = { 58.40 + read: file_read, 58.41 + write: file_write, 58.42 + error: file_error, 58.43 + close: file_close, 58.44 + free: file_free, 58.45 + flush: file_flush, 58.46 +}; 58.47 + 58.48 +/** IOStream for stdin. */ 58.49 +static IOStream _iostdin = { 58.50 + methods: &file_methods, 58.51 + data: (void*)1, 58.52 + nofree: 1, 58.53 +}; 58.54 + 58.55 +/** IOStream for stdout. */ 58.56 +static IOStream _iostdout = { 58.57 + methods: &file_methods, 58.58 + data: (void*)2, 58.59 + nofree: 1, 58.60 +}; 58.61 + 58.62 +/** IOStream for stderr. */ 58.63 +static IOStream _iostderr = { 58.64 + methods: &file_methods, 58.65 + data: (void*)3, 58.66 + nofree: 1, 58.67 +}; 58.68 + 58.69 +/** IOStream for stdin. */ 58.70 +IOStream *iostdin = &_iostdin; 58.71 + 58.72 +/** IOStream for stdout. */ 58.73 +IOStream *iostdout = &_iostdout; 58.74 + 58.75 +/** IOStream for stderr. */ 58.76 +IOStream *iostderr = &_iostderr; 58.77 + 58.78 +/* Get the underlying FILE*. 58.79 + * 58.80 + * @param s file stream 58.81 + * @return the stream s wraps 58.82 + */ 58.83 +static inline FILE *get_file(IOStream *s){ 58.84 + FILE *data = NULL; 58.85 + switch((long)s->data){ 58.86 + case 1: 58.87 + data = stdin; 58.88 + break; 58.89 + case 2: 58.90 + data = stdout; 58.91 + break; 58.92 + case 3: 58.93 + data = stderr; 58.94 + break; 58.95 + default: 58.96 + data = (FILE*)s->data; 58.97 + break; 58.98 + } 58.99 + return data; 58.100 +} 58.101 + 58.102 +/** Control buffering on the underlying stream, like setvbuf(). 58.103 + * 58.104 + * @param io file stream 58.105 + * @param buf buffer 58.106 + * @param mode buffering mode (see man setvbuf()) 58.107 + * @param size buffer size 58.108 + * @return 0 on success, non-zero otherwise 58.109 + */ 58.110 +int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){ 58.111 + return setvbuf(get_file(io), buf, mode, size); 58.112 +} 58.113 + 58.114 +/** Write to the underlying stream using fwrite(); 58.115 + * 58.116 + * @param stream input 58.117 + * @param buf where to put input 58.118 + * @param n number of bytes to write 58.119 + * @return number of bytes written 58.120 + */ 58.121 +static int file_write(IOStream *s, const void *buf, size_t n){ 58.122 + return fwrite(buf, 1, n, get_file(s)); 58.123 +} 58.124 + 58.125 +/** Read from the underlying stream using fread(); 58.126 + * 58.127 + * @param stream input 58.128 + * @param buf where to put input 58.129 + * @param n number of bytes to read 58.130 + * @return number of bytes read 58.131 + */ 58.132 +static int file_read(IOStream *s, void *buf, size_t n){ 58.133 + return fread(buf, 1, n, get_file(s)); 58.134 +} 58.135 + 58.136 +/** Fush the underlying stream using fflush(). 58.137 + * 58.138 + * @param s file stream 58.139 + * @return 0 on success, error code otherwise 58.140 + */ 58.141 +static int file_flush(IOStream *s){ 58.142 + return fflush(get_file(s)); 58.143 +} 58.144 + 58.145 +/** Check if a stream has an error. 58.146 + * 58.147 + * @param s file stream 58.148 + * @return 1 if has an error, 0 otherwise 58.149 + */ 58.150 +static int file_error(IOStream *s){ 58.151 + return ferror(get_file(s)); 58.152 +} 58.153 + 58.154 +/** Close a file stream. 58.155 + * 58.156 + * @param s file stream to close 58.157 + * @return result of the close 58.158 + */ 58.159 +static int file_close(IOStream *s){ 58.160 + int result = 0; 58.161 + result = fclose(get_file(s)); 58.162 + return result; 58.163 +} 58.164 + 58.165 +/** Free a file stream. 58.166 + * 58.167 + * @param s file stream 58.168 + */ 58.169 +static void file_free(IOStream *s){ 58.170 + // Nothing extra to do - close did it all. 58.171 +} 58.172 + 58.173 +/** Create an IOStream for a stream. 58.174 + * 58.175 + * @param f stream to wrap 58.176 + * @return new IOStream using f for i/o 58.177 + */ 58.178 +IOStream *file_stream_new(FILE *f){ 58.179 + IOStream *io = ALLOCATE(IOStream); 58.180 + if(io){ 58.181 + io->methods = &file_methods; 58.182 + io->data = (void*)f; 58.183 + } 58.184 + return io; 58.185 +} 58.186 + 58.187 +/** IOStream version of fopen(). 58.188 + * 58.189 + * @param file name of the file to open 58.190 + * @param flags giving the mode to open in (as for fopen()) 58.191 + * @return new stream for the open file, or 0 if failed 58.192 + */ 58.193 +IOStream *file_stream_fopen(const char *file, const char *flags){ 58.194 + IOStream *io = 0; 58.195 + FILE *fin = fopen(file, flags); 58.196 + if(fin){ 58.197 + io = file_stream_new(fin); 58.198 + if(!io){ 58.199 + fclose(fin); 58.200 + } 58.201 + } 58.202 + return io; 58.203 +} 58.204 + 58.205 +/** IOStream version of fdopen(). 58.206 + * 58.207 + * @param fd file descriptor 58.208 + * @param flags giving the mode to open in (as for fdopen()) 58.209 + * @return new stream for the open file, or 0 if failed. Always takes 58.210 + * ownership of fd. 58.211 + */ 58.212 +IOStream *file_stream_fdopen(int fd, const char *flags){ 58.213 + IOStream *io = 0; 58.214 + FILE *fin = fdopen(fd, flags); 58.215 + if(fin){ 58.216 + io = file_stream_new(fin); 58.217 + if(!io){ 58.218 + fclose(fin); 58.219 + } 58.220 + } 58.221 + return io; 58.222 +} 58.223 +#endif
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/tools/vnet/libxutil/file_stream.h Tue May 24 21:17:29 2005 +0000 59.3 @@ -0,0 +1,35 @@ 59.4 +/* 59.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 59.6 + * 59.7 + * This library is free software; you can redistribute it and/or modify 59.8 + * it under the terms of the GNU Lesser General Public License as published by 59.9 + * the Free Software Foundation; either version 2.1 of the License, or 59.10 + * (at your option) any later version. 59.11 + * 59.12 + * This library is distributed in the hope that it will be useful, 59.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 59.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 59.15 + * GNU Lesser General Public License for more details. 59.16 + * 59.17 + * You should have received a copy of the GNU Lesser General Public License 59.18 + * along with this library; if not, write to the Free Software 59.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 59.20 + */ 59.21 + 59.22 +#ifndef _XUTIL_FILE_STREAM_H_ 59.23 +#define _XUTIL_FILE_STREAM_H_ 59.24 + 59.25 +#ifndef __KERNEL__ 59.26 +#include "iostream.h" 59.27 +#include <stdio.h> 59.28 + 59.29 +extern IOStream *file_stream_new(FILE *f); 59.30 +extern IOStream *file_stream_fopen(const char *file, const char *flags); 59.31 +extern IOStream *file_stream_fdopen(int fd, const char *flags); 59.32 +extern IOStream get_stream_stdout(void); 59.33 +extern IOStream get_stream_stderr(void); 59.34 +extern IOStream get_stream_stdin(void); 59.35 + 59.36 +extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size); 59.37 +#endif 59.38 +#endif /* !_XUTIL_FILE_STREAM_H_ */
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/tools/vnet/libxutil/gzip_stream.c Tue May 24 21:17:29 2005 +0000 60.3 @@ -0,0 +1,174 @@ 60.4 +/* 60.5 + * Copyright (C) 2003 Hewlett-Packard Company. 60.6 + * 60.7 + * This library is free software; you can redistribute it and/or modify 60.8 + * it under the terms of the GNU Lesser General Public License as published by 60.9 + * the Free Software Foundation; either version 2.1 of the License, or 60.10 + * (at your option) any later version. 60.11 + * 60.12 + * This library is distributed in the hope that it will be useful, 60.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 60.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 60.15 + * GNU Lesser General Public License for more details. 60.16 + * 60.17 + * You should have received a copy of the GNU Lesser General Public License 60.18 + * along with this library; if not, write to the Free Software 60.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 60.20 + */ 60.21 + 60.22 +/** @file 60.23 + * An IOStream implementation using zlib gzFile to provide 60.24 + * compression and decompression. 60.25 + */ 60.26 +#ifndef __KERNEL__ 60.27 + 60.28 +#include <stdio.h> 60.29 +#include <stdlib.h> 60.30 + 60.31 +#include "zlib.h" 60.32 + 60.33 +#include "allocate.h" 60.34 +#include "gzip_stream.h" 60.35 + 60.36 +static int gzip_read(IOStream *s, void *buf, size_t n); 60.37 +static int gzip_write(IOStream *s, const void *buf, size_t n); 60.38 +static int gzip_error(IOStream *s); 60.39 +static int gzip_close(IOStream *s); 60.40 +static void gzip_free(IOStream *s); 60.41 +static int gzip_flush(IOStream *s); 60.42 + 60.43 +/** Methods used by a gzFile* IOStream. */ 60.44 +static const IOMethods gzip_methods = { 60.45 + read: gzip_read, 60.46 + write: gzip_write, 60.47 + error: gzip_error, 60.48 + close: gzip_close, 60.49 + free: gzip_free, 60.50 + flush: gzip_flush, 60.51 +}; 60.52 + 60.53 +/** Get the underlying gzFile*. 60.54 + * 60.55 + * @param s gzip stream 60.56 + * @return the stream s wraps 60.57 + */ 60.58 +static inline gzFile get_gzfile(IOStream *s){ 60.59 + return (gzFile)s->data; 60.60 +} 60.61 + 60.62 +/** Write to the underlying stream. 60.63 + * 60.64 + * @param stream destination 60.65 + * @param buf data 60.66 + * @param n number of bytes to write 60.67 + * @return number of bytes written 60.68 + */ 60.69 +static int gzip_write(IOStream *s, const void *buf, size_t n){ 60.70 + return gzwrite(get_gzfile(s), (void*)buf, n); 60.71 +} 60.72 + 60.73 +/** Read from the underlying stream. 60.74 + * 60.75 + * @param stream input 60.76 + * @param buf where to put input 60.77 + * @param n number of bytes to read 60.78 + * @return number of bytes read 60.79 + */ 60.80 +static int gzip_read(IOStream *s, void *buf, size_t n){ 60.81 + return gzread(get_gzfile(s), buf, n); 60.82 +} 60.83 + 60.84 +/** Flush the underlying stream. 60.85 + * 60.86 + * @param s gzip stream 60.87 + * @return 0 on success, error code otherwise 60.88 + */ 60.89 +static int gzip_flush(IOStream *s){ 60.90 + //return gzflush(get_gzfile(s), Z_NO_FLUSH); 60.91 + return gzflush(get_gzfile(s), Z_SYNC_FLUSH); 60.92 + //return gzflush(get_gzfile(s), Z_FULL_FLUSH); 60.93 +} 60.94 + 60.95 +/** Check if a stream has an error. 60.96 + * 60.97 + * @param s gzip stream 60.98 + * @return 1 if has an error, 0 otherwise 60.99 + */ 60.100 +static int gzip_error(IOStream *s){ 60.101 + int err; 60.102 + gzFile *gz = get_gzfile(s); 60.103 + gzerror(gz, &err); 60.104 + return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err); 60.105 +} 60.106 + 60.107 +/** Close a gzip stream. 60.108 + * 60.109 + * @param s gzip stream to close 60.110 + * @return result of the close 60.111 + */ 60.112 +static int gzip_close(IOStream *s){ 60.113 + int result = 0; 60.114 + result = gzclose(get_gzfile(s)); 60.115 + return result; 60.116 +} 60.117 + 60.118 +/** Free a gzip stream. 60.119 + * 60.120 + * @param s gzip stream 60.121 + */ 60.122 +static void gzip_free(IOStream *s){ 60.123 + // Nothing to do - close did it all. 60.124 +} 60.125 + 60.126 +/** Create an IOStream for a gzip stream. 60.127 + * 60.128 + * @param f stream to wrap 60.129 + * @return new IOStream using f for i/o 60.130 + */ 60.131 +IOStream *gzip_stream_new(gzFile *f){ 60.132 + IOStream *io = ALLOCATE(IOStream); 60.133 + if(io){ 60.134 + io->methods = &gzip_methods; 60.135 + io->data = (void*)f; 60.136 + } 60.137 + return io; 60.138 +} 60.139 + 60.140 +/** IOStream version of fopen(). 60.141 + * 60.142 + * @param file name of the file to open 60.143 + * @param flags giving the mode to open in (as for fopen()) 60.144 + * @return new stream for the open file, or NULL if failed 60.145 + */ 60.146 +IOStream *gzip_stream_fopen(const char *file, const char *flags){ 60.147 + IOStream *io = NULL; 60.148 + gzFile *fgz; 60.149 + fgz = gzopen(file, flags); 60.150 + if(fgz){ 60.151 + io = gzip_stream_new(fgz); 60.152 + if(!io){ 60.153 + gzclose(fgz); 60.154 + } 60.155 + } 60.156 + return io; 60.157 +} 60.158 + 60.159 +/** IOStream version of fdopen(). 60.160 + * 60.161 + * @param fd file descriptor 60.162 + * @param flags giving the mode to open in (as for fdopen()) 60.163 + * @return new stream for the open file, or NULL if failed. Always takes 60.164 + * ownership of fd. 60.165 + */ 60.166 +IOStream *gzip_stream_fdopen(int fd, const char *flags){ 60.167 + IOStream *io = NULL; 60.168 + gzFile *fgz; 60.169 + fgz = gzdopen(fd, flags); 60.170 + if(fgz){ 60.171 + io = gzip_stream_new(fgz); 60.172 + if(!io) 60.173 + gzclose(fgz); 60.174 + } 60.175 + return io; 60.176 +} 60.177 +#endif
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/tools/vnet/libxutil/gzip_stream.h Tue May 24 21:17:29 2005 +0000 61.3 @@ -0,0 +1,30 @@ 61.4 +/* 61.5 + * Copyright (C) 2003 Hewlett-Packard Company. 61.6 + * 61.7 + * This library is free software; you can redistribute it and/or modify 61.8 + * it under the terms of the GNU Lesser General Public License as published by 61.9 + * the Free Software Foundation; either version 2.1 of the License, or 61.10 + * (at your option) any later version. 61.11 + * 61.12 + * This library is distributed in the hope that it will be useful, 61.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 61.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 61.15 + * GNU Lesser General Public License for more details. 61.16 + * 61.17 + * You should have received a copy of the GNU Lesser General Public License 61.18 + * along with this library; if not, write to the Free Software 61.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 61.20 + */ 61.21 + 61.22 +#ifndef _XUTIL_GZIP_STREAM_H_ 61.23 +#define _XUTIL_GZIP_STREAM_H_ 61.24 + 61.25 +#ifndef __KERNEL__ 61.26 +#include "iostream.h" 61.27 +#include "zlib.h" 61.28 + 61.29 +extern IOStream *gzip_stream_new(gzFile *f); 61.30 +extern IOStream *gzip_stream_fopen(const char *file, const char *flags); 61.31 +extern IOStream *gzip_stream_fdopen(int fd, const char *flags); 61.32 +#endif 61.33 +#endif /* !_XUTIL_GZIP_STREAM_H_ */
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/tools/vnet/libxutil/hash_table.c Tue May 24 21:17:29 2005 +0000 62.3 @@ -0,0 +1,640 @@ 62.4 +/* 62.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 62.6 + * 62.7 + * This library is free software; you can redistribute it and/or modify 62.8 + * it under the terms of the GNU Lesser General Public License as published by 62.9 + * the Free Software Foundation; either version 2.1 of the License, or 62.10 + * (at your option) any later version. 62.11 + * 62.12 + * This library is distributed in the hope that it will be useful, 62.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 62.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 62.15 + * GNU Lesser General Public License for more details. 62.16 + * 62.17 + * You should have received a copy of the GNU Lesser General Public License 62.18 + * along with this library; if not, write to the Free Software 62.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 62.20 + */ 62.21 + 62.22 +#ifdef __KERNEL__ 62.23 +# include <linux/config.h> 62.24 +# include <linux/module.h> 62.25 +# include <linux/kernel.h> 62.26 +# include <linux/errno.h> 62.27 +#else 62.28 +# include <errno.h> 62.29 +# include <stddef.h> 62.30 +#endif 62.31 + 62.32 +//#include <limits.h> 62.33 + 62.34 +#include "allocate.h" 62.35 +#include "hash_table.h" 62.36 + 62.37 +/** @file 62.38 + * Base support for hashtables. 62.39 + * 62.40 + * Hash codes are reduced modulo the number of buckets to index tables, 62.41 + * so there is no need for hash functions to limit the range of hashcodes. 62.42 + * In fact it is assumed that hashcodes do not change when the number of 62.43 + * buckets in the table changes. 62.44 + */ 62.45 + 62.46 +/*==========================================================================*/ 62.47 +/** Number of bits in half a word. */ 62.48 +//#if __WORDSIZE == 64 62.49 +//#define HALF_WORD_BITS 32 62.50 +//#else 62.51 +#define HALF_WORD_BITS 16 62.52 +//#endif 62.53 + 62.54 +/** Mask for lo half of a word. On 32-bit this is 62.55 + * (1<<16) - 1 = 65535 = 0xffff 62.56 + * It's 4294967295 = 0xffffffff on 64-bit. 62.57 + */ 62.58 +#define LO_HALF_MASK ((1 << HALF_WORD_BITS) - 1) 62.59 + 62.60 +/** Get the lo half of a word. */ 62.61 +#define LO_HALF(x) ((x) & LO_HALF_MASK) 62.62 + 62.63 +/** Get the hi half of a word. */ 62.64 +#define HI_HALF(x) ((x) >> HALF_WORD_BITS) 62.65 + 62.66 +/** Do a full hash on both inputs, using DES-style non-linear scrambling. 62.67 + * Both inputs are replaced with the results of the hash. 62.68 + * 62.69 + * @param pleft input/output word 62.70 + * @param pright input/output word 62.71 + */ 62.72 +void pseudo_des(unsigned long *pleft, unsigned long *pright){ 62.73 + // Bit-rich mixing constant. 62.74 + static const unsigned long a_mixer[] = { 62.75 + 0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L, }; 62.76 + 62.77 + // Bit-rich mixing constant. 62.78 + static const unsigned long b_mixer[] = { 62.79 + 0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L, }; 62.80 + 62.81 + // Number of iterations - must be 2 or 4. 62.82 + static const int ncycle = 4; 62.83 + //static const int ncycle = 2; 62.84 + 62.85 + unsigned long left = *pleft, right = *pright; 62.86 + unsigned long v, v_hi, v_lo; 62.87 + int i; 62.88 + 62.89 + for(i=0; i<ncycle; i++){ 62.90 + // Flip some bits in right to get v. 62.91 + v = right; 62.92 + v ^= a_mixer[i]; 62.93 + // Get lo and hi halves of v. 62.94 + v_lo = LO_HALF(v); 62.95 + v_hi = HI_HALF(v); 62.96 + // Non-linear mix of the halves of v. 62.97 + v = ((v_lo * v_lo) + ~(v_hi * v_hi)); 62.98 + // Swap the halves of v. 62.99 + v = (HI_HALF(v) | (LO_HALF(v) << HALF_WORD_BITS)); 62.100 + // Flip some bits. 62.101 + v ^= b_mixer[i]; 62.102 + // More non-linear mixing. 62.103 + v += (v_lo * v_hi); 62.104 + v ^= left; 62.105 + left = right; 62.106 + right = v; 62.107 + } 62.108 + *pleft = left; 62.109 + *pright = right; 62.110 +} 62.111 + 62.112 +/** Hash a string. 62.113 + * 62.114 + * @param s input to hash 62.115 + * @return hashcode 62.116 + */ 62.117 +Hashcode hash_string(char *s){ 62.118 + Hashcode h = 0; 62.119 + if(s){ 62.120 + for( ; *s; s++){ 62.121 + h = hash_2ul(h, *s); 62.122 + } 62.123 + } 62.124 + return h; 62.125 +} 62.126 + 62.127 +/** Get the bucket for a hashcode in a hash table. 62.128 + * 62.129 + * @param table to get bucket from 62.130 + * @param hashcode to get bucket for 62.131 + * @return bucket 62.132 + */ 62.133 +inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){ 62.134 + return table->buckets + (hashcode % table->buckets_n); 62.135 +} 62.136 + 62.137 +/** Initialize a hash table. 62.138 + * Can be safely called more than once. 62.139 + * 62.140 + * @param table to initialize 62.141 + */ 62.142 +void HashTable_init(HashTable *table){ 62.143 + int i; 62.144 + 62.145 + if(!table->init_done){ 62.146 + table->init_done = 1; 62.147 + table->next_id = 0; 62.148 + for(i=0; i<table->buckets_n; i++){ 62.149 + HTBucket *bucket = get_bucket(table, i); 62.150 + bucket->head = 0; 62.151 + bucket->count = 0; 62.152 + } 62.153 + table->entry_count = 0; 62.154 + } 62.155 +} 62.156 + 62.157 +/** Allocate a new hashtable. 62.158 + * If the number of buckets is not positive the default is used. 62.159 + * The number of buckets should usually be prime. 62.160 + * 62.161 + * @param buckets_n number of buckets 62.162 + * @return new hashtable or null 62.163 + */ 62.164 +HashTable *HashTable_new(int buckets_n){ 62.165 + HashTable *z = ALLOCATE(HashTable); 62.166 + if(!z) goto exit; 62.167 + if(buckets_n <= 0){ 62.168 + buckets_n = HT_BUCKETS_N; 62.169 + } 62.170 + z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); 62.171 + if(!z->buckets){ 62.172 + deallocate(z); 62.173 + z = 0; 62.174 + goto exit; 62.175 + } 62.176 + z->buckets_n = buckets_n; 62.177 + HashTable_init(z); 62.178 + exit: 62.179 + return z; 62.180 +} 62.181 + 62.182 +/** Free a hashtable. 62.183 + * Any entries are removed and freed. 62.184 + * 62.185 + * @param h hashtable (ignored if null) 62.186 + */ 62.187 +void HashTable_free(HashTable *h){ 62.188 + if(h){ 62.189 + HashTable_clear(h); 62.190 + deallocate(h->buckets); 62.191 + deallocate(h); 62.192 + } 62.193 +} 62.194 + 62.195 +/** Push an entry on the list in the bucket for a given hashcode. 62.196 + * 62.197 + * @param table to add entry to 62.198 + * @param hashcode for the entry 62.199 + * @param entry to add 62.200 + */ 62.201 +static inline void push_on_bucket(HashTable *table, Hashcode hashcode, 62.202 + HTEntry *entry){ 62.203 + HTBucket *bucket; 62.204 + HTEntry *old_head; 62.205 + 62.206 + bucket = get_bucket(table, hashcode); 62.207 + old_head = bucket->head; 62.208 + bucket->count++; 62.209 + bucket->head = entry; 62.210 + entry->next = old_head; 62.211 +} 62.212 + 62.213 +/** Change the number of buckets in a hashtable. 62.214 + * No-op if the number of buckets is not positive. 62.215 + * Existing entries are reallocated to buckets based on their hashcodes. 62.216 + * The table is unmodified if the number of buckets cannot be changed. 62.217 + * 62.218 + * @param table hashtable 62.219 + * @param buckets_n new number of buckets 62.220 + * @return 0 on success, error code otherwise 62.221 + */ 62.222 +int HashTable_set_buckets_n(HashTable *table, int buckets_n){ 62.223 + int err = 0; 62.224 + HTBucket *old_buckets = table->buckets; 62.225 + int old_buckets_n = table->buckets_n; 62.226 + int i; 62.227 + 62.228 + if(buckets_n <= 0){ 62.229 + err = -EINVAL; 62.230 + goto exit; 62.231 + } 62.232 + table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); 62.233 + if(!table->buckets){ 62.234 + err = -ENOMEM; 62.235 + table->buckets = old_buckets; 62.236 + goto exit; 62.237 + } 62.238 + table->buckets_n = buckets_n; 62.239 + for(i=0; i<old_buckets_n; i++){ 62.240 + HTBucket *bucket = old_buckets + i; 62.241 + HTEntry *entry, *next; 62.242 + for(entry = bucket->head; entry; entry = next){ 62.243 + next = entry->next; 62.244 + push_on_bucket(table, entry->hashcode, entry); 62.245 + } 62.246 + } 62.247 + deallocate(old_buckets); 62.248 + exit: 62.249 + return err; 62.250 +} 62.251 + 62.252 +/** Adjust the number of buckets so the table is neither too full nor too empty. 62.253 + * The table is unmodified if adjusting fails. 62.254 + * 62.255 + * @param table hash table 62.256 + * @param buckets_min minimum number of buckets (use default if 0 or negative) 62.257 + * @return 0 on success, error code otherwise 62.258 + */ 62.259 +int HashTable_adjust(HashTable *table, int buckets_min){ 62.260 + int buckets_n = 0; 62.261 + int err = 0; 62.262 + if(buckets_min <= 0) buckets_min = HT_BUCKETS_N; 62.263 + if(table->entry_count >= table->buckets_n){ 62.264 + // The table is dense - expand it. 62.265 + buckets_n = 2 * table->buckets_n; 62.266 + } else if((table->buckets_n > buckets_min) && 62.267 + (4 * table->entry_count < table->buckets_n)){ 62.268 + // The table is more than minimum size and sparse - shrink it. 62.269 + buckets_n = 2 * table->entry_count; 62.270 + if(buckets_n < buckets_min) buckets_n = buckets_min; 62.271 + } 62.272 + if(buckets_n){ 62.273 + err = HashTable_set_buckets_n(table, buckets_n); 62.274 + } 62.275 + return err; 62.276 +} 62.277 + 62.278 +/** Allocate a new entry for a given value. 62.279 + * 62.280 + * @param value to put in the entry 62.281 + * @return entry, or 0 on failure 62.282 + */ 62.283 +HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){ 62.284 + HTEntry *z = ALLOCATE(HTEntry); 62.285 + if(z){ 62.286 + z->hashcode = hashcode; 62.287 + z->key = key; 62.288 + z->value = value; 62.289 + } 62.290 + return z; 62.291 +} 62.292 + 62.293 +/** Free an entry. 62.294 + * 62.295 + * @param z entry to free 62.296 + */ 62.297 +inline void HTEntry_free(HTEntry *z){ 62.298 + if(z){ 62.299 + deallocate(z); 62.300 + } 62.301 +} 62.302 + 62.303 +/** Free an entry in a hashtable. 62.304 + * The table's entry_free_fn is used is defined, otherwise 62.305 + * the HTEntry itself is freed. 62.306 + * 62.307 + * @param table hashtable 62.308 + * @param entry to free 62.309 + */ 62.310 +inline void HashTable_free_entry(HashTable *table, HTEntry *entry){ 62.311 + if(!entry)return; 62.312 + if(table && table->entry_free_fn){ 62.313 + table->entry_free_fn(table, entry); 62.314 + } else { 62.315 + HTEntry_free(entry); 62.316 + } 62.317 +} 62.318 + 62.319 +/** Get the first entry satisfying a test from the bucket for the 62.320 + * given hashcode. 62.321 + * 62.322 + * @param table to look in 62.323 + * @param hashcode indicates the bucket 62.324 + * @param test_fn test to apply to elements 62.325 + * @param arg first argument to calls to test_fn 62.326 + * @return entry found, or 0 62.327 + */ 62.328 +inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, 62.329 + TableTestFn *test_fn, TableArg arg){ 62.330 + HTBucket *bucket; 62.331 + HTEntry *entry = 0; 62.332 + HTEntry *next; 62.333 + 62.334 + bucket = get_bucket(table, hashcode); 62.335 + for(entry = bucket->head; entry; entry = next){ 62.336 + next = entry->next; 62.337 + if(test_fn(arg, table, entry)){ 62.338 + break; 62.339 + } 62.340 + } 62.341 + return entry; 62.342 +} 62.343 + 62.344 +/** Test hashtable keys for equality. 62.345 + * Uses the table's key_equal_fn if defined, otherwise pointer equality. 62.346 + * 62.347 + * @param key1 key to compare 62.348 + * @param key2 key to compare 62.349 + * @return 1 if equal, 0 otherwise 62.350 + */ 62.351 +inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){ 62.352 + return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1==key2); 62.353 +} 62.354 + 62.355 +/** Compute the hashcode of a hashtable key. 62.356 + * The table's key_hash_fn is used if defined, otherwise the address of 62.357 + * the key is hashed. 62.358 + * 62.359 + * @param table hashtable 62.360 + * @param key to hash 62.361 + * @return hashcode 62.362 + */ 62.363 +inline Hashcode HashTable_key_hash(HashTable *table, void *key){ 62.364 + return (table->key_hash_fn ? table->key_hash_fn(key) : hash_ul((unsigned long)key)); 62.365 +} 62.366 + 62.367 +/** Test if an entry has a given key. 62.368 + * 62.369 + * @param arg containing key to test for 62.370 + * @param table the entry is in 62.371 + * @param entry to test 62.372 + * @return 1 if the entry has the key, 0 otherwise 62.373 + */ 62.374 +static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){ 62.375 + return HashTable_key_equal(table, arg.ptr, entry->key); 62.376 +} 62.377 + 62.378 +/** Get an entry with a given key. 62.379 + * 62.380 + * @param table to search 62.381 + * @param key to look for 62.382 + * @return entry if found, null otherwise 62.383 + */ 62.384 +#if 0 62.385 +inline HTEntry * HashTable_get_entry(HashTable *table, void *key){ 62.386 + TableArg arg = { ptr: key }; 62.387 + return HashTable_find_entry(table, HashTable_key_hash(table, key), has_key, arg); 62.388 +} 62.389 +#else 62.390 +inline HTEntry * HashTable_get_entry(HashTable *table, void *key){ 62.391 + Hashcode hashcode; 62.392 + HTBucket *bucket; 62.393 + HTEntry *entry = 0; 62.394 + HTEntry *next; 62.395 + 62.396 + hashcode = HashTable_key_hash(table, key); 62.397 + bucket = get_bucket(table, hashcode); 62.398 + for(entry = bucket->head; entry; entry = next){ 62.399 + next = entry->next; 62.400 + if(HashTable_key_equal(table, key, entry->key)){ 62.401 + break; 62.402 + } 62.403 + } 62.404 + return entry; 62.405 +} 62.406 +#endif 62.407 + 62.408 +/** Get the value of an entry with a given key. 62.409 + * 62.410 + * @param table to search 62.411 + * @param key to look for 62.412 + * @return value if an entry was found, null otherwise 62.413 + */ 62.414 +inline void * HashTable_get(HashTable *table, void *key){ 62.415 + HTEntry *entry = HashTable_get_entry(table, key); 62.416 + return (entry ? entry->value : 0); 62.417 +} 62.418 + 62.419 +/** Print the buckets in a table. 62.420 + * 62.421 + * @param table to print 62.422 + */ 62.423 +void show_buckets(HashTable *table, IOStream *io){ 62.424 + int i,j ; 62.425 + IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n); 62.426 + for(i=0; i<table->buckets_n; i++){ 62.427 + if(0 || table->buckets[i].count>0){ 62.428 + IOStream_print(io, "bucket %3d %3d %10p ", i, 62.429 + table->buckets[i].count, 62.430 + table->buckets[i].head); 62.431 + for(j = table->buckets[i].count; j>0; j--){ 62.432 + IOStream_print(io, "+"); 62.433 + } 62.434 + IOStream_print(io, "\n"); 62.435 + } 62.436 + } 62.437 + HashTable_print(table, io); 62.438 +} 62.439 + 62.440 +/** Print an entry in a table. 62.441 + * 62.442 + * @param entry to print 62.443 + * @param arg a pointer to an IOStream to print to 62.444 + * @return 0 62.445 + */ 62.446 +static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){ 62.447 + IOStream *io = (IOStream*)arg.ptr; 62.448 + IOStream_print(io, " b=%4lx h=%08lx i=%08lx |-> e=%8p k=%8p v=%8p\n", 62.449 + entry->hashcode % table->buckets_n, 62.450 + entry->hashcode, 62.451 + entry->index, 62.452 + entry, entry->key, entry->value); 62.453 + return 0; 62.454 +} 62.455 + 62.456 +/** Print a hash table. 62.457 + * 62.458 + * @param table to print 62.459 + */ 62.460 +void HashTable_print(HashTable *table, IOStream *io){ 62.461 + IOStream_print(io, "{\n"); 62.462 + HashTable_map(table, print_entry, (TableArg){ ptr: io }); 62.463 + IOStream_print(io, "}\n"); 62.464 +} 62.465 +/*==========================================================================*/ 62.466 + 62.467 +/** Get the next entry id to use for a table. 62.468 + * 62.469 + * @param table hash table 62.470 + * @return non-zero entry id 62.471 + */ 62.472 +static inline unsigned long get_next_id(HashTable *table){ 62.473 + unsigned long id; 62.474 + 62.475 + if(table->next_id == 0){ 62.476 + table->next_id = 1; 62.477 + } 62.478 + id = table->next_id++; 62.479 + return id; 62.480 +} 62.481 + 62.482 +/** Add an entry to the bucket for the 62.483 + * given hashcode. 62.484 + * 62.485 + * @param table to insert in 62.486 + * @param hashcode indicates the bucket 62.487 + * @param key to add an entry for 62.488 + * @param value to add an entry for 62.489 + * @return entry on success, 0 on failure 62.490 + */ 62.491 +inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){ 62.492 + HTEntry *entry = HTEntry_new(hashcode, key, value); 62.493 + if(entry){ 62.494 + entry->index = get_next_id(table); 62.495 + push_on_bucket(table, hashcode, entry); 62.496 + table->entry_count++; 62.497 + } 62.498 + return entry; 62.499 +} 62.500 + 62.501 +/** Move the front entry for a bucket to the correct point in the bucket order as 62.502 + * defined by the order function. If this is called every time a new entry is added 62.503 + * the bucket will be maintained in sorted order. 62.504 + * 62.505 + * @param table to modify 62.506 + * @param hashcode indicates the bucket 62.507 + * @param order entry comparison function 62.508 + * @return 0 if an entry was moved, 1 if not 62.509 + */ 62.510 +int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){ 62.511 + HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL; 62.512 + HTBucket *bucket; 62.513 + int err = 1; 62.514 + 62.515 + bucket = get_bucket(table, hashcode); 62.516 + new_entry = bucket->head; 62.517 + if(!new_entry || !new_entry->next) goto exit; 62.518 + for(entry = new_entry->next; entry; prev = entry, entry = entry->next){ 62.519 + if(order(new_entry, entry) <= 0) break; 62.520 + } 62.521 + if(prev){ 62.522 + err = 0; 62.523 + bucket->head = new_entry->next; 62.524 + new_entry->next = entry; 62.525 + prev->next = new_entry; 62.526 + } 62.527 + exit: 62.528 + return err; 62.529 +} 62.530 + 62.531 +/** Add an entry to a hashtable. 62.532 + * The entry is added to the bucket for its key's hashcode. 62.533 + * 62.534 + * @param table to insert in 62.535 + * @param key to add an entry for 62.536 + * @param value to add an entry for 62.537 + * @return entry on success, 0 on failure 62.538 + */ 62.539 +inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){ 62.540 + return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value); 62.541 +} 62.542 + 62.543 + 62.544 +/** Remove entries satisfying a test from the bucket for the 62.545 + * given hashcode. 62.546 + * 62.547 + * @param table to remove from 62.548 + * @param hashcode indicates the bucket 62.549 + * @param test_fn test to apply to elements 62.550 + * @param arg first argument to calls to test_fn 62.551 + * @return number of entries removed 62.552 + */ 62.553 +inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode, 62.554 + TableTestFn *test_fn, TableArg arg){ 62.555 + HTBucket *bucket; 62.556 + HTEntry *entry, *prev = 0, *next; 62.557 + int removed_count = 0; 62.558 + 62.559 + bucket = get_bucket(table, hashcode); 62.560 + for(entry = bucket->head; entry; entry = next){ 62.561 + next = entry->next; 62.562 + if(test_fn(arg, table, entry)){ 62.563 + if(prev){ 62.564 + prev->next = next; 62.565 + } else { 62.566 + bucket->head = next; 62.567 + } 62.568 + bucket->count--; 62.569 + table->entry_count--; 62.570 + removed_count++; 62.571 + HashTable_free_entry(table, entry); 62.572 + entry = 0; 62.573 + } 62.574 + prev = entry; 62.575 + } 62.576 + return removed_count; 62.577 +} 62.578 + 62.579 +/** Remove entries with a given key. 62.580 + * 62.581 + * @param table to remove from 62.582 + * @param key of entries to remove 62.583 + * @return number of entries removed 62.584 + */ 62.585 +inline int HashTable_remove(HashTable *table, void *key){ 62.586 +#if 1 62.587 + Hashcode hashcode; 62.588 + HTBucket *bucket; 62.589 + HTEntry *entry, *prev = 0, *next; 62.590 + int removed_count = 0; 62.591 + 62.592 + hashcode = HashTable_key_hash(table, key); 62.593 + bucket = get_bucket(table, hashcode); 62.594 + for(entry = bucket->head; entry; entry = next){ 62.595 + next = entry->next; 62.596 + if(HashTable_key_equal(table, key, entry->key)){ 62.597 + if(prev){ 62.598 + prev->next = next; 62.599 + } else { 62.600 + bucket->head = next; 62.601 + } 62.602 + bucket->count--; 62.603 + table->entry_count--; 62.604 + removed_count++; 62.605 + HashTable_free_entry(table, entry); 62.606 + entry = 0; 62.607 + } 62.608 + prev = entry; 62.609 + } 62.610 + return removed_count; 62.611 +#else 62.612 + return HashTable_remove_entry(table, HashTable_key_hash(table, key), 62.613 + has_key, (TableArg){ ptr: key}); 62.614 +#endif 62.615 +} 62.616 + 62.617 +/** Remove (and free) all the entries in a bucket. 62.618 + * 62.619 + * @param bucket to clear 62.620 + */ 62.621 +static inline void bucket_clear(HashTable *table, HTBucket *bucket){ 62.622 + HTEntry *entry, *next; 62.623 + 62.624 + for(entry = bucket->head; entry; entry = next){ 62.625 + next = entry->next; 62.626 + HashTable_free_entry(table, entry); 62.627 + } 62.628 + bucket->head = 0; 62.629 + table->entry_count -= bucket->count; 62.630 + bucket->count = 0; 62.631 +} 62.632 + 62.633 +/** Remove (and free) all the entries in a table. 62.634 + * 62.635 + * @param table to clear 62.636 + */ 62.637 +void HashTable_clear(HashTable *table){ 62.638 + int i, n = table->buckets_n; 62.639 + 62.640 + for(i=0; i<n; i++){ 62.641 + bucket_clear(table, table->buckets + i); 62.642 + } 62.643 +}
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/tools/vnet/libxutil/hash_table.h Tue May 24 21:17:29 2005 +0000 63.3 @@ -0,0 +1,294 @@ 63.4 +/* 63.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 63.6 + * 63.7 + * This library is free software; you can redistribute it and/or modify 63.8 + * it under the terms of the GNU Lesser General Public License as published by 63.9 + * the Free Software Foundation; either version 2.1 of the License, or 63.10 + * (at your option) any later version. 63.11 + * 63.12 + * This library is distributed in the hope that it will be useful, 63.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 63.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 63.15 + * GNU Lesser General Public License for more details. 63.16 + * 63.17 + * You should have received a copy of the GNU Lesser General Public License 63.18 + * along with this library; if not, write to the Free Software 63.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 63.20 + */ 63.21 + 63.22 +#ifndef _XUTIL_HASH_TABLE_H_ 63.23 +#define _XUTIL_HASH_TABLE_H_ 63.24 + 63.25 +#include "iostream.h" 63.26 + 63.27 +typedef unsigned long Hashcode; 63.28 + 63.29 +/** Type used to pass parameters to table functions. */ 63.30 +typedef union TableArg { 63.31 + unsigned long ul; 63.32 + void *ptr; 63.33 +} TableArg; 63.34 + 63.35 +/** An entry in a bucket list. */ 63.36 +typedef struct HTEntry { 63.37 + /** Hashcode of the entry's key. */ 63.38 + Hashcode hashcode; 63.39 + /** Identifier for this entry in the table. */ 63.40 + int index; 63.41 + /** The key for this entry. */ 63.42 + void *key; 63.43 + /** The value in this entry. */ 63.44 + void *value; 63.45 + /** The next entry in the list. */ 63.46 + struct HTEntry *next; 63.47 +} HTEntry; 63.48 + 63.49 +/** A bucket in a rule table. */ 63.50 +typedef struct HTBucket { 63.51 + /** Number of entries in the bucket. */ 63.52 + int count; 63.53 + /** First entry in the bucket (may be null). */ 63.54 + HTEntry *head; 63.55 +} HTBucket; 63.56 + 63.57 +/** Default number of buckets in a hash table. 63.58 + * You want enough buckets so the lists in the buckets will typically be short. 63.59 + * It's a good idea if this is prime, since that will help to spread hashcodes 63.60 + * around the table. 63.61 + */ 63.62 +//#define HT_BUCKETS_N 1 63.63 +//#define HT_BUCKETS_N 3 63.64 +//#define HT_BUCKETS_N 7 63.65 +//#define HT_BUCKETS_N 17 63.66 +//#define HT_BUCKETS_N 97 63.67 +//#define HT_BUCKETS_N 211 63.68 +//#define HT_BUCKETS_N 401 63.69 +#define HT_BUCKETS_N 1021 63.70 + 63.71 +typedef struct HashTable HashTable; 63.72 + 63.73 +/** Type for a function used to select table entries. */ 63.74 +typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry); 63.75 + 63.76 +/** Type for a function to map over table entries. */ 63.77 +typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry); 63.78 + 63.79 +/** Type for a function to free table entries. */ 63.80 +typedef void TableFreeFn(HashTable *table, HTEntry *entry); 63.81 + 63.82 +/** Type for a function to hash table keys. */ 63.83 +typedef Hashcode TableHashFn(void *key); 63.84 + 63.85 +/** Type for a function to test table keys for equality. */ 63.86 +typedef int TableEqualFn(void *key1, void *key2); 63.87 + 63.88 +/** Type for a function to order table entries. */ 63.89 +typedef int TableOrderFn(HTEntry *e1, HTEntry *e2); 63.90 + 63.91 +/** General hash table. 63.92 + * A hash table with a list in each bucket. 63.93 + * Functions can be supplied for freeing entries, hashing keys, and comparing keys. 63.94 + * These all default to 0, when default behaviour treating keys as integers is used. 63.95 + */ 63.96 +struct HashTable { 63.97 + /** Flag indicating whether the table has been initialised. */ 63.98 + int init_done; 63.99 + /** Next value for the id field in inserted rules. */ 63.100 + unsigned long next_id; 63.101 + /** Number of buckets in the bucket array. */ 63.102 + int buckets_n; 63.103 + /** Array of buckets, each with its own list. */ 63.104 + HTBucket *buckets; 63.105 + /** Number of entries in the table. */ 63.106 + int entry_count; 63.107 + /** Function to free keys and values in entries. */ 63.108 + TableFreeFn *entry_free_fn; 63.109 + /** Function to hash keys. */ 63.110 + TableHashFn *key_hash_fn; 63.111 + /** Function to compare keys for equality. */ 63.112 + TableEqualFn *key_equal_fn; 63.113 + /** Place for the user of the table to hang extra data. */ 63.114 + void *user_data; 63.115 +}; 63.116 + 63.117 +extern HashTable *HashTable_new(int bucket_n); 63.118 +extern void HashTable_free(HashTable *table); 63.119 +extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value); 63.120 +extern void HTEntry_free(HTEntry *entry); 63.121 +extern int HashTable_set_bucket_n(HashTable *table, int bucket_n); 63.122 +extern void HashTable_clear(HashTable *table); 63.123 +extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value); 63.124 +extern HTEntry * HashTable_get_entry(HashTable *table, void *key); 63.125 +extern HTEntry * HashTable_add(HashTable *table, void *key, void *value); 63.126 +extern void * HashTable_get(HashTable *table, void *key); 63.127 +extern int HashTable_remove(HashTable *table, void *key); 63.128 +extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, 63.129 + TableTestFn *test_fn, TableArg arg); 63.130 +extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode, 63.131 + TableTestFn *test_fn, TableArg arg); 63.132 +//extern int HashTable_map(HashTable *table, TableMapFn *map_fn, TableArg arg); 63.133 +extern void HashTable_print(HashTable *table, IOStream *out); 63.134 +extern int HashTable_set_buckets_n(HashTable *table, int buckets_n); 63.135 +extern int HashTable_adjust(HashTable *table, int buckets_min); 63.136 +extern void pseudo_des(unsigned long *pleft, unsigned long *pright); 63.137 +extern Hashcode hash_string(char *s); 63.138 + 63.139 +extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order); 63.140 + 63.141 +/** Control whether to use hashing based on DES or simple 63.142 + * hashing. DES hashing is `more random' but much more expensive. 63.143 + */ 63.144 +#define HASH_PSEUDO_DES 0 63.145 + 63.146 +/** Hash a long using a quick and dirty linear congruential random number generator. 63.147 + * See `Numerical Recipes in C', Chapter 7, "An Even Quicker Generator". 63.148 + * 63.149 + * @param a value to hash 63.150 + * @return hashed input 63.151 + */ 63.152 +static inline unsigned long lcrng_hash(unsigned long a){ 63.153 + return (1664525L * a + 1013904223L); 63.154 +} 63.155 + 63.156 +/** Hash an unsigned long. 63.157 + * 63.158 + * @param a input to hash 63.159 + * @return hashcode 63.160 + */ 63.161 +static inline Hashcode hash_ul(unsigned long a){ 63.162 +#if HASH_PSEUDO_DES 63.163 + unsigned long left = a; 63.164 + unsigned long right = 0L; 63.165 + pseudo_des(&left, &right); 63.166 + return right; 63.167 +#else 63.168 + a = lcrng_hash(a); 63.169 + a = lcrng_hash(a); 63.170 + return a; 63.171 +#endif 63.172 +} 63.173 + 63.174 +/** Hash two unsigned longs together. 63.175 + * 63.176 + * @param a input to hash 63.177 + * @param b input to hash 63.178 + * @return hashcode 63.179 + */ 63.180 +static inline Hashcode hash_2ul(unsigned long a, unsigned long b){ 63.181 +#if HASH_PSEUDO_DES 63.182 + unsigned long left = a; 63.183 + unsigned long right = b; 63.184 + pseudo_des(&left, &right); 63.185 + return right; 63.186 +#else 63.187 + a = lcrng_hash(a); 63.188 + a ^= b; 63.189 + a = lcrng_hash(a); 63.190 + return a; 63.191 +#endif 63.192 +} 63.193 + 63.194 +/** Hash a hashcode and an unsigned long together. 63.195 + * 63.196 + * @param a input hashcode 63.197 + * @param b input to hash 63.198 + * @return hashcode 63.199 + */ 63.200 +static inline Hashcode hash_hul(Hashcode a, unsigned long b){ 63.201 +#if HASH_PSEUDO_DES 63.202 + unsigned long left = a; 63.203 + unsigned long right = b; 63.204 + pseudo_des(&left, &right); 63.205 + return right; 63.206 +#else 63.207 + a ^= b; 63.208 + a = lcrng_hash(a); 63.209 + return a; 63.210 +#endif 63.211 +} 63.212 + 63.213 +/** Macro to declare variables for HashTable_for_each() to use. 63.214 + * 63.215 + * @param entry variable that is set to entries in the table 63.216 + */ 63.217 +#define HashTable_for_decl(entry) \ 63.218 + HashTable *_var_table; \ 63.219 + HTBucket *_var_bucket; \ 63.220 + HTBucket *_var_end; \ 63.221 + HTEntry *_var_next; \ 63.222 + HTEntry *entry 63.223 + 63.224 +/** Macro to iterate over the entries in a hashtable. 63.225 + * Must be in a scope where HashTable_for_decl() has been used to declare 63.226 + * variables for it to use. 63.227 + * The variable 'entry' is iterated over entries in the table. 63.228 + * The code produced is syntactically a loop, so it must be followed by 63.229 + * a loop body, typically some statements in braces: 63.230 + * HashTable_for_each(entry, table){ ...loop body... } 63.231 + * 63.232 + * HashTable_for_each() and HashTable_for_decl() cannot be used for nested 63.233 + * loops as variables will clash. 63.234 + * 63.235 + * @note The simplest way to code a direct loop over the entries in a hashtable 63.236 + * is to use a loop over the buckets, with a nested loop over the entries 63.237 + * in a bucket. Using this approach in a macro means the macro contains 63.238 + * an opening brace, and calls to it must be followed by 2 braces! 63.239 + * To avoid this the code has been restructured so that it is a for loop. 63.240 + * So that statements could be used in the test expression of the for loop, 63.241 + * we have used the gcc statement expression extension ({ ... }). 63.242 + * 63.243 + * @param entry variable to iterate over the entries 63.244 + * @param table to iterate over (non-null) 63.245 + */ 63.246 +#define HashTable_for_each(entry, table) \ 63.247 + _var_table = table; \ 63.248 + _var_bucket = _var_table->buckets; \ 63.249 + _var_end = _var_bucket + _var_table->buckets_n; \ 63.250 + for(entry=0, _var_next=0; \ 63.251 + ({ if(_var_next){ \ 63.252 + entry = _var_next; \ 63.253 + _var_next = entry->next; \ 63.254 + } else { \ 63.255 + while(_var_bucket < _var_end){ \ 63.256 + entry = _var_bucket->head; \ 63.257 + _var_bucket++; \ 63.258 + if(entry){ \ 63.259 + _var_next = entry->next; \ 63.260 + break; \ 63.261 + } \ 63.262 + } \ 63.263 + }; \ 63.264 + entry; }); \ 63.265 + entry = _var_next ) 63.266 + 63.267 +/** Map a function over the entries in a table. 63.268 + * Mapping stops when the function returns a non-zero value. 63.269 + * Uses the gcc statement expression extension ({ ... }). 63.270 + * 63.271 + * @param table to map over 63.272 + * @param fn function to apply to entries 63.273 + * @param arg first argument to call the function with 63.274 + * @return 0 if fn always returned 0, first non-zero value otherwise 63.275 + */ 63.276 +#define HashTable_map(table, fn, arg) \ 63.277 + ({ HashTable_for_decl(_var_entry); \ 63.278 + TableArg _var_arg = arg; \ 63.279 + int _var_value = 0; \ 63.280 + HashTable_for_each(_var_entry, table){ \ 63.281 + if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \ 63.282 + } \ 63.283 + _var_value; }) 63.284 + 63.285 +/** Cast x to the type for a key or value in a hash table. 63.286 + * This avoids compiler warnings when using short integers 63.287 + * as keys or values (especially on 64-bit platforms). 63.288 + */ 63.289 +#define HKEY(x) ((void*)(unsigned long)(x)) 63.290 + 63.291 +/** Cast x from the type for a key or value in a hash table. 63.292 + * to an unsigned long. This avoids compiler warnings when using 63.293 + * short integers as keys or values (especially on 64-bit platforms). 63.294 + */ 63.295 +#define HVAL(x) ((unsigned long)(x)) 63.296 + 63.297 +#endif /* !_XUTIL_HASH_TABLE_H_ */
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/tools/vnet/libxutil/iostream.c Tue May 24 21:17:29 2005 +0000 64.3 @@ -0,0 +1,55 @@ 64.4 +/* 64.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 64.6 + * 64.7 + * This library is free software; you can redistribute it and/or modify 64.8 + * it under the terms of the GNU Lesser General Public License as published by 64.9 + * the Free Software Foundation; either version 2.1 of the License, or 64.10 + * (at your option) any later version. 64.11 + * 64.12 + * This library is distributed in the hope that it will be useful, 64.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 64.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 64.15 + * GNU Lesser General Public License for more details. 64.16 + * 64.17 + * You should have received a copy of the GNU Lesser General Public License 64.18 + * along with this library; if not, write to the Free Software 64.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 64.20 + */ 64.21 + 64.22 +#include "iostream.h" 64.23 +#include "sys_string.h" 64.24 + 64.25 +/** Print on a stream, like vfprintf(). 64.26 + * 64.27 + * @param stream to print to 64.28 + * @param format for the print (as fprintf()) 64.29 + * @param args arguments to print 64.30 + * @return result code from the print 64.31 + */ 64.32 +int IOStream_vprint(IOStream *stream, const char *format, va_list args){ 64.33 + char buffer[1024]; 64.34 + int k = sizeof(buffer), n; 64.35 + 64.36 + n = vsnprintf(buffer, k, (char*)format, args); 64.37 + if(n < 0 || n > k ){ 64.38 + n = k; 64.39 + } 64.40 + n = IOStream_write(stream, buffer, n); 64.41 + return n; 64.42 +} 64.43 + 64.44 +/** Print on a stream, like fprintf(). 64.45 + * 64.46 + * @param stream to print to 64.47 + * @param format for the print (as fprintf()) 64.48 + * @return result code from the print 64.49 + */ 64.50 +int IOStream_print(IOStream *stream, const char *format, ...){ 64.51 + va_list args; 64.52 + int result = -1; 64.53 + 64.54 + va_start(args, format); 64.55 + result = IOStream_vprint(stream, format, args); 64.56 + va_end(args); 64.57 + return result; 64.58 +}
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/tools/vnet/libxutil/iostream.h Tue May 24 21:17:29 2005 +0000 65.3 @@ -0,0 +1,269 @@ 65.4 +/* 65.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 65.6 + * 65.7 + * This library is free software; you can redistribute it and/or modify 65.8 + * it under the terms of the GNU Lesser General Public License as published by 65.9 + * the Free Software Foundation; either version 2.1 of the License, or 65.10 + * (at your option) any later version. 65.11 + * 65.12 + * This library is distributed in the hope that it will be useful, 65.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 65.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 65.15 + * GNU Lesser General Public License for more details. 65.16 + * 65.17 + * You should have received a copy of the GNU Lesser General Public License 65.18 + * along with this library; if not, write to the Free Software 65.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 65.20 + */ 65.21 + 65.22 +#ifndef _XUTIL_IOSTREAM_H_ 65.23 +#define _XUTIL_IOSTREAM_H_ 65.24 + 65.25 +#include <stdarg.h> 65.26 + 65.27 +#ifdef __KERNEL__ 65.28 +#include <linux/config.h> 65.29 +#include <linux/types.h> 65.30 +#include <linux/errno.h> 65.31 +#else 65.32 +#include <errno.h> 65.33 +#include <stdint.h> 65.34 +#include <stddef.h> 65.35 +#endif 65.36 + 65.37 +#include "allocate.h" 65.38 + 65.39 +/** End of input return value (for getc). */ 65.40 +#define IOSTREAM_EOF -1 65.41 + 65.42 +/** An input/output abstraction. 65.43 + */ 65.44 +typedef struct IOStream IOStream; 65.45 + 65.46 +/** Record of the functions to use for operations on an 65.47 + * IOStream implementation. 65.48 + */ 65.49 +typedef struct IOMethods { 65.50 + /** Read function. Called with the user data, buffer to read into 65.51 + * and number of bytes to read. Must return number of bytes read 65.52 + * on success, less than zero on error. 65.53 + */ 65.54 + int (*read)(IOStream *stream, void *buf, size_t n); 65.55 + 65.56 + /** Write function. Called with user data, buffer to write and 65.57 + * number of bytes to write. Must return number of bytes written on 65.58 + * success, less than zero otherwise. 65.59 + */ 65.60 + int (*write)(IOStream *stream, const void *buf, size_t n); 65.61 + 65.62 + int (*flush)(IOStream *s); 65.63 + 65.64 + int (*error)(IOStream *s); 65.65 + 65.66 + int (*close)(IOStream *s); 65.67 + 65.68 + void (*free)(IOStream *s); 65.69 + 65.70 + void (*lock)(IOStream *s); 65.71 + void (*unlock)(IOStream *s); 65.72 + 65.73 +} IOMethods; 65.74 + 65.75 +/** Abstract i/o object. 65.76 + */ 65.77 +struct IOStream { 65.78 + /** Methods to use to implement operations. */ 65.79 + const IOMethods *methods; 65.80 + /** Private state for the implementation. */ 65.81 + const void *data; 65.82 + /** Flag indicating whether the stream is closed. */ 65.83 + int closed; 65.84 + /** Number of bytes written. */ 65.85 + int written; 65.86 + /** Number of bytes read. */ 65.87 + int read; 65.88 + /** Flag indicating whether not to free when closed. */ 65.89 + int nofree; 65.90 +}; 65.91 + 65.92 + 65.93 +/** IOStream version of stdin. */ 65.94 +extern IOStream *iostdin; 65.95 + 65.96 +/** IOStream version of stdout, */ 65.97 +extern IOStream *iostdout; 65.98 + 65.99 +/** IOStream version of stderr. */ 65.100 +extern IOStream *iostderr; 65.101 + 65.102 +extern int IOStream_print(IOStream *io, const char *format, ...); 65.103 +extern int IOStream_vprint(IOStream *io, const char *format, va_list args); 65.104 + 65.105 +/** Read from a stream. 65.106 + * 65.107 + * @param stream input 65.108 + * @param buf where to put input 65.109 + * @param n number of bytes to read 65.110 + * @return if ok, number of bytes read, otherwise negative error code 65.111 + */ 65.112 +static inline int IOStream_read(IOStream *stream, void *buf, size_t n){ 65.113 + int result; 65.114 + if(stream->closed){ 65.115 + result = -EIO; 65.116 + goto exit; 65.117 + } 65.118 + if(!stream->methods || !stream->methods->read){ 65.119 + result = -EINVAL; 65.120 + goto exit; 65.121 + } 65.122 + result = (stream->methods->read)(stream, buf, n); 65.123 + if(result > 0){ 65.124 + stream->read += result; 65.125 + } 65.126 + exit: 65.127 + return result; 65.128 +} 65.129 + 65.130 +/** Write to a stream. 65.131 + * 65.132 + * @param stream input 65.133 + * @param buf where to put input 65.134 + * @param n number of bytes to write 65.135 + * @return if ok, number of bytes written, otherwise negative error code 65.136 + */ 65.137 +static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){ 65.138 + int result; 65.139 + if(stream->closed){ 65.140 + result = -EIO; 65.141 + goto exit; 65.142 + } 65.143 + if(!stream->methods || !stream->methods->write){ 65.144 + result = -EINVAL; 65.145 + goto exit; 65.146 + } 65.147 + result = (stream->methods->write)(stream, buf, n); 65.148 + if(result > 0){ 65.149 + stream->written += result; 65.150 + } 65.151 + exit: 65.152 + return result; 65.153 +} 65.154 + 65.155 +/** Flush the stream. 65.156 + * 65.157 + * @param stream stream 65.158 + * @return 0 on success, negative error code otherwise 65.159 + */ 65.160 +static inline int IOStream_flush(IOStream *stream){ 65.161 + int result = 0; 65.162 + if(stream->closed){ 65.163 + result = -EIO; 65.164 + } else if(stream->methods->flush){ 65.165 + result = (stream->methods->flush)(stream); 65.166 + } 65.167 + return result; 65.168 +} 65.169 + 65.170 +/** Check whether the stream has an error. 65.171 + * 65.172 + * @param stream to check 65.173 + * @return 1 for error, 0 otherwise 65.174 + */ 65.175 +static inline int IOStream_error(IOStream *stream){ 65.176 + int err = 0; 65.177 + if(stream->methods && stream->methods->error){ 65.178 + err = (stream->methods->error)(stream); 65.179 + } 65.180 + return err; 65.181 +} 65.182 + 65.183 +/** Close the stream. 65.184 + * 65.185 + * @param stream to close 65.186 + * @return 0 on success, negative error code otherwise 65.187 + */ 65.188 +static inline int IOStream_close(IOStream *stream){ 65.189 + int err = 0; 65.190 + if(!stream || stream->closed){ 65.191 + err = -EIO; 65.192 + goto exit; 65.193 + } 65.194 + if(stream->methods && stream->methods->close){ 65.195 + err = (stream->methods->close)(stream); 65.196 + stream->closed = 1; 65.197 + } 65.198 + if(stream->nofree) goto exit; 65.199 + if(stream->methods && stream->methods->free){ 65.200 + (stream->methods->free)(stream); 65.201 + } 65.202 + *stream = (IOStream){}; 65.203 + deallocate(stream); 65.204 + exit: 65.205 + return err; 65.206 +} 65.207 + 65.208 +/** Test if the stream has been closed. 65.209 + * 65.210 + * @param stream to check 65.211 + * @return 1 if closed, 0 otherwise 65.212 + */ 65.213 +static inline int IOStream_is_closed(IOStream *stream){ 65.214 + return stream->closed; 65.215 +} 65.216 + 65.217 +/** Print a character to a stream, like fputc(). 65.218 + * 65.219 + * @param stream to print to 65.220 + * @param c character to print 65.221 + * @return result code from the print 65.222 + */ 65.223 +static inline int IOStream_putc(IOStream *stream, int c){ 65.224 + int err; 65.225 + unsigned char b = (unsigned char)c; 65.226 + err = IOStream_write(stream, &b, 1); 65.227 + if(err < 1){ 65.228 + err = IOSTREAM_EOF; 65.229 + } else { 65.230 + err = b; 65.231 + } 65.232 + return err; 65.233 +} 65.234 + 65.235 +/** Read from a stream, like fgetc(). 65.236 + * 65.237 + * @param stream to read from 65.238 + * @return IOSTREAM_EOF on error, character read otherwise 65.239 + */ 65.240 +static inline int IOStream_getc(IOStream *stream){ 65.241 + int err, rc; 65.242 + unsigned char b; 65.243 + 65.244 + err = IOStream_read(stream, &b, 1); 65.245 + if(err < 1){ 65.246 + rc = IOSTREAM_EOF; 65.247 + } else { 65.248 + rc = b; 65.249 + } 65.250 + return rc; 65.251 +} 65.252 + 65.253 +/** Get number of bytes read. 65.254 + * 65.255 + * @param stream to get from 65.256 + * @return number of bytes read 65.257 + */ 65.258 +static inline int IOStream_get_read(IOStream *stream){ 65.259 + return stream->read; 65.260 +} 65.261 + 65.262 +/** Get number of bytes written. 65.263 + * 65.264 + * @param stream to get from 65.265 + * @return number of bytes written 65.266 + */ 65.267 +static inline int IOStream_get_written(IOStream *stream){ 65.268 + return stream->written; 65.269 +} 65.270 + 65.271 + 65.272 +#endif /* ! _XUTIL_IOSTREAM_H_ */
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/tools/vnet/libxutil/kernel_stream.c Tue May 24 21:17:29 2005 +0000 66.3 @@ -0,0 +1,178 @@ 66.4 +/* 66.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 66.6 + * 66.7 + * This library is free software; you can redistribute it and/or modify 66.8 + * it under the terms of the GNU Lesser General Public License as published by 66.9 + * the Free Software Foundation; either version 2.1 of the License, or 66.10 + * (at your option) any later version. 66.11 + * 66.12 + * This library is distributed in the hope that it will be useful, 66.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 66.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 66.15 + * GNU Lesser General Public License for more details. 66.16 + * 66.17 + * You should have received a copy of the GNU Lesser General Public License 66.18 + * along with this library; if not, write to the Free Software 66.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 66.20 + */ 66.21 + 66.22 +/** @file 66.23 + * An IOStream implementation using printk() for output. 66.24 + * Input is not implemented. 66.25 + */ 66.26 +#ifdef __KERNEL__ 66.27 + 66.28 +#include <linux/config.h> 66.29 +#include <linux/module.h> 66.30 +#include <linux/kernel.h> 66.31 +#include <linux/types.h> 66.32 +#include <linux/errno.h> 66.33 +#include <linux/slab.h> 66.34 +#include <linux/spinlock.h> 66.35 + 66.36 +#include "kernel_stream.h" 66.37 +#include "allocate.h" 66.38 + 66.39 +/** Number of characters in the output buffer. 66.40 + * The kernel uses 1024 for printk, so that should suffice. 66.41 + */ 66.42 +#define BUF_N 1024 66.43 + 66.44 +/** State for a kernel stream. */ 66.45 +typedef struct KernelData { 66.46 + /** Stream lock. We need a lock to serialize access to the stream. */ 66.47 + spinlock_t lock; 66.48 + /** Saved flags for locking. */ 66.49 + unsigned long flags; 66.50 + /** Size of the output buffer. */ 66.51 + int buf_n; 66.52 + /** Output buffer. */ 66.53 + char buf[BUF_N]; 66.54 +} KernelData; 66.55 + 66.56 +static int kernel_write(IOStream *s, const void *msg, size_t n); 66.57 +static void kernel_free(IOStream *s); 66.58 +static void kernel_stream_lock(IOStream *s); 66.59 +static void kernel_stream_unlock(IOStream *s); 66.60 + 66.61 +/** Methods for a kernel stream. Output only. */ 66.62 +static const IOMethods kernel_methods = { 66.63 + write: kernel_write, 66.64 + free: kernel_free, 66.65 + lock: kernel_stream_lock, 66.66 + unlock: kernel_stream_unlock, 66.67 +}; 66.68 + 66.69 +/** Shared state for kernel streams. 66.70 + * All implementations write using printk, so we can use 66.71 + * shared state and avoid allocating it. 66.72 + */ 66.73 +static const KernelData kernel_data = { 66.74 + lock: SPIN_LOCK_UNLOCKED, 66.75 + flags: 0, 66.76 + buf_n: BUF_N, 66.77 +}; 66.78 + 66.79 +/** Stream for kernel printk. */ 66.80 +static IOStream iokernel = { 66.81 + methods: &kernel_methods, 66.82 + data: &kernel_data, 66.83 + nofree: 1, 66.84 +}; 66.85 + 66.86 +/** Stream for kernel printk. */ 66.87 +IOStream *iostdout = &iokernel; 66.88 + 66.89 +/** Stream for kernel printk. */ 66.90 +IOStream *iostdin = &iokernel; 66.91 + 66.92 +/** Stream for kernel printk. */ 66.93 +IOStream *iostderr = &iokernel; 66.94 + 66.95 +/** Get an output-only stream implementation using 66.96 + * printk(). The stream uses static storage, and must not be freed. 66.97 + * 66.98 + * @return kernel stream 66.99 + */ 66.100 +IOStream get_stream_kernel(void){ 66.101 + return iokernel; 66.102 +} 66.103 + 66.104 +/** Obtain the lock on the stream state. 66.105 + * 66.106 + * @param kdata stream state 66.107 + */ 66.108 +static inline void KernelData_lock(KernelData *kdata){ 66.109 + spin_lock_irqsave(&kdata->lock, kdata->flags); 66.110 +} 66.111 + 66.112 +/** Release the lock on the stream state. 66.113 + * 66.114 + * @param kdata stream state 66.115 + */ 66.116 +static inline void KernelData_unlock(KernelData *kdata){ 66.117 + spin_unlock_irqrestore(&kdata->lock, kdata->flags); 66.118 +} 66.119 + 66.120 +/** Get the stream state. 66.121 + * 66.122 + * @param s kernel stream 66.123 + * @return stream state 66.124 + */ 66.125 +static inline KernelData *get_kernel_data(IOStream *s){ 66.126 + return (KernelData*)s->data; 66.127 +} 66.128 + 66.129 +/** Obtain the lock on the stream state. 66.130 + * 66.131 + * @param s stream 66.132 + */ 66.133 +void kernel_stream_lock(IOStream *s){ 66.134 + KernelData_lock(get_kernel_data(s)); 66.135 +} 66.136 + 66.137 +/** Release the lock on the stream state. 66.138 + * 66.139 + * @param s stream 66.140 + */ 66.141 +void kernel_stream_unlock(IOStream *s){ 66.142 + KernelData_unlock(get_kernel_data(s)); 66.143 +} 66.144 + 66.145 +/** Write to a kernel stream. 66.146 + * 66.147 + * @param stream kernel stream 66.148 + * @param format print format 66.149 + * @param args print arguments 66.150 + * @return result of the print 66.151 + */ 66.152 +static int kernel_write(IOStream *stream, const void *buf, size_t n){ 66.153 + KernelData *kdata = get_kernel_data(stream); 66.154 + int k; 66.155 + k = kdata->buf_n - 1; 66.156 + if(n < k) k = n; 66.157 + memcpy(kdata->buf, buf, k); 66.158 + kdata->buf[k] = '\0'; 66.159 + printk(kdata->buf); 66.160 + return k; 66.161 +} 66.162 + 66.163 +/** Free a kernel stream. 66.164 + * Frees the internal state of the stream. 66.165 + * Do not call this unless the stream was dynamically allocated. 66.166 + * Do not call this on a stream returned from get_stream_kernel(). 66.167 + * 66.168 + * @param io stream to free 66.169 + */ 66.170 +static void kernel_free(IOStream *io){ 66.171 + KernelData *kdata; 66.172 + if(io == &iokernel) return; 66.173 + kdata = get_kernel_data(io); 66.174 + memset(kdata, 0, sizeof(*kdata)); 66.175 + deallocate(kdata); 66.176 +} 66.177 +#endif /* __KERNEL__ */ 66.178 + 66.179 + 66.180 + 66.181 +
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/tools/vnet/libxutil/kernel_stream.h Tue May 24 21:17:29 2005 +0000 67.3 @@ -0,0 +1,29 @@ 67.4 +/* 67.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 67.6 + * 67.7 + * This library is free software; you can redistribute it and/or modify 67.8 + * it under the terms of the GNU Lesser General Public License as published by 67.9 + * the Free Software Foundation; either version 2.1 of the License, or 67.10 + * (at your option) any later version. 67.11 + * 67.12 + * This library is distributed in the hope that it will be useful, 67.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 67.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 67.15 + * GNU Lesser General Public License for more details. 67.16 + * 67.17 + * You should have received a copy of the GNU Lesser General Public License 67.18 + * along with this library; if not, write to the Free Software 67.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 67.20 + */ 67.21 + 67.22 +#ifndef _XUTIL_KERNEL_STREAM_H_ 67.23 +#define _XUTIL_KERNEL_STREAM_H_ 67.24 + 67.25 +#ifdef __KERNEL__ 67.26 +#include "iostream.h" 67.27 + 67.28 +extern IOStream get_stream_kernel(void); 67.29 +#define get_stream_stdout get_stream_kernel 67.30 + 67.31 +#endif /* __KERNEL__ */ 67.32 +#endif /* !_XUTIL_KERNEL_STREAM_H_ */
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/tools/vnet/libxutil/lexis.c Tue May 24 21:17:29 2005 +0000 68.3 @@ -0,0 +1,94 @@ 68.4 +/* 68.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 68.6 + * 68.7 + * This library is free software; you can redistribute it and/or modify 68.8 + * it under the terms of the GNU Lesser General Public License as 68.9 + * published by the Free Software Foundation; either version 2.1 of the 68.10 + * License, or (at your option) any later version. This library is 68.11 + * distributed in the hope that it will be useful, but WITHOUT ANY 68.12 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or 68.13 + * FITNESS FOR A PARTICULAR PURPOSE. 68.14 + * See the GNU Lesser General Public License for more details. 68.15 + * 68.16 + * You should have received a copy of the GNU Lesser General Public License 68.17 + * along with this library; if not, write to the Free Software Foundation, 68.18 + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 68.19 + */ 68.20 + 68.21 +/** @file 68.22 + * Lexical analysis. 68.23 + */ 68.24 + 68.25 +#include "sys_string.h" 68.26 +#include "lexis.h" 68.27 +#include <errno.h> 68.28 + 68.29 +/** Check if a value lies in a (closed) range. 68.30 + * 68.31 + * @param x value to test 68.32 + * @param lo low end of the range 68.33 + * @param hi high end of the range 68.34 + * @return 1 if x is in the interval [lo, hi], 0 otherwise 68.35 + */ 68.36 +inline static int in_range(int x, int lo, int hi){ 68.37 + return (lo <= x) && (x <= hi); 68.38 +} 68.39 + 68.40 +/** Determine if a string is an (unsigned) decimal number. 68.41 + * 68.42 + * @param s pointer to characters to test 68.43 + * @param n length of string 68.44 + * @return 1 if s is a decimal number, 0 otherwise. 68.45 + */ 68.46 +int is_decimal_number(const char *s, int n){ 68.47 + int i; 68.48 + if(n <= 0)return 0; 68.49 + for(i = 0; i < n; i++){ 68.50 + if(!in_decimal_digit_class(s[i])) return 0; 68.51 + } 68.52 + return 1; 68.53 +} 68.54 + 68.55 +/** Determine if a string is a hex number. 68.56 + * Hex numbers are 0, or start with 0x or 0X followed 68.57 + * by a non-zero number of hex digits (0-9,a-f,A-F). 68.58 + * 68.59 + * @param s pointer to characters to test 68.60 + * @param n length of string 68.61 + * @return 1 if s is a hex number, 0 otherwise. 68.62 + */ 68.63 +int is_hex_number(const char *s, int n){ 68.64 + int i; 68.65 + if(n <= 0) return 0; 68.66 + if(n == 1){ 68.67 + return s[0]=='0'; 68.68 + } 68.69 + if(n <= 3) return 0; 68.70 + if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0; 68.71 + for(i = 2; i < n; i++){ 68.72 + if(!in_hex_digit_class(s[i])) return 0; 68.73 + } 68.74 + return 1; 68.75 +} 68.76 + 68.77 +/** Test if a string matches a keyword. 68.78 + * The comparison is case-insensitive. 68.79 + * The comparison fails if either argument is null. 68.80 + * 68.81 + * @param s string 68.82 + * @param k keyword 68.83 + * @return 1 if they match, 0 otherwise 68.84 + */ 68.85 +int is_keyword(const char *s, const char *k){ 68.86 + return s && k && !strcasecmp(s, k); 68.87 +} 68.88 + 68.89 +/** Test if a string matches a character. 68.90 + * 68.91 + * @param s string 68.92 + * @param c character (non-null) 68.93 + * @return 1 if s contains exactly c, 0 otherwise 68.94 + */ 68.95 +int is_keychar(const char *s, char c){ 68.96 + return c && (s[0] == c) && !s[1]; 68.97 +}
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/tools/vnet/libxutil/lexis.h Tue May 24 21:17:29 2005 +0000 69.3 @@ -0,0 +1,128 @@ 69.4 +/* 69.5 + * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 69.6 + * 69.7 + * This library is free software; you can redistribute it and/or modify 69.8 + * it under the terms of the GNU Lesser General Public License as 69.9 + * published by the Free Software Foundation; either version 2.1 of the 69.10 + * License, or (at your option) any later version. This library is 69.11 + * distributed in the hope that it will be useful, but WITHOUT ANY 69.12 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or 69.13 + * FITNESS FOR A PARTICULAR PURPOSE. 69.14 + * See the GNU Lesser General Public License for more details. 69.15 + * 69.16 + * You should have received a copy of the GNU Lesser General Public License 69.17 + * along with this library; if not, write to the Free Software Foundation, 69.18 + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 69.19 + */ 69.20 + 69.21 +#ifndef _XUTIL_LEXIS_H_ 69.22 +#define _XUTIL_LEXIS_H_ 69.23 + 69.24 +#include "sys_string.h" 69.25 + 69.26 +#ifdef __KERNEL__ 69.27