diff options
author | Jason Linehan <patientulysses@gmail.com> | 2012-08-30 17:39:47 -0400 |
---|---|---|
committer | Jason Linehan <patientulysses@gmail.com> | 2012-08-30 17:39:47 -0400 |
commit | e371fe077514ed27715ca8ec7854078f2520a2ee (patch) | |
tree | bd1dfebcfa3444847e4dc986d378af9f4b411a2e | |
parent | aeb8af6763aa384af3baa3c108bac2b83187cb39 (diff) | |
download | plex-dev.tar.gz plex-dev.tar.bz2 plex-dev.zip |
Little tweaksdev
-rw-r--r-- | .gitignore | 40 | ||||
-rw-r--r-- | HISTORY (renamed from src/lib/alloc.h) | 0 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | build/Makefile.am | 28 | ||||
-rw-r--r-- | build/Makefile.in (renamed from src/Makefile.in) | 236 | ||||
-rw-r--r-- | build/doc/plex.man | 54 | ||||
-rw-r--r-- | build/src/dfa.c (renamed from src/dfa.c) | 0 | ||||
-rw-r--r-- | build/src/dfa.h (renamed from src/dfa.h) | 0 | ||||
-rw-r--r-- | build/src/driver.c (renamed from src/driver.c) | 0 | ||||
-rw-r--r-- | build/src/gen.c (renamed from src/gen.c) | 4 | ||||
-rw-r--r-- | build/src/gen.h (renamed from src/gen.h) | 0 | ||||
-rw-r--r-- | build/src/input.c (renamed from src/input.c) | 0 | ||||
-rw-r--r-- | build/src/input.h (renamed from src/input.h) | 0 | ||||
-rw-r--r-- | build/src/input_driver/input.c (renamed from src/input_driver/input.c) | 0 | ||||
-rw-r--r-- | build/src/input_driver/input.h (renamed from src/input_driver/input.h) | 0 | ||||
-rw-r--r-- | build/src/lex.c (renamed from src/lex.c) | 0 | ||||
-rw-r--r-- | build/src/lex.h (renamed from src/lex.h) | 0 | ||||
-rw-r--r-- | build/src/lib/bits.h (renamed from src/lib/bits.h) | 0 | ||||
-rw-r--r-- | build/src/lib/debug.c (renamed from src/lib/debug.c) | 0 | ||||
-rw-r--r-- | build/src/lib/debug.h (renamed from src/lib/debug.h) | 0 | ||||
-rw-r--r-- | build/src/lib/file.c (renamed from src/lib/file.c) | 0 | ||||
-rw-r--r-- | build/src/lib/file.h (renamed from src/lib/file.h) | 0 | ||||
-rw-r--r-- | build/src/lib/list.h (renamed from src/lib/list.h) | 0 | ||||
-rw-r--r-- | build/src/lib/map.h (renamed from src/lib/map.h) | 0 | ||||
-rw-r--r-- | build/src/lib/set.c (renamed from src/lib/set.c) | 0 | ||||
-rw-r--r-- | build/src/lib/set.h (renamed from src/lib/set.h) | 0 | ||||
-rw-r--r-- | build/src/lib/stack.h (renamed from src/lib/stack.h) | 0 | ||||
-rw-r--r-- | build/src/lib/textutils.c (renamed from src/lib/textutils.c) | 0 | ||||
-rw-r--r-- | build/src/lib/textutils.h (renamed from src/lib/textutils.h) | 0 | ||||
-rw-r--r-- | build/src/lib/util.h (renamed from src/lib/util.h) | 0 | ||||
-rw-r--r-- | build/src/macro.c (renamed from src/macro.c) | 0 | ||||
-rw-r--r-- | build/src/macro.h (renamed from src/macro.h) | 0 | ||||
-rw-r--r-- | build/src/main.c (renamed from src/main.c) | 16 | ||||
-rw-r--r-- | build/src/main.h (renamed from src/main.h) | 0 | ||||
-rw-r--r-- | build/src/nfa.c (renamed from src/nfa.c) | 0 | ||||
-rw-r--r-- | build/src/nfa.h (renamed from src/nfa.h) | 0 | ||||
-rwxr-xr-x | build/src/plex | bin | 0 -> 211218 bytes | |||
-rw-r--r-- | build/src/scan.c (renamed from src/scan.c) | 0 | ||||
-rw-r--r-- | build/src/scan.h (renamed from src/scan.h) | 0 | ||||
-rw-r--r-- | build/src/test.lex | 6 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rwxr-xr-x | install | 15 | ||||
-rw-r--r-- | libinput.a | bin | 0 -> 10948 bytes | |||
-rw-r--r-- | main.c | 99 | ||||
-rw-r--r-- | src/Makefile.am | 26 | ||||
-rw-r--r-- | src/lib/alloc.c | 1843 | ||||
-rw-r--r-- | src/lib/mystack.h | 37 | ||||
-rw-r--r-- | src/lib/old_set.c | 503 | ||||
-rw-r--r-- | src/lib/old_set.h | 130 | ||||
-rw-r--r-- | src/lib/redblack.c | 486 | ||||
-rw-r--r-- | src/lib/redblack.h | 37 |
51 files changed, 331 insertions, 3235 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..daee6a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Junk left behind by... +# autotools + *.log + *.cache + *.m4 + *.o + */*/*.o + depcomp + install-sh + missing + configure + config.status + +# gprof + build/*.out + build/src/*/*.out + +# objdump + *.s + +# vim + *.swp + .*.sw* + */*/.*.sw* # ffs + +# Big files that shouldn't be accidentally committed + *.pdf + *.djvu + *.jpg + *.jpeg + *.Jpg + *.Jpeg + *.JPG + *.JPEG + *.gif + *.Gif + *.GIF + *.png + *.Png + *.PNG diff --git a/src/lib/alloc.h b/HISTORY index e69de29..e69de29 100644 --- a/src/lib/alloc.h +++ b/HISTORY diff --git a/Makefile.am b/Makefile.am index 948a117..57b95b0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS = src +SUBDIRS = build diff --git a/build/Makefile.am b/build/Makefile.am new file mode 100644 index 0000000..d5dfdf4 --- /dev/null +++ b/build/Makefile.am @@ -0,0 +1,28 @@ +AUTOMAKE_OPTIONS = foreign subdir-objects +# | \ +# non-GNU compile objects in the +# indicated relative paths +# optimize warnings debug info +# lvl 3 \ / / +CFLAGS=-O3 -Wall -g -DVERSION=\"$(VERSION)\" -DPROG="\"$(PACKAGE)\"" +# +# +# + +man1_MANS = doc/plex.man + +bin_PROGRAMS = plex + +plex_SOURCES = src/main.c \ + src/lib/file.c \ + src/lib/set.c \ + src/lib/textutils.c \ + src/lib/debug.c \ + src/input.c \ + src/scan.c \ + src/lex.c \ + src/macro.c \ + src/nfa.c \ + src/dfa.c \ + src/gen.c + diff --git a/src/Makefile.in b/build/Makefile.in index ee1b4e2..a7f7939 100644 --- a/src/Makefile.in +++ b/build/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.12.1 from Makefile.am. +# Makefile.in generated by automake 1.12.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. @@ -49,7 +49,7 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = plex$(EXEEXT) -subdir = src +subdir = build DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -59,13 +59,14 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp -am_plex_OBJECTS = main.$(OBJEXT) lib/file.$(OBJEXT) lib/set.$(OBJEXT) \ - lib/textutils.$(OBJEXT) lib/debug.$(OBJEXT) input.$(OBJEXT) \ - scan.$(OBJEXT) lex.$(OBJEXT) macro.$(OBJEXT) nfa.$(OBJEXT) \ - dfa.$(OBJEXT) gen.$(OBJEXT) +am_plex_OBJECTS = src/main.$(OBJEXT) src/lib/file.$(OBJEXT) \ + src/lib/set.$(OBJEXT) src/lib/textutils.$(OBJEXT) \ + src/lib/debug.$(OBJEXT) src/input.$(OBJEXT) src/scan.$(OBJEXT) \ + src/lex.$(OBJEXT) src/macro.$(OBJEXT) src/nfa.$(OBJEXT) \ + src/dfa.$(OBJEXT) src/gen.$(OBJEXT) plex_OBJECTS = $(am_plex_OBJECTS) plex_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ @@ -83,6 +84,36 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man1_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -163,6 +194,7 @@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ +mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -177,18 +209,22 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign subdir-objects -plex_SOURCES = main.c \ - lib/file.c \ - lib/set.c \ - lib/textutils.c \ - lib/debug.c \ - input.c \ - scan.c \ - lex.c \ - macro.c \ - nfa.c \ - dfa.c \ - gen.c +# +# +# +man1_MANS = doc/plex.man +plex_SOURCES = src/main.c \ + src/lib/file.c \ + src/lib/set.c \ + src/lib/textutils.c \ + src/lib/debug.c \ + src/input.c \ + src/scan.c \ + src/lex.c \ + src/macro.c \ + src/nfa.c \ + src/dfa.c \ + src/gen.c all: all-am @@ -203,9 +239,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/Makefile + $(AUTOMAKE) --foreign build/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -264,43 +300,58 @@ uninstall-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -lib/$(am__dirstamp): - @$(MKDIR_P) lib - @: > lib/$(am__dirstamp) -lib/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) lib/$(DEPDIR) - @: > lib/$(DEPDIR)/$(am__dirstamp) -lib/file.$(OBJEXT): lib/$(am__dirstamp) lib/$(DEPDIR)/$(am__dirstamp) -lib/set.$(OBJEXT): lib/$(am__dirstamp) lib/$(DEPDIR)/$(am__dirstamp) -lib/textutils.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) -lib/debug.$(OBJEXT): lib/$(am__dirstamp) lib/$(DEPDIR)/$(am__dirstamp) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/main.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/lib/$(am__dirstamp): + @$(MKDIR_P) src/lib + @: > src/lib/$(am__dirstamp) +src/lib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/lib/$(DEPDIR) + @: > src/lib/$(DEPDIR)/$(am__dirstamp) +src/lib/file.$(OBJEXT): src/lib/$(am__dirstamp) \ + src/lib/$(DEPDIR)/$(am__dirstamp) +src/lib/set.$(OBJEXT): src/lib/$(am__dirstamp) \ + src/lib/$(DEPDIR)/$(am__dirstamp) +src/lib/textutils.$(OBJEXT): src/lib/$(am__dirstamp) \ + src/lib/$(DEPDIR)/$(am__dirstamp) +src/lib/debug.$(OBJEXT): src/lib/$(am__dirstamp) \ + src/lib/$(DEPDIR)/$(am__dirstamp) +src/input.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/scan.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/lex.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/macro.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/nfa.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/dfa.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gen.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) plex$(EXEEXT): $(plex_OBJECTS) $(plex_DEPENDENCIES) $(EXTRA_plex_DEPENDENCIES) @rm -f plex$(EXEEXT) $(LINK) $(plex_OBJECTS) $(plex_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f lib/debug.$(OBJEXT) - -rm -f lib/file.$(OBJEXT) - -rm -f lib/set.$(OBJEXT) - -rm -f lib/textutils.$(OBJEXT) + -rm -f src/*.$(OBJEXT) + -rm -f src/lib/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/macro.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/debug.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/file.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/set.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/textutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dfa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/lex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/macro.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/nfa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/scan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/lib/$(DEPDIR)/debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/lib/$(DEPDIR)/file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/lib/$(DEPDIR)/set.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/lib/$(DEPDIR)/textutils.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -317,6 +368,47 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-man1: $(man1_MANS) + @$(NORMAL_INSTALL) + @list1='$(man1_MANS)'; \ + list2=''; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -385,6 +477,19 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically 'make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -416,9 +521,9 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) +all-am: Makefile $(PROGRAMS) $(MANS) installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -447,8 +552,10 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f lib/$(DEPDIR)/$(am__dirstamp) - -rm -f lib/$(am__dirstamp) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -rm -f src/lib/$(DEPDIR)/$(am__dirstamp) + -rm -f src/lib/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -458,7 +565,7 @@ clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) lib/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/lib/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -475,7 +582,7 @@ info: info-am info-am: -install-data-am: +install-data-am: install-man install-dvi: install-dvi-am @@ -491,7 +598,7 @@ install-info: install-info-am install-info-am: -install-man: +install-man: install-man1 install-pdf: install-pdf-am @@ -504,7 +611,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) lib/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/lib/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -520,7 +627,9 @@ ps: ps-am ps-am: -uninstall-am: uninstall-binPROGRAMS +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 .MAKE: install-am install-strip @@ -530,12 +639,13 @@ uninstall-am: uninstall-binPROGRAMS html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/build/doc/plex.man b/build/doc/plex.man new file mode 100644 index 0000000..988cc33 --- /dev/null +++ b/build/doc/plex.man @@ -0,0 +1,54 @@ +.TH PLEX 1 "AUGUST 2012" Linux "User Manuals" +.SH NAME +plex \- lexer analyzer generator +.SH SYNOPSIS +.B plex < +.I +grammar_file +> [ +.B +\-i +.I +input_file +] [ +.B +\-o +.I +compiled_output +] [ +.B +\-s +.I +source_output +] [ +.B +\-d +.I +driver_file +] +.I +.SH DESCRIPTION +Works like lex, only not as well. +.SH OPTIONS +.TP 10 +.B -i +Specify an input grammar file. +.TP +.B -o +Specify the filename of the compiled output (your lexer). +.TP +.B -s +Specify the filename of the uncompiled lexer output. +.TP +.B -d +Specify a custom driver file. +.TP +.SH FILES +.I /usr/share/plex/driver_default.conf +.RE +.SH BUGS +Hm? +.SH AUTHOR +Jason Linehan <jason at linehan dot me> +.SH "SEE ALSO" +.BR lex(1), diff --git a/src/dfa.c b/build/src/dfa.c index d303719..d303719 100644 --- a/src/dfa.c +++ b/build/src/dfa.c diff --git a/src/dfa.h b/build/src/dfa.h index 8d31d63..8d31d63 100644 --- a/src/dfa.h +++ b/build/src/dfa.h diff --git a/src/driver.c b/build/src/driver.c index 13380c8..13380c8 100644 --- a/src/driver.c +++ b/build/src/driver.c diff --git a/src/gen.c b/build/src/gen.c index 62d34ab..1195388 100644 --- a/src/gen.c +++ b/build/src/gen.c @@ -12,9 +12,11 @@ * */ +#define DEFAULT_DRIVER "/usr/share/plex/driver_default.c" enum driver_mode { DRIVER_HEADER, DRIVER_TOP, DRIVER_BOTTOM }; + /** * driver * `````` @@ -34,7 +36,7 @@ void driver(FILE *output, enum driver_mode mode) char line[4096]; if (!input) { - input = fopen("/home/linehan/src/mine/plex/src/driver.c", "r"); + input = fopen(DEFAULT_DRIVER, "r"); } while ((fgets(line, 4096, input))) { diff --git a/src/gen.h b/build/src/gen.h index 305456d..305456d 100644 --- a/src/gen.h +++ b/build/src/gen.h diff --git a/src/input.c b/build/src/input.c index 0c1eaf4..0c1eaf4 100644 --- a/src/input.c +++ b/build/src/input.c diff --git a/src/input.h b/build/src/input.h index 1184eec..1184eec 100644 --- a/src/input.h +++ b/build/src/input.h diff --git a/src/input_driver/input.c b/build/src/input_driver/input.c index ee9e67a..ee9e67a 100644 --- a/src/input_driver/input.c +++ b/build/src/input_driver/input.c diff --git a/src/input_driver/input.h b/build/src/input_driver/input.h index 1184eec..1184eec 100644 --- a/src/input_driver/input.h +++ b/build/src/input_driver/input.h diff --git a/src/lex.c b/build/src/lex.c index 39c1470..39c1470 100644 --- a/src/lex.c +++ b/build/src/lex.c diff --git a/src/lex.h b/build/src/lex.h index 2a19601..2a19601 100644 --- a/src/lex.h +++ b/build/src/lex.h diff --git a/src/lib/bits.h b/build/src/lib/bits.h index ec3d8f2..ec3d8f2 100644 --- a/src/lib/bits.h +++ b/build/src/lib/bits.h diff --git a/src/lib/debug.c b/build/src/lib/debug.c index eac6640..eac6640 100644 --- a/src/lib/debug.c +++ b/build/src/lib/debug.c diff --git a/src/lib/debug.h b/build/src/lib/debug.h index 01a82d0..01a82d0 100644 --- a/src/lib/debug.h +++ b/build/src/lib/debug.h diff --git a/src/lib/file.c b/build/src/lib/file.c index 8c551df..8c551df 100644 --- a/src/lib/file.c +++ b/build/src/lib/file.c diff --git a/src/lib/file.h b/build/src/lib/file.h index 3f70d80..3f70d80 100644 --- a/src/lib/file.h +++ b/build/src/lib/file.h diff --git a/src/lib/list.h b/build/src/lib/list.h index 6a8aaa2..6a8aaa2 100644 --- a/src/lib/list.h +++ b/build/src/lib/list.h diff --git a/src/lib/map.h b/build/src/lib/map.h index 18cfc13..18cfc13 100644 --- a/src/lib/map.h +++ b/build/src/lib/map.h diff --git a/src/lib/set.c b/build/src/lib/set.c index 0a72c32..0a72c32 100644 --- a/src/lib/set.c +++ b/build/src/lib/set.c diff --git a/src/lib/set.h b/build/src/lib/set.h index 28cea29..28cea29 100644 --- a/src/lib/set.h +++ b/build/src/lib/set.h diff --git a/src/lib/stack.h b/build/src/lib/stack.h index 14967be..14967be 100644 --- a/src/lib/stack.h +++ b/build/src/lib/stack.h diff --git a/src/lib/textutils.c b/build/src/lib/textutils.c index 27bc781..27bc781 100644 --- a/src/lib/textutils.c +++ b/build/src/lib/textutils.c diff --git a/src/lib/textutils.h b/build/src/lib/textutils.h index 2791c27..2791c27 100644 --- a/src/lib/textutils.h +++ b/build/src/lib/textutils.h diff --git a/src/lib/util.h b/build/src/lib/util.h index ded250a..ded250a 100644 --- a/src/lib/util.h +++ b/build/src/lib/util.h diff --git a/src/macro.c b/build/src/macro.c index 0a01922..0a01922 100644 --- a/src/macro.c +++ b/build/src/macro.c diff --git a/src/macro.h b/build/src/macro.h index 6529e56..6529e56 100644 --- a/src/macro.h +++ b/build/src/macro.h diff --git a/src/main.c b/build/src/main.c index f48e355..7d198c1 100644 --- a/src/main.c +++ b/build/src/main.c @@ -15,11 +15,11 @@ /** - * flex + * plex * ```` - * Lex the input file. + * Do it. */ -void flex(struct pgen_t *pgen) +void plex(struct pgen_t *pgen) { struct dfa_t *dfa; struct accept_t *accept; @@ -53,7 +53,7 @@ void do_pgen(FILE *input, FILE *output) pgen->in = input; pgen->out = output; - flex(pgen); + plex(pgen); } @@ -63,7 +63,7 @@ void do_pgen(FILE *input, FILE *output) */ int main(int argc, char *argv[]) { - FILE *input_file = NULL; + FILE *input_file = NULL; FILE *output_file = NULL; char buf[1024]; int c; @@ -85,11 +85,13 @@ int main(int argc, char *argv[]) } } - if (!input_file) + if (!input_file) { halt(SIGABRT, "Not a valid input file.\n"); + } - if (!output_file) + if (!output_file) { output_file = stdout; + } do_pgen(input_file, output_file); diff --git a/src/main.h b/build/src/main.h index a0d91b4..a0d91b4 100644 --- a/src/main.h +++ b/build/src/main.h diff --git a/src/nfa.c b/build/src/nfa.c index b8c3606..b8c3606 100644 --- a/src/nfa.c +++ b/build/src/nfa.c diff --git a/src/nfa.h b/build/src/nfa.h index 03832d2..03832d2 100644 --- a/src/nfa.h +++ b/build/src/nfa.h diff --git a/build/src/plex b/build/src/plex Binary files differnew file mode 100755 index 0000000..faff3eb --- /dev/null +++ b/build/src/plex diff --git a/src/scan.c b/build/src/scan.c index ff3e8b1..ff3e8b1 100644 --- a/src/scan.c +++ b/build/src/scan.c diff --git a/src/scan.h b/build/src/scan.h index 05b74b5..05b74b5 100644 --- a/src/scan.h +++ b/build/src/scan.h diff --git a/build/src/test.lex b/build/src/test.lex new file mode 100644 index 0000000..c618257 --- /dev/null +++ b/build/src/test.lex @@ -0,0 +1,6 @@ +%% +@ printf("MV "); +\{ printf("SET_BEG "); +\} printf("SET_END "); +% printf("FMT "); +%% diff --git a/configure.ac b/configure.ac index 07bbc0d..99b8916 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.68]) AC_INIT([PLEX], [0.0.1], [jason@linehan.me]) -AC_CONFIG_SRCDIR([src]) +AC_CONFIG_SRCDIR([build]) AM_INIT_AUTOMAKE([PLEX], [0.0.1]) # Checks for programs. @@ -22,4 +22,4 @@ AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_MALLOC AC_CHECK_FUNCS([setlocale]) -AC_OUTPUT([Makefile src/Makefile]) +AC_OUTPUT([Makefile build/Makefile]) @@ -0,0 +1,15 @@ +#!/bin/sh + +PROGRAM_NAME=plex +BUILD_SUBDIR=src +SHARED_FILES=/usr/share/$PROGRAM_NAME +INSTALL_PATH=/usr/bin + +[ ! -d $SHARED_FILES ] && mkdir $SHARED_FILES + +[ ! -f $BUILD_SUBDIR/$PROGRAM_NAME] && echo "You need to run make first." + +install $BUILD_SUBDIR/driver.c $SHARED_FILES/driver_default.c +install $BUILD_SUBDIR/$PROGRAM_NAME $INSTALL_PATH + +echo "All done" diff --git a/libinput.a b/libinput.a Binary files differnew file mode 100644 index 0000000..60b4352 --- /dev/null +++ b/libinput.a @@ -1,99 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <stdarg.h> -#include <unistd.h> -#include <stdbool.h> - -#include "lib/debug.h" -#include "lib/textutils.h" -#include "lib/file.h" -#include "scan.h" -#include "nfa.h" -#include "dfa.h" -#include "gen.h" - - -/** - * flex - * ```` - * Lex the input file. - */ -void flex(struct pgen_t *pgen) -{ - struct dfa_t *dfa; - struct accept_t *accept; - - /* Print the input file header */ - scan_head(pgen); - - /* Construct the DFA */ - dfa = do_build(pgen, &accept); - - print_driver(pgen, dfa, accept); - - scan_tail(pgen); -} - - -/** - * pgen - * ```` - * Create the parser generator object and begin execution. - * - * @input : input file. - * @output: output file. - */ -void do_pgen(FILE *input, FILE *output) -{ - struct pgen_t *pgen; - - pgen = calloc(1, sizeof(struct pgen_t)); - - pgen->in = input; - pgen->out = output; - - flex(pgen); -} - - - -/** - * This is the actual main function. - */ -int main(int argc, char *argv[]) -{ - FILE *input_file = NULL; - FILE *output_file = NULL; - char buf[1024]; - int c; - - while ((c = getopt(argc, argv, "m:i:o:")) != -1) { - switch (c) { - case 'm': - sprintf(buf, "gcc -static %s -L. -linput -o y.out", optarg); - system(buf); - return 0; - case 'i': - input_file = sfopen(optarg, "r"); - break; - case 'o': - output_file = sfopen(optarg, "w"); - break; - default: - break; - } - } - - if (!input_file) - halt(SIGABRT, "Missing input (-i <INPUT>)\n"); - - if (!output_file) - output_file = stdout; - - do_pgen(input_file, output_file); - - return 0; -} - - diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 3f36082..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -AUTOMAKE_OPTIONS = foreign subdir-objects -# | \ -# non-GNU compile objects in the -# indicated relative paths -# optimize warnings debug info -# lvl 3 \ / / -CFLAGS=-O3 -Wall -g -DVERSION=\"$(VERSION)\" -DPROG="\"$(PACKAGE)\"" -# -# -# - -bin_PROGRAMS = plex - -plex_SOURCES = main.c \ - lib/file.c \ - lib/set.c \ - lib/textutils.c \ - lib/debug.c \ - input.c \ - scan.c \ - lex.c \ - macro.c \ - nfa.c \ - dfa.c \ - gen.c - diff --git a/src/lib/alloc.c b/src/lib/alloc.c deleted file mode 100644 index c37c889..0000000 --- a/src/lib/alloc.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* - Samba Unix SMB/CIFS implementation. - - Samba trivial allocation library - new interface - - NOTE: Please read talloc_guide.txt for full documentation - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - inspired by http://swapped.cc/halloc/ -*/ - -#include "talloc.h" -#include <string.h> -#include <stdint.h> -#include <errno.h> -#include <sys/types.h> -#include <unistd.h> - -/* - * use this to force every realloc to change the pointer, to stress test - * code that might not cope - */ -#define ALWAYS_REALLOC 0 - - -#define MAX_TALLOC_SIZE 0x7FFFFFFF -#define TALLOC_MAGIC 0xe814ec70 -#define TALLOC_FLAG_FREE 0x01 -#define TALLOC_FLAG_LOOP 0x02 -#define TALLOC_FLAG_EXT_ALLOC 0x04 -#define TALLOC_MAGIC_REFERENCE ((const char *)1) - - -/* - * by default we abort when given a bad pointer - * (such as when talloc_free() is called on a pointer - * that came from malloc() - */ -#ifndef TALLOC_ABORT -#define TALLOC_ABORT(reason) abort() -#endif - - -#ifndef discard_const_p -#if defined(INTPTR_MIN) -# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) -#else -# define discard_const_p(type, ptr) ((type *)(ptr)) -#endif -#endif - - -/* these macros gain us a few percent of speed on gcc */ -#if HAVE_BUILTIN_EXPECT -/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 - as its first argument */ -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#else -#define likely(x) x -#define unlikely(x) x -#endif - -/* this null_context is only used if talloc_enable_leak_report() or - talloc_enable_leak_report_full() is called, otherwise it remains - NULL -*/ -static void *null_context; -static pid_t *autofree_context; - -static void *(*tc_malloc)(size_t size) = malloc; -static void (*tc_free)(void *ptr) = free; -static void *(*tc_realloc)(void *ptr, size_t size) = realloc; - -static void *(*tc_external_realloc)(const void *parent, void *ptr, size_t size); -static void (*tc_lock)(const void *ctx); -static void (*tc_unlock)(void); - -struct talloc_reference_handle { - struct talloc_reference_handle *next, *prev; - void *ptr; -}; - -typedef int (*talloc_destructor_t)(void *); - -struct talloc_chunk { - struct talloc_chunk *next, *prev; - struct talloc_chunk *parent, *child; - struct talloc_reference_handle *refs; - talloc_destructor_t destructor; - const char *name; - size_t size; - unsigned flags; -}; - -/* 16 byte alignment seems to keep everyone happy */ -#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) -#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) - -/** - * talloc_chunk_from_ptr - * ````````````````````` - * NOTE - * Panic if we get a bad magic value - */ -static inline -struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) -{ - struct talloc_chunk *tc; - const char *pp; - - pp = (const char *)ptr; - tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - - if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { - if (tc->flags & TALLOC_FLAG_FREE) { - TALLOC_ABORT("Bad talloc magic value - double free"); - } else { - TALLOC_ABORT("Bad talloc magic value - unknown value"); - } - } - return tc; -} - - -/* hook into the front of the list */ -#define _TLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - } \ -} while (0) - - -/* remove an element from a list - element doesn't have to be in list. */ -#define _TLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ -} while (0) - - -static int locked; -static inline void lock(const void *p) -{ - if (tc_lock && p) { - struct talloc_chunk *tc = talloc_chunk_from_ptr(p); - - if (tc->flags & TALLOC_FLAG_EXT_ALLOC) { - if (locked) - TALLOC_ABORT("nested locking"); - tc_lock(tc); - locked = 1; - } - } -} - - -static inline void unlock(void) -{ - if (locked) { - tc_unlock(); - locked = 0; - } -} - - -/** - * talloc_parent_chunk - * ``````````````````` - * Return the parent chunk of a pointer. - */ -static inline -struct talloc_chunk *talloc_parent_chunk(const void *ptr) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return NULL; - } - - tc = talloc_chunk_from_ptr(ptr); - - while (tc->prev) tc=tc->prev; - - return tc->parent; -} - - -/** - * talloc_parent_nolock - * ```````````````````` - * NOTE - * This version doesn't do locking, so you must already have it. - */ -static void *talloc_parent_nolock(const void *ptr) -{ - struct talloc_chunk *tc; - - tc = talloc_parent_chunk(ptr); - return tc ? TC_PTR_FROM_CHUNK(tc) : NULL; -} - -/** - * talloc_parent - * ````````````` - * Get the parent - */ -void *talloc_parent(const void *ptr) -{ - void *parent; - - lock(ptr); - parent = talloc_parent_nolock(ptr); - unlock(); - return parent; -} - - -/** - * talloc_parent_name - * `````````````````` - * Find parents name. - */ -const char *talloc_parent_name(const void *ptr) -{ - struct talloc_chunk *tc; - - lock(ptr); - tc = talloc_parent_chunk(ptr); - unlock(); - - return tc? tc->name : NULL; -} - -/** - * init_talloc - * ``````````` - * Start it up. - */ -static void *init_talloc(struct talloc_chunk *parent, - struct talloc_chunk *tc, - size_t size, int external) -{ - if (unlikely(tc == NULL)) - return NULL; - - tc->size = size; - tc->flags = TALLOC_MAGIC; - - if (external) - tc->flags |= TALLOC_FLAG_EXT_ALLOC; - - tc->destructor = NULL; - tc->child = NULL; - tc->name = NULL; - tc->refs = NULL; - - if (likely(parent)) { - if (parent->child) { - parent->child->parent = NULL; - tc->next = parent->child; - tc->next->prev = tc; - } else { - tc->next = NULL; - } - tc->parent = parent; - tc->prev = NULL; - parent->child = tc; - } else { - tc->next = tc->prev = tc->parent = NULL; - } - - return TC_PTR_FROM_CHUNK(tc); -} - - -/** - * __talloc - * ```````` - * Allocate a bit of memory as a child of an existing pointer. - */ -static inline void *__talloc(const void *context, size_t size) -{ - struct talloc_chunk *tc; - struct talloc_chunk *parent = NULL; - int external = 0; - - if (unlikely(context == NULL)) { - context = null_context; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - if (likely(context)) { - parent = talloc_chunk_from_ptr(context); - if (unlikely(parent->flags & TALLOC_FLAG_EXT_ALLOC)) { - tc = tc_external_realloc(context, NULL, - TC_HDR_SIZE+size); - external = 1; - goto alloc_done; - } - } - - tc = (struct talloc_chunk *)tc_malloc(TC_HDR_SIZE+size); - - alloc_done: - return init_talloc(parent, tc, size, external); -} - -/** - * _talloc_set_destructor - * `````````````````````` - * Set up a destructor to be called on free of a pointer - * the destructor should return 0 on success, or -1 on failure. - * - * If the destructor fails, then the free is failed, and the memory - * can continue to be used. - */ -void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) -{ - struct talloc_chunk *tc; - - tc = talloc_chunk_from_ptr(ptr); - tc->destructor = destructor; -} - - -/** - * talloc_increase_ref_count - * ````````````````````````` - * Increase the reference count on a piece of memory. - */ -int talloc_increase_ref_count(const void *ptr) -{ - return (unlikely(!talloc_reference(null_context, ptr))) ? -1 : 0; -} - - -/** - * talloc_reference_destructor - * ``````````````````````````` - * Helper for talloc_reference(). - * - * CAVEAT - * This is referenced by a function pointer and should not be inlined. - */ -static int talloc_reference_destructor(struct talloc_reference_handle *handle) -{ - struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); - _TLIST_REMOVE(ptr_tc->refs, handle); - return 0; -} - - -/** - * _talloc_set_name_const - * `````````````````````` - * More efficient way to add a name to a pointer. The name must point to a - * true string constant - */ -static inline void _talloc_set_name_const(const void *ptr, const char *name) -{ - struct talloc_chunk *tc; - - tc = talloc_chunk_from_ptr(ptr); - tc->name = name; -} - - -/** - * _talloc_named_const - * ``````````````````` - * Internal (inline) version of talloc_named_const - */ -static inline void *_talloc_named_const(const void *context, size_t size, const char *name) -{ - void *ptr; - - ptr = __talloc(context, size); - - if (unlikely(ptr == NULL)) { - return NULL; - } - - _talloc_set_name_const(ptr, name); - - return ptr; -} - - -/** - * _talloc_reference - * ````````````````` - * Make a secondary reference to a pointer, hanging off the given context. - * The pointer remains valid until both the original caller and this given - * context are freed. - * - * The major use for this is when two different structures need to - * reference the same underlying data, and you want to be able to free - * the two instances separately, and in any order. - */ -void *_talloc_reference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc; - struct talloc_reference_handle *handle; - - if (unlikely(ptr == NULL)) - return NULL; - - lock(context); - - tc = talloc_chunk_from_ptr(ptr); - handle = (struct talloc_reference_handle *)_talloc_named_const(context, - sizeof(struct talloc_reference_handle), - TALLOC_MAGIC_REFERENCE); - if (unlikely(handle == NULL)) { - unlock(); - return NULL; - } - - /* - * NOTE - * We hang the destructor off the handle, not the main - * context, as this allows the caller to still set up - * their own destructor on the context if they wish. - */ - talloc_set_destructor(handle, talloc_reference_destructor); - handle->ptr = discard_const_p(void, ptr); - _TLIST_ADD(tc->refs, handle); - - unlock(); - - return handle->ptr; -} - - -/** - * _talloc_is_parent - * ````````````````` - * Return 1 if ptr is a parent of context. - */ -static int _talloc_is_parent(const void *context, const void *ptr) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(context); - - while (tc) { - if (TC_PTR_FROM_CHUNK(tc) == ptr) { - return 1; - } - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - return 0; -} - - -/** - * __talloc_steal - * `````````````` - * Move a lump of memory from one talloc context to another. - * - * Return the ptr on success, or NULL if the memory could not be transferred. - * Passing NULL as ptr will always return NULL, with no side effects. - */ -static void *__talloc_steal(const void *new_ctx, const void *ptr) -{ - struct talloc_chunk *tc; - struct talloc_chunk *new_tc; - - if (unlikely(!ptr)) { - return NULL; - } - - if (unlikely(new_ctx == NULL)) { - new_ctx = null_context; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(new_ctx == NULL)) { - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = tc->next = tc->prev = NULL; - return discard_const_p(void, ptr); - } - - new_tc = talloc_chunk_from_ptr(new_ctx); - - if (unlikely(tc == new_tc || tc->parent == new_tc)) { - return discard_const_p(void, ptr); - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = new_tc; - - if (new_tc->child) - new_tc->child->parent = NULL; - - _TLIST_ADD(new_tc->child, tc); - - return discard_const_p(void, ptr); -} - - -/** - * _talloc_free - * ```````````` - * Internal talloc_free call. - */ -static inline int _talloc_free(const void *ptr) -{ - struct talloc_chunk *tc; - void *oldparent = NULL; - - if (unlikely(ptr == NULL)) { - return -1; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(tc->refs)) { - int is_child; - /* - * Check this is a reference from a child or grantchild - * back to it's parent or grantparent - * - * in that case we need to remove the reference and - * call another instance of talloc_free() on the current - * pointer. - */ - is_child = _talloc_is_parent(tc->refs, ptr); - _talloc_free(tc->refs); - if (is_child) { - return _talloc_free(ptr); - } - return -1; - } - - if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { - /* we have a free loop - stop looping */ - return 0; - } - - if (unlikely(tc->destructor)) { - talloc_destructor_t d = tc->destructor; - if (d == (talloc_destructor_t)-1) { - return -1; - } - tc->destructor = (talloc_destructor_t)-1; - if (d(discard_const_p(void, ptr)) == -1) { - tc->destructor = d; - return -1; - } - tc->destructor = NULL; - } - - if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) - oldparent = talloc_parent_nolock(ptr); - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - while (tc->child) { - /* we need to work out who will own an abandoned child - if it cannot be freed. In priority order, the first - choice is owner of any remaining reference to this - pointer, the second choice is our parent, and the - final choice is the null context. */ - void *child = TC_PTR_FROM_CHUNK(tc->child); - const void *new_parent = null_context; - struct talloc_chunk *old_parent = NULL; - if (unlikely(tc->child->refs)) { - struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - /* finding the parent here is potentially quite - expensive, but the alternative, which is to change - talloc to always have a valid tc->parent pointer, - makes realloc more expensive where there are a - large number of children. - - The reason we need the parent pointer here is that - if _talloc_free_internal() fails due to references - or a failing destructor we need to re-parent, but - the free call can invalidate the prev pointer. - */ - if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) { - old_parent = talloc_parent_chunk(ptr); - } - if (unlikely(_talloc_free(child) == -1)) { - if (new_parent == null_context) { - struct talloc_chunk *p = old_parent; - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - __talloc_steal(new_parent, child); - } - } - - tc->flags |= TALLOC_FLAG_FREE; - - if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) - tc_external_realloc(oldparent, tc, 0); - else - tc_free(tc); - - return 0; -} - - -/** - * _talloc_steal - * ````````````` - */ -void *_talloc_steal(const void *new_ctx, const void *ptr) -{ - void *p; - - lock(new_ctx); - p = __talloc_steal(new_ctx, ptr); - unlock(); - - return p; -} - - -/** - * talloc_unreference - * `````````````````` - * Remove a secondary reference to a pointer. This undoes - * what talloc_reference() has done. - * - * The context and pointer arguments must match those given - * to a talloc_reference() - */ -static inline -int talloc_unreference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - - if (unlikely(context == NULL)) { - context = null_context; - } - - for (h=tc->refs;h;h=h->next) { - struct talloc_chunk *p = talloc_parent_chunk(h); - if (p == NULL) { - if (context == NULL) break; - } else if (TC_PTR_FROM_CHUNK(p) == context) { - break; - } - } - if (h == NULL) { - return -1; - } - - return _talloc_free(h); -} - - -/** - * talloc_unlink - * ````````````` - * Remove a specific parent context from a pointer. - * This is a more controlled variant of talloc_free(). - */ -int talloc_unlink(const void *context, void *ptr) -{ - struct talloc_chunk *tc_p, *new_p; - void *new_parent; - - if (ptr == NULL) { - return -1; - } - - if (context == NULL) { - context = null_context; - } - - lock(context); - if (talloc_unreference(context, ptr) == 0) { - unlock(); - return 0; - } - - if (context == NULL) { - if (talloc_parent_chunk(ptr) != NULL) { - unlock(); - return -1; - } - } else { - if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) { - unlock(); - return -1; - } - } - - tc_p = talloc_chunk_from_ptr(ptr); - - if (tc_p->refs == NULL) { - int ret = _talloc_free(ptr); - unlock(); - return ret; - } - - new_p = talloc_parent_chunk(tc_p->refs); - if (new_p) { - new_parent = TC_PTR_FROM_CHUNK(new_p); - } else { - new_parent = NULL; - } - - if (talloc_unreference(new_parent, ptr) != 0) { - unlock(); - return -1; - } - - __talloc_steal(new_parent, ptr); - unlock(); - - return 0; -} - - -/** - * talloc_set_name_v - * ````````````````` - * Add a name to an existing pointer -- va_list version. - */ -static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_FMT(2,0); - - -/** - * talloc_set_name_v - * ````````````````` - * blah blah - */ -static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->name = talloc_vasprintf(ptr, fmt, ap); - if (likely(tc->name)) { - _talloc_set_name_const(tc->name, ".name"); - } - return tc->name; -} - - -/** - * talloc_set_name - * ``````````````` - * Add a name to an existing pointer. - */ -const char *talloc_set_name(const void *ptr, const char *fmt, ...) -{ - const char *name; - va_list ap; - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - return name; -} - - -/** - * talloc_named - * ```````````` - * Create a named talloc pointer. - * - * NOTES - * Any talloc pointer can be named, and talloc_named() operates just - * like talloc() except that it allows you to name the pointer. - */ -void *talloc_named(const void *context, size_t size, const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - - lock(context); - ptr = __talloc(context, size); - unlock(); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - talloc_free(ptr); - return NULL; - } - - return ptr; -} - - -/** - * talloc_get_name - * ``````````````` - * Return the name of a talloc ptr, else "UNNAMED". - */ -const char *talloc_get_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { - return ".reference"; - } - if (likely(tc->name)) { - return tc->name; - } - return "UNNAMED"; -} - - -/** - * talloc_check_name - * ````````````````` - * Check if a pointer has the given name. - * If it does, return the pointer, otherwise return NULL. - */ -void *talloc_check_name(const void *ptr, const char *name) -{ - const char *pname; - if (unlikely(ptr == NULL)) return NULL; - pname = talloc_get_name(ptr); - if (likely(pname == name || strcmp(pname, name) == 0)) { - return discard_const_p(void, ptr); - } - return NULL; -} - - -/** - * Compatibility. - */ -void *talloc_init(const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - - /* - * samba3 expects talloc_report_depth_cb(NULL, ...) - * reports all talloc'ed memory, so we need to enable - * null_tracking - */ - talloc_enable_null_tracking(); - - ptr = __talloc(NULL, 0); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - talloc_free(ptr); - return NULL; - } - - return ptr; -} - - -/** - * _talloc - * ``````` - * Allocate a bit of memory as a child of an existing pointer. - */ -void *_talloc(const void *context, size_t size) -{ - return __talloc(context, size); -} - - -/** - * talloc_destroy_pointer - * `````````````````````` - */ -static int talloc_destroy_pointer(void ***pptr) -{ - if ((uintptr_t)**pptr < getpagesize()) - TALLOC_ABORT("Double free or invalid talloc_set?"); - /* Invalidate pointer so it can't be used again. */ - **pptr = (void *)1; - return 0; -} - - -/** - * _talloc_set - * ``````````` - */ -void _talloc_set(void *ptr, const void *ctx, size_t size, const char *name) -{ - void ***child; - void *p; - - p = talloc_named_const(ctx, size, name); - if (unlikely(!p)) - goto set_ptr; - - child = talloc(p, void **); - if (unlikely(!child)) { - talloc_free(p); - p = NULL; - goto set_ptr; - } - *child = ptr; - talloc_set_name_const(child, "talloc_set destructor"); - talloc_set_destructor(child, talloc_destroy_pointer); - - set_ptr: - /* memcpy rather than cast avoids aliasing problems. */ - memcpy(ptr, &p, sizeof(p)); -} - - -/** - * talloc_set_name_const - * ````````````````````` - * External - */ -void talloc_set_name_const(const void *ptr, const char *name) -{ - _talloc_set_name_const(ptr, name); -} - - -/** - * talloc_named_const - * `````````````````` - * Create a named talloc pointer. - * - * NOTES - * Any talloc pointer can be named, and talloc_named() operates just - * like talloc() except that it allows you to name the pointer. - */ -void *talloc_named_const(const void *context, size_t size, const char *name) -{ - void *p; - lock(context); - p = _talloc_named_const(context, size, name); - unlock(); - return p; -} - - -/** - * talloc_free - * ``````````` - * Free a talloc pointer. - * This also frees all child pointers of this pointer recursively. - * - * Return 0 if the memory is actually freed, otherwise -1. - * - * NOTES - * The memory will not be freed if the ref_count is > 1 or if the - * destructor (if any) returns non-zero. - */ -int talloc_free(const void *ptr) -{ - int saved_errno = errno, ret; - - lock(ptr); - ret = _talloc_free(discard_const_p(void, ptr)); - unlock(); - if (ret == 0) - errno = saved_errno; - return ret; -} - - - -/** - * _talloc_realloc - * ``````````````` - * A talloc version of realloc. - * - * The context argument is only used if ptr is NULL. - */ -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) -{ - struct talloc_chunk *tc; - void *new_ptr; - - /* size zero is equivalent to free() */ - if (unlikely(size == 0)) { - talloc_free(ptr); - return NULL; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - /* realloc(NULL) is equivalent to malloc() */ - if (ptr == NULL) { - return talloc_named_const(context, size, name); - } - - tc = talloc_chunk_from_ptr(ptr); - - /* don't allow realloc on referenced pointers */ - if (unlikely(tc->refs)) { - return NULL; - } - - lock(ptr); - if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) { - /* need to get parent before setting free flag. */ - void *parent = talloc_parent_nolock(ptr); - tc->flags |= TALLOC_FLAG_FREE; - new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE); - } else { - /* by resetting magic we catch users of the old memory */ - tc->flags |= TALLOC_FLAG_FREE; - - #if ALWAYS_REALLOC - new_ptr = tc_malloc(size + TC_HDR_SIZE); - if (new_ptr) { - memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); - tc_free(tc); - } - #else - new_ptr = tc_realloc(tc, size + TC_HDR_SIZE); - #endif - } - - if (unlikely(!new_ptr)) { - tc->flags &= ~TALLOC_FLAG_FREE; - unlock(); - return NULL; - } - - tc = (struct talloc_chunk *)new_ptr; - tc->flags &= ~TALLOC_FLAG_FREE; - if (tc->parent) { - tc->parent->child = tc; - } - if (tc->child) { - tc->child->parent = tc; - } - - if (tc->prev) { - tc->prev->next = tc; - } - if (tc->next) { - tc->next->prev = tc; - } - - tc->size = size; - _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); - unlock(); - - return TC_PTR_FROM_CHUNK(tc); -} - - -/** - * _talloc_move - * ```````````` - * A wrapper around talloc_steal(), for situations where you are - * moving a pointer between two structures, and want the old pointer - * to be set to NULL - */ -void *_talloc_move(const void *new_ctx, const void *_pptr) -{ - const void **pptr = discard_const_p(const void *,_pptr); - void *ret = _talloc_steal(new_ctx, *pptr); - (*pptr) = NULL; - return ret; -} - - -/** - * _talloc_total_size - * `````````````````` - * Return the total size of a talloc pool (subtree) - */ -static size_t _talloc_total_size(const void *ptr) -{ - size_t total = 0; - struct talloc_chunk *c, *tc; - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total = tc->size; - for (c=tc->child;c;c=c->next) { - total += _talloc_total_size(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - - -/** - * talloc_total_size - * ````````````````` - */ -size_t talloc_total_size(const void *ptr) -{ - size_t total; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) { - return 0; - } - - lock(ptr); - total = _talloc_total_size(ptr); - unlock(); - return total; -} - - -/** - * _talloc_total_blocks - * ```````````````````` - * Return the total number of blocks in a talloc pool (subtree). - */ -static size_t _talloc_total_blocks(const void *ptr) -{ - size_t total = 0; - struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total++; - for (c=tc->child;c;c=c->next) { - total += _talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -size_t talloc_total_blocks(const void *ptr) -{ - size_t total; - - lock(ptr); - total = _talloc_total_blocks(ptr); - unlock(); - - return total; -} - -static size_t _talloc_reference_count(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - size_t ret = 0; - - for (h=tc->refs;h;h=h->next) { - ret++; - } - return ret; -} - - -/** - * talloc_reference_count - * `````````````````````` - * Return the number of external references to a pointer - */ -size_t talloc_reference_count(const void *ptr) -{ - size_t ret; - - lock(talloc_chunk_from_ptr(ptr)); - ret = _talloc_reference_count(ptr); - unlock(); - return ret; -} - -/** - * _talloc_report_depth_cb - * ``````````````````````` - * Report on memory usage by all children of a pointer, - * giving a full tree view - */ -static void _talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data) -{ - struct talloc_chunk *c, *tc; - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return; - } - - callback(ptr, depth, max_depth, 0, private_data); - - if (max_depth >= 0 && depth >= max_depth) { - return; - } - - tc->flags |= TALLOC_FLAG_LOOP; - for (c=tc->child;c;c=c->next) { - if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); - callback(h->ptr, depth + 1, max_depth, 1, private_data); - } else { - _talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); - } - } - tc->flags &= ~TALLOC_FLAG_LOOP; -} - - -/** - * talloc_report_depth_cb - * `````````````````````` - * Report on memory usage by all children of a pointer, - * giving a full tree view - */ -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data) -{ - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) return; - - lock(ptr); - _talloc_report_depth_cb(ptr, depth, max_depth, callback, private_data); - unlock(); -} - -static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) -{ - const char *name = talloc_get_name(ptr); - FILE *f = (FILE *)_f; - - if (is_ref) { - fprintf(f, "%*sreference to: %s\n", depth*4, "", name); - return; - } - - if (depth == 0) { - fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", - (max_depth < 0 ? "full " :""), name, - (unsigned long)_talloc_total_size(ptr), - (unsigned long)_talloc_total_blocks(ptr)); - return; - } - - fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", - depth*4, "", - name, - (unsigned long)_talloc_total_size(ptr), - (unsigned long)_talloc_total_blocks(ptr), - (int)_talloc_reference_count(ptr), ptr); - -#if 0 - fprintf(f, "content: "); - if (talloc_total_size(ptr)) { - int tot = talloc_total_size(ptr); - int i; - - for (i = 0; i < tot; i++) { - if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { - fprintf(f, "%c", ((char *)ptr)[i]); - } else { - fprintf(f, "~%02x", ((char *)ptr)[i]); - } - } - } - fprintf(f, "\n"); -#endif -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) -{ - talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); - fflush(f); -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_full(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, -1, f); -} - -/* - report on memory usage by all children of a pointer -*/ -void talloc_report(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, 1, f); -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report(null_context, stderr); - } -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null_full(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report_full(null_context, stderr); - } -} - -/* - enable tracking of the NULL context -*/ -void talloc_enable_null_tracking(void) -{ - if (null_context == NULL) { - null_context = _talloc_named_const(NULL, 0, "null_context"); - } -} - -/* - disable tracking of the NULL context -*/ -void talloc_disable_null_tracking(void) -{ - _talloc_free(null_context); - null_context = NULL; -} - -/* - enable leak reporting on exit -*/ -void talloc_enable_leak_report(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null); -} - -/* - enable full leak reporting on exit -*/ -void talloc_enable_leak_report_full(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null_full); -} - -/* - talloc and zero memory. -*/ -void *_talloc_zero(const void *ctx, size_t size, const char *name) -{ - void *p; - - lock(ctx); - p = _talloc_named_const(ctx, size, name); - unlock(); - - if (p) { - memset(p, '\0', size); - } - - return p; -} - -/* - memdup with a talloc. -*/ -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) -{ - void *newp; - - lock(t); - newp = _talloc_named_const(t, size, name); - unlock(); - - if (likely(newp)) { - memcpy(newp, p, size); - } - - return newp; -} - -/* - strdup with a talloc -*/ -char *talloc_strdup(const void *t, const char *p) -{ - char *ret; - if (!p) { - return NULL; - } - ret = (char *)talloc_memdup(t, p, strlen(p) + 1); - if (likely(ret)) { - _talloc_set_name_const(ret, ret); - } - return ret; -} - -/* - append to a talloced string -*/ -char *talloc_append_string(char *orig, const char *append) -{ - char *ret; - size_t olen = strlen(orig); - size_t alenz; - - if (!append) - return orig; - - alenz = strlen(append) + 1; - - ret = talloc_realloc(NULL, orig, char, olen + alenz); - if (!ret) - return NULL; - - /* append the string with the trailing \0 */ - memcpy(&ret[olen], append, alenz); - - _talloc_set_name_const(ret, ret); - - return ret; -} - -/* - strndup with a talloc -*/ -char *talloc_strndup(const void *t, const char *p, size_t n) -{ - size_t len; - char *ret; - - for (len=0; len<n && p[len]; len++) ; - - lock(t); - ret = (char *)__talloc(t, len + 1); - unlock(); - if (!ret) { return NULL; } - memcpy(ret, p, len); - ret[len] = 0; - _talloc_set_name_const(ret, ret); - return ret; -} - -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) -{ - int len; - char *ret; - va_list ap2; - char c; - - /* this call looks strange, but it makes it work on older solaris boxes */ - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - if (len < 0) { - return NULL; - } - - lock(t); - ret = (char *)__talloc(t, len+1); - unlock(); - if (ret) { - va_copy(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - _talloc_set_name_const(ret, ret); - } - - return ret; -} - - -/* - Perform string formatting, and return a pointer to newly allocated - memory holding the result, inside a memory pool. - */ -char *talloc_asprintf(const void *t, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = talloc_vasprintf(t, fmt, ap); - va_end(ap); - return ret; -} - - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. - **/ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc; - int len, s_len; - va_list ap2; - char c; - - if (s == NULL) { - return talloc_vasprintf(NULL, fmt, ap); - } - - tc = talloc_chunk_from_ptr(s); - - s_len = tc->size - 1; - - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - - if (len <= 0) { - /* Either the vsnprintf failed or the format resulted in - * no characters being formatted. In the former case, we - * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this - * function expect it to never return NULL. - */ - return s; - } - - s = talloc_realloc(NULL, s, char, s_len + len+1); - if (!s) return NULL; - - va_copy(ap2, ap); - vsnprintf(s+s_len, len+1, fmt, ap2); - va_end(ap2); - _talloc_set_name_const(s, s); - - return s; -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a string buffer. - */ -char *talloc_asprintf_append(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append(s, fmt, ap); - va_end(ap); - return s; -} - -/* - alloc an array, checking for integer overflow in the array size -*/ -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - void *p; - - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - lock(ctx); - p = _talloc_named_const(ctx, el_size * count, name); - unlock(); - return p; -} - -/* - alloc an zero array, checking for integer overflow in the array size -*/ -void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - void *p; - - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - p = _talloc_zero(ctx, el_size * count, name); - return p; -} - -/* - realloc an array, checking for integer overflow in the array size -*/ -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_realloc(ctx, ptr, el_size * count, name); -} - -/* - a function version of talloc_realloc(), so it can be passed as a function pointer - to libraries that want a realloc function (a realloc function encapsulates - all the basic capabilities of an allocation library, which is why this is useful) -*/ -void *talloc_realloc_fn(const void *context, void *ptr, size_t size) -{ - return _talloc_realloc(context, ptr, size, NULL); -} - - -static int talloc_autofree_destructor(void *ptr) -{ - autofree_context = NULL; - return 0; -} - -static void talloc_autofree(void) -{ - if (autofree_context && *autofree_context == getpid()) - talloc_free(autofree_context); -} - -/* - return a context which will be auto-freed on exit - this is useful for reducing the noise in leak reports -*/ -void *talloc_autofree_context(void) -{ - if (autofree_context == NULL || *autofree_context != getpid()) { - autofree_context = talloc(NULL, pid_t); - *autofree_context = getpid(); - talloc_set_name_const(autofree_context, "autofree_context"); - - talloc_set_destructor(autofree_context, talloc_autofree_destructor); - atexit(talloc_autofree); - } - return autofree_context; -} - -size_t talloc_get_size(const void *context) -{ - struct talloc_chunk *tc; - - if (context == NULL) - return 0; - - tc = talloc_chunk_from_ptr(context); - - return tc->size; -} - -/* - find a parent of this context that has the given name, if any -*/ -void *talloc_find_parent_byname(const void *context, const char *name) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return NULL; - } - - lock(context); - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (tc->name && strcmp(tc->name, name) == 0) { - unlock(); - return TC_PTR_FROM_CHUNK(tc); - } - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - unlock(); - return NULL; -} - -/* - show the parentage of a context -*/ -void talloc_show_parents(const void *context, FILE *file) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - fprintf(file, "talloc no parents for NULL\n"); - return; - } - - lock(context); - tc = talloc_chunk_from_ptr(context); - fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); - while (tc) { - fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - unlock(); - fflush(file); -} - -int talloc_is_parent(const void *context, const void *ptr) -{ - int ret; - lock(context); - ret = _talloc_is_parent(context, ptr); - unlock(); - return ret; -} - -void talloc_set_allocator(void *(*malloc)(size_t size), - void (*free)(void *ptr), - void *(*realloc)(void *ptr, size_t size)) -{ - tc_malloc = malloc; - tc_free = free; - tc_realloc = realloc; -} - -void *talloc_add_external(const void *ctx, - void *(*realloc)(const void *, void *, size_t), - void (*lock)(const void *p), - void (*unlock)(void)) -{ - struct talloc_chunk *tc, *parent; - void *p; - - if (tc_external_realloc && tc_external_realloc != realloc) - TALLOC_ABORT("talloc_add_external realloc replaced"); - tc_external_realloc = realloc; - - if (unlikely(ctx == NULL)) { - ctx = null_context; - parent = NULL; - } else - parent = talloc_chunk_from_ptr(ctx); - - tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE); - p = init_talloc(parent, tc, 0, 1); - tc_lock = lock; - tc_unlock = unlock; - - return p; -} diff --git a/src/lib/mystack.h b/src/lib/mystack.h deleted file mode 100644 index d2bc392..0000000 --- a/src/lib/mystack.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _STACK_H -#define _STACK_H - -struct stack_t { - void *stack; - void *stack_p; - int n; -}; - -static inline struct stack_t *new_stack(int number, size_t size) -{ - struct stack_t *new; - - new = malloc(sizeof(struct stack_t *)); - - new->stack = calloc(number, size); - new->stack_p = stack + size; - - return new; -} - -static inline int push(struct stack_t *stack, void *item) -{ - *--stack->stack_p = item; -} - -static inline void *pop(struct stack_t *stack) -{ - return *stack->stack_p++; -} - -static inline int stack - - - - - diff --git a/src/lib/old_set.c b/src/lib/old_set.c deleted file mode 100644 index 7711f8e..0000000 --- a/src/lib/old_set.c +++ /dev/null @@ -1,503 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <ctype.h> -#include <signal.h> -#include <string.h> -#include "debug.h" - -#include "set.h" - -/** - * new_set - * ``````` - * Create a new set. - * - * Returns: Pointer to an allocated default set. - */ -struct set_t *new_set(void) -{ - struct set_t *new; - - if (!(new = calloc(1, sizeof(struct set_t)))) { - halt(SIGABRT, "No memory to create SET.\n"); - return NULL; // "Shouldn't happen." - } - - new->map = new->defmap; - new->nwords = _DEFWORDS; - new->nbits = _DEFBITS; - - return new; -} - -/** - * del_set - * ``````` - * Destroy a set created with new_set(). - * - * @set : pointer to a SET. - * Returns: Nothing. - */ -void del_set(struct set_t *set) -{ - if (set->map != set->defmap) - free(set->map); - - free(set); -} - - -/** - * dup_set - * ``````` - * Create a new set that has the same members as the input set. - * - * @set : Input set (to be duplicated). - * Returns: Pointer to a new set with members identical to @set. - */ -struct set_t *dup_set(struct set_t *set) -{ - struct set_t *new; - - if (!(new = calloc(1, sizeof(struct set_t)))) { - halt(SIGABRT, "No memory to create SET.\n"); - return NULL; // "Shouldn't happen." - } - - new->compl = set->compl; - new->nwords = set->nwords; - new->nbits = set->nbits; - - if (set->map == set->defmap) { - new->map = new->defmap; - memcpy(new->defmap, set->defmap, _DEFWORDS * sizeof(_SETTYPE)); - } else { - new->map = (_SETTYPE *)malloc(set->nwords * sizeof(_SETTYPE)); - if (!new->map) - halt(SIGABRT, "No memory to duplicate SET.\n"); - - memcpy(new->map, set->map, set->nwords * sizeof(_SETTYPE)); - } - - return new; -} - - -/** - * _add_set - * ```````` - * Called by the ADD() macro when the set isn't big enough. - * - * @set: Pointer to a set. - * @bit: Bit to be added to set. - */ -int _add_set(struct set_t *set, int bit) -{ - grow_set(set, _ROUND(bit)); - return _GETBIT(set, bit, |=); -} - - -/** - * grow_set - * ```````` - * @set : Pointer to set to be enlarged. - * @need: Number of words needed (target). - * - * NOTE - * This routine calls malloc() and is rather slow. Its use should be - * limited, and avoided if possible. - */ -void grow_set(struct set_t *set, int need) -{ - _SETTYPE *new; - - if (!set || need <= set->nwords) - return; - - if (!(new = (_SETTYPE *) malloc(need * sizeof(_SETTYPE)))) - halt(SIGABRT, "No memory to expand SET.\n"); - - memcpy(new, set->map, set->nwords * sizeof(_SETTYPE)); - memset(new + set->nwords, 0, (need - set->nwords) * sizeof(_SETTYPE)); - - if (set->map != set->defmap) - free(set->map); - - set->map = new; - set->nwords = (unsigned char)need; - set->nbits = need * _BITS_IN_WORD; -} - - -/** - * num_set - * ``````` - * Get the number of elements (non-zero bits) in a set. NULL sets are empty. - * - * @set : Pointer to the set. - * Return: number of set bits in @set. - */ -int num_set(struct set_t *set) -{ - /* - * Neat macro that will expand to a lookup table indexed by a - * number in the range 0-255, with tab[i] == the number of set - * bits in i. - * - * Hallvard Furuseth suggested this approach on Sean Anderson's - * Bit Twiddling Hacks website on July 14, 2009. - */ - static const unsigned char nbits[256] = - { - #define B2(n) n, n+1, n+1, n+2 - #define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2) - #define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2) - B6(0), B6(1), B6(1), B6(2) - }; - - unsigned int count = 0; - unsigned char *p; - int i; - - if (!set) - return 0; - - p = (unsigned char *)set->map; - - for (i=_BYTES_IN_ARRAY(set->nwords); --i >= 0;) - count += nbits[*p++]; - - return count; -} - - -/** - * _set_test - * ````````` - * Compares two sets. Returns as follows: - * - * _SET_EQUIV Sets are equivalent. - * _SET_INTER Sets intersect but aren't equivalent. - * _SET_DISJ Sets are disjoint. - * - * NOTE - * The smaller set is made larger if the two sets are different sizes. - */ -int _set_test(struct set_t *set1, struct set_t *set2) -{ - _SETTYPE *p1; - _SETTYPE *p2; - int rval; - int i; - int j; - - rval = _SET_EQUIV; - i = max(set1->nwords, set2->nwords); - - grow_set(set1, i); - grow_set(set2, i); - - p1 = set1->map; - p2 = set2->map; - - for (; --i >= 0; p1++, p2++) { - if (*p1 != *p2) - return *p1 - *p2; - } - - /* - * You get here if the sets are not equivalent. - * If the sets intersect, you can return immediately, - * but have to keep going in the case of disjoint - * sets because they might actually intersect - * at some yet-unseen byte. - */ - if ((j = set1->nwords - i) > 0) { // set1 is larger - while (--j >= 0) { - if (*p1++) - return 1; - } - } else if ((j = set2->nwords - i) > 0) { // set2 is larger - while (--j >= 0) { - if (*p2++) - return -1; - } - } - return 0; // they are equivalent. -} - - -/** - * set_cmp - * ``````` - * Yet another comparison function. Works like strcmp(). - * - * @set1 : Pointer to a set to be compared. - * @set2 : Pointer to another set. - * Returns: 0 if set1==set2, < 0 if set1<set2, > 0 if set1>set2. - */ -int set_cmp(struct set_t *set1, struct set_t *set2) -{ - _SETTYPE *p1; - _SETTYPE *p2; - int j; - int i; - - i = j = min(set1->nwords, set2->nwords); - - for (p1 = set1->map, p2 = set2->map; --j >= 0; p1++, p2++) { - if (*p1 != *p2) - return *p1 - *p2; - } - - /* - * You get here only if all words in both sets are the same. - * Check the tail end of the larger array for all zeroes. - */ - if ((j = set1->nwords - i) > 0) { // set1 is larger - while (--j >= 0) { - if (*p1++) - return 1; - } - } else if ((j = set2->nwords - i) > 0) { // set2 is larger - while (--j >= 0) { - if (*p2++) - return -1; - } - } - return 0; // they are equivalent. -} - - -/** - * sethash - * ``````` - * Hash a set by summing together the words in the bitmap. - * - * @set : Pointer to a set. - * Return: hashed value. - */ -unsigned sethash(struct set_t *set) -{ - _SETTYPE *p; - unsigned total; - int j; - - total = 0; - j = set->nwords; - p = set->map; - - while (--j >= 0) - total += *p++; - - return total; -} - -/** - * is_subset - * ````````` - * Attempt to determine if 'sub' is a subset of 'set'. - * - * @set : Pointer to a set. - * @sub : Pointer to a possible subset of @set. - * Return: 1 if @sub is a subset of @set, otherwise 0. - * - * NOTE - * If @sub is larger than @set, the extra bytes must be all zeroes. - */ -int is_subset(struct set_t *set, struct set_t *sub) -{ - _SETTYPE *subsetp; - _SETTYPE *setp; - int common; // Number of bytes in potential subset. - int tail; // Number of implied 0 bytes in subset. - - if (sub->nwords > set->nwords) { - common = set->nwords; - tail = sub->nwords - common; - } else { - common = sub->nwords; - tail = 0; - } - - subsetp = sub->map; - setp = set->map; - - for (; --common >= 0; subsetp++, setp++) { - if ((*subsetp & *setp) != *subsetp) - return 0; - } - - while (--tail >= 0) { - if (*subsetp++) - return 0; - } - - return 1; -} - - -/** - * _set_op - * ``````` - * Performs binary operations depending on op. - * - * @op: One of _UNION, _INTERSECT, _DIFFERENCE, or _ASSIGN. - * @dest : Destination set. - * @src : Source set. - * Returns: nothing. - */ -void _set_op(int op, struct set_t *dest, struct set_t *src) -{ - _SETTYPE *d; // Destination map. - _SETTYPE *s; // Source map. - unsigned ssize; // Number of words in source set. - int tail; // Dest is this many words bigger than source. - - ssize = src->nwords; - - /* Make sure destination is big enough. */ - if ((unsigned)dest->nwords < ssize) - grow_set(dest, ssize); - - tail = dest->nwords - ssize; - d = dest->map; - s = src->map; - - switch (op) { - case _UNION: - while (--ssize >= 0) - *d++ |= *s++; - break; - case _INTERSECT: - while (--ssize >= 0) - *d++ &= *s++; - while (--tail >= 0) - *d++ = 0; - break; - case _DIFFERENCE: - while (--ssize >= 0) - *d++ ^= *s++; - break; - case _ASSIGN: - while (--ssize >= 0) - *d++ = *s++; - while (--tail >= 0) - *d++ = 0; - break; - } -} - -/** - * invert_set - * `````````` - * Physically invert the bits in the set. Compare with COMPLIMENT(). - * - * @set : Pointer to a set. - * Return: Nothing. - */ -void invert_set(struct set_t *set) -{ - _SETTYPE *p; - _SETTYPE *end; - - for (p = set->map, end = p + set->nwords; p < end; p++) - *p = ~*p; -} - - -/** - * trunc_set - * ````````` - * Clear a set and truncate it to the default size. Compare with CLEAR(). - * - * @set : Pointer to a set. - * Return: Nothing. - */ -void trunc_set(struct set_t *set) -{ - if (set->map != set->defmap) { - free(set->map); - set->map = set->defmap; - } - set->nwords = _DEFWORDS; - set->nbits = _DEFBITS; - memset(set->defmap, 0, sizeof(set->defmap)); -} - - -/** - * next_member - * ``````````` - * Access all members of a set sequentially. - * - * @set : Pointer to a set. - * Return: value of each bit. - * - * USAGE - * Like strtok() - * set == NULL resets. - * set changed from last call resets and returns first element. - * otherwise the next element is returned, or else -1 if none. - */ -int next_member(struct set_t *set) -{ - static struct set_t *oset = 0; - static int current = 0; - _SETTYPE *map; - - if (!set) - return ((int)(oset = NULL)); - - if (oset != set) { - oset = set; - current = 0; - - for (map = set->map; *map == 0 && current < set->nbits; ++map) - current += _BITS_IN_WORD; - } - - /* - * The increment must be put in the test because if TEST() - * evaluates true, the increment on the right of the for would - * never be executed. - */ - while (current++ < set->nbits) { - if (TEST(set, current-1)) - return (current - 1); - } - return (-1); -} - - -/** - * print_set - * ````````` - * Print a set in human-readable form. - * - * @set: pointer to a set - */ -void print_set(struct set_t *set) -{ - int did_something=0; - int i; - - if (!set) - printf("Null set.\n"); - - else { - next_member(NULL); - while ((i = next_member(set)) >= 0) { - did_something++; - printf("%d", i); - } - next_member(NULL); - - if (!did_something) - printf("Empty set.\n"); - } -} - - diff --git a/src/lib/old_set.h b/src/lib/old_set.h deleted file mode 100644 index 475800f..0000000 --- a/src/lib/old_set.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef _SET_H -#define _SET_H - - -/* One cell in the bitmap */ -typedef unsigned short _SETTYPE; - - -#define _BITS_IN_WORD (16) -#define _BYTES_IN_ARRAY(x) (x << 1) -#define _DEFWORDS 32 -#define _DEFBITS (_DEFWORDS * _BITS_IN_WORD) - -/* - * Evaluates to the array element that holds the bit x. - * Performs a simple integer divide by 16, which is - * implemented as a right shift of 4. - */ -#define _DIV_WSIZE(x) ((unsigned)(x) >> 4) - -/* - * Evaluates to the position of the bit within the word, - * i.e. the offset in bits from the least-significant bit. - * Performs a modulus 16 using a bitwise AND. - */ -#define _MOD_WSIZE(x) ((x) & 0x0f) - -/* - * Used to expand the size of the array. An array grows in - * _DEFWORDS-sized chunks. - * - * >>3 is equivalent to integer division by 8. - * <<3 is equivalent to integer multiplication by 8. - * - * Imagine we start with the default array of 8 chunks, and - * wish to add the number 200 to the set. The array must be - * expanded to do this, and after the expansion, the array - * should have 16 elements in it: - * - * (((_DIV_WSIZE(200) + 8) >> 3) << 3) - * - * (((((unsigned)(200) >> 4) + 8) >> 3) << 3) - * (((12 + 8) >> 3) << 3) - * ((20 >> 3) << 3) - * (2 << 3) - * 16 - */ -#define _ROUND(bit) (((_DIV_WSIZE(bit) + 8) >> 3) << 3) - - -/* - * The defmap array is the default bitmap. Initially, map is - * set to point at defmap. When the array grows, however, instead - * of calling realloc() to change the size of defmap (and thus _set_), - * map is simply pointed at the newly malloc'd array. - * - * The reason for this is that realloc() will copy the entire memory - * array to the newly allocated one, whereas only the map needs to be - * copied. You can thus save time at the expense of some memory if you - * do it yourself. - */ -struct set_t { - unsigned char nwords; // Number of words in the map - unsigned char compl; // Is a negative true set if true - unsigned nbits; // Number of bits in map - _SETTYPE *map; // Pointer to the map - _SETTYPE defmap[_DEFWORDS]; // The map itself -}; - - -/* - * Op arguments passed to _set_op - */ -#define _UNION 0 // x is in s1 or s2 -#define _INTERSECT 1 // x is in s1 and s2 -#define _DIFFERENCE 2 // (x in s1) && (x not in s2) -#define _ASSIGN 4 // s1 = s2 - -#define UNION(d,s) _set_op(_UNION, d, s) -#define INTERSECT(d,s) _set_op(_INTERSECT, d, s) -#define DIFFERENCE(d,s) _set_op(_DIFFERENCE, d, s) -#define ASSIGN(d,s) _set_op(_ASSIGN, d, s) - -#define CLEAR(s) memset((s)->map, 0, (s)->nwords * sizeof(_SETTYPE)) -#define FILL(s) memset((s)->map, ~0, (s)->nwords * sizeof(_SETTYPE)) -#define COMPLEMENT(s) ((s)->compl = ~(s)->compl) -#define INVERT(s) invert(s) - -/* Value returned from _set_test */ -#define _SET_EQUIV 0 -#define _SET_DISJ 1 -#define _SET_INTER 2 - -#define IS_DISJOINT(s1,s2) (_set_test(s1,s2) == _SET_DISJ) -#define IS_INTERSECTING(s1,s2) (_set_test(s1,s2) == _SET_INTER) -#define IS_EQUIVALENT(s1,s2) (set_cmp((s1),(s2)) == 0) -#define IS_EMPTY(s) (set_num(s) == 0) - -/* - * CAVEAT - * Heavy duty side effects ahead, be aware. - */ - -#define _GETBIT(s,x,op) (((s)->map)[_DIV_WSIZE(x)] op (1 << _MOD_WSIZE(x))) - -#define ADD(s,x) (((x) >= (s)->nbits) ? _add_set(s,x) : _GETBIT(s,x,|=)) -#define REMOVE(s,x) (((x) >= (s)->nbits) ? 0 : _GETBIT(s,x,&=~)) -#define TEST(s,x) ((MEMBER(s,x)) ? !(s)->compl : (s)->compl ) -#define MEMBER(s,x) (((x) >= (s)->nbits) ? 0 : _GETBIT(s,x,&)) - - -struct set_t *new_set(void); -void del_set(struct set_t *set); -struct set_t *dup_set(struct set_t *set); -int _add_set(struct set_t *set, int bit); -void grow_set(struct set_t *set, int need); -void _set_op(int op, struct set_t *dest, struct set_t *src); -int _set_test(struct set_t *set1, struct set_t *set2); - -int set_num (struct set_t *set); -int set_cmp (struct set_t *set1, struct set_t *set2); -unsigned set_hash (struct set_t *set); -void set_invert(struct set_t *set); -void set_trunc (struct set_t *set); -int next_member(struct set_t *set); -void print_set (struct set_t *set); -int is_subset (struct set_t *set, struct set_t *sub); - - -#endif diff --git a/src/lib/redblack.c b/src/lib/redblack.c deleted file mode 100644 index ec7c0bd..0000000 --- a/src/lib/redblack.c +++ /dev/null @@ -1,486 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include "debug.h" -#include "redblack.h" - -/* - * RED BLACK TREES - * - * 1. A node is either red or black. - * 2. The root is black. (sometimes) - * 3. All leaves are the same color as the root. - * 4. Both children of every red node are black. - * 5. Every simple path from a given node to any of its descendant - * leaves contains the same number of black nodes. - */ - -/****************************************************************************** - * CREATION AND HOUSEKEEPING - ******************************************************************************/ - - -/** - * make_node - * ````````` - * Create a new node of the red-black tree. - * - * @key : Key to be stored at the node. - * Return: Pointer to a new rb_node. - */ -struct rb_node *make_node(uint32_t key) -{ - struct rb_node *new; - - if (!(new = malloc(sizeof(struct rb_node)))) - halt(SIGABRT, "make_node: Out of memory.\n"); - - new->key = key; - new->red = true; - new->link[0] = NULL; - new->link[1] = NULL; - new->extra = NULL; - - return new; -} - - -/** - * rb_new - * `````` - * Create a new red-black tree root node. - * - * Return: Pointer to a red-black tree root node. - */ -struct rb_tree *rb_new(void) -{ - struct rb_tree *new; - - if (!(new = malloc(sizeof(struct rb_tree)))) - halt(SIGABRT, "rb_new: Out of memory.\n"); - - new->root = NULL; - new->peek = NULL; - new->n = 0; - - return new; -} - - -/** - * rb_init - * ``````` - * Initialize a statically-allocated red-black tree root node. - * - * Return: Nothing. - */ -void rb_init(struct rb_tree *tree) -{ - tree->root = NULL; - tree->peek = NULL; - tree->n = 0; -} - - -/** - * is_red - * `````` - * Return true if the red-black tree node is red, else return false. - */ -bool is_red(struct rb_node *root) -{ - return (root!=NULL && root->red==true) ? true : false; -} - - -/****************************************************************************** - * BALANCING OPERATIONS - ******************************************************************************/ - - -/** - * rot_single - * `````````` - * Perform a single rotation that rotates the nodes as normal, - * then sets the old root to be red, and the new root to be - * black. - * - * Return: Rotated red-black tree root node. - */ -struct rb_node *rot_single(struct rb_node *root, int dir) -{ - struct rb_node *save; - - save = root->link[!dir]; - - root->link[!dir] = save->link[dir]; - save->link[dir] = root; - - root->red = true; - save->red = false; - - return save; -} - - -/** - * rot_double - * `````````` - * Perform two single rotations. - * - * Return: Rotated red-black tree root node. - */ -struct rb_node *rot_double(struct rb_node *root, int dir) -{ - root->link[!dir] = rot_single(root->link[!dir], !dir); - - return rot_single(root, dir); -} - - -/** - * rb_assert - * ````````` - * Test for various erroneous conditions. - */ -int rb_assert(struct rb_node *root) -{ - struct rb_node *ln; - struct rb_node *rn; - int lh; - int rh; - - if (root == NULL) - return 1; - - ln = root->link[0]; - rn = root->link[1]; - - /* Consecutive red links */ - if (is_red(root)) { - if (is_red(ln) || is_red(rn)) { - halt(SIGABRT, "rb_assert: Red violation\n"); - return 0; - } - } - - lh = rb_assert(ln); - rh = rb_assert(ln); - - /* Invalid binary search tree */ - if ((ln != NULL && ln->key >= root->key) - || (rn != NULL && rn->key <= root->key)) - { - halt(SIGABRT, "rb_assert: Binary tree violation.\n"); - return 0; - } - - /* Black height mismatch. */ - if (lh != 0 && rh != 0 && lh != rh) { - halt(SIGABRT, "rb_assert: Black violation"); - return (0); - } - - /* Only count black links. */ - if (ln != 0 && rh != 0) - return is_red(root) ? lh : lh+1; - else - return 0; -} - - -/****************************************************************************** - * SINGLE-PASS INSERTION AND DELETION - ******************************************************************************/ - - -/** - * rb_insert - * ````````` - * Top-down single-pass tree insertion routine. - * - * @tree: Root node of the red-black tree. - * @key : Value to be inserted. - */ -int rb_insert(struct rb_tree *tree, uint32_t key) -{ - struct rb_node head = {0}; /* False root */ - struct rb_node *g; /* Grandparent */ - struct rb_node *t; /* Parent */ - struct rb_node *p; /* Iterator */ - struct rb_node *q; /* Parent */ - int dir = 0; - int dir2; - int last; - - /* Create tree root if none exists. */ - if (tree->root == NULL && (!(tree->root = make_node(key)))) { - halt(SIGABRT, "rb_insert: Filthy malloc...\n"); - return 0; - } - - /* - * Initialize helpers. This should always occur AFTER - * the root node has been initialized. - */ - t = &head; - g = p = NULL; - q = t->link[1] = tree->root; - - - /* - * Traverse down into the tree. - */ - for (;;) { - if (q == NULL) { - /* Insert new node at the bottom */ - p->link[dir] = q = make_node(key); - if (q == NULL) - return 0; - - } else if (is_red(q->link[0]) && is_red(q->link[1])) { - /* Flip the color */ - q->red = 1; - q->link[0]->red = 0; - q->link[1]->red = 0; - } - - /* Repair red violation */ - if (is_red(q) && is_red(p)) { - dir2 = (t->link[1] == g); // Boolean - - if (q == p->link[last]) - t->link[dir2] = rot_single(g, !last); - else - t->link[dir2] = rot_double(g, !last); - } - - /* Stop if key has been found */ - if (q->key == key) - break; // out of the infinite for loop - - /* Otherwise... */ - last = dir; - dir = (q->key < key); - - t = (g) ? g : t; - g = p; - p = q; - q = q->link[dir]; - } - - /* - * If we're here, insertion was a success. - * - * Update root node, make it black, and increment the - * counter since we have added a new node to the tree. - */ - tree->root = head.link[1]; - tree->root->red = false; - tree->n++; - - return 1; -} - - -/** - * rb_remove - * ````````` - * Top-down single-pass tree deletion. Not for the faint-hearted. - * - * @tree: Root node of the red-black tree. - * @key : Value to be removed. - */ -int rb_remove(struct rb_tree *tree, uint32_t key) -{ - struct rb_node head = {0}; /* False root */ - struct rb_node *g; /* Grandparent */ - struct rb_node *p; /* Iterator */ - struct rb_node *q; /* Parent */ - struct rb_node *f; /* Found item */ - struct rb_node *s; - int dir = 1; - int dir2; - int last; - - if (tree->root == NULL) - return 0; - - q = &head; - g = p = NULL; - q->link[1] = tree->root; - - /* Search and push a red node down. */ - while (q->link[dir] != NULL) { - - last = dir; - - /* Update helpers. */ - g = p; - p = q; - q = q->link[dir]; - dir = (q->key < key); - - /* Save found node */ - f = (q->key == key) ? q : f; - - /* Push the red node down. */ - if (!is_red(q) && !is_red(q->link[dir])) { - - if (is_red(q->link[!dir])) - p = p->link[last] = rot_single(q, dir); - - else if (!is_red(q->link[!dir])) { - - s = p->link[!last]; - - if (s != NULL) { - if (!is_red(s->link[!last]) && !is_red(s->link[last])) { - /* Color flip */ - p->red = false; - s->red = true; - q->red = true; - } else { - dir2 = g->link[1] == p; - - if (is_red(s->link[last])) - g->link[dir2] = rot_double(p, last); - else if (is_red(s->link[!last])) - g->link[dir2] = rot_single(p, last); - - /* Ensure correct coloring */ - q->red = g->link[dir2]->red = true; - g->link[dir2]->link[0]->red = false; - g->link[dir2]->link[1]->red = false; - } - } - } - } - } - /* Replace and remove if found */ - if (f != NULL) { - f->key = q->key; - p->link[(p->link[1] == q)] = q->link[(q->link[0] == NULL)]; - free (q); - } - - /* Update root and make it black */ - tree->root = head.link[1]; - - if (tree->root != NULL) - tree->root->red = false; - - if (tree->n > 0) - tree->n--; - - return 1; -} - - -/****************************************************************************** - * RETREIVAL - ******************************************************************************/ - - -/** - * _rb_retreive - * ```````````` - * Return a node from the red-black tree. - * - * @node : The root node of the red-black tree. - * @key : The value to retreive. - * Return: The node with value @key if it exists, or else NULL. - * - * NOTE - * This function proceeds by recursive descent of the tree. - */ -struct rb_node *_rb_retreive(struct rb_node *node, uint32_t key) -{ - if (node == NULL) - return NULL; - - if (key == node->key) - return node; - else { - if (key < node->key) - _rb_retreive(node->link[0], key); // go left - else if (key > node->key) - _rb_retreive(node->link[1], key); // go right - } - /* return (NULL); This is a no-no */ -} - - -/** - * rb_retreive - * ``````````` - * Since the typical interface requires struct rb_tree, this is useful. - * - * @tree : Red-black tree structure. - * @key : Value to be retreived. - * Return: Pointer to an rb_node indexed by @key. - */ -struct rb_node *rb_retreive(struct rb_tree *tree, uint32_t key) -{ - return (_rb_retreive(tree->root, key)); -} - - -/** - * rb_peek - * ``````` - * Instead of returning a node, direct the peek pointer to it. - * - * @tree : Red-black tree structure. - * @key : Value to be peeked at. - * Return: Nothing (sets tree->peek pointer). - */ -void rb_peek(struct rb_tree *tree, uint32_t key) -{ - if (!tree->root) - return; - else - tree->peek = _rb_retreive(tree->root, key); -} - - -/** - * rb_store - * ```````` - * Store data at a particular node, indexed by @key. - * - * @tree : Red-black tree structure. - * @key : Value of the node reference. - * @extra: Data to be stored at node. - * Return: Nothing. - */ -void rb_store(struct rb_tree *tree, uint32_t key, void *extra) -{ - rb_peek(tree, key); - - /* No entry with @key yet exists. */ - if (tree->peek == NULL) { - rb_insert(tree, key); // Insert a new record. - rb_store(tree, key, extra); // Call self recursively. - } else { - tree->peek->extra = extra; // Attach extra to node. - } -} - - -/** - * rb_extra - * ```````` - * Return the 'extra' data stored at a node with key @key. - * - * @tree : Red-black tree structure. - * @key : value of the node reference. - * Return: Data stored at node indexed by @key. - */ -void *rb_extra(struct rb_tree *tree, uint32_t key) -{ - rb_peek(tree, key); - - return (tree->peek) ? tree->peek->extra : NULL; -} - - diff --git a/src/lib/redblack.h b/src/lib/redblack.h deleted file mode 100644 index 428c99a..0000000 --- a/src/lib/redblack.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _RED_BLACK_TREE_H -#define _RED_BLACK_TREE_H - -#include <stdint.h> -#include <stdbool.h> - -/* - * Node in the red-black tree. - */ -struct rb_node { - uint32_t key; - bool red; - void *extra; - struct rb_node *link[2]; -}; - -/* - * Container for the red-black tree. - */ -struct rb_tree { - struct rb_node *root; - struct rb_node *peek; - int n; -}; - - -struct rb_tree *rb_new(void); -void rb_init(struct rb_tree *tree); -void rb_peek(struct rb_tree *tree, uint32_t key); -void rb_store(struct rb_tree *tree, uint32_t key, void *extra); -void *rb_extra(struct rb_tree *tree, uint32_t key); -int rb_remove(struct rb_tree *tree, uint32_t key); -int rb_insert(struct rb_tree *tree, uint32_t key); -struct rb_node *rb_retreive(struct rb_tree *tree, uint32_t key); - - -#endif |