diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..4bd06db --- /dev/null +++ b/Doxyfile @@ -0,0 +1,283 @@ +# Doxyfile 1.4.1-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "UbixOS V2" +PROJECT_NUMBER = 2.0 +OUTPUT_DIRECTORY = /usr/home/reddawg/source/ubix2/doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /usr/home/reddawg/source/ubix2/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = YES +SORT_BY_SCOPE_NAME = YES +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /usr/home/reddawg/source/ubix2/src/sys/ +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox \ + *.s \ + *.S +RECURSIVE = YES +EXCLUDE = /usr/home/reddawg/source/ubix2/src/sys/sde \ + /usr/home/reddawg/source/ubix2/src/lib/objgfx40 \ + /usr/home/reddawg/source/ubix2/src/sys/ubixfsv2 \ + /usr/home/reddawg/source/ubix2/src/sys/include/objgfx \ + /usr/home/reddawg/source/ubix2/src/sys/compile \ + /usr/home/reddawg/source/ubix2/src/sys/net \ + /usr/home/reddawg/source/ubix2/src/sys/include/net +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = Makefile.inc +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = YES +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = YES +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = ubix2.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = YES +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = YES diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..898354e --- /dev/null +++ b/src/Makefile @@ -0,0 +1,102 @@ +# $Id: Makefile 148 2016-01-18 19:34:32Z reddawg $ +# The System Makefile (C) 2002 The UbixOS Project + +MAKE=make + +CURDIR=${.CURDIR} + +OBJ_DIR?= ${CURDIR}/obj + +CLEANDIR=clean + +WORLD_LIB_SRC=${CURDIR}/lib +WORLD_BIN_SRC=${CURDIR}/bin +WORLD_INC=${CURDIR}/include.new +WORLD_FLAGS=_ARCH=${_ARCH} CC="cc" CXX="c++" AS="as" AR="ar" LD="ld" NM=nm OBJDUMP= OBJCOPY="objcopy" RANLIB=ranlib + +WMAKE= ${MAKE} ${WORLD_FLAGS} INCLUDE=${WORLD_INC} BUILD_DIR=${CURDIR}/build + +TMP_PATH=${PATH} +ROOT=/ubixos + +all: kernel world install-kernel install-world +# csu ubix_api libc_old libc ubix libcpp bin tools +# depend kernel tools + +kernel: + @cd sys;make + +world: + @echo + @echo "***************************************************************" + @echo "World Build For ${_ARCH} Started On `LC_ALL=C date`" + @echo "***************************************************************" + @echo + @echo "***************************************************************" + @echo "Step 1: Clean World" + @echo "***************************************************************" + #cd ${WORLD_LIB_SRC}; ${WMAKE} ${CLEANDIR} + #cd ${WORLD_BIN_SRC}; ${WMAKE} ${CLEANDIR} + @echo + @echo "***************************************************************" + @echo "Step 2: Build World Libraries" + @echo "***************************************************************" + cd ${WORLD_LIB_SRC}; ${WMAKE} all + @echo + @echo "***************************************************************" + @echo "Step 3: Build World Binaries" + @echo "***************************************************************" + cd ${WORLD_BIN_SRC}; ${WMAKE} all + @echo + @echo "***************************************************************" + @echo "World Build For ${_ARCH} Completed On `LC_ALL=C date`" + @echo "***************************************************************" + + + +install-world: + @echo + @echo "***************************************************************" + @echo "World Install For ${_ARCH} Started On `LC_ALL=C date`" + @echo "***************************************************************" + @echo + @echo "***************************************************************" + @echo "Step 1: Copy Binaries" + @echo "***************************************************************" + cp -pr build/bin/* ${ROOT}/bin/ + sync + @echo + @echo "***************************************************************" + @echo "Step 2: Copy Libraries" + @echo "***************************************************************" + cp -pr build/lib/* ${ROOT}/lib/ + cp -pr build/libexec/* ${ROOT}/libexec/ + sync + @echo + @echo "***************************************************************" + @echo "Step 3: Copy Etc" + @echo "***************************************************************" + cp -pr etc/* ${ROOT}/etc/ + sync + @echo + @echo "***************************************************************" + @echo "World Install For ${_ARCH} Completed On `LC_ALL=C date`" + @echo "***************************************************************" + +clean-kernel: + (cd sys;${MAKE} clean) + +install-kernel: + (cd sys;${MAKE} install-kernel) + +install: install-world install-kernel + +clean: + (cd sys;${MAKE} clean) + (cd bin;${WMAKE} clean) + (cd lib;${WMAKE} clean) +# (cd src/lib/ubix;make clean) +# (cd src/lib/objgfx40;make clean) +# (cd src/lib/libcpp;make clean) +# (cd src/lib/views/sunlight;make clean) +# (cd src/lib/libstdc++;make clean) diff --git a/src/Makefile.incl b/src/Makefile.incl new file mode 100644 index 0000000..30939ec --- /dev/null +++ b/src/Makefile.incl @@ -0,0 +1,19 @@ +# $Id: Makefile.inc 89 2016-01-12 00:20:40Z reddawg $ +# Global 'Source' Options + +# allow you to change your default compiler without affecting your other work +#MrOlsen (2016-01-10) NOTE: I pass all this now +#CFLAGS = -m32 +#CC = cc +#CXX = c++ +#LD = ld +#AR = ar + +#Glogal Override And Defs +_ARCH?=${MACHINE_ARCH} + +_ARCH=i386 + +REMOVE = rm -rf + +FD_DEVICE = /dev/md0 diff --git a/src/bin/Makefile b/src/bin/Makefile new file mode 100644 index 0000000..a123b29 --- /dev/null +++ b/src/bin/Makefile @@ -0,0 +1,95 @@ +# $Id: Makefile 121 2016-01-14 03:18:20Z reddawg $ +# The System Makefile (C) 2002 The UbixOS Project + +all: init-bin login-bin shell-bin clock-bin cp-bin fdisk-bin format-bin disklabel-bin ubistry-bin ld-bin ttyd-bin stat-bin ls-bin #rtld-elf-bin +# MrOlsen (2016-01-11) ERROR: weird it didnt like -elf rtld-elf-bin +# MrOlsen (2016-01-11) NOTE: edit-bin cat-bin +# test-bin pwd-bin cat-bin de-bin ls-bin goofball-bin mount-bin + +init-bin: init + (cd init;make) + +login-bin: login + (cd login;make) + +shell-bin: shell + (cd shell;make) + +test-bin: test + (cd test;make) + +ls-bin: ls + (cd ls;make) + +pwd-bin: pwd + (cd pwd;make) + +cat-bin: cat + (cd cat;make) + +ld-bin: ld + (cd ld;make) + +de-bin: de + (cd de;make) + +muffin-bin: muffin + (cd muffin;make) + +goofball-bin: goofball + (cd goofball;make) + +clock-bin: clock + (cd clock;make) + +fdisk-bin: fdisk + (cd fdisk;make) + +cp-bin: cp + (cd cp;make) + +format-bin: format + (cd format;make) + +disklabel-bin: disklabel + (cd disklabel;make) + +launcher-bin: launcher + (cd launcher;make) + +ubistry-bin: ubistry + (cd ubistry;make) + +edit-bin: edit + (cd edit;make) + +ttyd-bin: ttyd + (cd ttyd;make) + +stat-bin: stat + (cd stat;make) + +mount-bin: mount + (cd mount;make) + +rtld-elf-bin: rtld-elf + (cd rtld-elf;make) + +clean: + (cd cp;make clean) + (cd fdisk;make clean) + (cd init;make clean) + (cd shell;make clean) + (cd ls;make clean) + (cd login;make clean) + (cd clock;make clean) + (cd muffin;make clean) + (cd format;make clean) + (cd disklabel;make clean) + (cd ubistry;make clean) + (cd ld;make clean) + (cd edit;make clean) + (cd ttyd;make clean) + (cd stat;make clean) + (cd mount;make clean) + (cd rtld-elf;make clean) diff --git a/src/bin/Makefile.incl b/src/bin/Makefile.incl new file mode 100644 index 0000000..2d0ca5d --- /dev/null +++ b/src/bin/Makefile.incl @@ -0,0 +1,11 @@ +# 'bin' options + +CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin + +INCLUDES = -I../../include + +#LIBRARIES = ../../lib/libc_old/math/*.o ../../lib/libc_old/quad/*.o ../../lib/libc_old/stdio/*.o ../../lib/libc_old/stdlib/*.o ../../lib/libc_old/sys/*.o ../../lib/libc_old/string/*.o ../../lib/libc_old/locale/*.o ../../lib/libc_old/gen/*.o ../../lib/libc_old/generic/*.o ../../lib/libc_old/*/*.o + +LIBRARIES = ../../lib/libc_old/*/*.o + +STARTUP = ../../lib/ubix/*.o diff --git a/src/bin/clock/Makefile b/src/bin/clock/Makefile new file mode 100644 index 0000000..3f7b34d --- /dev/null +++ b/src/bin/clock/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = clock + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) +# strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/clock/main.c b/src/bin/clock/main.c new file mode 100644 index 0000000..397c3a4 --- /dev/null +++ b/src/bin/clock/main.c @@ -0,0 +1,101 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include + +void print2(char *string,int,int); + +#define MINUTE 60 +#define HOUR (60*MINUTE) +#define DAY (24*HOUR) +#define YEAR (365*DAY) +extern const char *__progname; + + +static int monthSecs[12] = { + 0, + DAY*(31), + DAY*(31+29), + DAY*(31+29+31), + DAY*(31+29+31+30), + DAY*(31+29+31+30+31), + DAY*(31+29+31+30+31+30), + DAY*(31+29+31+30+31+30+31), + DAY*(31+29+31+30+31+30+31+31), + DAY*(31+29+31+30+31+30+31+31+30), + DAY*(31+29+31+30+31+30+31+31+30+31), + DAY*(31+29+31+30+31+30+31+31+30+31+30) +}; + +int main(int argc,char **argv) { + int sysTime = 0x0; + int i = 0x0; + + int year = 0x0; + int month = 0x0; + int day = 0x0; + int hour = 0x0; + int min = 0x0; + int sec = 0x0; + + sysTime = gettime(); + + year = (sysTime/YEAR) + 1970; + sysTime -= (YEAR * (year-1970)); + sysTime -= DAY*(((year-1970)+1)/4); + for (i = 11;i >= 0;i--) { + if ((sysTime - monthSecs[i]) > 0) { + month = i; + break; + } + } + sysTime -= monthSecs[i]; + if (((month > 1) && (((year-1970)+2)%4)) == 0x0) { + sysTime += DAY; + } + + day = (sysTime/DAY); + sysTime -= (day*DAY); + hour = (sysTime/HOUR); + sysTime -= (hour*HOUR); + min = (sysTime/MINUTE); + sysTime -= (min*MINUTE); + sec = sysTime; + + printf("[%s][%02d/%02d/%i, %02d:%02d.%02d]\n",argv[0],month,day,year,hour,min,sec); + return(0); + } + +/*** + END + ***/ + diff --git a/src/bin/cp/Makefile b/src/bin/cp/Makefile new file mode 100644 index 0000000..e1d1ea1 --- /dev/null +++ b/src/bin/cp/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = cp + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/cp/main.c b/src/bin/cp/main.c new file mode 100644 index 0000000..e45c71c --- /dev/null +++ b/src/bin/cp/main.c @@ -0,0 +1,68 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + int i = 0x0; + char *buffer = (char *)malloc(0x2000); + FILE *in = 0x0; + FILE *out = 0x0; + in = fopen(argv[1],"rb"); + out = fopen(argv[2],"wb"); + /* + while (!feof(in)) { + */ + for (i=0;i<21;i++) { + fread(buffer,0x1000,1,in); + fwrite(buffer,0x1000,1,out); + } + fclose(in); + fclose(out); + return(0x0); + } + +/*** + $Log: main.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:57 reddawg + no message + + Revision 1.3 2004/05/24 13:40:35 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/disklabel/Makefile b/src/bin/disklabel/Makefile new file mode 100644 index 0000000..26003be --- /dev/null +++ b/src/bin/disklabel/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = disklabel + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/disklabel/main.c b/src/bin/disklabel/main.c new file mode 100644 index 0000000..bdbf664 --- /dev/null +++ b/src/bin/disklabel/main.c @@ -0,0 +1,120 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include + +#include "ubixfs.h" + + +int main(int argc,char **argv) { + FILE *fd; + struct ubixDiskLabel *d = (struct ubixDiskLabel *)malloc(512); + int i = 0x0; + char buf[256]; + + printf("Ubix Disk Label Editor Version 1.0\n"); + printf("(c) 2004 Ubix Corp \n\n"); + + if (argc >= 2) { + printf("Drive Info (%s):\n",argv[1]); + fd = fopen(argv[1],"rb"); + } + else { + printf("Drive Info (hd0):\n"); + fd = fopen("hd0@devfs","rb"); + } + fseek(fd,512,0); + fread(d,512,1,fd); + + if (argc >= 3) { + i = atoi(argv[2]); + printf("d->partitions[%i].p_size = %i, ",i,d->partitions[i].p_size); + printf("New Value: "); + gets((char *)&buf); + d->partitions[i].p_size = atoi(buf); + printf("d->partitions[%i].p_offset = %i, ",i,d->partitions[i].p_offset); + printf("New Value: "); + gets((char *)&buf); + d->partitions[i].p_offset = atoi(buf); + printf("d->partitions[%i].p_fstype = %i, ",i,d->partitions[i].p_fstype); + printf("New Value: "); + gets((char *)&buf); + d->partitions[i].p_fstype = atoi(buf); + printf("d->partitions[%i].p_bsize = %i, ",i,d->partitions[i].p_bsize); + printf("New Value: "); + gets((char *)&buf); + d->partitions[i].p_bsize = atoi(buf); + printf("\n"); + printf("d->partitions[%i].p_size = %i\n",i,d->partitions[i].p_size); + printf("d->partitions[%i].p_offset = %i\n",i,d->partitions[i].p_offset); + printf("d->partitions[%i].p_fstype = %i\n",i,d->partitions[i].p_fstype); + printf("d->partitions[%i].p_bsize = %i\n",i,d->partitions[i].p_bsize); + fseek(fd,512,0); + fwrite(d,512,1,fd); + } + else { + for (i=0;i<4;i++) { + if (d->partitions[i].p_fstype != 0x0) { + printf("d->partitions[%i].p_size = %i\n",i,d->partitions[i].p_size); + printf("d->partitions[%i].p_offset = %i\n",i,d->partitions[i].p_offset); + printf("d->partitions[%i].p_fstype = 0x%X\n",i,d->partitions[i].p_fstype); + printf("d->partitions[%i].p_bsize = 0x%X\n",i,d->partitions[i].p_bsize); + } + } + } + + fclose(fd); + + return(0); + } + +/*** + $Log: main.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:58 reddawg + no message + + Revision 1.3 2004/06/01 01:30:43 reddawg + No more warnings and organized make files + + Revision 1.2 2004/05/24 13:42:29 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/disklabel/ubixfs.h b/src/bin/disklabel/ubixfs.h new file mode 100644 index 0000000..42662cf --- /dev/null +++ b/src/bin/disklabel/ubixfs.h @@ -0,0 +1,92 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: ubixfs.h 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include + +#define DOSPTYP_UBX 0x2A /* UbixFS partition type */ +#define UBIXDISKMAGIC ((uInt32)0x45) /* The disk magic number */ +#define MAXUBIXPARTITIONS 16 +#define UBIXFSMAGIC ((uInt32)0x69) /* The File System Magic Number */ + +struct ubixDiskLabel { + uInt32 magicNum; + uInt32 magicNum2; + uInt16 driveType; + uInt16 numPartitions; + struct ubixPartitions { /* the partition table */ + uInt32 p_size; /* number of sectors in partition */ + uInt32 p_offset; /* starting sector */ + uInt32 p_fsize; /* filesystem basic fragment size */ + uInt32 p_bsize; /* BAT size */ + uInt8 p_fstype; /* filesystem type, see below */ + uInt8 p_frag; /* filesystem fragments per block */ + } partitions[MAXUBIXPARTITIONS]; + }; + +//Block Allocation Table Entry +struct blockAllocationTableEntry { + long attributes; //Block Attributes + long realSector; //Real Sector + long nextBlock; //Sector Of Next Block + long reserved; //Reserved + }; + + +struct directoryEntry { + uInt32 startCluster; //Starting Cluster Of File + uInt32 size; //Size Of File + uInt32 creationDate; //Date Created + uInt32 lastModified; //Date Last Modified + uInt32 uid; //UID Of Owner + uInt32 gid; //GID Of Owner + uInt16 attributes; //Files Attributes + uInt16 permissions; //Files Permissions + char fileName[256]; //File Name + }; + +/*** + $Log: ubixfs.h,v $ + Revision 1.2 2006/10/26 23:52:26 reddawg + Fixens + + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:59 reddawg + no message + + Revision 1.2 2004/05/24 13:54:52 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/edit/Makefile b/src/bin/edit/Makefile new file mode 100644 index 0000000..44505b1 --- /dev/null +++ b/src/bin/edit/Makefile @@ -0,0 +1,49 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = edit + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +INCLUDES = -I../../include.new + +LIBRARIES = ../../lib/libc/libc.so + +STARTUP = ../../lib/csu/*.o + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + #strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/edit/main.c b/src/bin/edit/main.c new file mode 100644 index 0000000..558afa2 --- /dev/null +++ b/src/bin/edit/main.c @@ -0,0 +1,60 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + extern char *environ; + char in[1024]; + FILE *out; + size_t count = 0x0; + printf("UbixOS Text Editor\n"); + printf("V1.0\n"); + printf("ARGC: [%i]\n",argc); + printf("ARGV[0]: [%s]\n",argv[0]); + + out = fopen("/test.txt","r"); + + while (!feof(out)) { + printf("%c",fgetc(out)); + } + + //printf("[%S]",getenv("TEST")); + printf("\nENV TEST: [0x%X]\n",environ); + setenv("BLAH","WOOT",1); + printf("[%s]",getenv("BLAH")); + + return(0); + } + +/*** + END + ***/ + diff --git a/src/bin/fdisk/Makefile b/src/bin/fdisk/Makefile new file mode 100644 index 0000000..b125aae --- /dev/null +++ b/src/bin/fdisk/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = fdisk + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/fdisk/main.c b/src/bin/fdisk/main.c new file mode 100644 index 0000000..1648d30 --- /dev/null +++ b/src/bin/fdisk/main.c @@ -0,0 +1,151 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include + +#include "ubixfs.h" + +struct dos_partition { + unsigned char dp_flag; /* bootstrap flags */ + unsigned char dp_shd; /* starting head */ + unsigned char dp_ssect; /* starting sector */ + unsigned char dp_scyl; /* starting cylinder */ + unsigned char dp_type; /* partition type */ + unsigned char dp_ehd; /* end head */ + unsigned char dp_esect; /* end sector */ + unsigned char dp_ecyl; /* end cylinder */ + uInt32 dp_start; /* absolute starting sector number */ + uInt32 dp_size; /* partition size in sectors */ +}; + + +int main(int argc,char **argv) { + FILE *fd; + FILE *mbr; + struct dos_partition *d = 0x0; + char *data = (char *)malloc(512); + int i = 0x0; + char buf[256]; + + d = (struct dos_partition *)(data + 0x1BE); + + printf("Ubix Disk Editor Version 1.0\n"); + printf("(c) 2004 Ubix Corp \n\n"); + + if (argc >= 2) { + printf("Drive Info (%s):\n",argv[1]); + fd = fopen(argv[1],"rb"); + } + else { + printf("Drive Info (ad0):\n"); + fd = fopen("devfs:ad0","rb"); + } + if (fd->size == 0x0) { + printf("Invalid Device\n"); + exit(0x1); + } + + fseek(fd,0,0); + fread(data,512,1,fd); + + if (argc >= 3) { + i = atoi(argv[2]); + if (i == 0) { + mbr = fopen("sys:mrb","rb"); + fseek(mbr,0,0); + fread(data,512,1,mbr); + printf("Installing Ubix MBR\n"); + } + else { + i--; + printf("d[%i].dp_type = %i, ",i,d[i].dp_type); + printf("New Value: "); + gets((char *)&buf); + d[i].dp_type = atoi(buf); + printf("d[%i].dp_start: %i, ",i,d[i].dp_start); + printf("New Value: "); + gets((char *)&buf); + d[i].dp_start = atoi(buf); + printf("d[%i].dp_size: %i, ",i,d[i].dp_size); + printf("New Value: "); + gets((char *)&buf); + d[i].dp_size = atoi(buf); + printf("d[%i].dp_type: 0x%X\n",i,d[i].dp_type); + printf("d[%i].dp_start: %i\n",i,d[i].dp_start); + printf("d[%i].dp_size: %i\n",i,d[i].dp_size); + } + fseek(fd,0,0); + fwrite(data,512,1,fd); + } + else { + printf("Partition Table:\n"); + for (i=0;i<4;i++) { + if (d[i].dp_type != 0x0) { + printf("d[%i].dp_type: 0x%X\n",i,d[i].dp_type); + printf("d[%i].dp_start: %i\n",i,d[i].dp_start); + printf("d[%i].dp_size: %i\n",i,d[i].dp_size); + } + } + } + + fclose(fd); + + return(0); + } + +/*** + $Log: main.c,v $ + Revision 1.2 2006/10/12 15:00:26 reddawg + More changes + + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:58 reddawg + no message + + Revision 1.9 2004/08/15 00:33:02 reddawg + Wow the ide driver works again + + Revision 1.8 2004/06/01 01:30:43 reddawg + No more warnings and organized make files + + Revision 1.7 2004/05/24 13:54:52 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/fdisk/ubixfs.h b/src/bin/fdisk/ubixfs.h new file mode 100644 index 0000000..42662cf --- /dev/null +++ b/src/bin/fdisk/ubixfs.h @@ -0,0 +1,92 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: ubixfs.h 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include + +#define DOSPTYP_UBX 0x2A /* UbixFS partition type */ +#define UBIXDISKMAGIC ((uInt32)0x45) /* The disk magic number */ +#define MAXUBIXPARTITIONS 16 +#define UBIXFSMAGIC ((uInt32)0x69) /* The File System Magic Number */ + +struct ubixDiskLabel { + uInt32 magicNum; + uInt32 magicNum2; + uInt16 driveType; + uInt16 numPartitions; + struct ubixPartitions { /* the partition table */ + uInt32 p_size; /* number of sectors in partition */ + uInt32 p_offset; /* starting sector */ + uInt32 p_fsize; /* filesystem basic fragment size */ + uInt32 p_bsize; /* BAT size */ + uInt8 p_fstype; /* filesystem type, see below */ + uInt8 p_frag; /* filesystem fragments per block */ + } partitions[MAXUBIXPARTITIONS]; + }; + +//Block Allocation Table Entry +struct blockAllocationTableEntry { + long attributes; //Block Attributes + long realSector; //Real Sector + long nextBlock; //Sector Of Next Block + long reserved; //Reserved + }; + + +struct directoryEntry { + uInt32 startCluster; //Starting Cluster Of File + uInt32 size; //Size Of File + uInt32 creationDate; //Date Created + uInt32 lastModified; //Date Last Modified + uInt32 uid; //UID Of Owner + uInt32 gid; //GID Of Owner + uInt16 attributes; //Files Attributes + uInt16 permissions; //Files Permissions + char fileName[256]; //File Name + }; + +/*** + $Log: ubixfs.h,v $ + Revision 1.2 2006/10/26 23:52:26 reddawg + Fixens + + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:59 reddawg + no message + + Revision 1.2 2004/05/24 13:54:52 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/format/Makefile b/src/bin/format/Makefile new file mode 100644 index 0000000..418f569 --- /dev/null +++ b/src/bin/format/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 121 2016-01-14 03:18:20Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = format + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIIES = ../../lib/libc/libc.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ${BUILD_DIR}/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ${BUILD_DIR}/bin/$(BINARY) diff --git a/src/bin/format/main.c b/src/bin/format/main.c new file mode 100644 index 0000000..5872c27 --- /dev/null +++ b/src/bin/format/main.c @@ -0,0 +1,61 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include + + +int main(int argc,char **argv) { + printf("UbixOS Format V1.0\n"); + return(0); + } + +/*** + $Log: main.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:08 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:13:59 reddawg + no message + + Revision 1.4 2004/06/01 01:30:43 reddawg + No more warnings and organized make files + + Revision 1.3 2004/05/24 14:09:20 reddawg + Clean Up + + + END + ***/ diff --git a/src/bin/init/Makefile b/src/bin/init/Makefile new file mode 100644 index 0000000..bfbe689 --- /dev/null +++ b/src/bin/init/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 148 2016-01-18 19:34:32Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = init + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#LIBRARIES = ../../lib/build/libc_old.static.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -static -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) +# strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/init/main.c b/src/bin/init/main.c new file mode 100644 index 0000000..db777dd --- /dev/null +++ b/src/bin/init/main.c @@ -0,0 +1,126 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 158 2016-01-19 02:08:13Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc,char **argv) { + int i=0x0; + mpi_message_t myMsg; + + + + /* Create a mailbox for this task */ + /* + if (mpi_createMbox("init") != 0x0) { + printf("Error: Failed to creating mail box: init\n"); + exit(0x1); + } + */ + + /* Make sure we have superuser permissions if not exit */ + if ((getuid() != 0x0) || (getgid() != 0x0)) { + printf("Error: This program must be run by root.\n"); + exit(0x1); + } + + printf("Initializing UbixOS\n"); + + + /* Start TTYD */ +/* + i = fork(); + + + if (0x0 == i) { + printf("Error: Could not start TTYD\n"); + execve("sys:/bin/ttyd",0x0,0x0); + printf("Error: Could not start TTYD\n"); + exit(0x0); + } +*/ + + +/* + i = fork(); + if (0x0 == i) { + printf("Starting Ubix Registry (ubistry)\n"); + exec("sys:/ubistry",0x0); + printf("Error: Error Starting ubistry\n"); + exit(0x0); + } + + while (pidStatus(i) > 0x0) { + sched_yield(); + } +*/ + startup: + i = fork(); + + printf("FORKED: %i!\n", i); + + if (0 == i) { + printf("Starting Login Daemon.\n"); + execve("sys:/bin/login",0x0,0x0); + printf("Error Starting System\n"); + exit(0x0); + } + + while (pidStatus(i) > 0x0) { + /* + fetchAgain: + if (mpi_fetchMessage("init",&myMsg) == 0x0) { + switch (myMsg.header) { + case 10: + printf("Exec: (%s)\n",myMsg.data); + break; + default: + printf("MailBox: init Received Message %i:%s\n",myMsg.header,myMsg.data); + break; + } + goto fetchAgain; + } + */ + sched_yield(); + } + printf("login exited?"); + + goto startup; + + return(0x0); + } + +/*** + END + ***/ + diff --git a/src/bin/launcher/Makefile b/src/bin/launcher/Makefile new file mode 100644 index 0000000..21974b0 --- /dev/null +++ b/src/bin/launcher/Makefile @@ -0,0 +1,50 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +Makefile.incl +Makefile.incl + +INCLUDES += -I./include -I../../lib/views/sunlight/include -I../../lib/libcpp/include -I../../lib/objgfx40/objgfx40 +CFLAGS = -nostdlib -fno-exceptions -frtti +LIBRARIES += ../../lib/libstdc++/*.o + +#Linker +LD = ld + +#Binary File Name +BINARY = launcher + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = launcher.o ubixButton.o ubixDesktop.o + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../build/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O -DNOBOOL $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O -DNOBOOL $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BINARY) diff --git a/src/bin/launcher/include/ubixButton.h b/src/bin/launcher/include/ubixButton.h new file mode 100644 index 0000000..34ee379 --- /dev/null +++ b/src/bin/launcher/include/ubixButton.h @@ -0,0 +1,13 @@ +#ifndef UBIXBUTTON_H +#define UBIXBUTTON_H + +#include + +class ubixButton : public vButton { + public: + ubixButton(vContext *); +// virtual bool vCreate(void); + virtual void vDraw(void); + virtual ~ubixButton(void); +}; // ubixButton +#endif diff --git a/src/bin/launcher/include/ubixDesktop.h b/src/bin/launcher/include/ubixDesktop.h new file mode 100644 index 0000000..61a1a38 --- /dev/null +++ b/src/bin/launcher/include/ubixDesktop.h @@ -0,0 +1,14 @@ +#ifndef UBIXDESKTOP_H +#define UBIXDESKTOP_H + +#include + +class ubixDesktop : public vContext { + protected: + public: + ubixDesktop(vContext *); + virtual bool vCreate(void); + virtual void vDraw(void); + virtual ~ubixDesktop(void); +}; // ubixDesktop +#endif diff --git a/src/bin/launcher/launcher.cpp b/src/bin/launcher/launcher.cpp new file mode 100644 index 0000000..db6cd82 --- /dev/null +++ b/src/bin/launcher/launcher.cpp @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +int +main(void) { + ubixDesktop * desktop = new ubixDesktop(NULL); + ubixButton * daButton = new ubixButton(desktop); + desktop->vCreate(); + daButton->vCreate(); + delete daButton; + delete desktop; + + return 0; +} diff --git a/src/bin/launcher/ubixButton.cpp b/src/bin/launcher/ubixButton.cpp new file mode 100644 index 0000000..f74f65c --- /dev/null +++ b/src/bin/launcher/ubixButton.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +ubixButton::ubixButton(vContext * parent) : vButton(parent) { + vSetSize(48, 48); + vSetPos(0, 600-vGetHeight()); + vSetStyle("default.button.border.size", new sSize(0)); + return; +} // ubixButton::ubixButton() + +void +ubixButton::vDraw(void) { + return; +} // ubixButton::vDraw() + +ubixButton::~ubixButton(void) { + return; +} // ubixButton::~ubixButton() diff --git a/src/bin/launcher/ubixDesktop.cpp b/src/bin/launcher/ubixDesktop.cpp new file mode 100644 index 0000000..c9afad0 --- /dev/null +++ b/src/bin/launcher/ubixDesktop.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +ubixDesktop::ubixDesktop(vContext * parent) : vContext(parent) { + vSetStyle("default.button.border.size", new sSize(2)); + vSetStyle("default.font.filename", new sString("ROM8X14.DPF")); + vSetStyle("default.font.color.foreground", + new sRGBA8Color(255, 255, 255, 255)); + vSetStyle("default.font.color.background", + new sRGBA8Color(0, 0, 0, 255)); + vSetStyle("default.desktop.pixelformat", + new sPixelFormat(16, 11,5,0,0, 5,6,5,0)); + return; +} // ubixDesktop::ubixDesktop + +bool +ubixDesktop::vCreate(void) { + return true; +} // ubixDesktop::vCreate + +void +ubixDesktop::vDraw(void) { + return; +} // ubixDesktop::vDraw + +ubixDesktop::~ubixDesktop(void) { + return; +} diff --git a/src/bin/ld/Makefile b/src/bin/ld/Makefile new file mode 100644 index 0000000..db85020 --- /dev/null +++ b/src/bin/ld/Makefile @@ -0,0 +1,46 @@ +# $Id: Makefile 119 2016-01-14 03:06:36Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +OUTPUT = ld.so + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o findlibrary.o findfunc.o addlibrary.o entry.o + +# Link The Binary +$(OUTPUT) : $(OBJS) + $(CC) -m32 -nostdlib -shared -Wl,-soname,$(OUTPUT) -Wl,-m,elf_i386_fbsd -e _ld -o ../../build/libexec/$(OUTPUT) $(OBJS) $(LIBRARIES) $(SUBS) +# strip $(OUTPUT) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CFLAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(OUTPUT) diff --git a/src/bin/ld/addlibrary.c b/src/bin/ld/addlibrary.c new file mode 100644 index 0000000..e527520 --- /dev/null +++ b/src/bin/ld/addlibrary.c @@ -0,0 +1,161 @@ +#include +#include +#include "ld.h" + +ldLibrary *ldAddLibrary(const char *lib) { + int i = 0x0; + int x = 0x0; + int rel = 0x0; + uInt32 *reMap = 0x0; + char *newLoc = 0x0; + FILE *linkerFd = 0x0; + char tmpFile[1024]; + ldLibrary *tmpLib = 0x0; + + if ((tmpLib = (ldLibrary *)malloc(sizeof(ldLibrary))) == 0x0) { + printf("malloc failed: tmpLib\n"); + exit(0x1); + } + if (tmpLib->output == 0x0) { + /* Hack because we have no ld path set */ + sprintf(tmpFile,"sys:/lib/%s",lib); + linkerFd = fopen(tmpFile,"rb"); + if (linkerFd->fd == 0x0) { + printf("Could not open library: %s\n",lib); + exit(-1); + } + //if ((tmpLib->output = (char *)malloc((linkerFd->size+0x4000))) == 0x0) { + //if ((tmpLib->output = (char *)malloc(0x111000)) == 0x0) { + if ((tmpLib->output = (char *)getPage((0x111000/0x1000),2)) == 0x0) { + printf("malloc failed: tmpLib->output\n"); + exit(0x1); + } + sprintf(tmpLib->name,lib); + } + printf("Base: {0x%X}\n",tmpLib->output); + if (tmpLib->linkerHeader == 0x0) { + fseek(linkerFd,0x0,0x0); + if ((tmpLib->linkerHeader = (elfHeader *)malloc(sizeof(elfHeader))) == 0x0) { + printf("malloc failed: tmpLib->linkerHeader\n"); + exit(0x1); + } + fread(tmpLib->linkerHeader,sizeof(elfHeader),1,linkerFd); + } + if (tmpLib->linkerProgramHeader == 0x0) { + if ((tmpLib->linkerProgramHeader = (elfProgramHeader *)malloc(sizeof(elfProgramHeader)*tmpLib->linkerHeader->ePhnum)) == 0x0) { + printf("malloc failed: tmpLib->linkerProgramHeader\n"); + exit(0x1); + } + fseek(linkerFd,tmpLib->linkerHeader->ePhoff,0); + fread(tmpLib->linkerProgramHeader,sizeof(elfProgramHeader),tmpLib->linkerHeader->ePhnum,linkerFd); + + for (i=0;ilinkerHeader->ePhnum;i++) { + switch (tmpLib->linkerProgramHeader[i].phType) { + case PT_LOAD: + case PT_DYNAMIC: + newLoc = (char *)tmpLib->linkerProgramHeader[i].phVaddr + (uInt32)tmpLib->output; + fseek(linkerFd,tmpLib->linkerProgramHeader[i].phOffset,0); + fread(newLoc,tmpLib->linkerProgramHeader[i].phFilesz,1,linkerFd); + break; + case PT_GNU_STACK: + /* Tells us if the stack should be executable. Failsafe to + executable until we add checking */ + printf("NOT DEF1\n"); + break; + case PT_PAX_FLAGS: + /* Not sure... */ + printf("NOT DEF2\n"); + break; + default: + printf("Unhandled Header (ld.so) : %08x\n", tmpLib->linkerProgramHeader[i].phType); + break; + } + } + } + + if (tmpLib->linkerSectionHeader == 0x0) { + if ((tmpLib->linkerSectionHeader = (elfSectionHeader *)malloc(sizeof(elfSectionHeader)*tmpLib->linkerHeader->eShnum)) == 0x0) { + printf("malloc failed: tmpLib->linkerSectionHeader\n"); + exit(0x1); + } + fseek(linkerFd,tmpLib->linkerHeader->eShoff,0); + fread(tmpLib->linkerSectionHeader,sizeof(elfSectionHeader),tmpLib->linkerHeader->eShnum,linkerFd); + + if (tmpLib->linkerShStr == 0x0) { + tmpLib->linkerShStr = (char *)malloc(tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shOffset,0); + fread(tmpLib->linkerShStr,tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shSize,1,linkerFd); + } + + for (i = 0x0;i < tmpLib->linkerHeader->eShnum;i++) { + switch (tmpLib->linkerSectionHeader[i].shType) { + case 3: + if (!strcmp((tmpLib->linkerShStr + tmpLib->linkerSectionHeader[i].shName),".dynstr")) { + if (tmpLib->linkerDynStr == 0x0) { + if ((tmpLib->linkerDynStr = (char *)malloc(tmpLib->linkerSectionHeader[i].shSize)) == 0x0) { + printf("malloc failed: tmpLib->linkerDynStr\n"); + exit(0x1); + } + fseek(linkerFd,tmpLib->linkerSectionHeader[i].shOffset,0); + fread(tmpLib->linkerDynStr,tmpLib->linkerSectionHeader[i].shSize,1,linkerFd); + } + } + break; + case 9: + if ((tmpLib->linkerElfRel = (elfPltInfo *)malloc(tmpLib->linkerSectionHeader[i].shSize)) == 0x0) { + printf("malloc failed: tmpLib->linkerElfRel\n"); + exit(0x1); + } + fseek(linkerFd,tmpLib->linkerSectionHeader[i].shOffset,0x0); + fread(tmpLib->linkerElfRel,tmpLib->linkerSectionHeader[i].shSize,1,linkerFd); + + for (x=0x0;xlinkerSectionHeader[i].shSize/sizeof(elfPltInfo);x++) { + rel = ELF32_R_SYM(tmpLib->linkerElfRel[x].pltInfo); + reMap = (uInt32 *)((uInt32)tmpLib->output + tmpLib->linkerElfRel[x].pltOffset); + switch (ELF32_R_TYPE(tmpLib->linkerElfRel[x].pltInfo)) { + case R_386_32: + *reMap += ((uInt32)tmpLib->output + tmpLib->linkerRelSymTab[rel].dynValue); + //printf("[0x%X]",*reMap); + break; + case R_386_PC32: + *reMap += ((uInt32)tmpLib->output + tmpLib->linkerRelSymTab[rel].dynValue) - (uInt32)reMap; + break; + case R_386_RELATIVE: + *reMap += (uInt32)tmpLib->output; + break; + case R_386_JMP_SLOT: + *reMap += (uInt32)tmpLib->output; + break; + case R_386_GLOB_DAT: + *reMap = ((uInt32)tmpLib->output + tmpLib->linkerRelSymTab[rel].dynValue); + break; + default: + printf("Unhandled sym: [0x%X]\n", ELF32_R_TYPE(tmpLib->linkerElfRel[x].pltInfo)); + while (1); + break; + } + } + free(tmpLib->linkerElfRel); + break; + case 11: + if (tmpLib->linkerRelSymTab == 0x0) { + tmpLib->linkerRelSymTab = (elfDynSym *)malloc(tmpLib->linkerSectionHeader[i].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[i].shOffset,0); + fread(tmpLib->linkerRelSymTab,tmpLib->linkerSectionHeader[i].shSize,1,linkerFd); + tmpLib->sym = i; + } + break; + } + } + } + if (libs != 0x0) + libs->prev = tmpLib; + tmpLib->prev = 0x0; + tmpLib->next = libs; + libs = tmpLib; + + if (linkerFd) { + fclose(linkerFd); + } + return(tmpLib); + } diff --git a/src/bin/ld/elf.h b/src/bin/ld/elf.h new file mode 100644 index 0000000..d344299 --- /dev/null +++ b/src/bin/ld/elf.h @@ -0,0 +1,186 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: elf.h 89 2016-01-12 00:20:40Z reddawg $ + +**************************************************************************************/ + +#ifndef _ELF_H +#define _ELF_H + +#include + +#define elfExecutable 0x002 +#define elfLibrary 0x003 + +#define R_386_NONE 0 /* none none */ +#define R_386_32 1 /* word32 S + A */ +#define R_386_PC32 2 /* word32 S + A - P */ +#define R_386_GOT32 3 /* word32 G + A - P */ +#define R_386_PLT32 4 /* word32 L + A - P */ +#define R_386_COPY 5 /* none none */ +#define R_386_GLOB_DAT 6 /* word32 S */ +#define R_386_JMP_SLOT 7 /* word32 S */ +#define R_386_RELATIVE 8 /* word32 B + A */ +#define R_386_GOTOFF 9 /* word32 S + A - GOT */ +#define R_386_GOTPC 10 /* word32 GOT + A - P */ + + +/* Elf Types */ +#define ET_NONE 0 // No file type +#define ET_REL 1 // Relocatable file +#define ET_EXEC 2 // Executable file +#define ET_DYN 3 // Shared object file +#define ET_CORE 4 // Core file +#define ET_LOPROC 0xff00 // Processor-specific +#define ET_HIPROC 0xffff +/* End Elf Types */ + +/* Elf Machine Types */ +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola 68000 +#define EM_88K 5 // Motorola 88000 +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS RS3000 +/* End Elf Machines Types */ + +/* Elf Version */ +#define EV_NONE 0 // Invalid version +#define EV_CURRENT 1 // Current version +/* End Elf Version */ + +/* Elf Program Header Types */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME 0x6474e550 +#define PT_GNU_STACK (PT_LOOS + 0x474e551) +#define PT_GNU_RELRO (PT_LOOS + 0x474e552) +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) +/* End Elf Program Header Types */ + +typedef struct { + uInt8 eIdent[16]; /* File identification. */ + uInt16 eType; /* File type. */ + uInt16 eMachine; /* Machine architecture. */ + uInt32 eVersion; /* ELF format version. */ + uInt32 eEntry; /* Entry point. */ + uInt32 ePhoff; /* Program Header file offset. */ + uInt32 eShoff; /* Section header file offset. */ + uInt32 eFlags; /* Architecture-specific flags. */ + uInt16 eEhsize; /* Size of ELF header in bytes. */ + uInt16 ePhentsize; /* Size of program header entry. */ + uInt16 ePhnum; /* Number of program header entries. */ + uInt16 eShentsize; /* Size of section header entry. */ + uInt16 eShnum; /* Number of section header entries. */ + uInt16 eShstrndx; /* Section name strings section. */ + } elfHeader; + +typedef struct { + uInt32 phType; /* Entry type. */ + uInt32 phOffset; /* File offset of contents. */ + uInt32 phVaddr; /* Virtual address in memory image. */ + uInt32 phPaddr; /* Physical address (not used). */ + uInt32 phFilesz; /* Size of contents in file. */ + uInt32 phMemsz; /* Size of contents in memory. */ + uInt32 phFlags; /* Access permission flags. */ + uInt32 phAlign; /* Alignment in memory and file. */ + } elfProgramHeader; + +typedef struct { + uInt32 shName; /* Section name (index into the section header string table). */ + uInt32 shType; /* Section type. */ + uInt32 shFlags; /* Section flags. */ + uInt32 shAddr; /* Address in memory image. */ + uInt32 shOffset; /* Offset in file. */ + uInt32 shSize; /* Size in bytes. */ + uInt32 shLink; /* Index of a related section. */ + uInt32 shInfo; /* Depends on section type. */ + uInt32 shAddralign; /* Alignment in bytes. */ + uInt32 shEntsize; /* Size of each entry in section. */ + } elfSectionHeader; + +typedef struct { + uInt32 pltOffset; + uInt32 pltInfo; + } elfPltInfo; + +typedef struct { + uInt32 dynName; + uInt32 dynValue; + uInt32 dynSize; + uInt8 dynInfo; + uInt8 dynOther; + uInt16 dynShndx; + } elfDynSym; + +typedef struct { + uInt32 dynVal; + uInt32 dynPtr; + } elfDynamic; + + +char *elfGetShType(int); +char *elfGetPhType(int); +char *elfGetRelType(int); + +#define ELF32_R_SYM(i) ((i)>>8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s, t) ((s)<<8+(unsigned char)(t)) + +/* New Stuff */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +typedef struct { + long d_tag; + union { + uInt32 d_val; + uInt32 d_ptr; + } d_un; + } Elf32_Dyn; + + +#endif + diff --git a/src/bin/ld/entry.S b/src/bin/ld/entry.S new file mode 100644 index 0000000..5b7ba32 --- /dev/null +++ b/src/bin/ld/entry.S @@ -0,0 +1,57 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: entry.S 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +.globl _ld +.text +.code32 + +_ld: + call ld + add $8,%esp + push %eax + ret + +/*** + $Log: entry.S,v $ + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:14:00 reddawg + no message + + Revision 1.1 2004/06/17 11:58:10 reddawg + ld.so: Made a few changes to the way it functions hopefully it will + improve some of its performance. + + END + ***/ + diff --git a/src/bin/ld/findfunc.c b/src/bin/ld/findfunc.c new file mode 100644 index 0000000..527000c --- /dev/null +++ b/src/bin/ld/findfunc.c @@ -0,0 +1,32 @@ +#include +#include +#include "ld.h" + +uInt32 ldFindFunc(const char *func,const char *lib) { + int i = 0x0; + int x = 0x0; + uInt32 *funcPtr = 0x0; + ldLibrary *libPtr = 0x0; + + for (x = 0; x < lib_c;x++) { + libPtr = ldFindLibrary(lib + lib_s[x]); + if (libPtr == 0x0) { + libPtr = ldAddLibrary(lib + lib_s[x]); + } + + for (i=0x0;ilinkerSectionHeader[libPtr->sym].shSize/sizeof(elfDynSym);i++) { + if (!strcmp(func,(libPtr->linkerDynStr + libPtr->linkerRelSymTab[i].dynName))) { + funcPtr = (uInt32 *)((uInt32)(libPtr->linkerRelSymTab[i].dynValue) + (uInt32)libPtr->output); + if (funcPtr == 0x0) { + printf("[%s:0x%X]\n",func,funcPtr); + } + return((uInt32)funcPtr); + break; + } + } + } + + printf("ERROR COULDN'T FIND FUNCTION: %s:%s\n",func,lib); + return(0x0); + } + diff --git a/src/bin/ld/findlibrary.c b/src/bin/ld/findlibrary.c new file mode 100644 index 0000000..f071e7d --- /dev/null +++ b/src/bin/ld/findlibrary.c @@ -0,0 +1,13 @@ +#include +#include "ld.h" + +ldLibrary *ldFindLibrary(const char *lib) { + ldLibrary *tmpLibs = 0x0; + + for (tmpLibs = libs;tmpLibs != 0x0;tmpLibs = tmpLibs->next) { + if (!strcmp(tmpLibs->name,lib)) { + return(tmpLibs); + } + } + return(0x0); + } diff --git a/src/bin/ld/ld.h b/src/bin/ld/ld.h new file mode 100644 index 0000000..0255e4d --- /dev/null +++ b/src/bin/ld/ld.h @@ -0,0 +1,31 @@ +#include +#include +#include "elf.h" + +typedef struct ldLibrary_s { + struct ldLibrary_s *next; + struct ldLibrary_s *prev; + char name[256]; + elfHeader *linkerHeader; + elfSectionHeader *linkerSectionHeader; + elfProgramHeader *linkerProgramHeader; + elfDynSym *linkerRelSymTab; + elfPltInfo *linkerElfRel; + char *linkerShStr; + char *linkerDynStr; + char *output; + int sym; + } ldLibrary; + +extern ldLibrary *libs; +extern int lib_c; +extern int lib_s[10]; + +uInt32 ldFindFunc(const char *,const char *); +ldLibrary *ldFindLibrary(const char *); +ldLibrary *ldAddLibrary(const char *); + +/*** + END + ***/ + diff --git a/src/bin/ld/main.c b/src/bin/ld/main.c new file mode 100644 index 0000000..ee9f78b --- /dev/null +++ b/src/bin/ld/main.c @@ -0,0 +1,159 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 122 2016-01-14 03:45:52Z reddawg $ + + *****************************************************************************************/ + +#include +#include +#include +#include "ld.h" + +ldLibrary *libs = 0x0; +int lib_c = 0x0; +int lib_s[10]; + +static elfHeader *binaryHeader = 0x0; +static elfSectionHeader *binarySectionHeader = 0x0; +static char *binaryShStr = 0x0; +static char *binaryDynStr = 0x0; +static elfDynSym *binaryRelSymTab = 0x0; +static Elf32_Dyn *binaryElf32_Dyn = 0x0; +static elfPltInfo *binaryElfRelDyn = 0x0; +static elfPltInfo *binaryElfRel = 0x0; + +uInt32 ld( uInt32 got2, uInt32 entry ) { + int i = 0x0; + int x = 0x0; + int y = 0x0; + int rel = 0x0; + int relDyn = 0x0; + uInt32 *reMap = 0x0; + FILE *binaryFd = 0x0; + + if ( binaryHeader == 0x0 ) { + binaryFd = malloc( sizeof(FILE) ); + binaryFd->fd = (uInt32) got2; + fseek( binaryFd, 0x0, 0x0 ); + binaryHeader = (elfHeader *) malloc( sizeof(elfHeader) ); + fread( binaryHeader, sizeof(elfHeader), 1, binaryFd ); + } + + if ( binarySectionHeader == 0x0 ) { + binarySectionHeader = (elfSectionHeader *) malloc( sizeof(elfSectionHeader) * binaryHeader->eShnum ); + fseek( binaryFd, binaryHeader->eShoff, 0 ); + fread( binarySectionHeader, sizeof(elfSectionHeader), binaryHeader->eShnum, binaryFd ); + + if ( binaryShStr == 0x0 ) { + binaryShStr = (char *) malloc( binarySectionHeader[binaryHeader->eShstrndx].shSize ); + fseek( binaryFd, binarySectionHeader[binaryHeader->eShstrndx].shOffset, 0 ); + fread( binaryShStr, binarySectionHeader[binaryHeader->eShstrndx].shSize, 1, binaryFd ); + } + + for ( i = 0x0; i < binaryHeader->eShnum ; i++ ) { + switch ( binarySectionHeader[i].shType ) { + case 3: + if ( !strcmp( ( binaryShStr + binarySectionHeader[i].shName ), ".dynstr" ) ) { + if ( binaryDynStr == 0x0 ) { + binaryDynStr = (char *) malloc( binarySectionHeader[i].shSize ); + fseek( binaryFd, binarySectionHeader[i].shOffset, 0 ); + fread( binaryDynStr, binarySectionHeader[i].shSize, 1, binaryFd ); + } + } + break; + case SHT_DYNAMIC: + binaryElf32_Dyn = (Elf32_Dyn *) malloc( binarySectionHeader[i].shSize ); + fseek( binaryFd, binarySectionHeader[i].shOffset, 0 ); + fread( binaryElf32_Dyn, binarySectionHeader[i].shSize, 1, binaryFd ); + for ( x = 0; x < binarySectionHeader[i].shSize / sizeof(Elf32_Dyn) ; x++ ) { + if ( binaryElf32_Dyn[x].d_tag == 1 ) { + lib_s[lib_c] = binaryElf32_Dyn[x].d_un.d_ptr; + lib_c++; + } + } + break; + case SHT_REL: + // if (!strcmp(binaryShStr + binarySectionHeader[i].shName,".rel.dyn")) + // relDyn = i; + // else + rel = i; + break; + case 11: + if ( binaryRelSymTab == 0x0 ) { + binaryRelSymTab = (elfDynSym *) malloc( binarySectionHeader[i].shSize ); + fseek( binaryFd, binarySectionHeader[i].shOffset, 0 ); + fread( binaryRelSymTab, binarySectionHeader[i].shSize, 1, binaryFd ); + } + break; + } + } + } + + /* + if ((binaryElfRelDyn == 0x0) && (relDyn != 0)) { + binaryElfRelDyn = (elfPltInfo *)malloc(binarySectionHeader[i].shSize); + fseek(binaryFd,binarySectionHeader[relDyn].shOffset,0x0); + fread(binaryElfRelDyn,binarySectionHeader[relDyn].shSize,1,binaryFd); + + for (x = 0;x < binarySectionHeader[relDyn].shSize / sizeof(elfPltInfo);x++) { + switch (ELF32_R_TYPE(binaryElfRelDyn[x].pltInfo)) { + case R_386_COPY: + printf("COPY"); + reMap = (uInt32 *)binaryElfRelDyn[x].pltOffset; + *reMap = 0x1; + break; + default: + //printf("UNHANDLED THING"); + break; + } + printf("y: [%i:0x%X]",y,binaryElfRelDyn[x].pltOffset); + } + } + */ + + if ( binaryElfRel == 0x0 ) { + binaryElfRel = (elfPltInfo *) malloc( binarySectionHeader[rel].shSize ); + fseek( binaryFd, binarySectionHeader[rel].shOffset, 0x0 ); + fread( binaryElfRel, binarySectionHeader[rel].shSize, 1, binaryFd ); + } + + i = ( entry / sizeof(elfPltInfo) ); + x = ELF32_R_SYM( binaryElfRel[i].pltInfo ); + reMap = (uInt32 *) binaryElfRel[i].pltOffset; + *reMap = ldFindFunc( binaryDynStr + binaryRelSymTab[x].dynName, binaryDynStr ); + printf( "\nld(%s)", binaryDynStr + binaryRelSymTab[x].dynName ); + //*reMap = ldFindFunc(binaryDynStr + binaryRelSymTab[x].dynName,(char *)(binaryDynStr + 1)); + + if ( binaryFd ) { + fclose( binaryFd ); + } + + return ( *reMap ); +} + +/*** + END + ***/ diff --git a/src/bin/login/Makefile b/src/bin/login/Makefile new file mode 100644 index 0000000..01e2f78 --- /dev/null +++ b/src/bin/login/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = login + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#LIBRARIES = ../../lib/libc/libc.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) +# strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/login/main.c b/src/bin/login/main.c new file mode 100644 index 0000000..f620c5e --- /dev/null +++ b/src/bin/login/main.c @@ -0,0 +1,153 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 159 2016-01-19 03:07:04Z reddawg $ + +**************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +struct passwd { + char username[32]; + char password[32]; + int uid; + int gid; + char shell[128]; + char realname[256]; + char path[256]; + }; + +static char *pgets(char *string) { + int count=0,ch=0; + while (1) { + ch = fgetc(stdin); + if(ch == 10) { + printf("\n"); + break; + } + else if(ch == 8 && count > 0) count-=2; + else if(ch == 0) count--; + else string[count] = ch; + if (ch != 8) printf("*"); + count++; + } + string[count] = '\0'; + return(string); + } + +int main() { + FILE *fd; + int shellPid = 0,i = 0x0; + char userName[32]; + char passWord[32]; + char *data2 = 0x0; + struct passwd *data = 0x0; + + + if ((getuid() != 0x0) && (getgid() != 0x0)) { + printf("This Application Must Be Run As Root.\n"); + exit(-1); + } + + if ((data = (struct passwd *)malloc(0x1000)) == 0x0) { + printf("Malloc Failed\n"); + exit(0x1); + } + + fd = fopen("sys:/etc/userdb","r"); + if (fd->fd == 0x0) { + printf("Missing User Database.\n"); + exit(0x1); + } + + fread(data,0x1000,0x1,fd); + + fclose(fd); + + if ((data2 = (char *)malloc(384)) == 0x0) { + printf("Malloc Failed\n"); + exit(0x1); + } + +/* we need to move this into the libc for getpwent(), etc */ +/* + foo = auth("root", "user"); + if(foo != -1) + printf("yay\n"); + else + printf("damn\n"); +*/ + + login: + printf("\nUbixOS/IA-32 (devel.ubixos.com) (console)"); + printf("\n\nLogin: "); + gets((char *)&userName); + printf("Password: "); + pgets((char *)&passWord); + + for (i=0x0;i<(4096/sizeof(struct passwd));i++) { + if (0x0 == strcmp(userName,data[i].username)) { + if (0x0 == strcmp(passWord,data[i].password)) { + shellPid = fork(); + if (shellPid == 0x0) { + if (setuid(data[i].uid) != 0x0) { + printf("Set UID Failed\n"); + } + + if (setgid(data[i].gid) != 0x0) { + printf("Set GID Failed\n"); + } + + fd = 0x0; + fd = fopen("sys:/etc/motd","r"); + + //if ((fd = fopen("sys:/motd","r")) == 0x0) { + if (fd == 0x0) { + printf("No MOTD"); + } + else { + fread(data2,384,1,fd); + printf("%s\n",data2); + } + fclose(fd); + //chdir(data[i].path); + chdir("sys:/bin/"); + execve(data[i].shell,0x0,0x0); + printf("Error: Problem Starting Shell\n"); + exit(-1); + } + else { + while (pidStatus(shellPid) > 0) { + sched_yield(); + } + goto login; + } + } + } + } + printf("Login Incorrect!\n"); + goto login; + return(0x0); + } + diff --git a/src/bin/ls/Makefile b/src/bin/ls/Makefile new file mode 100644 index 0000000..55ec9fd --- /dev/null +++ b/src/bin/ls/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = ls + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../../build/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + #strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(BINARY) diff --git a/src/bin/ls/main.c b/src/bin/ls/main.c new file mode 100644 index 0000000..1574b9f --- /dev/null +++ b/src/bin/ls/main.c @@ -0,0 +1,138 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +**************************************************************************************/ + +#include +#include +#include +#include + + +#define permRead 0x8 +#define permWrite 0x4 +#define permExecute 0x2 +#define permHidden 0x1 + + +//UbixFS Directory Entry +struct directoryEntry { + uint32_t startCluster; //Starting Cluster Of File + uint32_t size; //Size Of File + uint32_t creationDate; //Date Created + uint32_t lastModified; //Date Last Modified + uint32_t uid; //UID Of Owner + uint32_t gid; //GID Of Owner + uint16_t attributes; //Files Attributes + uint16_t permissions; //Files Permissions + char fileName[256]; //File Name + }; + +#define typeFile 1 +#define typeContainer 2 +#define typeDirectory 4 +#define typeDeleted 8 + +int main(int argc,char **argv) { + int i = 0x0,x = 0x0,tmpPerms = 0x0; + char *pwd = 0x0; + char *permsData = 0x0; + FILE *fd; + struct directoryEntry *dirEntry = 0x0; + + pwd = (char *)malloc(256); + permsData = (char *)malloc(13); + + if (argv == 0x0) { + getcwd(pwd,256); +printf("PWD1: %s\n", pwd); + if ((fd = fopen(pwd,"rb")) == 0x0) { + printf("Error: Reading Directory\n"); + exit(1); + } + } + else if (argv[1] == 0x0) { + getcwd(pwd,256); +printf("PWD2: %s\n", pwd); + if ((fd = fopen(pwd,"rb")) == 0x0) { + printf("Error: Reading Directory\n"); + exit(1); + } + } + else { + getcwd(pwd,256); +printf("PWD3: %s\n", pwd); + fd = fopen(argv[1],"rb"); + if (fd->fd == 0x0) { + printf("Error: Reading Directory\n"); + exit(1); + } + } + dirEntry = (struct directoryEntry *)malloc(fd->size); + fread(dirEntry,fd->size,1,fd); + pwd[0] = '/'; + for (i=0;i<(fd->size/sizeof(struct directoryEntry));i++) { +printf("[fN: %s]", dirEntry[i].fileName); + if ((dirEntry[i].fileName[0] > 0) && (dirEntry[i].fileName[0] != '/')) { + for (x=0;x<12;x++) { + permsData[x] = '-'; + } + if ((dirEntry[i].attributes & typeDeleted) == typeDeleted) { + permsData[0] = 'd'; + goto next; + } + else if ((dirEntry[i].attributes & typeFile) == typeFile) { + permsData[0] = 'F'; + } + else if ((dirEntry[i].attributes & typeDirectory) == typeDirectory) { + permsData[0] = 'D'; + } + else if ((dirEntry[i].attributes & typeContainer) == typeContainer) { + permsData[0] = '@'; + } + else { + permsData[0] = 'U'; + } + tmpPerms = ((dirEntry[i].permissions & 0xF00) >> 8); + if ((tmpPerms & permRead) == permRead) permsData[1] = 'R'; + if ((tmpPerms & permWrite) == permWrite) permsData[2] = 'W'; + if ((tmpPerms & permExecute) == permExecute) permsData[3] = 'E'; + if ((tmpPerms & permHidden) == permHidden) permsData[4] = 'H'; + tmpPerms = ((dirEntry[i].permissions & 0x0F0) >> 4); + if ((tmpPerms & permRead) == permRead) permsData[5] = 'R'; + if ((tmpPerms & permWrite) == permWrite) permsData[6] = 'W'; + if ((tmpPerms & permExecute) == permExecute) permsData[7] = 'E'; + if ((tmpPerms & permHidden) == permHidden) permsData[8] = 'H'; + tmpPerms = ((dirEntry[i].permissions & 0x00F) >> 0); + if ((tmpPerms & permRead) == permRead) permsData[9] = 'R'; + if ((tmpPerms & permWrite) == permWrite) permsData[10] = 'W'; + if ((tmpPerms & permExecute) == permExecute) permsData[11] = 'E'; + if ((tmpPerms & permHidden) == permHidden) permsData[12] = 'H'; + printf("%s %i %i %i %s\n",permsData,(int)dirEntry[i].uid,(int)dirEntry[i].gid,(int)dirEntry[i].size,dirEntry[i].fileName); + next: + asm("nop"); + } + } + if (fclose(fd) != 0x0) { + printf("Error Closing Directory\n"); + } + return(0); + } diff --git a/src/bin/mount/Makefile b/src/bin/mount/Makefile new file mode 100644 index 0000000..a860e2d --- /dev/null +++ b/src/bin/mount/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = mount + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../../build/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(BINARY) diff --git a/src/bin/mount/main.c b/src/bin/mount/main.c new file mode 100644 index 0000000..75a03f1 --- /dev/null +++ b/src/bin/mount/main.c @@ -0,0 +1,28 @@ +#include +#include + +void usage(); + +int main(int argc,char * const argv[]) { + int ch = 0x0; + while ((ch = getopt(argc, argv, "adlF:fo:prwt:uv")) != -1) { + printf("[%i]\n",ch); + switch (ch) { + default: + usage(); + } + argc -= optind; + argv += optind; + } + return(0x0); + } + +void usage() { + + (void)printf("%s\n%s\n%s\n", +"usage: mount [-adflpruvw] [-F fstab] [-o options] [-t ufs | external_type]", +" mount [-dfpruvw] special | node", +" mount [-dfpruvw] [-o options] [-t ufs | external_type] special node"); + exit(1); +} + diff --git a/src/bin/muffin/Makefile b/src/bin/muffin/Makefile new file mode 100644 index 0000000..7d52000 --- /dev/null +++ b/src/bin/muffin/Makefile @@ -0,0 +1,52 @@ +# $Id: Makefile 119 2016-01-14 03:06:36Z reddawg $ +# Application Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Compiler Flags +CFLAGS = -DNOBOOL -fno-builtin -fno-exceptions -nostdlib -nostdinc + +#Linker +LD = ld + +#Binary File Name +BINARY = muffin + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#Libraries +LIBRARIES2 = ../../lib/objgfx40/*.o ../../lib/libcpp/*.o + +#Include +INCLUDE = -I../../lib/libc/include -I../../lib/libcpp/include -I../../lib/objgfx40 + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../../build/bin/$@ $(STARTUP) $(LIBRARIES) $(LIBRARIES2) $(OBJS) + strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -fomit-frame-pointer -O $(CFLAGS) $(INCLUDE) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -fomit-frame-pointer -O $(CFLAGS) $(INCLUDE) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDE) -c -o $@ $< + +.c.s: + $(CC) -Wall -fomit-frame-pointer -O $(CFLAGS) $(INCLUDE) -S -o $@ $< + +.S.o: + $(CC) -Wall -fomit-frame-pointer $(INCLUDE) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(BINARY) diff --git a/src/bin/muffin/main.cc b/src/bin/muffin/main.cc new file mode 100644 index 0000000..30868da --- /dev/null +++ b/src/bin/muffin/main.cc @@ -0,0 +1,35 @@ +#include +extern "C" { + #include + #include + #include + } + +int main() { + vWindow *window = new vWindow(); + uInt16 i = 0x0; + uInt16 ii = 0x0; + uInt16 iii = 0x0; + if (fork() == 0x0) { + window->vCreate(); + window->vSDECommand(1); + while (1) { + for (i=0x2;i<0xFF;i += 16) { + for (ii=0x0;ii<0xFF;ii+= 16) { + for (iii= 0x0;iii< 0xFF;iii+= 16) { + window->Clear(window->Pack(i,ii,iii)); + window->FillRect(50, 50, 100, 100, window->Pack(255, 0, 0)); + window->FillRect(50, 50, 100, 100, window->Pack(255, 0, 0)); + window->FillRect(100, 50, 150, 100, window->Pack(0, 255, 0)); + window->FillRect(150, 50, 200, 100, window->Pack(0, 0, 255)); + window->FillRect(200, 50, 250, 100, window->Pack(0, 0, 0)); + window->FillRect(250, 50, 300, 100, window->Pack(255, 255, 255)); + window->vSDECommand(3); + } + } + } + } + window->vSDECommand(4); + } + return(0); + } diff --git a/src/bin/rtld-elf/Makefile b/src/bin/rtld-elf/Makefile new file mode 100644 index 0000000..734c27d --- /dev/null +++ b/src/bin/rtld-elf/Makefile @@ -0,0 +1,59 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +INCLUDES = -I../../include.new -I./ + +CFLAGS+= -Wall -DFREEBSD_ELF -DIN_RTLD -DPIC +CFLAGS = -O2 -fno-strict-aliasing -pipe -Wall -DFREEBSD_ELF -DIN_RTLD -I./ -fpic -DPIC -std=gnu99 -Wformat=2 -Wno-format-extra-args -Werror -DDEBUG +#MrOlsen 2016-01-13 CFLAGS = -O2 -fno-strict-aliasing -pipe -Wall -DFREEBSD_ELF -DIN_RTLD -I./ -fpic -elf -DPIC -std=gnu99 -Wformat=2 -Wno-format-extra-args -Werror -DDEBUG + + +#Linker +LD = ld + +#Binary File Name +OUTPUT = ld-elf.so.1 + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = rtld_start.o reloc.o rtld.o rtld_lock.o map_object.o malloc.o xmalloc.o debug.o libmap.o + +LIBRARIES = #../../lib/libc/libc.so + + +# Link The Binary +$(OUTPUT) : $(OBJS) +# $(CC) -fpic -nostdlib -shared -Wl,-soname,$(OUTPUT) -e .rtld_start -o $(OUTPUT) $(OBJS) $(LIBRARIES) $(SUBS) +# $(CC) $(CFLAGS) -nostdlib -e .rtld_start -elf -shared -Wl,-Bsymbolic -o $(OUTPUT) $(OBJS) -lc_pic +# $(CC) $(CFLAGS) -nostdlib -e .rtld_start -elf -shared -Wl,-Bsymbolic -o $(OUTPUT) $(OBJS) ./libc_pic.a #-lc_pic + $(CC) $(CFLAGS) -nostdlib -e .rtld_start -elf -shared -Wl,-Bsymbolic -o ../../build/libexec/$(OUTPUT) $(OBJS) ../../lib/libc/pic.a #-lc_pic +# strip $(OUTPUT) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(OUTPUT) diff --git a/src/bin/rtld-elf/debug.c b/src/bin/rtld-elf/debug.c new file mode 100644 index 0000000..3a83b66 --- /dev/null +++ b/src/bin/rtld-elf/debug.c @@ -0,0 +1,143 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/debug.c,v 1.4 2003/06/19 16:09:18 mdodd Exp $ + */ + +/* + * Support for printing debugging messages. + */ + +#include +#include + +#include "debug.h" +#include "rtld.h" + +static const char rel_header[] = + " symbol name r_info r_offset st_value st_size address value\n" + " ------------------------------------------------------------------------------\n"; +static const char rel_format[] = " %-25s %6lx %08lx %08lx %7d %10p %08lx\n"; + +int debug = 0; + +void +debug_printf(const char *format, ...) +{ + if (debug) { + va_list ap; + va_start(ap, format); + + fflush(stdout); + vfprintf(stderr, format, ap); + putc('\n', stderr); + + va_end(ap); + } +} + +void +dump_relocations (Obj_Entry *obj0) +{ + Obj_Entry *obj; + + for (obj = obj0; obj != NULL; obj = obj->next) { + dump_obj_relocations(obj); + } +} + +void +dump_obj_relocations (Obj_Entry *obj) +{ + + printf("Object \"%s\", relocbase %p\n", obj->path, obj->relocbase); + + if (obj->relsize) { + printf("Non-PLT Relocations: %ld\n", + (obj->relsize / sizeof(Elf_Rel))); + dump_Elf_Rel(obj, obj->rel, obj->relsize); + } + + if (obj->relasize) { + printf("Non-PLT Relocations with Addend: %ld\n", + (obj->relasize / sizeof(Elf_Rela))); + dump_Elf_Rela(obj, obj->rela, obj->relasize); + } + + if (obj->pltrelsize) { + printf("PLT Relocations: %ld\n", + (obj->pltrelsize / sizeof(Elf_Rel))); + dump_Elf_Rel(obj, obj->pltrel, obj->pltrelsize); + } + + if (obj->pltrelasize) { + printf("PLT Relocations with Addend: %ld\n", + (obj->pltrelasize / sizeof(Elf_Rela))); + dump_Elf_Rela(obj, obj->pltrela, obj->pltrelasize); + } +} + +void +dump_Elf_Rel (Obj_Entry *obj, const Elf_Rel *rel0, u_long relsize) +{ + const Elf_Rel *rel; + const Elf_Rel *rellim; + const Elf_Sym *sym; + Elf_Addr *dstaddr; + + printf("%s", rel_header); + rellim = (const Elf_Rel *)((const char *)rel0 + relsize); + for (rel = rel0; rel < rellim; rel++) { + dstaddr = (Elf_Addr *)(obj->relocbase + rel->r_offset); + sym = obj->symtab + ELF_R_SYM(rel->r_info); + printf(rel_format, + obj->strtab + sym->st_name, + (u_long)rel->r_info, (u_long)rel->r_offset, + (u_long)sym->st_value, (int)sym->st_size, + dstaddr, (u_long)*dstaddr); + } + return; +} + +void +dump_Elf_Rela (Obj_Entry *obj, const Elf_Rela *rela0, u_long relasize) +{ + const Elf_Rela *rela; + const Elf_Rela *relalim; + const Elf_Sym *sym; + Elf_Addr *dstaddr; + + printf("%s", rel_header); + relalim = (const Elf_Rela *)((const char *)rela0 + relasize); + for (rela = rela0; rela < relalim; rela++) { + dstaddr = (Elf_Addr *)(obj->relocbase + rela->r_offset); + sym = obj->symtab + ELF_R_SYM(rela->r_info); + printf(rel_format, + obj->strtab + sym->st_name, + (u_long)rela->r_info, (u_long)rela->r_offset, + (u_long)sym->st_value, (int)sym->st_size, + dstaddr, (u_long)*dstaddr); + } + return; +} diff --git a/src/bin/rtld-elf/debug.h b/src/bin/rtld-elf/debug.h new file mode 100644 index 0000000..68faa0a --- /dev/null +++ b/src/bin/rtld-elf/debug.h @@ -0,0 +1,66 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/debug.h,v 1.6 2004/03/21 01:21:26 peter Exp $ + */ + +/* + * Support for printing debugging messages. + */ + +#ifndef DEBUG_H +#define DEBUG_H 1 + +#ifndef __GNUC__ +#error "This file must be compiled with GCC" +#endif + +#include + +#include +#include + +extern void debug_printf(const char *, ...) __printflike(1, 2); +extern int debug; + +#ifdef DEBUG +#define dbg(format, args...) debug_printf(format , ## args) +#else +#define dbg(format, args...) ((void) 0) +#endif + +#ifndef COMPAT_32BIT +#define _MYNAME "ld-elf.so.1" +#else +#define _MYNAME "ld-elf32.so.1" +#endif + +#define assert(cond) ((cond) ? (void) 0 : \ + (msg(_MYNAME ": assert failed: " __FILE__ ":" \ + __XSTRING(__LINE__) "\n"), abort())) +#define msg(s) write(STDOUT_FILENO, s, strlen(s)) +#define trace() msg(_MYNAME ": " __XSTRING(__LINE__) "\n") + + +#endif /* DEBUG_H */ diff --git a/src/bin/rtld-elf/libmap.c b/src/bin/rtld-elf/libmap.c new file mode 100644 index 0000000..b78fe4c --- /dev/null +++ b/src/bin/rtld-elf/libmap.c @@ -0,0 +1,371 @@ +/* + * $FreeBSD: src/libexec/rtld-elf/libmap.c,v 1.14 2005/02/04 02:46:41 mdodd Exp $ + */ + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" +#include "libmap.h" + +#ifndef _PATH_LIBMAP_CONF +#define _PATH_LIBMAP_CONF "/etc/libmap.conf" +#endif + +#ifdef COMPAT_32BIT +#undef _PATH_LIBMAP_CONF +#define _PATH_LIBMAP_CONF "/etc/libmap32.conf" +#endif + +TAILQ_HEAD(lm_list, lm); +struct lm { + char *f; + char *t; + + TAILQ_ENTRY(lm) lm_link; +}; + +TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head); +struct lmp { + char *p; + enum { T_EXACT=0, T_BASENAME, T_DIRECTORY } type; + struct lm_list lml; + TAILQ_ENTRY(lmp) lmp_link; +}; + +static int lm_count; + +static void lmc_parse (FILE *); +static void lm_add (const char *, const char *, const char *); +static void lm_free (struct lm_list *); +static char * lml_find (struct lm_list *, const char *); +static struct lm_list * lmp_find (const char *); +static struct lm_list * lmp_init (char *); +static const char * quickbasename (const char *); +static int readstrfn (void * cookie, char *buf, int len); +static int closestrfn (void * cookie); + +#define iseol(c) (((c) == '#') || ((c) == '\0') || \ + ((c) == '\n') || ((c) == '\r')) + +int +lm_init (char *libmap_override) +{ + FILE *fp; + + dbg("%s(\"%s\")", __func__, libmap_override); + + TAILQ_INIT(&lmp_head); + + fp = fopen(_PATH_LIBMAP_CONF, "r"); + if (fp) { + lmc_parse(fp); + fclose(fp); + } + + if (libmap_override) { + char *p; + /* do some character replacement to make $LIBMAP look like a + text file, then "open" it with funopen */ + libmap_override = xstrdup(libmap_override); + + for (p = libmap_override; *p; p++) { + switch (*p) { + case '=': + *p = ' '; break; + case ',': + *p = '\n'; break; + } + } + fp = funopen(libmap_override, readstrfn, NULL, NULL, closestrfn); + if (fp) { + lmc_parse(fp); + fclose(fp); + } + } + + return (lm_count == 0); +} + +static void +lmc_parse (FILE *fp) +{ + char *cp; + char *f, *t, *c, *p; + char prog[MAXPATHLEN]; + char line[MAXPATHLEN + 2]; + + dbg("%s(%p)", __func__, fp); + + p = NULL; + while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) { + t = f = c = NULL; + + /* Skip over leading space */ + while (isspace(*cp)) cp++; + + /* Found a comment or EOL */ + if (iseol(*cp)) continue; + + /* Found a constraint selector */ + if (*cp == '[') { + cp++; + + /* Skip leading space */ + while (isspace(*cp)) cp++; + + /* Found comment, EOL or end of selector */ + if (iseol(*cp) || *cp == ']') + continue; + + c = cp++; + /* Skip to end of word */ + while (!isspace(*cp) && !iseol(*cp) && *cp != ']') + cp++; + + /* Skip and zero out trailing space */ + while (isspace(*cp)) *cp++ = '\0'; + + /* Check if there is a closing brace */ + if (*cp != ']') continue; + + /* Terminate string if there was no trailing space */ + *cp++ = '\0'; + + /* + * There should be nothing except whitespace or comment + from this point to the end of the line. + */ + while(isspace(*cp)) cp++; + if (!iseol(*cp)) continue; + + strcpy(prog, c); + p = prog; + continue; + } + + /* Parse the 'from' candidate. */ + f = cp++; + while (!isspace(*cp) && !iseol(*cp)) cp++; + + /* Skip and zero out the trailing whitespace */ + while (isspace(*cp)) *cp++ = '\0'; + + /* Found a comment or EOL */ + if (iseol(*cp)) continue; + + /* Parse 'to' mapping */ + t = cp++; + while (!isspace(*cp) && !iseol(*cp)) cp++; + + /* Skip and zero out the trailing whitespace */ + while (isspace(*cp)) *cp++ = '\0'; + + /* Should be no extra tokens at this point */ + if (!iseol(*cp)) continue; + + *cp = '\0'; + lm_add(p, f, t); + } +} + +static void +lm_free (struct lm_list *lml) +{ + struct lm *lm; + + dbg("%s(%p)", __func__, lml); + + while (!TAILQ_EMPTY(lml)) { + lm = TAILQ_FIRST(lml); + TAILQ_REMOVE(lml, lm, lm_link); + free(lm->f); + free(lm->t); + free(lm); + } + return; +} + +void +lm_fini (void) +{ + struct lmp *lmp; + + dbg("%s()", __func__); + + while (!TAILQ_EMPTY(&lmp_head)) { + lmp = TAILQ_FIRST(&lmp_head); + TAILQ_REMOVE(&lmp_head, lmp, lmp_link); + free(lmp->p); + lm_free(&lmp->lml); + free(lmp); + } + return; +} + +static void +lm_add (const char *p, const char *f, const char *t) +{ + struct lm_list *lml; + struct lm *lm; + + if (p == NULL) + p = "$DEFAULT$"; + + dbg("%s(\"%s\", \"%s\", \"%s\")", __func__, p, f, t); + + if ((lml = lmp_find(p)) == NULL) + lml = lmp_init(xstrdup(p)); + + lm = xmalloc(sizeof(struct lm)); + lm->f = xstrdup(f); + lm->t = xstrdup(t); + TAILQ_INSERT_HEAD(lml, lm, lm_link); + lm_count++; +} + +char * +lm_find (const char *p, const char *f) +{ + struct lm_list *lml; + char *t; + + dbg("%s(\"%s\", \"%s\")", __func__, p, f); + + if (p != NULL && (lml = lmp_find(p)) != NULL) { + t = lml_find(lml, f); + if (t != NULL) { + /* + * Add a global mapping if we have + * a successful constrained match. + */ + lm_add(NULL, f, t); + return (t); + } + } + lml = lmp_find("$DEFAULT$"); + if (lml != NULL) + return (lml_find(lml, f)); + else + return (NULL); +} + +/* Given a libmap translation list and a library name, return the + replacement library, or NULL */ +#ifdef COMPAT_32BIT +char * +lm_findn (const char *p, const char *f, const int n) +{ + char pathbuf[64], *s, *t; + + if (n < sizeof(pathbuf) - 1) { + memcpy(pathbuf, f, n); + pathbuf[n] = '\0'; + s = pathbuf; + } else { + s = xmalloc(n + 1); + strcpy(s, f); + } + t = lm_find(p, s); + if (s != pathbuf) + free(s); + return (t); +} +#endif + +static char * +lml_find (struct lm_list *lmh, const char *f) +{ + struct lm *lm; + + dbg("%s(%p, \"%s\")", __func__, lmh, f); + + TAILQ_FOREACH(lm, lmh, lm_link) + if (strcmp(f, lm->f) == 0) + return (lm->t); + return (NULL); +} + +/* Given an executable name, return a pointer to the translation list or + NULL if no matches */ +static struct lm_list * +lmp_find (const char *n) +{ + struct lmp *lmp; + + dbg("%s(\"%s\")", __func__, n); + + TAILQ_FOREACH(lmp, &lmp_head, lmp_link) + if ((lmp->type == T_EXACT && strcmp(n, lmp->p) == 0) || + (lmp->type == T_DIRECTORY && strncmp(n, lmp->p, strlen(lmp->p)) == 0) || + (lmp->type == T_BASENAME && strcmp(quickbasename(n), lmp->p) == 0)) + return (&lmp->lml); + return (NULL); +} + +static struct lm_list * +lmp_init (char *n) +{ + struct lmp *lmp; + + dbg("%s(\"%s\")", __func__, n); + + lmp = xmalloc(sizeof(struct lmp)); + lmp->p = n; + if (n[strlen(n)-1] == '/') + lmp->type = T_DIRECTORY; + else if (strchr(n,'/') == NULL) + lmp->type = T_BASENAME; + else + lmp->type = T_EXACT; + TAILQ_INIT(&lmp->lml); + TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link); + + return (&lmp->lml); +} + +/* libc basename is overkill. Return a pointer to the character after the + last /, or the original string if there are no slashes. */ +static const char * +quickbasename (const char *path) +{ + const char *p = path; + for (; *path; path++) { + if (*path == '/') + p = path+1; + } + return (p); +} + +static int +readstrfn(void * cookie, char *buf, int len) +{ + static char *current; + static int left; + int copied; + + copied = 0; + if (!current) { + current = cookie; + left = strlen(cookie); + } + while (*current && left && len) { + *buf++ = *current++; + left--; + len--; + copied++; + } + return copied; +} + +static int +closestrfn(void * cookie) +{ + free(cookie); + return 0; +} diff --git a/src/bin/rtld-elf/libmap.h b/src/bin/rtld-elf/libmap.h new file mode 100644 index 0000000..6b0991d --- /dev/null +++ b/src/bin/rtld-elf/libmap.h @@ -0,0 +1,10 @@ +/* + * $FreeBSD: src/libexec/rtld-elf/libmap.h,v 1.4 2005/02/04 02:46:41 mdodd Exp $ + */ + +int lm_init (char *); +void lm_fini (void); +char * lm_find (const char *, const char *); +#ifdef COMPAT_32BIT +char * lm_findn (const char *, const char *, const int); +#endif diff --git a/src/bin/rtld-elf/malloc.c b/src/bin/rtld-elf/malloc.c new file mode 100644 index 0000000..3c43e5f --- /dev/null +++ b/src/bin/rtld-elf/malloc.c @@ -0,0 +1,491 @@ +/*- + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ +static char *rcsid = "$FreeBSD: releng/10.2/libexec/rtld-elf/malloc.c 281452 2015-04-12 06:43:13Z kib $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * malloc.c (Caltech) 2/21/82 + * Chris Kingsley, kingsley@cit-20. + * + * This is a very fast storage allocator. It allocates blocks of a small + * number of different sizes, and keeps free lists of each size. Blocks that + * don't exactly fit are passed up to the next larger size. In this + * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. + * This is designed for use in a virtual memory environment. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rtld_printf.h" + +static void morecore(); +static int findbucket(); + +/* + * Pre-allocate mmap'ed pages + */ +#define NPOOLPAGES (32*1024/pagesz) +static caddr_t pagepool_start, pagepool_end; +static int morepages(); + +/* + * The overhead on a block is at least 4 bytes. When free, this space + * contains a pointer to the next free block, and the bottom two bits must + * be zero. When in use, the first byte is set to MAGIC, and the second + * byte is the size index. The remaining bytes are for alignment. + * If range checking is enabled then a second word holds the size of the + * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC). + * The order of elements is critical: ov_magic must overlay the low order + * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern. + */ +union overhead { + union overhead *ov_next; /* when free */ + struct { + u_char ovu_magic; /* magic number */ + u_char ovu_index; /* bucket # */ +#ifdef RCHECK + u_short ovu_rmagic; /* range magic number */ + u_int ovu_size; /* actual block size */ +#endif + } ovu; +#define ov_magic ovu.ovu_magic +#define ov_index ovu.ovu_index +#define ov_rmagic ovu.ovu_rmagic +#define ov_size ovu.ovu_size +}; + +#define MAGIC 0xef /* magic # on accounting info */ +#define RMAGIC 0x5555 /* magic # on range info */ + +#ifdef RCHECK +#define RSLOP sizeof (u_short) +#else +#define RSLOP 0 +#endif + +/* + * nextf[i] is the pointer to the next free block of size 2^(i+3). The + * smallest allocatable block is 8 bytes. The overhead information + * precedes the data area returned to the user. + */ +#define NBUCKETS 30 +static union overhead *nextf[NBUCKETS]; + +static int pagesz; /* page size */ +static int pagebucket; /* page size bucket */ + +#ifdef MSTATS +/* + * nmalloc[i] is the difference between the number of mallocs and frees + * for a given block size. + */ +static u_int nmalloc[NBUCKETS]; +#include +#endif + +#if defined(MALLOC_DEBUG) || defined(RCHECK) +#define ASSERT(p) if (!(p)) botch("p") +#include +static void +botch(s) + char *s; +{ + fprintf(stderr, "\r\nassertion botched: %s\r\n", s); + (void) fflush(stderr); /* just in case user buffered it */ + abort(); +} +#else +#define ASSERT(p) +#endif + +/* Debugging stuff */ +#define TRACE() rtld_printf("TRACE %s:%d\n", __FILE__, __LINE__) + +/* + * The array of supported page sizes is provided by the user, i.e., the + * program that calls this storage allocator. That program must initialize + * the array before making its first call to allocate storage. The array + * must contain at least one page size. The page sizes must be stored in + * increasing order. + */ +extern size_t *pagesizes; + +void * +malloc(nbytes) + size_t nbytes; +{ + register union overhead *op; + register int bucket; + register long n; + register unsigned amt; + + /* + * First time malloc is called, setup page size and + * align break pointer so all data will be page aligned. + */ + if (pagesz == 0) { + pagesz = n = pagesizes[0]; + if (morepages(NPOOLPAGES) == 0) + return NULL; + op = (union overhead *)(pagepool_start); + n = n - sizeof (*op) - ((long)op & (n - 1)); + if (n < 0) + n += pagesz; + if (n) { + pagepool_start += n; + } + bucket = 0; + amt = 8; + while ((unsigned)pagesz > amt) { + amt <<= 1; + bucket++; + } + pagebucket = bucket; + } + /* + * Convert amount of memory requested into closest block size + * stored in hash buckets which satisfies request. + * Account for space used per block for accounting. + */ + if (nbytes <= (unsigned long)(n = pagesz - sizeof (*op) - RSLOP)) { +#ifndef RCHECK + amt = 8; /* size of first bucket */ + bucket = 0; +#else + amt = 16; /* size of first bucket */ + bucket = 1; +#endif + n = -(sizeof (*op) + RSLOP); + } else { + amt = pagesz; + bucket = pagebucket; + } + while (nbytes > amt + n) { + amt <<= 1; + if (amt == 0) + return (NULL); + bucket++; + } + /* + * If nothing in hash bucket right now, + * request more memory from the system. + */ + if ((op = nextf[bucket]) == NULL) { + morecore(bucket); + if ((op = nextf[bucket]) == NULL) + return (NULL); + } + /* remove from linked list */ + nextf[bucket] = op->ov_next; + op->ov_magic = MAGIC; + op->ov_index = bucket; +#ifdef MSTATS + nmalloc[bucket]++; +#endif +#ifdef RCHECK + /* + * Record allocated size of block and + * bound space with magic numbers. + */ + op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); + op->ov_rmagic = RMAGIC; + *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; +#endif + return ((char *)(op + 1)); +} + +void * +calloc(size_t num, size_t size) +{ + void *ret; + + if (size != 0 && (num * size) / size != num) { + /* size_t overflow. */ + return (NULL); + } + + if ((ret = malloc(num * size)) != NULL) + memset(ret, 0, num * size); + + return (ret); +} + +/* + * Allocate more memory to the indicated bucket. + */ +static void +morecore(bucket) + int bucket; +{ + register union overhead *op; + register int sz; /* size of desired block */ + int amt; /* amount to allocate */ + int nblks; /* how many blocks we get */ + + /* + * sbrk_size <= 0 only for big, FLUFFY, requests (about + * 2^30 bytes on a VAX, I think) or for a negative arg. + */ + sz = 1 << (bucket + 3); +#ifdef MALLOC_DEBUG + ASSERT(sz > 0); +#else + if (sz <= 0) + return; +#endif + if (sz < pagesz) { + amt = pagesz; + nblks = amt / sz; + } else { + amt = sz + pagesz; + nblks = 1; + } + if (amt > pagepool_end - pagepool_start) + if (morepages(amt/pagesz + NPOOLPAGES) == 0) + return; + op = (union overhead *)pagepool_start; + pagepool_start += amt; + + /* + * Add new memory allocated to that on + * free list for this hash bucket. + */ + nextf[bucket] = op; + while (--nblks > 0) { + op->ov_next = (union overhead *)((caddr_t)op + sz); + op = (union overhead *)((caddr_t)op + sz); + } +} + +void +free(cp) + void *cp; +{ + register int size; + register union overhead *op; + + if (cp == NULL) + return; + op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); +#ifdef MALLOC_DEBUG + ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ +#else + if (op->ov_magic != MAGIC) + return; /* sanity */ +#endif +#ifdef RCHECK + ASSERT(op->ov_rmagic == RMAGIC); + ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); +#endif + size = op->ov_index; + ASSERT(size < NBUCKETS); + op->ov_next = nextf[size]; /* also clobbers ov_magic */ + nextf[size] = op; +#ifdef MSTATS + nmalloc[size]--; +#endif +} + +/* + * When a program attempts "storage compaction" as mentioned in the + * old malloc man page, it realloc's an already freed block. Usually + * this is the last block it freed; occasionally it might be farther + * back. We have to search all the free lists for the block in order + * to determine its bucket: 1st we make one pass thru the lists + * checking only the first block in each; if that fails we search + * ``realloc_srchlen'' blocks in each list for a match (the variable + * is extern so the caller can modify it). If that fails we just copy + * however many bytes was given to realloc() and hope it's not huge. + */ +int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ + +void * +realloc(cp, nbytes) + void *cp; + size_t nbytes; +{ + register u_int onb; + register int i; + union overhead *op; + char *res; + int was_alloced = 0; + + if (cp == NULL) + return (malloc(nbytes)); + op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); + if (op->ov_magic == MAGIC) { + was_alloced++; + i = op->ov_index; + } else { + /* + * Already free, doing "compaction". + * + * Search for the old block of memory on the + * free list. First, check the most common + * case (last element free'd), then (this failing) + * the last ``realloc_srchlen'' items free'd. + * If all lookups fail, then assume the size of + * the memory block being realloc'd is the + * largest possible (so that all "nbytes" of new + * memory are copied into). Note that this could cause + * a memory fault if the old area was tiny, and the moon + * is gibbous. However, that is very unlikely. + */ + if ((i = findbucket(op, 1)) < 0 && + (i = findbucket(op, realloc_srchlen)) < 0) + i = NBUCKETS; + } + onb = 1 << (i + 3); + if (onb < (u_int)pagesz) + onb -= sizeof (*op) + RSLOP; + else + onb += pagesz - sizeof (*op) - RSLOP; + /* avoid the copy if same size block */ + if (was_alloced) { + if (i) { + i = 1 << (i + 2); + if (i < pagesz) + i -= sizeof (*op) + RSLOP; + else + i += pagesz - sizeof (*op) - RSLOP; + } + if (nbytes <= onb && nbytes > (size_t)i) { +#ifdef RCHECK + op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); + *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; +#endif + return(cp); + } else + free(cp); + } + if ((res = malloc(nbytes)) == NULL) + return (NULL); + if (cp != res) /* common optimization if "compacting" */ + bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + return (res); +} + +/* + * Search ``srchlen'' elements of each free list for a block whose + * header starts at ``freep''. If srchlen is -1 search the whole list. + * Return bucket number, or -1 if not found. + */ +static int +findbucket(freep, srchlen) + union overhead *freep; + int srchlen; +{ + register union overhead *p; + register int i, j; + + for (i = 0; i < NBUCKETS; i++) { + j = 0; + for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { + if (p == freep) + return (i); + j++; + } + } + return (-1); +} + +#ifdef MSTATS +/* + * mstats - print out statistics about malloc + * + * Prints two lines of numbers, one showing the length of the free list + * for each size category, the second showing the number of mallocs - + * frees for each size category. + */ +mstats(s) + char *s; +{ + register int i, j; + register union overhead *p; + int totfree = 0, + totused = 0; + + fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); + for (i = 0; i < NBUCKETS; i++) { + for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) + ; + fprintf(stderr, " %d", j); + totfree += j * (1 << (i + 3)); + } + fprintf(stderr, "\nused:\t"); + for (i = 0; i < NBUCKETS; i++) { + fprintf(stderr, " %d", nmalloc[i]); + totused += nmalloc[i] * (1 << (i + 3)); + } + fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", + totused, totfree); +} +#endif + + +static int +morepages(n) +int n; +{ + int fd = -1; + int offset; + + if (pagepool_end - pagepool_start > pagesz) { + caddr_t addr = (caddr_t) + (((long)pagepool_start + pagesz - 1) & ~(pagesz - 1)); + if (munmap(addr, pagepool_end - addr) != 0) + rtld_fdprintf(STDERR_FILENO, "morepages: munmap %p", + addr); + } + + offset = (long)pagepool_start - ((long)pagepool_start & ~(pagesz - 1)); + + if ((pagepool_start = mmap(0, n * pagesz, + PROT_READ|PROT_WRITE, + MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) { + rtld_printf("Cannot map anonymous memory\n"); + return 0; + } + pagepool_end = pagepool_start + n * pagesz; + pagepool_start += offset; + + return n; +} diff --git a/src/bin/rtld-elf/map_object.c b/src/bin/rtld-elf/map_object.c new file mode 100644 index 0000000..8d5f24a --- /dev/null +++ b/src/bin/rtld-elf/map_object.c @@ -0,0 +1,372 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/map_object.c,v 1.16 2005/02/27 12:55:40 dfr Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" + +static Elf_Ehdr *get_elf_header (int, const char *); +static int convert_prot(int); /* Elf flags -> mmap protection */ +static int convert_flags(int); /* Elf flags -> mmap flags */ + +/* + * Map a shared object into memory. The "fd" argument is a file descriptor, + * which must be open on the object and positioned at its beginning. + * The "path" argument is a pathname that is used only for error messages. + * + * The return value is a pointer to a newly-allocated Obj_Entry structure + * for the shared object. Returns NULL on failure. + */ +Obj_Entry * +map_object(int fd, const char *path, const struct stat *sb) +{ + Obj_Entry *obj; + Elf_Ehdr *hdr; + int i; + Elf_Phdr *phdr; + Elf_Phdr *phlimit; + Elf_Phdr **segs; + int nsegs; + Elf_Phdr *phdyn; + Elf_Phdr *phphdr; + Elf_Phdr *phinterp; + Elf_Phdr *phtls; + caddr_t mapbase; + size_t mapsize; + Elf_Off base_offset; + Elf_Addr base_vaddr; + Elf_Addr base_vlimit; + caddr_t base_addr; + Elf_Off data_offset; + Elf_Addr data_vaddr; + Elf_Addr data_vlimit; + caddr_t data_addr; + int data_prot; + int data_flags; + Elf_Addr clear_vaddr; + caddr_t clear_addr; + caddr_t clear_page; + size_t nclear; + Elf_Addr bss_vaddr; + Elf_Addr bss_vlimit; + caddr_t bss_addr; + + hdr = get_elf_header(fd, path); + if (hdr == NULL) + return (NULL); + + /* + * Scan the program header entries, and save key information. + * + * We rely on there being exactly two load segments, text and data, + * in that order. + */ + phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff); + phlimit = phdr + hdr->e_phnum; + nsegs = -1; + phdyn = phphdr = phinterp = phtls = NULL; + segs = alloca(sizeof(segs[0]) * hdr->e_phnum); + while (phdr < phlimit) { + switch (phdr->p_type) { + + case PT_INTERP: + phinterp = phdr; + break; + + case PT_LOAD: + segs[++nsegs] = phdr; + if (segs[nsegs]->p_align < PAGE_SIZE) { + _rtld_error("%s: PT_LOAD segment %d not page-aligned", + path, nsegs); + return NULL; + } + break; + + case PT_PHDR: + phphdr = phdr; + break; + + case PT_DYNAMIC: + phdyn = phdr; + break; + + case PT_TLS: + phtls = phdr; + break; + } + + ++phdr; + } + if (phdyn == NULL) { + _rtld_error("%s: object is not dynamically-linked", path); + return NULL; + } + + if (nsegs < 0) { + _rtld_error("%s: too few PT_LOAD segments", path); + return NULL; + } + + /* + * Map the entire address space of the object, to stake out our + * contiguous region, and to establish the base address for relocation. + */ + base_offset = trunc_page(segs[0]->p_offset); + base_vaddr = trunc_page(segs[0]->p_vaddr); + base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); + mapsize = base_vlimit - base_vaddr; + base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; + + mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), + convert_flags(segs[0]->p_flags), fd, base_offset); + if (mapbase == (caddr_t) -1) { + _rtld_error("%s: mmap of entire address space failed: %s", + path, strerror(errno)); + return NULL; + } + if (base_addr != NULL && mapbase != base_addr) { + _rtld_error("%s: mmap returned wrong address: wanted %p, got %p", + path, base_addr, mapbase); + munmap(mapbase, mapsize); + return NULL; + } + + for (i = 0; i <= nsegs; i++) { + /* Overlay the segment onto the proper region. */ + data_offset = trunc_page(segs[i]->p_offset); + data_vaddr = trunc_page(segs[i]->p_vaddr); + data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz); + data_addr = mapbase + (data_vaddr - base_vaddr); + data_prot = convert_prot(segs[i]->p_flags); + data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; + /* Do not call mmap on the first segment - this is redundant */ + if (i && mmap(data_addr, data_vlimit - data_vaddr, data_prot, + data_flags, fd, data_offset) == (caddr_t) -1) { + _rtld_error("%s: mmap of data failed: %s", path, strerror(errno)); + return NULL; + } + + /* Clear any BSS in the last page of the segment. */ + clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; + clear_addr = mapbase + (clear_vaddr - base_vaddr); + clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); + if ((nclear = data_vlimit - clear_vaddr) > 0) { + /* Make sure the end of the segment is writable */ + if ((data_prot & PROT_WRITE) == 0 && + -1 == mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { + _rtld_error("%s: mprotect failed: %s", path, + strerror(errno)); + return NULL; + } + + memset(clear_addr, 0, nclear); + + /* Reset the data protection back */ + if ((data_prot & PROT_WRITE) == 0) + mprotect(clear_page, PAGE_SIZE, data_prot); + } + + /* Overlay the BSS segment onto the proper region. */ + bss_vaddr = data_vlimit; + bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); + bss_addr = mapbase + (bss_vaddr - base_vaddr); + if (bss_vlimit > bss_vaddr) { /* There is something to do */ + if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot, + MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) == (caddr_t) -1) { + _rtld_error("%s: mmap of bss failed: %s", path, + strerror(errno)); + return NULL; + } + } + } + + obj = obj_new(); + if (sb != NULL) { + obj->dev = sb->st_dev; + obj->ino = sb->st_ino; + } + obj->mapbase = mapbase; + obj->mapsize = mapsize; + obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - + base_vaddr; + obj->vaddrbase = base_vaddr; + obj->relocbase = mapbase - base_vaddr; + obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); + if (hdr->e_entry != 0) + obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry); + if (phphdr != NULL) { + obj->phdr = (const Elf_Phdr *) (obj->relocbase + phphdr->p_vaddr); + obj->phsize = phphdr->p_memsz; + } + if (phinterp != NULL) + obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr); + if (phtls != NULL) { + tls_dtv_generation++; + obj->tlsindex = ++tls_max_index; + obj->tlssize = phtls->p_memsz; + obj->tlsalign = phtls->p_align; + obj->tlsinitsize = phtls->p_filesz; + obj->tlsinit = mapbase + phtls->p_vaddr; + } + return obj; +} + +static Elf_Ehdr * +get_elf_header (int fd, const char *path) +{ + static union { + Elf_Ehdr hdr; + char buf[PAGE_SIZE]; + } u; + ssize_t nbytes; + + if ((nbytes = read(fd, u.buf, PAGE_SIZE)) == -1) { + _rtld_error("%s: read error: %s", path, strerror(errno)); + return NULL; + } + + /* Make sure the file is valid */ + if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) { + _rtld_error("%s: invalid file format", path); + return NULL; + } + if (u.hdr.e_ident[EI_CLASS] != ELF_TARG_CLASS + || u.hdr.e_ident[EI_DATA] != ELF_TARG_DATA) { + _rtld_error("%s: unsupported file layout", path); + return NULL; + } + if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT + || u.hdr.e_version != EV_CURRENT) { + _rtld_error("%s: unsupported file version", path); + return NULL; + } + if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) { + _rtld_error("%s: unsupported file type", path); + return NULL; + } + if (u.hdr.e_machine != ELF_TARG_MACH) { + _rtld_error("%s: unsupported machine", path); + return NULL; + } + + /* + * We rely on the program header being in the first page. This is + * not strictly required by the ABI specification, but it seems to + * always true in practice. And, it simplifies things considerably. + */ + if (u.hdr.e_phentsize != sizeof(Elf_Phdr)) { + _rtld_error( + "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path); + return NULL; + } + if (u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) > (size_t)nbytes) { + _rtld_error("%s: program header too large", path); + return NULL; + } + + return (&u.hdr); +} + +void +obj_free(Obj_Entry *obj) +{ + Objlist_Entry *elm; + + if (obj->tls_done) { + free_tls_offset(obj); + } + free(obj->path); + while (obj->needed != NULL) { + Needed_Entry *needed = obj->needed; + obj->needed = needed->next; + free(needed); + } + while (!STAILQ_EMPTY(&obj->dldags)) { + elm = STAILQ_FIRST(&obj->dldags); + STAILQ_REMOVE_HEAD(&obj->dldags, link); + free(elm); + } + while (!STAILQ_EMPTY(&obj->dagmembers)) { + elm = STAILQ_FIRST(&obj->dagmembers); + STAILQ_REMOVE_HEAD(&obj->dagmembers, link); + free(elm); + } + free(obj->origin_path); + free(obj->priv); + free(obj); +} + +Obj_Entry * +obj_new(void) +{ + Obj_Entry *obj; + + obj = CNEW(Obj_Entry); + STAILQ_INIT(&obj->dldags); + STAILQ_INIT(&obj->dagmembers); + return obj; +} + +/* + * Given a set of ELF protection flags, return the corresponding protection + * flags for MMAP. + */ +static int +convert_prot(int elfflags) +{ + int prot = 0; + if (elfflags & PF_R) + prot |= PROT_READ; + if (elfflags & PF_W) + prot |= PROT_WRITE; + if (elfflags & PF_X) + prot |= PROT_EXEC; + return prot; +} + +static int +convert_flags(int elfflags) +{ + int flags = MAP_PRIVATE; /* All mappings are private */ + + /* + * Readonly mappings are marked "MAP_NOCORE", because they can be + * reconstructed by a debugger. + */ + if (!(elfflags & PF_W)) + flags |= MAP_NOCORE; + return flags; +} diff --git a/src/bin/rtld-elf/reloc.c b/src/bin/rtld-elf/reloc.c new file mode 100644 index 0000000..ba9be47 --- /dev/null +++ b/src/bin/rtld-elf/reloc.c @@ -0,0 +1,367 @@ +/*- + * Copyright 1996, 1997, 1998, 1999 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/i386/reloc.c,v 1.18 2005/06/29 23:15:36 peter Exp $ + */ + +/* + * Dynamic linker for ELF. + * + * John Polstra . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" + +/* + * Process the special R_386_COPY relocations in the main program. These + * copy data from a shared object into a region in the main program's BSS + * segment. + * + * Returns 0 on success, -1 on failure. + */ +int +do_copy_relocations(Obj_Entry *dstobj) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; + + assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */ + + rellim = (const Elf_Rel *) ((caddr_t) dstobj->rel + dstobj->relsize); + for (rel = dstobj->rel; rel < rellim; rel++) { + if (ELF_R_TYPE(rel->r_info) == R_386_COPY) { + void *dstaddr; + const Elf_Sym *dstsym; + const char *name; + unsigned long hash; + size_t size; + const void *srcaddr; + const Elf_Sym *srcsym; + Obj_Entry *srcobj; + + dstaddr = (void *) (dstobj->relocbase + rel->r_offset); + dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info); + name = dstobj->strtab + dstsym->st_name; + hash = elf_hash(name); + size = dstsym->st_size; + + for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next) + if ((srcsym = symlook_obj(name, hash, srcobj, false)) != NULL) + break; + + if (srcobj == NULL) { + _rtld_error("Undefined symbol \"%s\" referenced from COPY" + " relocation in %s", name, dstobj->path); + return -1; + } + + srcaddr = (const void *) (srcobj->relocbase + srcsym->st_value); + memcpy(dstaddr, srcaddr, size); + } + } + + return 0; +} + +/* Initialize the special GOT entries. */ +void +init_pltgot(Obj_Entry *obj) +{ + if (obj->pltgot != NULL) { + obj->pltgot[1] = (Elf_Addr) obj; + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start; + } +} + +/* Process the non-PLT relocations. */ +int +reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; + SymCache *cache; + int bytes = obj->nchains * sizeof(SymCache); + int r = -1; + + /* + * The dynamic loader may be called from a thread, we have + * limited amounts of stack available so we cannot use alloca(). + */ + cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); + if (cache == MAP_FAILED) + cache = NULL; + + rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize); + for (rel = obj->rel; rel < rellim; rel++) { + Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rel->r_offset); + + switch (ELF_R_TYPE(rel->r_info)) { + + case R_386_NONE: + break; + + case R_386_32: + { + const Elf_Sym *def; + const Obj_Entry *defobj; + + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); + + if (def == NULL) + goto done; + *where += (Elf_Addr) (defobj->relocbase + def->st_value); + } + break; + + case R_386_PC32: + /* + * I don't think the dynamic linker should ever see this + * type of relocation. But the binutils-2.6 tools sometimes + * generate it. + */ + { + const Elf_Sym *def; + const Obj_Entry *defobj; +//dbg("A.1"); + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); +//dbg("A.2"); + if (def == NULL) + goto done; + + *where += + (Elf_Addr) (defobj->relocbase + def->st_value) - + (Elf_Addr) where; + } + break; + + case R_386_COPY: + /* + * These are deferred until all other relocations have + * been done. All we do here is make sure that the COPY + * relocation is not in a shared library. They are allowed + * only in executable files. + */ +//dbg("386_COPY"); + if (!obj->mainprog) { + _rtld_error("%s: Unexpected R_386_COPY relocation" + " in shared library", obj->path); + goto done; + } + break; + + case R_386_GLOB_DAT: + { +//dbg("386_GD"); + const Elf_Sym *def; + const Obj_Entry *defobj; + + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); + if (def == NULL) + goto done; + + *where = (Elf_Addr) (defobj->relocbase + def->st_value); + } + break; + + case R_386_RELATIVE: + *where += (Elf_Addr) obj->relocbase; + break; + + case R_386_TLS_TPOFF: + { + const Elf_Sym *def; + const Obj_Entry *defobj; + + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); + if (def == NULL) + goto done; + + /* + * We lazily allocate offsets for static TLS as we + * see the first relocation that references the + * TLS block. This allows us to support (small + * amounts of) static TLS in dynamically loaded + * modules. If we run out of space, we generate an + * error. + */ + if (!defobj->tls_done) { + if (!allocate_tls_offset((Obj_Entry*) defobj)) { + _rtld_error("%s: No space available for static " + "Thread Local Storage", obj->path); + goto done; + } + } + + *where += (Elf_Addr) (def->st_value - defobj->tlsoffset); + } + break; + + case R_386_TLS_DTPMOD32: + { + const Elf_Sym *def; + const Obj_Entry *defobj; + + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); + if (def == NULL) + goto done; + + *where += (Elf_Addr) defobj->tlsindex; + } + break; + + case R_386_TLS_DTPOFF32: + { + const Elf_Sym *def; + const Obj_Entry *defobj; + + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + false, cache); + if (def == NULL) + goto done; + + *where += (Elf_Addr) def->st_value; + } + break; + + default: + _rtld_error("%s: Unsupported relocation type %d" + " in non-PLT relocations\n", obj->path, + ELF_R_TYPE(rel->r_info)); + goto done; + } + } + r = 0; +done: + if (cache) + munmap(cache, bytes); + return(r); +} + +/* Process the PLT relocations. */ +int +reloc_plt(Obj_Entry *obj) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; + + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); + for (rel = obj->pltrel; rel < rellim; rel++) { + Elf_Addr *where; + + assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT); + + /* Relocate the GOT slot pointing into the PLT. */ + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + *where += (Elf_Addr)obj->relocbase; + } + return 0; +} + +/* Relocate the jump slots in an object. */ +int +reloc_jmpslots(Obj_Entry *obj) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; + + if (obj->jmpslots_done) + return 0; + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); + for (rel = obj->pltrel; rel < rellim; rel++) { + Elf_Addr *where, target; + const Elf_Sym *def; + const Obj_Entry *defobj; + + assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT); + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL); + if (def == NULL) + return -1; + target = (Elf_Addr)(defobj->relocbase + def->st_value); + reloc_jmpslot(where, target, defobj, obj, rel); + } + obj->jmpslots_done = true; + return 0; +} + +void +allocate_initial_tls(Obj_Entry *objs) +{ + void* tls; + + /* + * Fix the size of the static TLS block by using the maximum + * offset allocated so far and adding a bit for dynamic modules to + * use. + */ + tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA; + tls = allocate_tls(objs, NULL, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); + i386_set_gsbase(tls); +} + +/* GNU ABI */ +__attribute__((__regparm__(1))) +void *___tls_get_addr(tls_index *ti) +{ + Elf_Addr** segbase; + Elf_Addr* dtv; + + __asm __volatile("movl %%gs:0, %0" : "=r" (segbase)); + dtv = segbase[1]; + + return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset); +} + +/* Sun ABI */ +void *__tls_get_addr(tls_index *ti) +{ + Elf_Addr** segbase; + Elf_Addr* dtv; + + __asm __volatile("movl %%gs:0, %0" : "=r" (segbase)); + dtv = segbase[1]; + + return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset); +} diff --git a/src/bin/rtld-elf/rtld.c b/src/bin/rtld-elf/rtld.c new file mode 100644 index 0000000..789071b --- /dev/null +++ b/src/bin/rtld-elf/rtld.c @@ -0,0 +1,2840 @@ +/*- + * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. + * Copyright 2003 Alexander Kabaev . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: rtld.c 114 2016-01-14 02:30:09Z reddawg $ + */ + +/* + * Dynamic linker for ELF. + * + * John Polstra . + */ + +#ifndef __GNUC__ +#error "GCC is needed to compile this file" +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" +#include "libmap.h" +#include "rtld_tls.h" + +#ifndef COMPAT_32BIT +#define PATH_RTLD "/libexec/ld-elf.so.1" +#else +#define PATH_RTLD "/libexec/ld-elf32.so.1" +#endif + +/* Types. */ +typedef void (*func_ptr_type)(); +typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg); + +/* + * This structure provides a reentrant way to keep a list of objects and + * check which ones have already been processed in some way. + */ +typedef struct Struct_DoneList { + const Obj_Entry **objs; /* Array of object pointers */ + unsigned int num_alloc; /* Allocated size of the array */ + unsigned int num_used; /* Number of array slots used */ +} DoneList; + +/* + * Function declarations. + */ +static const char *basename(const char *); +static void die(void); +static void digest_dynamic(Obj_Entry *, int); +static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); +static Obj_Entry *dlcheck(void *); +static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *); +static bool donelist_check(DoneList *, const Obj_Entry *); +static void errmsg_restore(char *); +static char *errmsg_save(void); +static void *fill_search_info(const char *, size_t, void *); +static char *find_library(const char *, const Obj_Entry *); +static const char *gethints(void); +static void init_dag(Obj_Entry *); +static void init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *); +static void init_rtld(caddr_t); +static void initlist_add_neededs(Needed_Entry *needed, Objlist *list); +static void initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, + Objlist *list); +static bool is_exported(const Elf_Sym *); +static void linkmap_add(Obj_Entry *); +static void linkmap_delete(Obj_Entry *); +static int load_needed_objects(Obj_Entry *); +static int load_preload_objects(void); +static Obj_Entry *load_object(char *); +static Obj_Entry *obj_from_addr(const void *); +static void objlist_call_fini(Objlist *); +static void objlist_call_init(Objlist *); +static void objlist_clear(Objlist *); +static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *); +static void objlist_init(Objlist *); +static void objlist_push_head(Objlist *, Obj_Entry *); +static void objlist_push_tail(Objlist *, Obj_Entry *); +static void objlist_remove(Objlist *, Obj_Entry *); +static void objlist_remove_unref(Objlist *); +static void *path_enumerate(const char *, path_enum_proc, void *); +static int relocate_objects(Obj_Entry *, bool, Obj_Entry *); +static int rtld_dirname(const char *, char *); +static void rtld_exit(void); +static char *search_library_path(const char *, const char *); +static const void **get_program_var_addr(const char *name); +static void set_program_var(const char *, const void *); +static const Elf_Sym *symlook_default(const char *, unsigned long hash, + const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt); +static const Elf_Sym *symlook_list(const char *, unsigned long, + Objlist *, const Obj_Entry **, bool in_plt, DoneList *); +static void trace_loaded_objects(Obj_Entry *obj); +static void unlink_object(Obj_Entry *); +static void unload_object(Obj_Entry *); +static void unref_dag(Obj_Entry *); +static void ref_dag(Obj_Entry *); + +void r_debug_state(struct r_debug*, struct link_map*); + +/* + * Data declarations. + */ +static char *error_message; /* Message for dlerror(), or NULL */ +struct r_debug r_debug; /* for GDB; */ +static bool libmap_disable; /* Disable libmap */ +static char *libmap_override; /* Maps to use in addition to libmap.conf */ +static bool trust; /* False for setuid and setgid programs */ +static bool dangerous_ld_env; /* True if environment variables have been + used to affect the libraries loaded */ +static char *ld_bind_now; /* Environment variable for immediate binding */ +static char *ld_debug; /* Environment variable for debugging */ +static char *ld_library_path; /* Environment variable for search path */ +static char *ld_preload; /* Environment variable for libraries to + load first */ +static char *ld_tracing; /* Called from ldd to print libs */ +static Obj_Entry *obj_list; /* Head of linked list of shared objects */ +static Obj_Entry **obj_tail; /* Link field of last object in list */ +static Obj_Entry *obj_main; /* The main program shared object */ +static Obj_Entry obj_rtld; /* The dynamic linker shared object */ +static unsigned int obj_count; /* Number of objects in obj_list */ + +static Objlist list_global = /* Objects dlopened with RTLD_GLOBAL */ + STAILQ_HEAD_INITIALIZER(list_global); +static Objlist list_main = /* Objects loaded at program startup */ + STAILQ_HEAD_INITIALIZER(list_main); +static Objlist list_fini = /* Objects needing fini() calls */ + STAILQ_HEAD_INITIALIZER(list_fini); + +static Elf_Sym sym_zero; /* For resolving undefined weak refs. */ + +#define GDB_STATE(s,m) r_debug.r_state = s; r_debug_state(&r_debug,m); + +extern Elf_Dyn _DYNAMIC; +#pragma weak _DYNAMIC +#ifndef RTLD_IS_DYNAMIC +#define RTLD_IS_DYNAMIC() (&_DYNAMIC != NULL) +#endif + +/* + * These are the functions the dynamic linker exports to application + * programs. They are the only symbols the dynamic linker is willing + * to export from itself. + */ +static func_ptr_type exports[] = { + (func_ptr_type) &_rtld_error, + (func_ptr_type) &dlclose, + (func_ptr_type) &dlerror, + (func_ptr_type) &dlopen, + (func_ptr_type) &dlsym, + (func_ptr_type) &dladdr, + (func_ptr_type) &dllockinit, + (func_ptr_type) &dlinfo, + (func_ptr_type) &_rtld_thread_init, +#ifdef __i386__ + (func_ptr_type) &___tls_get_addr, +#endif + (func_ptr_type) &__tls_get_addr, + (func_ptr_type) &_rtld_allocate_tls, + (func_ptr_type) &_rtld_free_tls, + NULL +}; + +/* + * Global declarations normally provided by crt1. The dynamic linker is + * not built with crt1, so we have to provide them ourselves. + */ +char *__progname; +char **environ; + +/* + * Globals to control TLS allocation. + */ +size_t tls_last_offset; /* Static TLS offset of last module */ +size_t tls_last_size; /* Static TLS size of last module */ +size_t tls_static_space; /* Static TLS space allocated */ +int tls_dtv_generation = 1; /* Used to detect when dtv size changes */ +int tls_max_index = 1; /* Largest module index allocated */ + +/* + * Fill in a DoneList with an allocation large enough to hold all of + * the currently-loaded objects. Keep this as a macro since it calls + * alloca and we want that to occur within the scope of the caller. + */ +#define donelist_init(dlp) \ + ((dlp)->objs = alloca(obj_count * sizeof (dlp)->objs[0]), \ + assert((dlp)->objs != NULL), \ + (dlp)->num_alloc = obj_count, \ + (dlp)->num_used = 0) + +/* + * Main entry point for dynamic linking. The first argument is the + * stack pointer. The stack is expected to be laid out as described + * in the SVR4 ABI specification, Intel 386 Processor Supplement. + * Specifically, the stack pointer points to a word containing + * ARGC. Following that in the stack is a null-terminated sequence + * of pointers to argument strings. Then comes a null-terminated + * sequence of pointers to environment strings. Finally, there is a + * sequence of "auxiliary vector" entries. + * + * The second argument points to a place to store the dynamic linker's + * exit procedure pointer and the third to a place to store the main + * program's object. + * + * The return value is the main program's entry point. + */ +func_ptr_type +_rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) +{ + Elf_Auxinfo *aux_info[AT_COUNT]; + int i; + int argc; + char **argv; + char **env; + Elf_Auxinfo *aux; + Elf_Auxinfo *auxp; + const char *argv0; + Objlist_Entry *entry; + Obj_Entry *obj; + Obj_Entry **preload_tail; + Objlist initlist; + int lockstate; + + /* + * On entry, the dynamic linker itself has not been relocated yet. + * Be very careful not to reference any global data until after + * init_rtld has returned. It is OK to reference file-scope statics + * and string constants, and to call static and global functions. + */ + + /* Find the auxiliary vector on the stack. */ + argc = *sp++; + argv = (char **) sp; + + sp += argc + 1; /* Skip over arguments and NULL terminator */ + env = (char **) sp; + + while (*sp++ != 0); /* Skip over environment, and NULL terminator */ + + aux = (Elf_Auxinfo *) sp; + + + /* Digest the auxiliary vector. */ + for (i = 0; i < AT_COUNT; i++) + aux_info[i] = NULL; + + for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { + if (auxp->a_type < AT_COUNT) { + aux_info[auxp->a_type] = auxp; + } + } + + /* Initialize and relocate ourselves. */ + assert(aux_info[AT_BASE] != NULL); + + init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr); + + __progname = obj_rtld.path; + argv0 = argv[0] != NULL ? argv[0] : "(null)"; + environ = env; + + trust = !issetugid(); + + ld_bind_now = getenv(LD_ "BIND_NOW"); + if (trust) { + ld_debug = getenv(LD_ "DEBUG"); + libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL; + libmap_override = getenv(LD_ "LIBMAP"); + ld_library_path = "/lib";//getenv(LD_ "LIBRARY_PATH"); + ld_preload = getenv(LD_ "PRELOAD"); + dangerous_ld_env = libmap_disable || (libmap_override != NULL) || + (ld_library_path != NULL) || (ld_preload != NULL); + } else + dangerous_ld_env = 0; + ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS"); + + + if (ld_debug != NULL && *ld_debug != '\0') + debug = 1; + + dbg("%s is initialized, base address = %p", __progname, + (caddr_t) aux_info[AT_BASE]->a_un.a_ptr); + dbg("RTLD dynamic = %p", obj_rtld.dynamic); + dbg("RTLD pltgot = %p", obj_rtld.pltgot); + + /* + * Load the main program, or process its program header if it is + * already loaded. + */ + if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */ + int fd = aux_info[AT_EXECFD]->a_un.a_val; + dbg("loading main program"); + obj_main = map_object(fd, argv0, NULL); + close(fd); + if (obj_main == NULL) + die(); + } else { /* Main program already loaded. */ + const Elf_Phdr *phdr; + int phnum; + caddr_t entry; + + dbg("processing main program's program header"); + assert(aux_info[AT_PHDR] != NULL); + phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr; + assert(aux_info[AT_PHNUM] != NULL); + phnum = aux_info[AT_PHNUM]->a_un.a_val; + assert(aux_info[AT_PHENT] != NULL); + assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr)); + assert(aux_info[AT_ENTRY] != NULL); + entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr; + if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL) + die(); + } + + obj_main->path = xstrdup(argv0); + obj_main->mainprog = true; + + /* + * Get the actual dynamic linker pathname from the executable if + * possible. (It should always be possible.) That ensures that + * gdb will find the right dynamic linker even if a non-standard + * one is being used. + */ + if (obj_main->interp != NULL && + strcmp(obj_main->interp, obj_rtld.path) != 0) { + free(obj_rtld.path); + obj_rtld.path = xstrdup(obj_main->interp); + __progname = obj_rtld.path; + } + + + digest_dynamic(obj_main, 0); + + linkmap_add(obj_main); + linkmap_add(&obj_rtld); + + /* Link the main program into the list of objects. */ + *obj_tail = obj_main; + obj_tail = &obj_main->next; + obj_count++; + /* Make sure we don't call the main program's init and fini functions. */ + obj_main->init = obj_main->fini = (Elf_Addr)NULL; + + /* Initialize a fake symbol for resolving undefined weak references. */ + sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); + sym_zero.st_shndx = SHN_UNDEF; + + if (!libmap_disable) + libmap_disable = (bool)lm_init(libmap_override); + + dbg("loading LD_PRELOAD libraries"); + if (load_preload_objects() == -1) + die(); + preload_tail = obj_tail; + + dbg("loading needed objects"); + if (load_needed_objects(obj_main) == -1) + die(); + + /* Make a list of all objects loaded at startup. */ + for (obj = obj_list; obj != NULL; obj = obj->next) { + objlist_push_tail(&list_main, obj); + obj->refcount++; + } + + if (ld_tracing) { /* We're done */ + trace_loaded_objects(obj_main); + exit(0); + } + + if (getenv(LD_ "DUMP_REL_PRE") != NULL) { + dump_relocations(obj_main); + exit (0); + } + + /* setup TLS for main thread */ + dbg("initializing initial thread local storage"); + STAILQ_FOREACH(entry, &list_main, link) { + /* + * Allocate all the initial objects out of the static TLS + * block even if they didn't ask for it. + */ + allocate_tls_offset(entry->obj); + } + + allocate_initial_tls(obj_list); + +debug = 1; + if (relocate_objects(obj_main, + ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld) == -1) + die(); + + dbg("doing copy relocations"); + if (do_copy_relocations(obj_main) == -1) + die(); + + if (getenv(LD_ "DUMP_REL_POST") != NULL) { + dump_relocations(obj_main); + exit (0); + } + + dbg("initializing key program variables"); + set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : ""); + set_program_var("environ", env); + + dbg("initializing thread locks"); + lockdflt_init(); + + /* Make a list of init functions to call. */ + objlist_init(&initlist); + initlist_add_objects(obj_list, preload_tail, &initlist); + + r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */ + + objlist_call_init(&initlist); + lockstate = wlock_acquire(rtld_bind_lock); + objlist_clear(&initlist); + wlock_release(rtld_bind_lock, lockstate); + + dbg("transferring control to program entry point = %p", obj_main->entry); + + /* Return the exit procedure and the program entry point. */ + *exit_proc = rtld_exit; + *objp = obj_main; + return (func_ptr_type) obj_main->entry; +} + +Elf_Addr +_rtld_bind(Obj_Entry *obj, Elf_Size reloff) +{ + const Elf_Rel *rel; + const Elf_Sym *def; + const Obj_Entry *defobj; + Elf_Addr *where; + Elf_Addr target; + int lockstate; + + lockstate = rlock_acquire(rtld_bind_lock); + if (obj->pltrel) + rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff); + else + rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff); + + where = (Elf_Addr *) (obj->relocbase + rel->r_offset); + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL); + if (def == NULL) + die(); + + target = (Elf_Addr)(defobj->relocbase + def->st_value); + + dbg("\"%s\" in \"%s\" ==> %p in \"%s\"", + defobj->strtab + def->st_name, basename(obj->path), + (void *)target, basename(defobj->path)); + + /* + * Write the new contents for the jmpslot. Note that depending on + * architecture, the value which we need to return back to the + * lazy binding trampoline may or may not be the target + * address. The value returned from reloc_jmpslot() is the value + * that the trampoline needs. + */ + target = reloc_jmpslot(where, target, defobj, obj, rel); + rlock_release(rtld_bind_lock, lockstate); + return target; +} + +/* + * Error reporting function. Use it like printf. If formats the message + * into a buffer, and sets things up so that the next call to dlerror() + * will return the message. + */ +void +_rtld_error(const char *fmt, ...) +{ + static char buf[512]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + error_message = buf; + va_end(ap); +} + +/* + * Return a dynamically-allocated copy of the current error message, if any. + */ +static char * +errmsg_save(void) +{ + return error_message == NULL ? NULL : xstrdup(error_message); +} + +/* + * Restore the current error message from a copy which was previously saved + * by errmsg_save(). The copy is freed. + */ +static void +errmsg_restore(char *saved_msg) +{ + if (saved_msg == NULL) + error_message = NULL; + else { + _rtld_error("%s", saved_msg); + free(saved_msg); + } +} + +static const char * +basename(const char *name) +{ + const char *p = strrchr(name, '/'); + return p != NULL ? p + 1 : name; +} + +static void +die(void) +{ + const char *msg = dlerror(); + + if (msg == NULL) + msg = "Fatal error"; + errx(1, "%s", msg); +} + +/* + * Process a shared object's DYNAMIC section, and save the important + * information in its Obj_Entry structure. + */ +static void +digest_dynamic(Obj_Entry *obj, int early) +{ + const Elf_Dyn *dynp; + Needed_Entry **needed_tail = &obj->needed; + const Elf_Dyn *dyn_rpath = NULL; + int plttype = DT_REL; + + obj->bind_now = false; + for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) { + switch (dynp->d_tag) { + + case DT_REL: + obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_RELSZ: + obj->relsize = dynp->d_un.d_val; + break; + + case DT_RELENT: + assert(dynp->d_un.d_val == sizeof(Elf_Rel)); + break; + + case DT_JMPREL: + obj->pltrel = (const Elf_Rel *) + (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_PLTRELSZ: + obj->pltrelsize = dynp->d_un.d_val; + break; + + case DT_RELA: + obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_RELASZ: + obj->relasize = dynp->d_un.d_val; + break; + + case DT_RELAENT: + assert(dynp->d_un.d_val == sizeof(Elf_Rela)); + break; + + case DT_PLTREL: + plttype = dynp->d_un.d_val; + assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA); + break; + + case DT_SYMTAB: + obj->symtab = (const Elf_Sym *) + (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_SYMENT: + assert(dynp->d_un.d_val == sizeof(Elf_Sym)); + break; + + case DT_STRTAB: + obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_STRSZ: + obj->strsize = dynp->d_un.d_val; + break; + + case DT_HASH: + { + const Elf_Hashelt *hashtab = (const Elf_Hashelt *) + (obj->relocbase + dynp->d_un.d_ptr); + obj->nbuckets = hashtab[0]; + obj->nchains = hashtab[1]; + obj->buckets = hashtab + 2; + obj->chains = obj->buckets + obj->nbuckets; + } + break; + + case DT_NEEDED: + if (!obj->rtld) { + Needed_Entry *nep = NEW(Needed_Entry); + nep->name = dynp->d_un.d_val; + nep->obj = NULL; + nep->next = NULL; + + *needed_tail = nep; + needed_tail = &nep->next; + } + break; + + case DT_PLTGOT: + obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_TEXTREL: + obj->textrel = true; + break; + + case DT_SYMBOLIC: + obj->symbolic = true; + break; + + case DT_RPATH: + case DT_RUNPATH: /* XXX: process separately */ + /* + * We have to wait until later to process this, because we + * might not have gotten the address of the string table yet. + */ + dyn_rpath = dynp; + break; + + case DT_SONAME: + /* Not used by the dynamic linker. */ + break; + + case DT_INIT: + obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_FINI: + obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr); + break; + + case DT_DEBUG: + /* XXX - not implemented yet */ + if (!early) + dbg("Filling in DT_DEBUG entry"); + ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug; + break; + + case DT_FLAGS: + if (dynp->d_un.d_val & DF_ORIGIN) { + obj->origin_path = xmalloc(PATH_MAX); + if (rtld_dirname(obj->path, obj->origin_path) == -1) + die(); + } + if (dynp->d_un.d_val & DF_SYMBOLIC) + obj->symbolic = true; + if (dynp->d_un.d_val & DF_TEXTREL) + obj->textrel = true; + if (dynp->d_un.d_val & DF_BIND_NOW) + obj->bind_now = true; + if (dynp->d_un.d_val & DF_STATIC_TLS) + ; + break; + + default: + if (!early) { + dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag, + (long)dynp->d_tag); + } + break; + } + } + + obj->traced = false; + + if (plttype == DT_RELA) { + obj->pltrela = (const Elf_Rela *) obj->pltrel; + obj->pltrel = NULL; + obj->pltrelasize = obj->pltrelsize; + obj->pltrelsize = 0; + } + + if (dyn_rpath != NULL) + obj->rpath = obj->strtab + dyn_rpath->d_un.d_val; +} + +/* + * Process a shared object's program header. This is used only for the + * main program, when the kernel has already loaded the main program + * into memory before calling the dynamic linker. It creates and + * returns an Obj_Entry structure. + */ +static Obj_Entry * +digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) +{ + Obj_Entry *obj; + const Elf_Phdr *phlimit = phdr + phnum; + const Elf_Phdr *ph; + int nsegs = 0; + + obj = obj_new(); + for (ph = phdr; ph < phlimit; ph++) { + switch (ph->p_type) { + + case PT_PHDR: + if ((const Elf_Phdr *)ph->p_vaddr != phdr) { + _rtld_error("%s: invalid PT_PHDR", path); + return NULL; + } + obj->phdr = (const Elf_Phdr *) ph->p_vaddr; + obj->phsize = ph->p_memsz; + break; + + case PT_INTERP: + obj->interp = (const char *) ph->p_vaddr; + break; + + case PT_LOAD: + if (nsegs == 0) { /* First load segment */ + obj->vaddrbase = trunc_page(ph->p_vaddr); + obj->mapbase = (caddr_t) obj->vaddrbase; + obj->relocbase = obj->mapbase - obj->vaddrbase; + obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) - + obj->vaddrbase; + } else { /* Last load segment */ + obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) - + obj->vaddrbase; + } + nsegs++; + break; + + case PT_DYNAMIC: + obj->dynamic = (const Elf_Dyn *) ph->p_vaddr; + break; + + case PT_TLS: + obj->tlsindex = 1; + obj->tlssize = ph->p_memsz; + obj->tlsalign = ph->p_align; + obj->tlsinitsize = ph->p_filesz; + obj->tlsinit = (void*) ph->p_vaddr; + break; + } + } + if (nsegs < 1) { + _rtld_error("%s: too few PT_LOAD segments", path); + return NULL; + } + + obj->entry = entry; + return obj; +} + +static Obj_Entry * +dlcheck(void *handle) +{ + Obj_Entry *obj; + + for (obj = obj_list; obj != NULL; obj = obj->next) + if (obj == (Obj_Entry *) handle) + break; + + if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) { + _rtld_error("Invalid shared object handle %p", handle); + return NULL; + } + return obj; +} + +/* + * If the given object is already in the donelist, return true. Otherwise + * add the object to the list and return false. + */ +static bool +donelist_check(DoneList *dlp, const Obj_Entry *obj) +{ + unsigned int i; + + for (i = 0; i < dlp->num_used; i++) + if (dlp->objs[i] == obj) + return true; + /* + * Our donelist allocation should always be sufficient. But if + * our threads locking isn't working properly, more shared objects + * could have been loaded since we allocated the list. That should + * never happen, but we'll handle it properly just in case it does. + */ + if (dlp->num_used < dlp->num_alloc) + dlp->objs[dlp->num_used++] = obj; + return false; +} + +/* + * Hash function for symbol table lookup. Don't even think about changing + * this. It is specified by the System V ABI. + */ +unsigned long +elf_hash(const char *name) +{ + const unsigned char *p = (const unsigned char *) name; + unsigned long h = 0; + unsigned long g; + + while (*p != '\0') { + h = (h << 4) + *p++; + if ((g = h & 0xf0000000) != 0) + h ^= g >> 24; + h &= ~g; + } + return h; +} + +/* + * Find the library with the given name, and return its full pathname. + * The returned string is dynamically allocated. Generates an error + * message and returns NULL if the library cannot be found. + * + * If the second argument is non-NULL, then it refers to an already- + * loaded shared object, whose library search path will be searched. + * + * The search order is: + * LD_LIBRARY_PATH + * rpath in the referencing file + * ldconfig hints + * /lib:/usr/lib + */ +static char * +find_library(const char *xname, const Obj_Entry *refobj) +{ + char *pathname; + char *name; + + if (strchr(xname, '/') != NULL) { /* Hard coded pathname */ + if (xname[0] != '/' && !trust) { + _rtld_error("Absolute pathname required for shared object \"%s\"", + xname); + return NULL; + } + return xstrdup(xname); + } + + if (libmap_disable || (refobj == NULL) || + (name = lm_find(refobj->path, xname)) == NULL) + name = (char *)xname; + + dbg(" Searching for \"%s\"", name); + if ((pathname = search_library_path(name, ld_library_path)) != NULL || + (refobj != NULL && + (pathname = search_library_path(name, refobj->rpath)) != NULL) || + (pathname = search_library_path(name, gethints())) != NULL || + (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) + return pathname; + + if(refobj != NULL && refobj->path != NULL) { + _rtld_error("Shared object \"%s\" not found, required by \"%s\"", + name, basename(refobj->path)); + } else { + _rtld_error("Shared object \"%s\" not found", name); + } + return NULL; +} + +/* + * Given a symbol number in a referencing object, find the corresponding + * definition of the symbol. Returns a pointer to the symbol, or NULL if + * no definition was found. Returns a pointer to the Obj_Entry of the + * defining object via the reference parameter DEFOBJ_OUT. + */ +const Elf_Sym * +find_symdef(unsigned long symnum, const Obj_Entry *refobj, + const Obj_Entry **defobj_out, bool in_plt, SymCache *cache) +{ + const Elf_Sym *ref; + const Elf_Sym *def; + const Obj_Entry *defobj; + const char *name; + unsigned long hash; + + /* + * If we have already found this symbol, get the information from + * the cache. + */ + if (symnum >= refobj->nchains) + return NULL; /* Bad object */ + + if (cache != NULL && cache[symnum].sym != NULL) { + *defobj_out = cache[symnum].obj; + return cache[symnum].sym; + } + + ref = refobj->symtab + symnum; + name = refobj->strtab + ref->st_name; + defobj = NULL; + + /* + * We don't have to do a full scale lookup if the symbol is local. + * We know it will bind to the instance in this load module; to + * which we already have a pointer (ie ref). By not doing a lookup, + * we not only improve performance, but it also avoids unresolvable + * symbols when local symbols are not in the hash table. This has + * been seen with the ia64 toolchain. + */ + if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) { + if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) { + _rtld_error("%s: Bogus symbol table entry %lu", refobj->path, + symnum); + } + hash = elf_hash(name); + def = symlook_default(name, hash, refobj, &defobj, in_plt); + } else { + def = ref; + defobj = refobj; + } + + /* + * If we found no definition and the reference is weak, treat the + * symbol as having the value zero. + */ + if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) { + def = &sym_zero; + defobj = obj_main; + } + + if (def != NULL) { + *defobj_out = defobj; + /* Record the information in the cache to avoid subsequent lookups. */ + if (cache != NULL) { + cache[symnum].sym = def; + cache[symnum].obj = defobj; + } + } else { + if (refobj != &obj_rtld) + _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name); + } + return def; +} + +/* + * Return the search path from the ldconfig hints file, reading it if + * necessary. Returns NULL if there are problems with the hints file, + * or if the search path there is empty. + */ +static const char * +gethints(void) +{ + static char *hints; + + if (hints == NULL) { + int fd; + struct elfhints_hdr hdr; + char *p; + + /* Keep from trying again in case the hints file is bad. */ + hints = ""; + + if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1) + return NULL; + if (read(fd, &hdr, sizeof hdr) != sizeof hdr || + hdr.magic != ELFHINTS_MAGIC || + hdr.version != 1) { + close(fd); + return NULL; + } + p = xmalloc(hdr.dirlistlen + 1); + if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 || + read(fd, p, hdr.dirlistlen + 1) != (ssize_t)hdr.dirlistlen + 1) { + free(p); + close(fd); + return NULL; + } + hints = p; + close(fd); + } + return hints[0] != '\0' ? hints : NULL; +} + +static void +init_dag(Obj_Entry *root) +{ + DoneList donelist; + + donelist_init(&donelist); + init_dag1(root, root, &donelist); +} + +static void +init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *dlp) +{ + const Needed_Entry *needed; + + if (donelist_check(dlp, obj)) + return; + + obj->refcount++; + objlist_push_tail(&obj->dldags, root); + objlist_push_tail(&root->dagmembers, obj); + for (needed = obj->needed; needed != NULL; needed = needed->next) + if (needed->obj != NULL) + init_dag1(root, needed->obj, dlp); +} + +/* + * Initialize the dynamic linker. The argument is the address at which + * the dynamic linker has been mapped into memory. The primary task of + * this function is to relocate the dynamic linker. + */ +static void +init_rtld(caddr_t mapbase) +{ + Obj_Entry objtmp; /* Temporary rtld object */ + + /* + * Conjure up an Obj_Entry structure for the dynamic linker. + * + * The "path" member can't be initialized yet because string constatns + * cannot yet be acessed. Below we will set it correctly. + */ + memset(&objtmp, 0, sizeof(objtmp)); + objtmp.path = NULL; + objtmp.rtld = true; + objtmp.mapbase = mapbase; +#ifdef PIC + objtmp.relocbase = mapbase; +#endif + if (RTLD_IS_DYNAMIC()) { + objtmp.dynamic = rtld_dynamic(&objtmp); + digest_dynamic(&objtmp, 1); + assert(objtmp.needed == NULL); + assert(!objtmp.textrel); + + /* + * Temporarily put the dynamic linker entry into the object list, so + * that symbols can be found. + */ + + relocate_objects(&objtmp, true, &objtmp); + } + + /* Initialize the object list. */ + obj_tail = &obj_list; + + /* Now that non-local variables can be accesses, copy out obj_rtld. */ + memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld)); + + /* Replace the path with a dynamically allocated copy. */ + obj_rtld.path = xstrdup(PATH_RTLD); + + r_debug.r_brk = r_debug_state; + r_debug.r_state = RT_CONSISTENT; +} + +/* + * Add the init functions from a needed object list (and its recursive + * needed objects) to "list". This is not used directly; it is a helper + * function for initlist_add_objects(). The write lock must be held + * when this function is called. + */ +static void +initlist_add_neededs(Needed_Entry *needed, Objlist *list) +{ + /* Recursively process the successor needed objects. */ + if (needed->next != NULL) + initlist_add_neededs(needed->next, list); + + /* Process the current needed object. */ + if (needed->obj != NULL) + initlist_add_objects(needed->obj, &needed->obj->next, list); +} + +/* + * Scan all of the DAGs rooted in the range of objects from "obj" to + * "tail" and add their init functions to "list". This recurses over + * the DAGs and ensure the proper init ordering such that each object's + * needed libraries are initialized before the object itself. At the + * same time, this function adds the objects to the global finalization + * list "list_fini" in the opposite order. The write lock must be + * held when this function is called. + */ +static void +initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list) +{ + if (obj->init_done) + return; + obj->init_done = true; + + /* Recursively process the successor objects. */ + if (&obj->next != tail) + initlist_add_objects(obj->next, tail, list); + + /* Recursively process the needed objects. */ + if (obj->needed != NULL) + initlist_add_neededs(obj->needed, list); + + /* Add the object to the init list. */ + if (obj->init != (Elf_Addr)NULL) + objlist_push_tail(list, obj); + + /* Add the object to the global fini list in the reverse order. */ + if (obj->fini != (Elf_Addr)NULL) + objlist_push_head(&list_fini, obj); +} + +#ifndef FPTR_TARGET +#define FPTR_TARGET(f) ((Elf_Addr) (f)) +#endif + +static bool +is_exported(const Elf_Sym *def) +{ + Elf_Addr value; + const func_ptr_type *p; + + value = (Elf_Addr)(obj_rtld.relocbase + def->st_value); + for (p = exports; *p != NULL; p++) + if (FPTR_TARGET(*p) == value) + return true; + return false; +} + +/* + * Given a shared object, traverse its list of needed objects, and load + * each of them. Returns 0 on success. Generates an error message and + * returns -1 on failure. + */ +static int +load_needed_objects(Obj_Entry *first) +{ + Obj_Entry *obj; + + for (obj = first; obj != NULL; obj = obj->next) { + Needed_Entry *needed; + + for (needed = obj->needed; needed != NULL; needed = needed->next) { + const char *name = obj->strtab + needed->name; + char *path = find_library(name, obj); + + needed->obj = NULL; + if (path == NULL && !ld_tracing) + return -1; +printf("\n\nPATH: [%s]\n",path); + if (path) { + needed->obj = load_object(path); + if (needed->obj == NULL && !ld_tracing) + return -1; /* XXX - cleanup */ + } + } + } + + return 0; +} + +static int +load_preload_objects(void) +{ + char *p = ld_preload; + static const char delim[] = " \t:;"; + + if (p == NULL) + return 0; + + p += strspn(p, delim); + while (*p != '\0') { + size_t len = strcspn(p, delim); + char *path; + char savech; + + savech = p[len]; + p[len] = '\0'; + if ((path = find_library(p, NULL)) == NULL) + return -1; + if (load_object(path) == NULL) + return -1; /* XXX - cleanup */ + p[len] = savech; + p += len; + p += strspn(p, delim); + } + return 0; +} + +/* + * Load a shared object into memory, if it is not already loaded. The + * argument must be a string allocated on the heap. This function assumes + * responsibility for freeing it when necessary. + * + * Returns a pointer to the Obj_Entry for the object. Returns NULL + * on failure. + */ +static Obj_Entry * +load_object(char *path) +{ + Obj_Entry *obj; + int fd = -1; + struct stat sb; + struct statfs fs; + + for (obj = obj_list->next; obj != NULL; obj = obj->next) + if (strcmp(obj->path, path) == 0) + break; + + /* + * If we didn't find a match by pathname, open the file and check + * again by device and inode. This avoids false mismatches caused + * by multiple links or ".." in pathnames. + * + * To avoid a race, we open the file and use fstat() rather than + * using stat(). + */ + if (obj == NULL) { + if ((fd = open(path, O_RDONLY)) == -1) { + _rtld_error("Cannot open \"%s\"", path); + return NULL; + } + if (fstat(fd, &sb) == -1) { + _rtld_error("Cannot fstat \"%s\"", path); + close(fd); + return NULL; + } + for (obj = obj_list->next; obj != NULL; obj = obj->next) { + if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) { + close(fd); + break; + } + } + } + + if (obj == NULL) { /* First use of this object, so we must map it in */ + /* + * but first, make sure that environment variables haven't been + * used to circumvent the noexec flag on a filesystem. + */ + if (dangerous_ld_env) { + if (fstatfs(fd, &fs) != 0) { + _rtld_error("Cannot fstatfs \"%s\"", path); + close(fd); + return NULL; + } + if (fs.f_flags & MNT_NOEXEC) { + _rtld_error("Cannot execute objects on %s\n", fs.f_mntonname); + close(fd); + return NULL; + } + } + dbg("loading \"%s\"", path); + printf("\n\n loading \"%s\"\n", path); + obj = map_object(fd, path, &sb); + printf("\nmapped object\n"); + close(fd); + if (obj == NULL) { + free(path); + return NULL; + } + + obj->path = path; + digest_dynamic(obj, 0); + + *obj_tail = obj; + obj_tail = &obj->next; + obj_count++; + linkmap_add(obj); /* for GDB & dlinfo() */ + + dbg(" %p .. %p: %s", obj->mapbase, + obj->mapbase + obj->mapsize - 1, obj->path); + if (obj->textrel) + dbg(" WARNING: %s has impure text", obj->path); + } else + free(path); + + return obj; +} + +static Obj_Entry * +obj_from_addr(const void *addr) +{ + Obj_Entry *obj; + + for (obj = obj_list; obj != NULL; obj = obj->next) { + if (addr < (void *) obj->mapbase) + continue; + if (addr < (void *) (obj->mapbase + obj->mapsize)) + return obj; + } + return NULL; +} + +/* + * Call the finalization functions for each of the objects in "list" + * which are unreferenced. All of the objects are expected to have + * non-NULL fini functions. + */ +static void +objlist_call_fini(Objlist *list) +{ + Objlist_Entry *elm; + char *saved_msg; + + /* + * Preserve the current error message since a fini function might + * call into the dynamic linker and overwrite it. + */ + saved_msg = errmsg_save(); + STAILQ_FOREACH(elm, list, link) { + if (elm->obj->refcount == 0) { + dbg("calling fini function for %s at %p", elm->obj->path, + (void *)elm->obj->fini); + call_initfini_pointer(elm->obj, elm->obj->fini); + } + } + errmsg_restore(saved_msg); +} + +/* + * Call the initialization functions for each of the objects in + * "list". All of the objects are expected to have non-NULL init + * functions. + */ +static void +objlist_call_init(Objlist *list) +{ + Objlist_Entry *elm; + char *saved_msg; + + /* + * Preserve the current error message since an init function might + * call into the dynamic linker and overwrite it. + */ + saved_msg = errmsg_save(); + STAILQ_FOREACH(elm, list, link) { + dbg("calling init function for %s at %p", elm->obj->path, + (void *)elm->obj->init); + call_initfini_pointer(elm->obj, elm->obj->init); + } + errmsg_restore(saved_msg); +} + +static void +objlist_clear(Objlist *list) +{ + Objlist_Entry *elm; + + while (!STAILQ_EMPTY(list)) { + elm = STAILQ_FIRST(list); + STAILQ_REMOVE_HEAD(list, link); + free(elm); + } +} + +static Objlist_Entry * +objlist_find(Objlist *list, const Obj_Entry *obj) +{ + Objlist_Entry *elm; + + STAILQ_FOREACH(elm, list, link) + if (elm->obj == obj) + return elm; + return NULL; +} + +static void +objlist_init(Objlist *list) +{ + STAILQ_INIT(list); +} + +static void +objlist_push_head(Objlist *list, Obj_Entry *obj) +{ + Objlist_Entry *elm; + + elm = NEW(Objlist_Entry); + elm->obj = obj; + STAILQ_INSERT_HEAD(list, elm, link); +} + +static void +objlist_push_tail(Objlist *list, Obj_Entry *obj) +{ + Objlist_Entry *elm; + + elm = NEW(Objlist_Entry); + elm->obj = obj; + STAILQ_INSERT_TAIL(list, elm, link); +} + +static void +objlist_remove(Objlist *list, Obj_Entry *obj) +{ + Objlist_Entry *elm; + + if ((elm = objlist_find(list, obj)) != NULL) { + STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link); + free(elm); + } +} + +/* + * Remove all of the unreferenced objects from "list". + */ +static void +objlist_remove_unref(Objlist *list) +{ + Objlist newlist; + Objlist_Entry *elm; + + STAILQ_INIT(&newlist); + while (!STAILQ_EMPTY(list)) { + elm = STAILQ_FIRST(list); + STAILQ_REMOVE_HEAD(list, link); + if (elm->obj->refcount == 0) + free(elm); + else + STAILQ_INSERT_TAIL(&newlist, elm, link); + } + *list = newlist; +} + +/* + * Relocate newly-loaded shared objects. The argument is a pointer to + * the Obj_Entry for the first such object. All objects from the first + * to the end of the list of objects are relocated. Returns 0 on success, + * or -1 on failure. + */ +static int +relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj) +{ + Obj_Entry *obj; + + for (obj = first; obj != NULL; obj = obj->next) { + if (obj != rtldobj) + dbg("relocating \"%s\"", obj->path); + if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL || + obj->symtab == NULL || obj->strtab == NULL) { + _rtld_error("%s: Shared object has no run-time symbol table", + obj->path); + return -1; + } + + if (obj->textrel) { + /* There are relocations to the write-protected text segment. */ + if (mprotect(obj->mapbase, obj->textsize, + PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { + _rtld_error("%s: Cannot write-enable text segment: %s", + obj->path, strerror(errno)); + return -1; + } + } + + /* Process the non-PLT relocations. */ + if (reloc_non_plt(obj, rtldobj)) + return -1; + + if (obj->textrel) { /* Re-protected the text segment. */ + if (mprotect(obj->mapbase, obj->textsize, + PROT_READ|PROT_EXEC) == -1) { + _rtld_error("%s: Cannot write-protect text segment: %s", + obj->path, strerror(errno)); + return -1; + } + } + + /* Process the PLT relocations. */ + if (reloc_plt(obj) == -1) + return -1; + /* Relocate the jump slots if we are doing immediate binding. */ + if (obj->bind_now || bind_now) + if (reloc_jmpslots(obj) == -1) + return -1; + + /* + * Set up the magic number and version in the Obj_Entry. These + * were checked in the crt1.o from the original ElfKit, so we + * set them for backward compatibility. + */ + obj->magic = RTLD_MAGIC; + obj->version = RTLD_VERSION; + + /* Set the special PLT or GOT entries. */ + init_pltgot(obj); + } + + return 0; +} + +/* + * Cleanup procedure. It will be called (by the atexit mechanism) just + * before the process exits. + */ +static void +rtld_exit(void) +{ + Obj_Entry *obj; + + dbg("rtld_exit()"); + /* Clear all the reference counts so the fini functions will be called. */ + for (obj = obj_list; obj != NULL; obj = obj->next) + obj->refcount = 0; + objlist_call_fini(&list_fini); + /* No need to remove the items from the list, since we are exiting. */ + if (!libmap_disable) + lm_fini(); +} + +static void * +path_enumerate(const char *path, path_enum_proc callback, void *arg) +{ +#ifdef COMPAT_32BIT + const char *trans; +#endif + if (path == NULL) + return (NULL); + + path += strspn(path, ":;"); + while (*path != '\0') { + size_t len; + char *res; + + len = strcspn(path, ":;"); +#ifdef COMPAT_32BIT + trans = lm_findn(NULL, path, len); + if (trans) + res = callback(trans, strlen(trans), arg); + else +#endif + res = callback(path, len, arg); + + if (res != NULL) + return (res); + + path += len; + path += strspn(path, ":;"); + } + + return (NULL); +} + +struct try_library_args { + const char *name; + size_t namelen; + char *buffer; + size_t buflen; +}; + +static void * +try_library_path(const char *dir, size_t dirlen, void *param) +{ + struct try_library_args *arg; + + arg = param; + if (*dir == '/' || trust) { + char *pathname; + + if (dirlen + 1 + arg->namelen + 1 > arg->buflen) + return (NULL); + + pathname = arg->buffer; + strncpy(pathname, dir, dirlen); + pathname[dirlen] = '/'; + strcpy(pathname + dirlen + 1, arg->name); + + dbg(" Trying \"%s\"", pathname); + if (access(pathname, F_OK) == 0) { /* We found it */ + pathname = xmalloc(dirlen + 1 + arg->namelen + 1); + strcpy(pathname, arg->buffer); + return (pathname); + } + } + return (NULL); +} + +static char * +search_library_path(const char *name, const char *path) +{ + char *p; + struct try_library_args arg; + + if (path == NULL) + return NULL; +printf("name: [%s]\n",name); + arg.name = name; + arg.namelen = strlen(name); + arg.buffer = xmalloc(PATH_MAX); + arg.buflen = PATH_MAX; + + p = path_enumerate(path, try_library_path, &arg); + + free(arg.buffer); + + return (p); +} + +int +dlclose(void *handle) +{ + Obj_Entry *root; + int lockstate; + + lockstate = wlock_acquire(rtld_bind_lock); + root = dlcheck(handle); + if (root == NULL) { + wlock_release(rtld_bind_lock, lockstate); + return -1; + } + + /* Unreference the object and its dependencies. */ + root->dl_refcount--; + + unref_dag(root); + + if (root->refcount == 0) { + /* + * The object is no longer referenced, so we must unload it. + * First, call the fini functions with no locks held. + */ + wlock_release(rtld_bind_lock, lockstate); + objlist_call_fini(&list_fini); + lockstate = wlock_acquire(rtld_bind_lock); + objlist_remove_unref(&list_fini); + + /* Finish cleaning up the newly-unreferenced objects. */ + GDB_STATE(RT_DELETE,&root->linkmap); + unload_object(root); + GDB_STATE(RT_CONSISTENT,NULL); + } + wlock_release(rtld_bind_lock, lockstate); + return 0; +} + +char * +dlerror(void) +{ + char *msg = error_message; + error_message = NULL; + return msg; +} + +/* + * This function is deprecated and has no effect. + */ +void +dllockinit(void *context, + void *(*lock_create)(void *context), + void (*rlock_acquire)(void *lock), + void (*wlock_acquire)(void *lock), + void (*lock_release)(void *lock), + void (*lock_destroy)(void *lock), + void (*context_destroy)(void *context)) +{ + static void *cur_context; + static void (*cur_context_destroy)(void *); + + /* Just destroy the context from the previous call, if necessary. */ + if (cur_context_destroy != NULL) + cur_context_destroy(cur_context); + cur_context = context; + cur_context_destroy = context_destroy; +} + +void * +dlopen(const char *name, int mode) +{ + Obj_Entry **old_obj_tail; + Obj_Entry *obj; + Objlist initlist; + int result, lockstate; + + ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1"; + if (ld_tracing != NULL) + environ = (char **)*get_program_var_addr("environ"); + + objlist_init(&initlist); + + lockstate = wlock_acquire(rtld_bind_lock); + GDB_STATE(RT_ADD,NULL); + + old_obj_tail = obj_tail; + obj = NULL; + if (name == NULL) { + obj = obj_main; + obj->refcount++; + } else { + char *path = find_library(name, obj_main); + if (path != NULL) + obj = load_object(path); + } + + if (obj) { + obj->dl_refcount++; + if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL) + objlist_push_tail(&list_global, obj); + mode &= RTLD_MODEMASK; + if (*old_obj_tail != NULL) { /* We loaded something new. */ + assert(*old_obj_tail == obj); + + result = load_needed_objects(obj); + if (result != -1 && ld_tracing) + goto trace; + + if (result == -1 || + (init_dag(obj), relocate_objects(obj, mode == RTLD_NOW, + &obj_rtld)) == -1) { + obj->dl_refcount--; + unref_dag(obj); + if (obj->refcount == 0) + unload_object(obj); + obj = NULL; + } else { + /* Make list of init functions to call. */ + initlist_add_objects(obj, &obj->next, &initlist); + } + } else { + + /* Bump the reference counts for objects on this DAG. */ + ref_dag(obj); + + if (ld_tracing) + goto trace; + } + } + + GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL); + + /* Call the init functions with no locks held. */ + wlock_release(rtld_bind_lock, lockstate); + objlist_call_init(&initlist); + lockstate = wlock_acquire(rtld_bind_lock); + objlist_clear(&initlist); + wlock_release(rtld_bind_lock, lockstate); + return obj; +trace: + trace_loaded_objects(obj); + wlock_release(rtld_bind_lock, lockstate); + exit(0); +} + +void * +dlsym(void *handle, const char *name) +{ + const Obj_Entry *obj; + unsigned long hash; + const Elf_Sym *def; + const Obj_Entry *defobj; + int lockstate; + + hash = elf_hash(name); + def = NULL; + defobj = NULL; + + lockstate = rlock_acquire(rtld_bind_lock); + if (handle == NULL || handle == RTLD_NEXT || + handle == RTLD_DEFAULT || handle == RTLD_SELF) { + void *retaddr; + + retaddr = __builtin_return_address(0); /* __GNUC__ only */ + if ((obj = obj_from_addr(retaddr)) == NULL) { + _rtld_error("Cannot determine caller's shared object"); + rlock_release(rtld_bind_lock, lockstate); + return NULL; + } + if (handle == NULL) { /* Just the caller's shared object. */ + def = symlook_obj(name, hash, obj, true); + defobj = obj; + } else if (handle == RTLD_NEXT || /* Objects after caller's */ + handle == RTLD_SELF) { /* ... caller included */ + if (handle == RTLD_NEXT) + obj = obj->next; + for (; obj != NULL; obj = obj->next) { + if ((def = symlook_obj(name, hash, obj, true)) != NULL) { + defobj = obj; + break; + } + } + } else { + assert(handle == RTLD_DEFAULT); + def = symlook_default(name, hash, obj, &defobj, true); + } + } else { + if ((obj = dlcheck(handle)) == NULL) { + rlock_release(rtld_bind_lock, lockstate); + return NULL; + } + + if (obj->mainprog) { + DoneList donelist; + + /* Search main program and all libraries loaded by it. */ + donelist_init(&donelist); + def = symlook_list(name, hash, &list_main, &defobj, true, + &donelist); + } else { + /* + * XXX - This isn't correct. The search should include the whole + * DAG rooted at the given object. + */ + def = symlook_obj(name, hash, obj, true); + defobj = obj; + } + } + + if (def != NULL) { + rlock_release(rtld_bind_lock, lockstate); + + /* + * The value required by the caller is derived from the value + * of the symbol. For the ia64 architecture, we need to + * construct a function descriptor which the caller can use to + * call the function with the right 'gp' value. For other + * architectures and for non-functions, the value is simply + * the relocated value of the symbol. + */ + if (ELF_ST_TYPE(def->st_info) == STT_FUNC) + return make_function_pointer(def, defobj); + else + return defobj->relocbase + def->st_value; + } + + _rtld_error("Undefined symbol \"%s\"", name); + rlock_release(rtld_bind_lock, lockstate); + return NULL; +} + +int +dladdr(const void *addr, Dl_info *info) +{ + const Obj_Entry *obj; + const Elf_Sym *def; + void *symbol_addr; + unsigned long symoffset; + int lockstate; + + lockstate = rlock_acquire(rtld_bind_lock); + obj = obj_from_addr(addr); + if (obj == NULL) { + _rtld_error("No shared object contains address"); + rlock_release(rtld_bind_lock, lockstate); + return 0; + } + info->dli_fname = obj->path; + info->dli_fbase = obj->mapbase; + info->dli_saddr = (void *)0; + info->dli_sname = NULL; + + /* + * Walk the symbol list looking for the symbol whose address is + * closest to the address sent in. + */ + for (symoffset = 0; symoffset < obj->nchains; symoffset++) { + def = obj->symtab + symoffset; + + /* + * For skip the symbol if st_shndx is either SHN_UNDEF or + * SHN_COMMON. + */ + if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON) + continue; + + /* + * If the symbol is greater than the specified address, or if it + * is further away from addr than the current nearest symbol, + * then reject it. + */ + symbol_addr = obj->relocbase + def->st_value; + if (symbol_addr > addr || symbol_addr < info->dli_saddr) + continue; + + /* Update our idea of the nearest symbol. */ + info->dli_sname = obj->strtab + def->st_name; + info->dli_saddr = symbol_addr; + + /* Exact match? */ + if (info->dli_saddr == addr) + break; + } + rlock_release(rtld_bind_lock, lockstate); + return 1; +} + +int +dlinfo(void *handle, int request, void *p) +{ + const Obj_Entry *obj; + int error, lockstate; + + lockstate = rlock_acquire(rtld_bind_lock); + + if (handle == NULL || handle == RTLD_SELF) { + void *retaddr; + + retaddr = __builtin_return_address(0); /* __GNUC__ only */ + if ((obj = obj_from_addr(retaddr)) == NULL) + _rtld_error("Cannot determine caller's shared object"); + } else + obj = dlcheck(handle); + + if (obj == NULL) { + rlock_release(rtld_bind_lock, lockstate); + return (-1); + } + + error = 0; + switch (request) { + case RTLD_DI_LINKMAP: + *((struct link_map const **)p) = &obj->linkmap; + break; + case RTLD_DI_ORIGIN: + error = rtld_dirname(obj->path, p); + break; + + case RTLD_DI_SERINFOSIZE: + case RTLD_DI_SERINFO: + error = do_search_info(obj, request, (struct dl_serinfo *)p); + break; + + default: + _rtld_error("Invalid request %d passed to dlinfo()", request); + error = -1; + } + + rlock_release(rtld_bind_lock, lockstate); + + return (error); +} + +struct fill_search_info_args { + int request; + unsigned int flags; + Dl_serinfo *serinfo; + Dl_serpath *serpath; + char *strspace; +}; + +static void * +fill_search_info(const char *dir, size_t dirlen, void *param) +{ + struct fill_search_info_args *arg; + + arg = param; + + if (arg->request == RTLD_DI_SERINFOSIZE) { + arg->serinfo->dls_cnt ++; + arg->serinfo->dls_size += sizeof(Dl_serpath) + dirlen + 1; + } else { + struct dl_serpath *s_entry; + + s_entry = arg->serpath; + s_entry->dls_name = arg->strspace; + s_entry->dls_flags = arg->flags; + + strncpy(arg->strspace, dir, dirlen); + arg->strspace[dirlen] = '\0'; + + arg->strspace += dirlen + 1; + arg->serpath++; + } + + return (NULL); +} + +static int +do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) +{ + struct dl_serinfo _info; + struct fill_search_info_args args; + + args.request = RTLD_DI_SERINFOSIZE; + args.serinfo = &_info; + + _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath); + _info.dls_cnt = 0; + + path_enumerate(ld_library_path, fill_search_info, &args); + path_enumerate(obj->rpath, fill_search_info, &args); + path_enumerate(gethints(), fill_search_info, &args); + path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args); + + + if (request == RTLD_DI_SERINFOSIZE) { + info->dls_size = _info.dls_size; + info->dls_cnt = _info.dls_cnt; + return (0); + } + + if (info->dls_cnt != _info.dls_cnt || info->dls_size != _info.dls_size) { + _rtld_error("Uninitialized Dl_serinfo struct passed to dlinfo()"); + return (-1); + } + + args.request = RTLD_DI_SERINFO; + args.serinfo = info; + args.serpath = &info->dls_serpath[0]; + args.strspace = (char *)&info->dls_serpath[_info.dls_cnt]; + + args.flags = LA_SER_LIBPATH; + if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL) + return (-1); + + args.flags = LA_SER_RUNPATH; + if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL) + return (-1); + + args.flags = LA_SER_CONFIG; + if (path_enumerate(gethints(), fill_search_info, &args) != NULL) + return (-1); + + args.flags = LA_SER_DEFAULT; + if (path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL) + return (-1); + return (0); +} + +static int +rtld_dirname(const char *path, char *bname) +{ + const char *endp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + bname[0] = '.'; + bname[1] = '\0'; + return (0); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + bname[0] = *endp == '/' ? '/' : '.'; + bname[1] = '\0'; + return (0); + } else { + do { + endp--; + } while (endp > path && *endp == '/'); + } + + if (endp - path + 2 > PATH_MAX) + { + _rtld_error("Filename is too long: %s", path); + return(-1); + } + + strncpy(bname, path, endp - path + 1); + bname[endp - path + 1] = '\0'; + return (0); +} + +static void +linkmap_add(Obj_Entry *obj) +{ + struct link_map *l = &obj->linkmap; + struct link_map *prev; + + obj->linkmap.l_name = obj->path; + obj->linkmap.l_addr = obj->mapbase; + obj->linkmap.l_ld = obj->dynamic; +#ifdef __mips__ + /* GDB needs load offset on MIPS to use the symbols */ + obj->linkmap.l_offs = obj->relocbase; +#endif + + if (r_debug.r_map == NULL) { + r_debug.r_map = l; + return; + } + + /* + * Scan to the end of the list, but not past the entry for the + * dynamic linker, which we want to keep at the very end. + */ + for (prev = r_debug.r_map; + prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap; + prev = prev->l_next) + ; + + /* Link in the new entry. */ + l->l_prev = prev; + l->l_next = prev->l_next; + if (l->l_next != NULL) + l->l_next->l_prev = l; + prev->l_next = l; +} + +static void +linkmap_delete(Obj_Entry *obj) +{ + struct link_map *l = &obj->linkmap; + + if (l->l_prev == NULL) { + if ((r_debug.r_map = l->l_next) != NULL) + l->l_next->l_prev = NULL; + return; + } + + if ((l->l_prev->l_next = l->l_next) != NULL) + l->l_next->l_prev = l->l_prev; +} + +/* + * Function for the debugger to set a breakpoint on to gain control. + * + * The two parameters allow the debugger to easily find and determine + * what the runtime loader is doing and to whom it is doing it. + * + * When the loadhook trap is hit (r_debug_state, set at program + * initialization), the arguments can be found on the stack: + * + * +8 struct link_map *m + * +4 struct r_debug *rd + * +0 RetAddr + */ +void +r_debug_state(struct r_debug* rd, struct link_map *m) +{ +} + +/* + * Get address of the pointer variable in the main program. + */ +static const void ** +get_program_var_addr(const char *name) +{ + const Obj_Entry *obj; + unsigned long hash; + + hash = elf_hash(name); + for (obj = obj_main; obj != NULL; obj = obj->next) { + const Elf_Sym *def; + + if ((def = symlook_obj(name, hash, obj, false)) != NULL) { + const void **addr; + + addr = (const void **)(obj->relocbase + def->st_value); + return addr; + } + } + return NULL; +} + +/* + * Set a pointer variable in the main program to the given value. This + * is used to set key variables such as "environ" before any of the + * init functions are called. + */ +static void +set_program_var(const char *name, const void *value) +{ + const void **addr; + + if ((addr = get_program_var_addr(name)) != NULL) { + dbg("\"%s\": *%p <-- %p", name, addr, value); + *addr = value; + } +} + +/* + * Given a symbol name in a referencing object, find the corresponding + * definition of the symbol. Returns a pointer to the symbol, or NULL if + * no definition was found. Returns a pointer to the Obj_Entry of the + * defining object via the reference parameter DEFOBJ_OUT. + */ +static const Elf_Sym * +symlook_default(const char *name, unsigned long hash, + const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt) +{ + DoneList donelist; + const Elf_Sym *def; + const Elf_Sym *symp; + const Obj_Entry *obj; + const Obj_Entry *defobj; + const Objlist_Entry *elm; + def = NULL; + defobj = NULL; + donelist_init(&donelist); + + /* Look first in the referencing object if linked symbolically. */ + if (refobj->symbolic && !donelist_check(&donelist, refobj)) { + symp = symlook_obj(name, hash, refobj, in_plt); + if (symp != NULL) { + def = symp; + defobj = refobj; + } + } + + /* Search all objects loaded at program start up. */ + if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) { + symp = symlook_list(name, hash, &list_main, &obj, in_plt, &donelist); + if (symp != NULL && + (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) { + def = symp; + defobj = obj; + } + } + + /* Search all DAGs whose roots are RTLD_GLOBAL objects. */ + STAILQ_FOREACH(elm, &list_global, link) { + if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK) + break; + symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt, + &donelist); + if (symp != NULL && + (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) { + def = symp; + defobj = obj; + } + } + + /* Search all dlopened DAGs containing the referencing object. */ + STAILQ_FOREACH(elm, &refobj->dldags, link) { + if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK) + break; + symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt, + &donelist); + if (symp != NULL && + (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) { + def = symp; + defobj = obj; + } + } + + /* + * Search the dynamic linker itself, and possibly resolve the + * symbol from there. This is how the application links to + * dynamic linker services such as dlopen. Only the values listed + * in the "exports" array can be resolved from the dynamic linker. + */ + if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) { + symp = symlook_obj(name, hash, &obj_rtld, in_plt); + if (symp != NULL && is_exported(symp)) { + def = symp; + defobj = &obj_rtld; + } + } + + if (def != NULL) + *defobj_out = defobj; + return def; +} + +static const Elf_Sym * +symlook_list(const char *name, unsigned long hash, Objlist *objlist, + const Obj_Entry **defobj_out, bool in_plt, DoneList *dlp) +{ + const Elf_Sym *symp; + const Elf_Sym *def; + const Obj_Entry *defobj; + const Objlist_Entry *elm; + + def = NULL; + defobj = NULL; + STAILQ_FOREACH(elm, objlist, link) { + if (donelist_check(dlp, elm->obj)) + continue; + if ((symp = symlook_obj(name, hash, elm->obj, in_plt)) != NULL) { + if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) { + def = symp; + defobj = elm->obj; + if (ELF_ST_BIND(def->st_info) != STB_WEAK) + break; + } + } + } + if (def != NULL) + *defobj_out = defobj; + return def; +} + +/* + * Search the symbol table of a single shared object for a symbol of + * the given name. Returns a pointer to the symbol, or NULL if no + * definition was found. + * + * The symbol's hash value is passed in for efficiency reasons; that + * eliminates many recomputations of the hash value. + */ +const Elf_Sym * +symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj, + bool in_plt) +{ + if (obj->buckets != NULL) { + unsigned long symnum = obj->buckets[hash % obj->nbuckets]; + + while (symnum != STN_UNDEF) { + const Elf_Sym *symp; + const char *strp; + + if (symnum >= obj->nchains) + return NULL; /* Bad object */ + symp = obj->symtab + symnum; + strp = obj->strtab + symp->st_name; + + if (name[0] == strp[0] && strcmp(name, strp) == 0) + return symp->st_shndx != SHN_UNDEF || + (!in_plt && symp->st_value != 0 && + ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL; + + symnum = obj->chains[symnum]; + } + } + return NULL; +} + +static void +trace_loaded_objects(Obj_Entry *obj) +{ + char *fmt1, *fmt2, *fmt, *main_local, *list_containers; + int c; + + if ((main_local = getenv(LD_ "TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) + main_local = ""; + + if ((fmt1 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT1")) == NULL) + fmt1 = "\t%o => %p (%x)\n"; + + if ((fmt2 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT2")) == NULL) + fmt2 = "\t%o (%x)\n"; + + list_containers = getenv(LD_ "TRACE_LOADED_OBJECTS_ALL"); + + for (; obj; obj = obj->next) { + Needed_Entry *needed; + char *name, *path; + bool is_lib; + + if (list_containers && obj->needed != NULL) + printf("%s:\n", obj->path); + for (needed = obj->needed; needed; needed = needed->next) { + if (needed->obj != NULL) { + if (needed->obj->traced && !list_containers) + continue; + needed->obj->traced = true; + path = needed->obj->path; + } else + path = "not found"; + + name = (char *)obj->strtab + needed->name; + is_lib = strncmp(name, "lib", 3) == 0; /* XXX - bogus */ + + fmt = is_lib ? fmt1 : fmt2; + while ((c = *fmt++) != '\0') { + switch (c) { + default: + putchar(c); + continue; + case '\\': + switch (c = *fmt) { + case '\0': + continue; + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + } + break; + case '%': + switch (c = *fmt) { + case '\0': + continue; + case '%': + default: + putchar(c); + break; + case 'A': + printf("%s", main_local); + break; + case 'a': + printf("%s", obj_main->path); + break; + case 'o': + printf("%s", name); + break; +#if 0 + case 'm': + printf("%d", sodp->sod_major); + break; + case 'n': + printf("%d", sodp->sod_minor); + break; +#endif + case 'p': + printf("%s", path); + break; + case 'x': + printf("%p", needed->obj ? needed->obj->mapbase : 0); + break; + } + break; + } + ++fmt; + } + } + } +} + +/* + * Unload a dlopened object and its dependencies from memory and from + * our data structures. It is assumed that the DAG rooted in the + * object has already been unreferenced, and that the object has a + * reference count of 0. + */ +static void +unload_object(Obj_Entry *root) +{ + Obj_Entry *obj; + Obj_Entry **linkp; + + assert(root->refcount == 0); + + /* + * Pass over the DAG removing unreferenced objects from + * appropriate lists. + */ + unlink_object(root); + + /* Unmap all objects that are no longer referenced. */ + linkp = &obj_list->next; + while ((obj = *linkp) != NULL) { + if (obj->refcount == 0) { + dbg("unloading \"%s\"", obj->path); + munmap(obj->mapbase, obj->mapsize); + linkmap_delete(obj); + *linkp = obj->next; + obj_count--; + obj_free(obj); + } else + linkp = &obj->next; + } + obj_tail = linkp; +} + +static void +unlink_object(Obj_Entry *root) +{ + Objlist_Entry *elm; + + if (root->refcount == 0) { + /* Remove the object from the RTLD_GLOBAL list. */ + objlist_remove(&list_global, root); + + /* Remove the object from all objects' DAG lists. */ + STAILQ_FOREACH(elm, &root->dagmembers , link) { + objlist_remove(&elm->obj->dldags, root); + if (elm->obj != root) + unlink_object(elm->obj); + } + } +} + +static void +ref_dag(Obj_Entry *root) +{ + Objlist_Entry *elm; + + STAILQ_FOREACH(elm, &root->dagmembers , link) + elm->obj->refcount++; +} + +static void +unref_dag(Obj_Entry *root) +{ + Objlist_Entry *elm; + + STAILQ_FOREACH(elm, &root->dagmembers , link) + elm->obj->refcount--; +} + +/* + * Common code for MD __tls_get_addr(). + */ +void * +tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset) +{ + Elf_Addr* dtv = *dtvp; + int lockstate; + + /* Check dtv generation in case new modules have arrived */ + if (dtv[0] != tls_dtv_generation) { + Elf_Addr* newdtv; + int to_copy; + + lockstate = wlock_acquire(rtld_bind_lock); + newdtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr)); + to_copy = dtv[1]; + if (to_copy > tls_max_index) + to_copy = tls_max_index; + memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(Elf_Addr)); + newdtv[0] = tls_dtv_generation; + newdtv[1] = tls_max_index; + free(dtv); + wlock_release(rtld_bind_lock, lockstate); + *dtvp = newdtv; + } + + /* Dynamically allocate module TLS if necessary */ + if (!dtv[index + 1]) { + /* Signal safe, wlock will block out signals. */ + lockstate = wlock_acquire(rtld_bind_lock); + if (!dtv[index + 1]) + dtv[index + 1] = (Elf_Addr)allocate_module_tls(index); + wlock_release(rtld_bind_lock, lockstate); + } + return (void*) (dtv[index + 1] + offset); +} + +/* XXX not sure what variants to use for arm. */ + +#if defined(__ia64__) || defined(__alpha__) || defined(__powerpc__) + +/* + * Allocate Static TLS using the Variant I method. + */ +void * +allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) +{ + Obj_Entry *obj; + char *tcb; + Elf_Addr **tls; + Elf_Addr *dtv; + Elf_Addr addr; + int i; + + if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) + return (oldtcb); + + assert(tcbsize >= TLS_TCB_SIZE); + tcb = calloc(1, tls_static_space - TLS_TCB_SIZE + tcbsize); + tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE); + + if (oldtcb != NULL) { + memcpy(tls, oldtcb, tls_static_space); + free(oldtcb); + + /* Adjust the DTV. */ + dtv = tls[0]; + for (i = 0; i < dtv[1]; i++) { + if (dtv[i+2] >= (Elf_Addr)oldtcb && + dtv[i+2] < (Elf_Addr)oldtcb + tls_static_space) { + dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tls; + } + } + } else { + dtv = calloc(tls_max_index + 2, sizeof(Elf_Addr)); + tls[0] = dtv; + dtv[0] = tls_dtv_generation; + dtv[1] = tls_max_index; + + for (obj = objs; obj; obj = obj->next) { + if (obj->tlsoffset) { + addr = (Elf_Addr)tls + obj->tlsoffset; + memset((void*) (addr + obj->tlsinitsize), + 0, obj->tlssize - obj->tlsinitsize); + if (obj->tlsinit) + memcpy((void*) addr, obj->tlsinit, + obj->tlsinitsize); + dtv[obj->tlsindex + 1] = addr; + } + } + } + + return (tcb); +} + +void +free_tls(void *tcb, size_t tcbsize, size_t tcbalign) +{ + Elf_Addr *dtv; + Elf_Addr tlsstart, tlsend; + int dtvsize, i; + + assert(tcbsize >= TLS_TCB_SIZE); + + tlsstart = (Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE; + tlsend = tlsstart + tls_static_space; + + dtv = *(Elf_Addr **)tlsstart; + dtvsize = dtv[1]; + for (i = 0; i < dtvsize; i++) { + if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] >= tlsend)) { + free((void*)dtv[i+2]); + } + } + free(dtv); + free(tcb); +} + +#endif + +#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ + defined(__arm__) + +/* + * Allocate Static TLS using the Variant II method. + */ +void * +allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) +{ + Obj_Entry *obj; + size_t size; + char *tls; + Elf_Addr *dtv, *olddtv; + Elf_Addr segbase, oldsegbase, addr; + int i; + + size = round(tls_static_space, tcbalign); + + assert(tcbsize >= 2*sizeof(Elf_Addr)); + tls = malloc(size + tcbsize); + dtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr)); + + segbase = (Elf_Addr)(tls + size); + ((Elf_Addr*)segbase)[0] = segbase; + ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; + + dtv[0] = tls_dtv_generation; + dtv[1] = tls_max_index; + + if (oldtls) { + /* + * Copy the static TLS block over whole. + */ + oldsegbase = (Elf_Addr) oldtls; + memcpy((void *)(segbase - tls_static_space), + (const void *)(oldsegbase - tls_static_space), + tls_static_space); + + /* + * If any dynamic TLS blocks have been created tls_get_addr(), + * move them over. + */ + olddtv = ((Elf_Addr**)oldsegbase)[1]; + for (i = 0; i < olddtv[1]; i++) { + if (olddtv[i+2] < oldsegbase - size || olddtv[i+2] > oldsegbase) { + dtv[i+2] = olddtv[i+2]; + olddtv[i+2] = 0; + } + } + + /* + * We assume that this block was the one we created with + * allocate_initial_tls(). + */ + free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); + } else { + for (obj = objs; obj; obj = obj->next) { + if (obj->tlsoffset) { + addr = segbase - obj->tlsoffset; + memset((void*) (addr + obj->tlsinitsize), + 0, obj->tlssize - obj->tlsinitsize); + if (obj->tlsinit) + memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize); + dtv[obj->tlsindex + 1] = addr; + } + } + } + + return (void*) segbase; +} + +void +free_tls(void *tls, size_t tcbsize, size_t tcbalign) +{ + size_t size; + Elf_Addr* dtv; + int dtvsize, i; + Elf_Addr tlsstart, tlsend; + + /* + * Figure out the size of the initial TLS block so that we can + * find stuff which ___tls_get_addr() allocated dynamically. + */ + size = round(tls_static_space, tcbalign); + + dtv = ((Elf_Addr**)tls)[1]; + dtvsize = dtv[1]; + tlsend = (Elf_Addr) tls; + tlsstart = tlsend - size; + for (i = 0; i < dtvsize; i++) { + if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] > tlsend)) { + free((void*) dtv[i+2]); + } + } + + free((void*) tlsstart); +} + +#endif + +/* + * Allocate TLS block for module with given index. + */ +void * +allocate_module_tls(int index) +{ + Obj_Entry* obj; + char* p; + + for (obj = obj_list; obj; obj = obj->next) { + if (obj->tlsindex == index) + break; + } + if (!obj) { + _rtld_error("Can't find module with TLS index %d", index); + die(); + } + + p = malloc(obj->tlssize); + memcpy(p, obj->tlsinit, obj->tlsinitsize); + memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize); + + return p; +} + +bool +allocate_tls_offset(Obj_Entry *obj) +{ + size_t off; + + if (obj->tls_done) + return true; + + if (obj->tlssize == 0) { + obj->tls_done = true; + return true; + } + + if (obj->tlsindex == 1) + off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign); + else + off = calculate_tls_offset(tls_last_offset, tls_last_size, + obj->tlssize, obj->tlsalign); + + /* + * If we have already fixed the size of the static TLS block, we + * must stay within that size. When allocating the static TLS, we + * leave a small amount of space spare to be used for dynamically + * loading modules which use static TLS. + */ + if (tls_static_space) { + if (calculate_tls_end(off, obj->tlssize) > tls_static_space) + return false; + } + + tls_last_offset = obj->tlsoffset = off; + tls_last_size = obj->tlssize; + obj->tls_done = true; + + return true; +} + +void +free_tls_offset(Obj_Entry *obj) +{ +#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ + defined(__arm__) + /* + * If we were the last thing to allocate out of the static TLS + * block, we give our space back to the 'allocator'. This is a + * simplistic workaround to allow libGL.so.1 to be loaded and + * unloaded multiple times. We only handle the Variant II + * mechanism for now - this really needs a proper allocator. + */ + if (calculate_tls_end(obj->tlsoffset, obj->tlssize) + == calculate_tls_end(tls_last_offset, tls_last_size)) { + tls_last_offset -= obj->tlssize; + tls_last_size = 0; + } +#endif +} + +void * +_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) +{ + void *ret; + int lockstate; + + lockstate = wlock_acquire(rtld_bind_lock); + ret = allocate_tls(obj_list, oldtls, tcbsize, tcbalign); + wlock_release(rtld_bind_lock, lockstate); + return (ret); +} + +void +_rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign) +{ + int lockstate; + + lockstate = wlock_acquire(rtld_bind_lock); + free_tls(tcb, tcbsize, tcbalign); + wlock_release(rtld_bind_lock, lockstate); +} diff --git a/src/bin/rtld-elf/rtld.h b/src/bin/rtld-elf/rtld.h new file mode 100644 index 0000000..890c5e5 --- /dev/null +++ b/src/bin/rtld-elf/rtld.h @@ -0,0 +1,409 @@ +/*- + * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/libexec/rtld-elf/rtld.h 282118 2015-04-28 01:15:17Z emaste $ + */ + +#ifndef RTLD_H /* { */ +#define RTLD_H 1 + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "rtld_lock.h" +#include "rtld_machdep.h" + +#ifdef COMPAT_32BIT +#undef STANDARD_LIBRARY_PATH +#undef _PATH_ELF_HINTS +#define _PATH_ELF_HINTS "/var/run/ld-elf32.so.hints" +/* For running 32 bit binaries */ +#define STANDARD_LIBRARY_PATH "/lib32:/usr/lib32" +#define LD_ "LD_32_" +#endif + +#ifndef STANDARD_LIBRARY_PATH +#define STANDARD_LIBRARY_PATH "/lib:/usr/lib" +#endif +#ifndef LD_ +#define LD_ "LD_" +#endif + +#define NEW(type) ((type *) xmalloc(sizeof(type))) +#define CNEW(type) ((type *) xcalloc(1, sizeof(type))) + +/* We might as well do booleans like C++. */ +typedef unsigned char bool; +#define false 0 +#define true 1 + +extern size_t tls_last_offset; +extern size_t tls_last_size; +extern size_t tls_static_space; +extern int tls_dtv_generation; +extern int tls_max_index; + +extern int npagesizes; +extern size_t *pagesizes; + +extern int main_argc; +extern char **main_argv; +extern char **environ; + +struct stat; +struct Struct_Obj_Entry; + +/* Lists of shared objects */ +typedef struct Struct_Objlist_Entry { + STAILQ_ENTRY(Struct_Objlist_Entry) link; + struct Struct_Obj_Entry *obj; +} Objlist_Entry; + +typedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist; + +/* Types of init and fini functions */ +typedef void (*InitFunc)(void); +typedef void (*InitArrFunc)(int, char **, char **); + +/* Lists of shared object dependencies */ +typedef struct Struct_Needed_Entry { + struct Struct_Needed_Entry *next; + struct Struct_Obj_Entry *obj; + unsigned long name; /* Offset of name in string table */ +} Needed_Entry; + +typedef struct Struct_Name_Entry { + STAILQ_ENTRY(Struct_Name_Entry) link; + char name[1]; +} Name_Entry; + +/* Lock object */ +typedef struct Struct_LockInfo { + void *context; /* Client context for creating locks */ + void *thelock; /* The one big lock */ + /* Debugging aids. */ + volatile int rcount; /* Number of readers holding lock */ + volatile int wcount; /* Number of writers holding lock */ + /* Methods */ + void *(*lock_create)(void *context); + void (*rlock_acquire)(void *lock); + void (*wlock_acquire)(void *lock); + void (*rlock_release)(void *lock); + void (*wlock_release)(void *lock); + void (*lock_destroy)(void *lock); + void (*context_destroy)(void *context); +} LockInfo; + +typedef struct Struct_Ver_Entry { + Elf_Word hash; + unsigned int flags; + const char *name; + const char *file; +} Ver_Entry; + +typedef struct Struct_Sym_Match_Result { + const Elf_Sym *sym_out; + const Elf_Sym *vsymp; + int vcount; +} Sym_Match_Result; + +#define VER_INFO_HIDDEN 0x01 + +/* + * Shared object descriptor. + * + * Items marked with "(%)" are dynamically allocated, and must be freed + * when the structure is destroyed. + * + * CAUTION: It appears that the JDK port peeks into these structures. + * It looks at "next" and "mapbase" at least. Don't add new members + * near the front, until this can be straightened out. + */ +typedef struct Struct_Obj_Entry { + /* + * These two items have to be set right for compatibility with the + * original ElfKit crt1.o. + */ + Elf_Size magic; /* Magic number (sanity check) */ + Elf_Size version; /* Version number of struct format */ + + struct Struct_Obj_Entry *next; + char *path; /* Pathname of underlying file (%) */ + char *origin_path; /* Directory path of origin file */ + int refcount; + int dl_refcount; /* Number of times loaded by dlopen */ + + /* These items are computed by map_object() or by digest_phdr(). */ + caddr_t mapbase; /* Base address of mapped region */ + size_t mapsize; /* Size of mapped region in bytes */ + size_t textsize; /* Size of text segment in bytes */ + Elf_Addr vaddrbase; /* Base address in shared object file */ + caddr_t relocbase; /* Relocation constant = mapbase - vaddrbase */ + const Elf_Dyn *dynamic; /* Dynamic section */ + caddr_t entry; /* Entry point */ + const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ + size_t phsize; /* Size of program header in bytes */ + const char *interp; /* Pathname of the interpreter, if any */ + Elf_Word stack_flags; + + /* TLS information */ + int tlsindex; /* Index in DTV for this module */ + void *tlsinit; /* Base address of TLS init block */ + size_t tlsinitsize; /* Size of TLS init block for this module */ + size_t tlssize; /* Size of TLS block for this module */ + size_t tlsoffset; /* Offset of static TLS block for this module */ + size_t tlsalign; /* Alignment of static TLS block */ + + caddr_t relro_page; + size_t relro_size; + + /* Items from the dynamic section. */ + Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */ + const Elf_Rel *rel; /* Relocation entries */ + unsigned long relsize; /* Size in bytes of relocation info */ + const Elf_Rela *rela; /* Relocation entries with addend */ + unsigned long relasize; /* Size in bytes of addend relocation info */ + const Elf_Rel *pltrel; /* PLT relocation entries */ + unsigned long pltrelsize; /* Size in bytes of PLT relocation info */ + const Elf_Rela *pltrela; /* PLT relocation entries with addend */ + unsigned long pltrelasize; /* Size in bytes of PLT addend reloc info */ + const Elf_Sym *symtab; /* Symbol table */ + const char *strtab; /* String table */ + unsigned long strsize; /* Size in bytes of string table */ +#ifdef __mips__ + Elf_Word local_gotno; /* Number of local GOT entries */ + Elf_Word symtabno; /* Number of dynamic symbols */ + Elf_Word gotsym; /* First dynamic symbol in GOT */ +#endif + + const Elf_Verneed *verneed; /* Required versions. */ + Elf_Word verneednum; /* Number of entries in verneed table */ + const Elf_Verdef *verdef; /* Provided versions. */ + Elf_Word verdefnum; /* Number of entries in verdef table */ + const Elf_Versym *versyms; /* Symbol versions table */ + + const Elf_Hashelt *buckets; /* Hash table buckets array */ + unsigned long nbuckets; /* Number of buckets */ + const Elf_Hashelt *chains; /* Hash table chain array */ + unsigned long nchains; /* Number of entries in chain array */ + + Elf32_Word nbuckets_gnu; /* Number of GNU hash buckets*/ + Elf32_Word symndx_gnu; /* 1st accessible symbol on dynsym table */ + Elf32_Word maskwords_bm_gnu; /* Bloom filter words - 1 (bitmask) */ + Elf32_Word shift2_gnu; /* Bloom filter shift count */ + Elf32_Word dynsymcount; /* Total entries in dynsym table */ + Elf_Addr *bloom_gnu; /* Bloom filter used by GNU hash func */ + const Elf_Hashelt *buckets_gnu; /* GNU hash table bucket array */ + const Elf_Hashelt *chain_zero_gnu; /* GNU hash table value array (Zeroed) */ + + char *rpath; /* Search path specified in object */ + char *runpath; /* Search path with different priority */ + Needed_Entry *needed; /* Shared objects needed by this one (%) */ + Needed_Entry *needed_filtees; + Needed_Entry *needed_aux_filtees; + + STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we + know about. */ + Ver_Entry *vertab; /* Versions required /defined by this object */ + int vernum; /* Number of entries in vertab */ + + Elf_Addr init; /* Initialization function to call */ + Elf_Addr fini; /* Termination function to call */ + Elf_Addr preinit_array; /* Pre-initialization array of functions */ + Elf_Addr init_array; /* Initialization array of functions */ + Elf_Addr fini_array; /* Termination array of functions */ + int preinit_array_num; /* Number of entries in preinit_array */ + int init_array_num; /* Number of entries in init_array */ + int fini_array_num; /* Number of entries in fini_array */ + + int32_t osrel; /* OSREL note value */ + + bool mainprog : 1; /* True if this is the main program */ + bool rtld : 1; /* True if this is the dynamic linker */ + bool relocated : 1; /* True if processed by relocate_objects() */ + bool ver_checked : 1; /* True if processed by rtld_verify_object_versions */ + bool textrel : 1; /* True if there are relocations to text seg */ + bool symbolic : 1; /* True if generated with "-Bsymbolic" */ + bool bind_now : 1; /* True if all relocations should be made first */ + bool traced : 1; /* Already printed in ldd trace output */ + bool jmpslots_done : 1; /* Already have relocated the jump slots */ + bool init_done : 1; /* Already have added object to init list */ + bool tls_done : 1; /* Already allocated offset for static TLS */ + bool phdr_alloc : 1; /* Phdr is allocated and needs to be freed. */ + bool z_origin : 1; /* Process rpath and soname tokens */ + bool z_nodelete : 1; /* Do not unload the object and dependencies */ + bool z_noopen : 1; /* Do not load on dlopen */ + bool z_loadfltr : 1; /* Immediately load filtees */ + bool z_interpose : 1; /* Interpose all objects but main */ + bool z_nodeflib : 1; /* Don't search default library path */ + bool z_global : 1; /* Make the object global */ + bool ref_nodel : 1; /* Refcount increased to prevent dlclose */ + bool init_scanned: 1; /* Object is already on init list. */ + bool on_fini_list: 1; /* Object is already on fini list. */ + bool dag_inited : 1; /* Object has its DAG initialized. */ + bool filtees_loaded : 1; /* Filtees loaded */ + bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */ + bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */ + bool non_plt_gnu_ifunc : 1; /* Object has non-plt IFUNC references */ + bool crt_no_init : 1; /* Object' crt does not call _init/_fini */ + bool valid_hash_sysv : 1; /* A valid System V hash hash tag is available */ + bool valid_hash_gnu : 1; /* A valid GNU hash tag is available */ + bool dlopened : 1; /* dlopen()-ed (vs. load statically) */ + + struct link_map linkmap; /* For GDB and dlinfo() */ + Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ + Objlist dagmembers; /* DAG has these members (%) */ + dev_t dev; /* Object's filesystem's device */ + ino_t ino; /* Object's inode number */ + void *priv; /* Platform-dependent */ +} Obj_Entry; + +#define RTLD_MAGIC 0xd550b87a +#define RTLD_VERSION 1 + +#define RTLD_STATIC_TLS_EXTRA 128 + +/* Flags to be passed into symlook_ family of functions. */ +#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */ +#define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol. Used by + dlsym. */ +#define SYMLOOK_EARLY 0x04 /* Symlook is done during initialization. */ +#define SYMLOOK_IFUNC 0x08 /* Allow IFUNC processing in + reloc_non_plt(). */ + +/* Flags for load_object(). */ +#define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */ +#define RTLD_LO_DLOPEN 0x02 /* Load_object() called from dlopen(). */ +#define RTLD_LO_TRACE 0x04 /* Only tracing. */ +#define RTLD_LO_NODELETE 0x08 /* Loaded object cannot be closed. */ +#define RTLD_LO_FILTEES 0x10 /* Loading filtee. */ +#define RTLD_LO_EARLY 0x20 /* Do not call ctors, postpone it to the + initialization during the image start. */ + +/* + * Symbol cache entry used during relocation to avoid multiple lookups + * of the same symbol. + */ +typedef struct Struct_SymCache { + const Elf_Sym *sym; /* Symbol table entry */ + const Obj_Entry *obj; /* Shared object which defines it */ +} SymCache; + +/* + * This structure provides a reentrant way to keep a list of objects and + * check which ones have already been processed in some way. + */ +typedef struct Struct_DoneList { + const Obj_Entry **objs; /* Array of object pointers */ + unsigned int num_alloc; /* Allocated size of the array */ + unsigned int num_used; /* Number of array slots used */ +} DoneList; + +struct Struct_RtldLockState { + int lockstate; + sigjmp_buf env; +}; + +struct fill_search_info_args { + int request; + unsigned int flags; + struct dl_serinfo *serinfo; + struct dl_serpath *serpath; + char *strspace; +}; + +/* + * The pack of arguments and results for the symbol lookup functions. + */ +typedef struct Struct_SymLook { + const char *name; + unsigned long hash; + uint32_t hash_gnu; + const Ver_Entry *ventry; + int flags; + const Obj_Entry *defobj_out; + const Elf_Sym *sym_out; + struct Struct_RtldLockState *lockstate; +} SymLook; + +void _rtld_error(const char *, ...) __printflike(1, 2) __exported; +void rtld_die(void) __dead2; +const char *rtld_strerror(int); +Obj_Entry *map_object(int, const char *, const struct stat *); +void *xcalloc(size_t, size_t); +void *xmalloc(size_t); +char *xstrdup(const char *); +void *malloc_aligned(size_t size, size_t align); +void free_aligned(void *ptr); +extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; +extern Elf_Sym sym_zero; /* For resolving undefined weak refs. */ + +void dump_relocations(Obj_Entry *); +void dump_obj_relocations(Obj_Entry *); +void dump_Elf_Rel(Obj_Entry *, const Elf_Rel *, u_long); +void dump_Elf_Rela(Obj_Entry *, const Elf_Rela *, u_long); + +/* + * Function declarations. + */ +unsigned long elf_hash(const char *); +const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *, + const Obj_Entry **, int, SymCache *, struct Struct_RtldLockState *); +void init_pltgot(Obj_Entry *); +void lockdflt_init(void); +void digest_notes(Obj_Entry *, Elf_Addr, Elf_Addr); +void obj_free(Obj_Entry *); +Obj_Entry *obj_new(void); +void _rtld_bind_start(void); +void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def); +void symlook_init(SymLook *, const char *); +int symlook_obj(SymLook *, const Obj_Entry *); +void *tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset); +void *allocate_tls(Obj_Entry *, void *, size_t, size_t); +void free_tls(void *, size_t, size_t); +void *allocate_module_tls(int index); +bool allocate_tls_offset(Obj_Entry *obj); +void free_tls_offset(Obj_Entry *obj); +const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long); + +/* + * MD function declarations. + */ +int do_copy_relocations(Obj_Entry *); +int reloc_non_plt(Obj_Entry *, Obj_Entry *, int flags, + struct Struct_RtldLockState *); +int reloc_plt(Obj_Entry *); +int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *); +int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *); +int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *); +void allocate_initial_tls(Obj_Entry *); + +#endif /* } */ diff --git a/src/bin/rtld-elf/rtld_lock.c b/src/bin/rtld-elf/rtld_lock.c new file mode 100644 index 0000000..0e4babf --- /dev/null +++ b/src/bin/rtld-elf/rtld_lock.c @@ -0,0 +1,404 @@ +/*- + * Copyright 1999, 2000 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * from: FreeBSD: src/libexec/rtld-elf/sparc64/lockdflt.c,v 1.3 2002/10/09 + * $FreeBSD: releng/10.2/libexec/rtld-elf/rtld_lock.c 281453 2015-04-12 06:45:40Z kib $ + */ + +/* + * Thread locking implementation for the dynamic linker. + * + * We use the "simple, non-scalable reader-preference lock" from: + * + * J. M. Mellor-Crummey and M. L. Scott. "Scalable Reader-Writer + * Synchronization for Shared-Memory Multiprocessors." 3rd ACM Symp. on + * Principles and Practice of Parallel Programming, April 1991. + * + * In this algorithm the lock is a single word. Its low-order bit is + * set when a writer holds the lock. The remaining high-order bits + * contain a count of readers desiring the lock. The algorithm requires + * atomic "compare_and_store" and "add" operations, which we implement + * using assembly language sequences in "rtld_start.S". + */ + +#include +#include +#include +#include + +#include "debug.h" +#include "rtld.h" +#include "rtld_machdep.h" + +void _rtld_thread_init(struct RtldLockInfo *) __exported; +void _rtld_atfork_pre(int *) __exported; +void _rtld_atfork_post(int *) __exported; + +#define WAFLAG 0x1 /* A writer holds the lock */ +#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */ + +typedef struct Struct_Lock { + volatile u_int lock; + void *base; +} Lock; + +static sigset_t fullsigmask, oldsigmask; +static int thread_flag; + +static void * +def_lock_create() +{ + void *base; + char *p; + uintptr_t r; + Lock *l; + + /* + * Arrange for the lock to occupy its own cache line. First, we + * optimistically allocate just a cache line, hoping that malloc + * will give us a well-aligned block of memory. If that doesn't + * work, we allocate a larger block and take a well-aligned cache + * line from it. + */ + base = xmalloc(CACHE_LINE_SIZE); + p = (char *)base; + if ((uintptr_t)p % CACHE_LINE_SIZE != 0) { + free(base); + base = xmalloc(2 * CACHE_LINE_SIZE); + p = (char *)base; + if ((r = (uintptr_t)p % CACHE_LINE_SIZE) != 0) + p += CACHE_LINE_SIZE - r; + } + l = (Lock *)p; + l->base = base; + l->lock = 0; + return l; +} + +static void +def_lock_destroy(void *lock) +{ + Lock *l = (Lock *)lock; + + free(l->base); +} + +static void +def_rlock_acquire(void *lock) +{ + Lock *l = (Lock *)lock; + + atomic_add_acq_int(&l->lock, RC_INCR); + while (l->lock & WAFLAG) + ; /* Spin */ +} + +static void +def_wlock_acquire(void *lock) +{ + Lock *l = (Lock *)lock; + sigset_t tmp_oldsigmask; + + for ( ; ; ) { + sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask); + if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG)) + break; + sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL); + } + oldsigmask = tmp_oldsigmask; +} + +static void +def_lock_release(void *lock) +{ + Lock *l = (Lock *)lock; + + if ((l->lock & WAFLAG) == 0) + atomic_add_rel_int(&l->lock, -RC_INCR); + else { + atomic_add_rel_int(&l->lock, -WAFLAG); + sigprocmask(SIG_SETMASK, &oldsigmask, NULL); + } +} + +static int +def_thread_set_flag(int mask) +{ + int old_val = thread_flag; + thread_flag |= mask; + return (old_val); +} + +static int +def_thread_clr_flag(int mask) +{ + int old_val = thread_flag; + thread_flag &= ~mask; + return (old_val); +} + +/* + * Public interface exposed to the rest of the dynamic linker. + */ +static struct RtldLockInfo lockinfo; +static struct RtldLockInfo deflockinfo; + +static __inline int +thread_mask_set(int mask) +{ + return lockinfo.thread_set_flag(mask); +} + +static __inline void +thread_mask_clear(int mask) +{ + lockinfo.thread_clr_flag(mask); +} + +#define RTLD_LOCK_CNT 3 +struct rtld_lock { + void *handle; + int mask; +} rtld_locks[RTLD_LOCK_CNT]; + +rtld_lock_t rtld_bind_lock = &rtld_locks[0]; +rtld_lock_t rtld_libc_lock = &rtld_locks[1]; +rtld_lock_t rtld_phdr_lock = &rtld_locks[2]; + +void +rlock_acquire(rtld_lock_t lock, RtldLockState *lockstate) +{ + + if (lockstate == NULL) + return; + + if (thread_mask_set(lock->mask) & lock->mask) { + dbg("rlock_acquire: recursed"); + lockstate->lockstate = RTLD_LOCK_UNLOCKED; + return; + } + lockinfo.rlock_acquire(lock->handle); + lockstate->lockstate = RTLD_LOCK_RLOCKED; +} + +void +wlock_acquire(rtld_lock_t lock, RtldLockState *lockstate) +{ + + if (lockstate == NULL) + return; + + if (thread_mask_set(lock->mask) & lock->mask) { + dbg("wlock_acquire: recursed"); + lockstate->lockstate = RTLD_LOCK_UNLOCKED; + return; + } + lockinfo.wlock_acquire(lock->handle); + lockstate->lockstate = RTLD_LOCK_WLOCKED; +} + +void +lock_release(rtld_lock_t lock, RtldLockState *lockstate) +{ + + if (lockstate == NULL) + return; + + switch (lockstate->lockstate) { + case RTLD_LOCK_UNLOCKED: + break; + case RTLD_LOCK_RLOCKED: + case RTLD_LOCK_WLOCKED: + thread_mask_clear(lock->mask); + lockinfo.lock_release(lock->handle); + break; + default: + assert(0); + } +} + +void +lock_upgrade(rtld_lock_t lock, RtldLockState *lockstate) +{ + + if (lockstate == NULL) + return; + + lock_release(lock, lockstate); + wlock_acquire(lock, lockstate); +} + +void +lock_restart_for_upgrade(RtldLockState *lockstate) +{ + + if (lockstate == NULL) + return; + + switch (lockstate->lockstate) { + case RTLD_LOCK_UNLOCKED: + case RTLD_LOCK_WLOCKED: + break; + case RTLD_LOCK_RLOCKED: + siglongjmp(lockstate->env, 1); + break; + default: + assert(0); + } +} + +void +lockdflt_init() +{ + int i; + + deflockinfo.rtli_version = RTLI_VERSION; + deflockinfo.lock_create = def_lock_create; + deflockinfo.lock_destroy = def_lock_destroy; + deflockinfo.rlock_acquire = def_rlock_acquire; + deflockinfo.wlock_acquire = def_wlock_acquire; + deflockinfo.lock_release = def_lock_release; + deflockinfo.thread_set_flag = def_thread_set_flag; + deflockinfo.thread_clr_flag = def_thread_clr_flag; + deflockinfo.at_fork = NULL; + + for (i = 0; i < RTLD_LOCK_CNT; i++) { + rtld_locks[i].mask = (1 << i); + rtld_locks[i].handle = NULL; + } + + memcpy(&lockinfo, &deflockinfo, sizeof(lockinfo)); + _rtld_thread_init(NULL); + /* + * Construct a mask to block all signals except traps which might + * conceivably be generated within the dynamic linker itself. + */ + sigfillset(&fullsigmask); + sigdelset(&fullsigmask, SIGILL); + sigdelset(&fullsigmask, SIGTRAP); + sigdelset(&fullsigmask, SIGABRT); + sigdelset(&fullsigmask, SIGEMT); + sigdelset(&fullsigmask, SIGFPE); + sigdelset(&fullsigmask, SIGBUS); + sigdelset(&fullsigmask, SIGSEGV); + sigdelset(&fullsigmask, SIGSYS); +} + +/* + * Callback function to allow threads implementation to + * register their own locking primitives if the default + * one is not suitable. + * The current context should be the only context + * executing at the invocation time. + */ +void +_rtld_thread_init(struct RtldLockInfo *pli) +{ + int flags, i; + void *locks[RTLD_LOCK_CNT]; + + /* disable all locking while this function is running */ + flags = thread_mask_set(~0); + + if (pli == NULL) + pli = &deflockinfo; + + + for (i = 0; i < RTLD_LOCK_CNT; i++) + if ((locks[i] = pli->lock_create()) == NULL) + break; + + if (i < RTLD_LOCK_CNT) { + while (--i >= 0) + pli->lock_destroy(locks[i]); + abort(); + } + + for (i = 0; i < RTLD_LOCK_CNT; i++) { + if (rtld_locks[i].handle == NULL) + continue; + if (flags & rtld_locks[i].mask) + lockinfo.lock_release(rtld_locks[i].handle); + lockinfo.lock_destroy(rtld_locks[i].handle); + } + + for (i = 0; i < RTLD_LOCK_CNT; i++) { + rtld_locks[i].handle = locks[i]; + if (flags & rtld_locks[i].mask) + pli->wlock_acquire(rtld_locks[i].handle); + } + + lockinfo.lock_create = pli->lock_create; + lockinfo.lock_destroy = pli->lock_destroy; + lockinfo.rlock_acquire = pli->rlock_acquire; + lockinfo.wlock_acquire = pli->wlock_acquire; + lockinfo.lock_release = pli->lock_release; + lockinfo.thread_set_flag = pli->thread_set_flag; + lockinfo.thread_clr_flag = pli->thread_clr_flag; + lockinfo.at_fork = pli->at_fork; + + /* restore thread locking state, this time with new locks */ + thread_mask_clear(~0); + thread_mask_set(flags); + dbg("_rtld_thread_init: done"); +} + +void +_rtld_atfork_pre(int *locks) +{ + RtldLockState ls[2]; + + if (locks == NULL) + return; + + /* + * Warning: this does not work with the rtld compat locks + * above, since the thread signal mask is corrupted (set to + * all signals blocked) if two locks are taken in write mode. + * The caller of the _rtld_atfork_pre() must provide the + * working implementation of the locks, and libthr locks are + * fine. + */ + wlock_acquire(rtld_phdr_lock, &ls[0]); + wlock_acquire(rtld_bind_lock, &ls[1]); + + /* XXXKIB: I am really sorry for this. */ + locks[0] = ls[1].lockstate; + locks[2] = ls[0].lockstate; +} + +void +_rtld_atfork_post(int *locks) +{ + RtldLockState ls[2]; + + if (locks == NULL) + return; + + bzero(ls, sizeof(ls)); + ls[0].lockstate = locks[2]; + ls[1].lockstate = locks[0]; + lock_release(rtld_bind_lock, &ls[1]); + lock_release(rtld_phdr_lock, &ls[0]); +} diff --git a/src/bin/rtld-elf/rtld_lock.h b/src/bin/rtld-elf/rtld_lock.h new file mode 100644 index 0000000..f30c63f --- /dev/null +++ b/src/bin/rtld-elf/rtld_lock.h @@ -0,0 +1,75 @@ +/*- + * Copyright 2003 Alexander Kabaev. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/libexec/rtld-elf/rtld_lock.h 281453 2015-04-12 06:45:40Z kib $ + */ + +#ifndef _RTLD_LOCK_H_ +#define _RTLD_LOCK_H_ + +#define RTLI_VERSION 0x01 +#define MAX_RTLD_LOCKS 8 + +struct RtldLockInfo +{ + unsigned int rtli_version; + void *(*lock_create)(void); + void (*lock_destroy)(void *); + void (*rlock_acquire)(void *); + void (*wlock_acquire)(void *); + void (*lock_release)(void *); + int (*thread_set_flag)(int); + int (*thread_clr_flag)(int); + void (*at_fork)(void); +}; + +extern void _rtld_thread_init(struct RtldLockInfo *) __exported; +extern void _rtld_atfork_pre(int *) __exported; +extern void _rtld_atfork_post(int *) __exported; + +#ifdef IN_RTLD + +struct rtld_lock; +typedef struct rtld_lock *rtld_lock_t; + +extern rtld_lock_t rtld_bind_lock; +extern rtld_lock_t rtld_libc_lock; +extern rtld_lock_t rtld_phdr_lock; + +#define RTLD_LOCK_UNLOCKED 0 +#define RTLD_LOCK_RLOCKED 1 +#define RTLD_LOCK_WLOCKED 2 + +struct Struct_RtldLockState; +typedef struct Struct_RtldLockState RtldLockState; + +void rlock_acquire(rtld_lock_t, RtldLockState *); +void wlock_acquire(rtld_lock_t, RtldLockState *); +void lock_release(rtld_lock_t, RtldLockState *); +void lock_upgrade(rtld_lock_t, RtldLockState *); +void lock_restart_for_upgrade(RtldLockState *); + +#endif /* IN_RTLD */ + +#endif diff --git a/src/bin/rtld-elf/rtld_machdep.h b/src/bin/rtld-elf/rtld_machdep.h new file mode 100644 index 0000000..3b2ccb9 --- /dev/null +++ b/src/bin/rtld-elf/rtld_machdep.h @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 1999, 2000 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/libexec/rtld-elf/i386/rtld_machdep.h 281453 2015-04-12 06:45:40Z kib $ + */ + +#ifndef RTLD_MACHDEP_H +#define RTLD_MACHDEP_H 1 + +#include +#include + +struct Struct_Obj_Entry; + +/* Return the address of the .dynamic section in the dynamic linker. */ +#define rtld_dynamic(obj) \ + ((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC)) + +/* Fixup the jump slot at "where" to transfer control to "target". */ +static inline Elf_Addr +reloc_jmpslot(Elf_Addr *where, Elf_Addr target, + const struct Struct_Obj_Entry *obj, + const struct Struct_Obj_Entry *refobj, const Elf_Rel *rel) +{ +#ifdef dbg + dbg("reloc_jmpslot: *%p = %p", (void *)(where), + (void *)(target)); +#endif + (*(Elf_Addr *)(where) = (Elf_Addr)(target)); + return target; +} + +#define make_function_pointer(def, defobj) \ + ((defobj)->relocbase + (def)->st_value) + +#define call_initfini_pointer(obj, target) \ + (((InitFunc)(target))()) + +#define call_init_pointer(obj, target) \ + (((InitArrFunc)(target))(main_argc, main_argv, environ)) + +#define round(size, align) \ + (((size) + (align) - 1) & ~((align) - 1)) +#define calculate_first_tls_offset(size, align) \ + round(size, align) +#define calculate_tls_offset(prev_offset, prev_size, size, align) \ + round((prev_offset) + (size), align) +#define calculate_tls_end(off, size) (off) + +typedef struct { + unsigned long ti_module; + unsigned long ti_offset; +} tls_index; + +void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1))) __exported; +void *__tls_get_addr(tls_index *ti) __exported; + +#define RTLD_DEFAULT_STACK_PF_EXEC PF_X +#define RTLD_DEFAULT_STACK_EXEC PROT_EXEC + +#endif diff --git a/src/bin/rtld-elf/rtld_printf.h b/src/bin/rtld-elf/rtld_printf.h new file mode 100644 index 0000000..b37bee6 --- /dev/null +++ b/src/bin/rtld-elf/rtld_printf.h @@ -0,0 +1,44 @@ +/*- + * Copyright 2011 Konstantin Belousov . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/libexec/rtld-elf/rtld_printf.h 225152 2011-08-24 20:05:13Z kib $ + */ + +#ifndef RTLD_PRINTF_H +#define RTLD_PRINTF_H 1 + +#include +#include + +int rtld_vsnprintf(char *buf, size_t bufsize, const char *fmt, va_list ap); +int rtld_vfdprintf(int fd, const char *fmt, va_list ap); +int rtld_fdprintf(int fd, const char *fmt, ...) __printflike(2, 3); +void rtld_fdputstr(int fd, const char *str); +void rtld_fdputchar(int fd, int c); + +#define rtld_printf(...) rtld_fdprintf(STDOUT_FILENO, __VA_ARGS__) +#define rtld_putstr(str) rtld_fdputstr(STDOUT_FILENO, (str)) +#define rtld_putchar(c) rtld_fdputchar(STDOUT_FILENO, (c)) + +#endif diff --git a/src/bin/rtld-elf/rtld_start.S b/src/bin/rtld-elf/rtld_start.S new file mode 100644 index 0000000..65d900d --- /dev/null +++ b/src/bin/rtld-elf/rtld_start.S @@ -0,0 +1,91 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/i386/rtld_start.S,v 1.4 2005/05/19 07:32:42 dfr Exp $ + */ + + .text + .align 4 + .globl .rtld_start + .type .rtld_start,@function +.rtld_start: + xorl %ebp,%ebp # Clear frame pointer for good form + movl %esp,%eax # Save initial stack pointer + movl %esp,%esi # Save initial stack pointer + andl $0xfffffff0,%esp # Align stack pointer + subl $16,%esp # A place to store exit procedure addr + movl %esp,%ebx # save address of exit proc + movl %esp,%ecx # construct address of obj_main + addl $4,%ecx + subl $4,%esp # Keep stack aligned + pushl %ecx # Pass address of obj_main + pushl %ebx # Pass address of exit proc + pushl %eax # Pass initial stack pointer to rtld + call _rtld@PLT # Call rtld(sp); returns entry point + addl $16,%esp # Remove arguments from stack + popl %edx # Get exit procedure address + movl %esi,%esp # Ignore obj_main +/* + * At this point, %eax contains the entry point of the main program, and + * %edx contains a pointer to a termination function that should be + * registered with atexit(). (crt1.o registers it.) + */ +.globl .rtld_goto_main +.rtld_goto_main: # This symbol exists just to make debugging easier. + jmp *%eax # Enter main program + + +/* + * Binder entry point. Control is transferred to here by code in the PLT. + * On entry, there are two arguments on the stack. In ascending address + * order, they are (1) "obj", a pointer to the calling object's Obj_Entry, + * and (2) "reloff", the byte offset of the appropriate relocation entry + * in the PLT relocation table. + * + * We are careful to preserve all registers, even the the caller-save + * registers. That is because this code may be invoked by low-level + * assembly-language code that is not ABI-compliant. + */ + .align 4 + .globl _rtld_bind_start + .type _rtld_bind_start,@function +_rtld_bind_start: + pushf # Save eflags + pushl %eax # Save %eax + pushl %edx # Save %edx + pushl %ecx # Save %ecx + pushl 20(%esp) # Copy reloff argument + pushl 20(%esp) # Copy obj argument + + call _rtld_bind@PLT # Transfer control to the binder + /* Now %eax contains the entry point of the function being called. */ + + addl $8,%esp # Discard binder arguments + movl %eax,20(%esp) # Store target over obj argument + popl %ecx # Restore %ecx + popl %edx # Restore %edx + popl %eax # Restore %eax + popf # Restore eflags + leal 4(%esp),%esp # Discard reloff, do not change eflags + ret # "Return" to target address diff --git a/src/bin/rtld-elf/rtld_tls.h b/src/bin/rtld-elf/rtld_tls.h new file mode 100644 index 0000000..4e17934 --- /dev/null +++ b/src/bin/rtld-elf/rtld_tls.h @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/rtld_tls.h,v 1.1 2004/08/03 08:50:58 dfr Exp $ + */ + +/* + * Semi-public interface from thread libraries to rtld for managing + * TLS. + */ + +#ifndef _RTLD_TLS_H_ +#define _RTLD_TLS_H_ + +/* + * Allocate a TLS block for a new thread. The memory allocated will + * include 'tcbsize' bytes aligned to a 'tcbalign' boundary (in bytes) + * for the thread library's private purposes. The location of the TCB + * block is returned by this function. For architectures using + * 'Variant I' TLS, the thread local storage follows the TCB, and for + * 'Variant II', the thread local storage precedes it. For + * architectures using the 'Variant II' model (e.g. i386, amd64, + * sparc64), the TCB must begin with two pointer fields which are used + * by rtld for its TLS implementation. For the 'Variant I' model, the + * TCB must begin with a single pointer field for rtld's + * implementation. + * + * If the value of 'oldtls' is non-NULL, the new TLS block will be + * initialised using the values contained in 'oldtls' and 'oldtls' + * will be freed. This is typically used when initialising a thread + * library to migrate from using the initial bootstrap TLS block + * created by rtld to one which contains suitable thread library + * private data. + * + * The value returned from this function is suitable for installing + * directly into the thread pointer register. + */ +extern void *_rtld_allocate_tls(void* oldtls, size_t tcbsize, size_t tcbalign); + +/* + * Free a TLS block allocated using _rtld_allocate_tls(). The tcbsize + * and tcbalign parameters must be the same as those used to allocate + * the block. + */ +extern void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign); + +#endif diff --git a/src/bin/rtld-elf/xmalloc.c b/src/bin/rtld-elf/xmalloc.c new file mode 100644 index 0000000..785e162 --- /dev/null +++ b/src/bin/rtld-elf/xmalloc.c @@ -0,0 +1,59 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/libexec/rtld-elf/xmalloc.c,v 1.3 2003/06/19 05:28:26 mdodd Exp $ + */ + +#include +#include +#include +#include + +void *xcalloc(size_t); +void *xmalloc(size_t); +char *xstrdup(const char *); + +void * +xcalloc(size_t size) +{ + return memset(xmalloc(size), 0, size); +} + +void * +xmalloc(size_t size) +{ + void *p = malloc(size); + if (p == NULL) + err(1, "Out of memory"); + return p; +} + +char * +xstrdup(const char *s) +{ + char *p = strdup(s); + if (p == NULL) + err(1, "Out of memory"); + return p; +} diff --git a/src/bin/sh/Makefile b/src/bin/sh/Makefile new file mode 100644 index 0000000..47eeb1d --- /dev/null +++ b/src/bin/sh/Makefile @@ -0,0 +1,49 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +Makefile.incl +Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = sh + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = sh1.o + +INCLUDES = -I../../include.new + +LIBRARIES = ../../lib/libc/libc.so + +STARTUP = ../../lib/csu/*.o + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../../build/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + #strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(BINARY) diff --git a/src/bin/shell/Makefile b/src/bin/shell/Makefile new file mode 100644 index 0000000..dbf897e --- /dev/null +++ b/src/bin/shell/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = shell + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o error.o commands.o exec.o input.o + +LIBRARIES = ../../build/lib/libc_old.so ../../build/lib/ubix_api.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/shell/commands.c b/src/bin/shell/commands.c new file mode 100644 index 0000000..e6f22d3 --- /dev/null +++ b/src/bin/shell/commands.c @@ -0,0 +1,157 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: commands.c 158 2016-01-19 02:08:13Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "shell.h" + +int commands(inputBuffer *data) { + int cPid = 0x0,i = 0x0,x = 0x0; + char **argv = &data->argv; + + mpi_message_t cmdMsg; + + if (data == NULL) return 1; + if (data->args->arg == NULL) return 1; + if (*data->args->arg == '\0') return 1; + + if (0 == memcmp(data->args->arg, "uname", 5)) { + printf("UbixOS v0.87 " __DATE__" " __TIME__ " \n"); + return(1); + } + else if (0 == memcmp(data->args->arg, "exit", 4)) { + exit(1); + } + else if (0 == memcmp(data->args->arg, "mypid", 5)) { + printf("My Pid: [%i]\n",getpid()); + return(1); + } + else if (memcmp(data->args->arg,"stress", 6) == 0) { + //for (i=0x0;i<100;i++) { + while (1) { + /* printf("Starting Clock\n"); */ + cPid = fork(); + if (cPid == 0x0) { + execve("clock",0x0,0x0); + exit(0x1); + } else { + printf("Childs Pid: [%i]\n",cPid); + while (pidStatus(cPid) > 0) + sched_yield(); + } + cPid = fork(); + if (cPid == 0x0) { + execve("ls", 0x0, 0x0); + exit(0x1); + } else { + printf("Childs Pid: [%i]\n",cPid); + while (pidStatus(cPid) > 0) + sched_yield(); + } + } + } + else if (memcmp(data->args->arg,"test2", 5) == 0) { + for (i=0x0;i<500;i++) { + cPid = fork(); + if (cPid == 0x0) { + printf("Pid: [%i:%i]\n",cPid,i); + execve("clock",0x0,0x0); + exit(0x1); + } + else { + printf("Childs Pid: [%i]\n",cPid); + } + } + } + else if (memcmp(data->args->arg,"test3", 5) == 0) { + for (i=0x0;i<50;i++) { + cPid = fork(); + if (cPid == 0x0) { + printf("Pid: [%i:%i]\n",cPid,i); + for (x=0x0;x<100;x++) sched_yield(); + printf("Exiting!!!\n"); + exit(0x1); + } + else { + printf("Childs Pid: [%i]\n",cPid); + } + } + } + else if (memcmp(data->args->arg,"echo",4) == 0) { + for (i=1;iargc;i++) { + printf("%s ",argv[i]); + } + printf("\n"); + } + else if (memcmp(data->args->arg,"about",5) == 0) { + printf("UbixOS Shell v0.99 (C) 2002\n"); + printf("Base Command Line Interface\n"); + } + else if (memcmp(data->args->arg,"cd",2) == 0) { + if (argv[1]) { + chdir(argv[1]); + getcwd(cwd,1024); + } + } + else if (memcmp(data->args->arg,"unlink",6) == 0) { + if (argv[1]) { + unlink(argv[1]); + } + } + else if (memcmp(data->args->arg,"msg",3) == 0x0) { + printf("Posting Message\n"); + cmdMsg.header = atoi(argv[2]); + sprintf(cmdMsg.data,argv[3]); + mpi_postMessage(argv[1],0x1,&cmdMsg); + } + else if (memcmp(data->args->arg,"mkdir",5) == 0x0) { + if (argv[1]) { + mkdir(argv[1],0xEAA); + } + } + else if (memcmp(data->args->arg,"id",2) == 0x0) { + printf("UID: %i, GID: %i\n",getuid(),getgid()); + } + else if (!strcmp(argv[1],"reboot")) { + cmdMsg.header = 1000; + cmdMsg.data[0] = '\0'; + mpi_postMessage("system",0x1,&cmdMsg); + } + else { + return(0); + } + return(1); + } diff --git a/src/bin/shell/error.c b/src/bin/shell/error.c new file mode 100644 index 0000000..3bba1a3 --- /dev/null +++ b/src/bin/shell/error.c @@ -0,0 +1,30 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: error.c 89 2016-01-12 00:20:40Z reddawg $ + +**************************************************************************************/ + +#include +#include + +void error(int errorCode,const char *errorMsg) { + printf("ERROR: #%i Message: %s\n", errorCode, errorMsg); + exit(errorCode); + } diff --git a/src/bin/shell/exec.c b/src/bin/shell/exec.c new file mode 100644 index 0000000..6a2ee04 --- /dev/null +++ b/src/bin/shell/exec.c @@ -0,0 +1,62 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: exec.c 158 2016-01-19 02:08:13Z reddawg $ + +**************************************************************************************/ + +#include +#include +#include +#include +#include +#include "shell.h" + + int boo = 0x0; + +void execProgram(inputBuffer *data) { + char file[1024]; + int cPid = 0x0; + + //printf("Executing App\n"); + + cPid = fork(); +printf("Forked: [%i]\n", cPid); + + if (!cPid) { + sprintf(file, "%s%s", cwd, data->argv[1]); + // if (boo == 0) + //execve(file,data->argv, 0x0); + execve(file,0x0, 0x0); + /* + else + execn(file,&data->argv); +*/ + printf("%s: Command Not Found.\n",data->argv[1]); + exit(-1); + } + else { + if (data->bg == 0x0) { + while (pidStatus(cPid) > 0) + sched_yield(); + } + if (cPid > 4) + boo = 1; + } + } diff --git a/src/bin/shell/input.c b/src/bin/shell/input.c new file mode 100644 index 0000000..11f8fe6 --- /dev/null +++ b/src/bin/shell/input.c @@ -0,0 +1,97 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors + in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: input.c 128 2016-01-14 14:06:43Z reddawg $ + + **************************************************************************************/ + +#include +#include +#include +#include "shell.h" + +void parseInput( inputBuffer *buffer, char *data ) { + int i = 0x0; + char *arg = 0x0; + // char **argv = 0x0; + struct argsStruct *tmpArgs = 0x0; + + while ( data[0] == ' ' ) { + data++; + } + + if ( *data == '\0' ) + return; + + buffer->args = (struct argsStruct *) malloc( sizeof(struct argsStruct) ); + + tmpArgs = buffer->args; + + while ( data != 0x0 ) { + + arg = strtok( data, " " ); + data = strtok( NULL, "\n" ); + +/* +if (data != 0x0) + printf( "sh[%s:%s]", arg, data ); +else + printf( "sh[%s]", arg ); +*/ + + if ( arg[0] == '&' ) { + buffer->bg = 0x1; + } + else { + buffer->argc++; + tmpArgs->arg = arg; + if ( data != 0x0 ) { + tmpArgs->next = (struct argsStruct *) malloc( sizeof(struct argsStruct) ); + } + tmpArgs = tmpArgs->next; + } + } + + /* Alloc memory for argv[] */ + buffer->argv = (char **) malloc( sizeof(char *) * ( buffer->argc + 1 ) ); + //buffer->envp = (char **)malloc(sizeof(char)); + + //buffer->envp[0] = 0x1; + + tmpArgs = buffer->args; + //argv = buffer->argv; + + //printf( "argc: [%i]\n", buffer->argc ); + //printf( "arg-1: [%i:%s]\n", buffer->args->arg, buffer->args->arg ); + + for ( i = 0x1; i <= buffer->argc ; i++ ) { + buffer->argv[i] = tmpArgs->arg; + //printf( "argv[%i]: %s\n", i, argv[i] ); + tmpArgs = tmpArgs->next; + } + buffer->argv[0] = (char *)buffer->argc; + //argv[buffer->argc+1] = buffer->envp; + //printf( "arg-1: [%i:%i:%s]\n", argv[0], buffer->args->arg, buffer->args->arg ); + +} + +void freeArgs( inputBuffer *ptr ) { + free( ptr->args ); + //free(tmpArgs->argv); +} diff --git a/src/bin/shell/main.c b/src/bin/shell/main.c new file mode 100644 index 0000000..36d564e --- /dev/null +++ b/src/bin/shell/main.c @@ -0,0 +1,76 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors + in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 160 2016-01-19 04:01:03Z reddawg $ + + **************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "shell.h" + +char *machine = 0x0; +char *cwd = 0x0; +char *cwc = 0x0; + +int main() { + + char *buffer = (char *) malloc( 512 ); + inputBuffer *inBuf = (inputBuffer *) malloc( sizeof(inputBuffer) ); + + machine = (char *) malloc( 32 ); + cwd = (char *) malloc( 1024 ); + + sprintf( machine, "uBixCube" ); + getcwd( cwd, 1024 ); + +printf("Is this My ERROR?"); + + //MrOlsen 2017-11-17 printf( "[0x%X]\n", ubix_test() ); + + while ( 1 ) { + aGain: printf( "%s@%s# ", machine, cwd ); + gets( (char *) buffer ); + + if ( buffer[0] == 0x0 ) + goto aGain; + + inBuf->argc = 0x0; + inBuf->args = 0x0; + inBuf->bg = 0x0; + + parseInput( inBuf, buffer ); + +printf( "m-arg: [%i]\n", inBuf->args->arg ); + + if ( inBuf->args->arg != 0x0 ) { + +// execProgram( inBuf ); + if (!commands(inBuf)) + execProgram(inBuf); + } + + freeArgs( inBuf ); + } + return ( 0x0 ); +} diff --git a/src/bin/shell/shell.h b/src/bin/shell/shell.h new file mode 100644 index 0000000..e140799 --- /dev/null +++ b/src/bin/shell/shell.h @@ -0,0 +1,22 @@ +#include + +extern char *cwd; + +struct argsStruct { + struct argsStruct *next; + char *arg; + }; + +typedef struct { + int argc; + char **argv; + char **envp; + uInt8 bg; + struct argsStruct *args; + } inputBuffer; + +void parseInput(inputBuffer *,char *); +int commands(inputBuffer *); +void execProgram(inputBuffer *); +void freeArgs(inputBuffer *ptr); +void error(int errorCode,const char *errorMsg); diff --git a/src/bin/stat/Makefile b/src/bin/stat/Makefile new file mode 100644 index 0000000..7730ee1 --- /dev/null +++ b/src/bin/stat/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 170 2016-01-20 02:28:45Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = stat + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#MrOlsen (2016-01-19) TEMP: This is just to make it static LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) +# strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/stat/main.c b/src/bin/stat/main.c new file mode 100644 index 0000000..b422f22 --- /dev/null +++ b/src/bin/stat/main.c @@ -0,0 +1,125 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 163 2016-01-19 15:34:38Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include + +void print2(char *string,int,int); + +#define MINUTE 60 +#define HOUR (60*MINUTE) +#define DAY (24*HOUR) +#define YEAR (365*DAY) + + +static int monthSecs[12] = { + 0, + DAY*(31), + DAY*(31+29), + DAY*(31+29+31), + DAY*(31+29+31+30), + DAY*(31+29+31+30+31), + DAY*(31+29+31+30+31+30), + DAY*(31+29+31+30+31+30+31), + DAY*(31+29+31+30+31+30+31+31), + DAY*(31+29+31+30+31+30+31+31+30), + DAY*(31+29+31+30+31+30+31+31+30+31), + DAY*(31+29+31+30+31+30+31+31+30+31+30) +}; + +int main(int argc,char **argv) { + int sysTime = 0x0; + int i = 0x0; + + int year = 0x0; + int month = 0x0; + int day = 0x0; + int hour = 0x0; + int min = 0x0; + int sec = 0x0; + + int x = 0x0; + + asm( + "movl %%gs,%%eax\n" + "movl %%eax, %0\n" + : "=g" (x) + : + : "eax" + ); + + printf("GS: [0x%X]\n", x); + asm( + "movl %%fs,%%eax\n" + "movl %%eax, %0\n" + : "=g" (x) + : + : "eax" + ); + printf("FS: [0x%X]\n", x); + exit(0); + + + + //start: + sysTime = gettime(); + + year = (sysTime/YEAR) + 1970; + sysTime -= (YEAR * (year-1970)); + sysTime -= DAY*(((year-1970)+1)/4); + for (i = 11;i >= 0;i--) { + if ((sysTime - monthSecs[i]) > 0) { + month = i; + break; + } + } + sysTime -= monthSecs[i]; + if (((month > 1) && (((year-1970)+2)%4)) == 0x0) { + sysTime += DAY; + } + + day = (sysTime/DAY); + sysTime -= (day*DAY); + hour = (sysTime/HOUR); + sysTime -= (hour*HOUR); + min = (sysTime/MINUTE); + sysTime -= (min*MINUTE); + sec = sysTime; + + printf("[%02d/%02d/%i, %02d:%02d.%02d]\n",month,day,year,hour,min,sec); +// goto start; + return(0); + } + +/*** + END + ***/ + diff --git a/src/bin/ttyd/Makefile b/src/bin/ttyd/Makefile new file mode 100644 index 0000000..60ee069 --- /dev/null +++ b/src/bin/ttyd/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = ttyd + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $(BUILD_DIR)/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(BUILD_DIR)/bin/$(BINARY) diff --git a/src/bin/ttyd/main.c b/src/bin/ttyd/main.c new file mode 100644 index 0000000..8cf8479 --- /dev/null +++ b/src/bin/ttyd/main.c @@ -0,0 +1,58 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + mpi_message_t myMsg; + + printf("Initializing TTYD\n"); + printf("mpi_post: [%i]\n",mpi_postMessage("system",0x1,&myMsg)); + + return(0x0); + } + +/*** + $Log: main.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:14:03 reddawg + no message + + Revision 1.1 2004/08/14 11:28:59 reddawg + ttyd + + END + ***/ + diff --git a/src/bin/ubistry/Makefile b/src/bin/ubistry/Makefile new file mode 100644 index 0000000..cdb7a53 --- /dev/null +++ b/src/bin/ubistry/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 129 2016-01-14 14:16:33Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = ubistry + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = db.o message.o main.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ${BUILD_DIR}/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip ${BUILD_DIR}/bin/$(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ${BUILD_DIR}/bin/$(BINARY) diff --git a/src/bin/ubistry/db.c b/src/bin/ubistry/db.c new file mode 100644 index 0000000..633d666 --- /dev/null +++ b/src/bin/ubistry/db.c @@ -0,0 +1,89 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: db.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include "./include/ubistry.h" + +static struct ubistryKey *keys = 0x0; + + +struct ubistryKey * ubistryFindKey(char *name) { + struct ubistryKey *tmpKey = keys; + + for (;tmpKey;tmpKey=tmpKey->next) { + if (!strcmp(name,tmpKey->name)) { + return(tmpKey); + } + } + return(0x0); + } + +int ubistryAddKey(char *name,char *value) { + struct ubistryKey *tmpKey = (struct ubistryKey *)malloc(sizeof(struct ubistryKey)); + + sprintf(tmpKey->name,name); + sprintf(tmpKey->value,value); + + if (keys == 0x0) { + keys = tmpKey; + keys->prev = 0x0; + keys->next = 0x0; + } + else { + tmpKey->next = keys; + tmpKey->prev = 0x0; + keys->prev = tmpKey; + keys = tmpKey; + } + + return(0x0); + } + +/*** + $Log: db.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:08 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:14:04 reddawg + no message + + Revision 1.2 2004/06/17 15:10:55 reddawg + Fixed Some Global Variables + + Revision 1.1 2004/05/26 15:41:20 reddawg + ubistry: added command 666 which will restart the registry server also added + command 51 to add a key format key,value + + END + ***/ diff --git a/src/bin/ubistry/include/ubistry.h b/src/bin/ubistry/include/ubistry.h new file mode 100644 index 0000000..231acea --- /dev/null +++ b/src/bin/ubistry/include/ubistry.h @@ -0,0 +1,15 @@ +#include + +#define MBOX_NAME "ubistry" + +struct ubistryKey { + struct ubistryKey *prev; + struct ubistryKey *next; + char name[128]; + char value[512]; + }; + +struct ubistryKey * ubistryFindKey(char *); +int ubistryAddKey(char *,char *); +int ubistryInitMbox(char *); +void ubistryProcessMessages(); diff --git a/src/bin/ubistry/main.c b/src/bin/ubistry/main.c new file mode 100644 index 0000000..c12c9f4 --- /dev/null +++ b/src/bin/ubistry/main.c @@ -0,0 +1,106 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include +#include "./include/ubistry.h" + +int main(int argc,char **argv) { + //FILE *pidFile; + + if (fork() != 0x0) { + exit(0x0); + } + + ubistryInitMbox(MBOX_NAME); + + ubistryAddKey("Ubu","Creator Of UbixOS"); + ubistryAddKey("TCA","The GUI GUY!!!"); + + while (1) { + ubistryProcessMessages(); + sched_yield(); + } + + exit(0x0); + } + +/*** + $Log: main.c,v $ + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:14:04 reddawg + no message + + Revision 1.10 2004/09/08 23:19:58 reddawg + hmm + + Revision 1.9 2004/08/02 18:50:13 reddawg + Updates to make some variable volatile to make work with gcc 3.3. However there are still some issues but we have not caused new issues with gcc 2.95 + + Revision 1.8 2004/07/17 16:43:10 reddawg + shell: fixed stress testing + ubistry: fixed some segfaults + spinlock: added assert() + + Revision 1.7 2004/06/17 15:10:55 reddawg + Fixed Some Global Variables + + Revision 1.6 2004/06/10 13:08:00 reddawg + Minor Bug Fixes + + Revision 1.5 2004/06/01 01:30:43 reddawg + No more warnings and organized make files + + Revision 1.4 2004/05/26 15:41:20 reddawg + ubistry: added command 666 which will restart the registry server also added + command 51 to add a key format key,value + + Revision 1.3 2004/05/26 13:10:39 reddawg + ubistry: added two functions + ubistryFindKey(char *name) <- Will find key with specified name + ubistryAddKey(char *name,char *value) <-> Will add key with specified + name and value + + Revision 1.2 2004/05/26 12:16:02 reddawg + ubistry: now runs as a deamon + + Revision 1.1 2004/05/26 12:09:12 reddawg + ubistry: this is the frame work for the ubix registry system more to come + over the next few days + + END + ***/ diff --git a/src/bin/ubistry/message.c b/src/bin/ubistry/message.c new file mode 100644 index 0000000..75523ab --- /dev/null +++ b/src/bin/ubistry/message.c @@ -0,0 +1,110 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: message.c 158 2016-01-19 02:08:13Z reddawg $ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "./include/ubistry.h" + +int ubistryInitMbox(char *name) { + + if (mpi_createMbox(name) != 0x0) { + printf("Error: Error Creating Mail Box: [%s]\n",name); + return(-1); + } + + return(0x0); + } + +void ubistryProcessMessages() { + mpi_message_t msg; + struct ubistryKey *tmpKey = 0x0; + char *key,*value; + + mfmStart: + if (mpi_fetchMessage("ubistry",&msg) == 0x0) { + switch (msg.header) { + case 50: + tmpKey = ubistryFindKey(msg.data); + if (tmpKey == 0x0) + printf("ubistry: Key (%s) Not Found\n",msg.data); + else + printf("ubistry: Key (%s) Found Has Value (%s)\n",tmpKey->name,tmpKey->value); + break; + case 51: + key = strtok(msg.data,","); + value = strtok(NULL,"\n"); + printf("ubistry: Adding key (%s) with value (%s)\n",key,value); + ubistryAddKey(key,value); + break; + case 666: + mpi_destroyMbox("ubistry"); + if (fork() == 0x0) { + printf("ubistry: Restarting\n"); + execve("ubistry@sys",0x0,0x0); + } + else { + exit(0x0); + } + break; + default: + printf("ubistry: Command (%i) With Data (%s) Not Valid\n",msg.header,msg.data); + break; + } + goto mfmStart; + } + return; + } + +/*** + $Log: message.c,v $ + Revision 1.2 2006/12/12 14:09:17 reddawg + Changes + + Revision 1.1.1.1 2006/06/01 12:46:09 reddawg + ubix2 + + Revision 1.2 2005/10/12 00:13:28 reddawg + Removed + + Revision 1.1.1.1 2005/09/26 17:14:04 reddawg + no message + + Revision 1.2 2004/08/14 11:23:02 reddawg + Changes + + Revision 1.1 2004/05/26 15:41:20 reddawg + ubistry: added command 666 which will restart the registry server also added + command 51 to add a key format key,value + + END + ***/ diff --git a/src/bin/views/Makefile b/src/bin/views/Makefile new file mode 100644 index 0000000..1de7a94 --- /dev/null +++ b/src/bin/views/Makefile @@ -0,0 +1,49 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +Makefile.incl + +#Compiler Flags +CFLAGS = -I../../lib/libc/include -fno-builtin -nostdlib -nostdinc + +#Linker +LD = ld + +#Binary File Name +BINARY = views + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#Libraries +#LIBRARIES = ../../lib/libc/libc.so +LIBRARIES = ../../lib/libc/locale/*.o ../../lib/libc/stdio/*.o ../../lib/libc/stdlib/*.o ../../lib/libc/sys/*.o ../../lib/libc/string/*.o + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../build/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + strip $(BINARY) + +# Compile the source files +.cc.o: + $(CXX) -Wall -fomit-frame-pointer -O $(CFLAGS) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -fomit-frame-pointer -O $(CFLAGS) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) -c -o $@ $< + +.c.s: + $(CC) -Wall -fomit-frame-pointer -O $(CFLAGS) -S -o $@ $< + +.S.o: + $(CC) -Wall -fomit-frame-pointer -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../build/$(BINARY) diff --git a/src/bin/views/main.c b/src/bin/views/main.c new file mode 100644 index 0000000..dcf041e --- /dev/null +++ b/src/bin/views/main.c @@ -0,0 +1,34 @@ +/************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors +in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id: main.c 89 2016-01-12 00:20:40Z reddawg $ + +**************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + return(0); + } + +/*** + END + ***/ + diff --git a/src/build/bin/.gitignore b/src/build/bin/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/build/bin/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/build/lib/.gitignore b/src/build/lib/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/build/lib/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/build/libexec/.gitignore b/src/build/libexec/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/build/libexec/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/etc/motd b/src/etc/motd new file mode 100644 index 0000000..f5a6ac4 --- /dev/null +++ b/src/etc/motd @@ -0,0 +1,12 @@ +Welcome to UbixOS + +This is an experimental kernel so it has the potential +to crash if it does please send us some info so we can +fix it or if you have access to the source fix it and +commit the changes. + +All reports can be sent to cwolsen@ubixos.com + +NOTICE!!!!! + +This is now 2016 and we're working again! diff --git a/src/etc/userdb b/src/etc/userdb new file mode 100644 index 0000000..ed464e7 --- /dev/null +++ b/src/etc/userdb Binary files differ diff --git a/src/include.new/Block.h b/src/include.new/Block.h new file mode 100644 index 0000000..55cdd01 --- /dev/null +++ b/src/include.new/Block.h @@ -0,0 +1,59 @@ +/* + * Block.h + * + * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef _BLOCK_H_ +#define _BLOCK_H_ + +#if !defined(BLOCK_EXPORT) +# if defined(__cplusplus) +# define BLOCK_EXPORT extern "C" +# else +# define BLOCK_EXPORT extern +# endif +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Create a heap based copy of a Block or simply add a reference to an existing one. + * This must be paired with Block_release to recover memory, even when running + * under Objective-C Garbage Collection. + */ +BLOCK_EXPORT void *_Block_copy(const void *aBlock); + +/* Lose the reference, and if heap based and last reference, recover the memory. */ +BLOCK_EXPORT void _Block_release(const void *aBlock); + +#if defined(__cplusplus) +} +#endif + +/* Type correct macros. */ + +#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) +#define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) + + +#endif diff --git a/src/include.new/Block_private.h b/src/include.new/Block_private.h new file mode 100644 index 0000000..8ae8218 --- /dev/null +++ b/src/include.new/Block_private.h @@ -0,0 +1,179 @@ +/* + * Block_private.h + * + * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef _BLOCK_PRIVATE_H_ +#define _BLOCK_PRIVATE_H_ + +#if !defined(BLOCK_EXPORT) +# if defined(__cplusplus) +# define BLOCK_EXPORT extern "C" +# else +# define BLOCK_EXPORT extern +# endif +#endif + +#ifndef _MSC_VER +#include +#else +/* MSVC doesn't have . Compensate. */ +typedef char bool; +#define true (bool)1 +#define false (bool)0 +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +enum { + BLOCK_REFCOUNT_MASK = (0xffff), + BLOCK_NEEDS_FREE = (1 << 24), + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ + BLOCK_IS_GC = (1 << 27), + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_HAS_DESCRIPTOR = (1 << 29) +}; + + +/* Revised new layout. */ +struct Block_descriptor { + unsigned long int reserved; + unsigned long int size; + void (*copy)(void *dst, void *src); + void (*dispose)(void *); +}; + + +struct Block_layout { + void *isa; + int flags; + int reserved; + void (*invoke)(void *, ...); + struct Block_descriptor *descriptor; + /* Imported variables. */ +}; + + +struct Block_byref { + void *isa; + struct Block_byref *forwarding; + int flags; /* refcount; */ + int size; + void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); + void (*byref_destroy)(struct Block_byref *); + /* long shared[0]; */ +}; + + +struct Block_byref_header { + void *isa; + struct Block_byref *forwarding; + int flags; + int size; +}; + + +/* Runtime support functions used by compiler when generating copy/dispose helpers. */ + +enum { + /* See function implementation for a more complete description of these fields and combinations */ + BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ + BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ + BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ + BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ + BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ +}; + +/* Runtime entry point called by compiler when assigning objects inside copy helper routines */ +BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); + /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ + + +/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ +BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); + + + +/* Other support functions */ + +/* Runtime entry to get total size of a closure */ +BLOCK_EXPORT unsigned long int Block_size(void *block_basic); + + + +/* the raw data space for runtime classes for blocks */ +/* class+meta used for stack, malloc, and collectable based blocks */ +BLOCK_EXPORT void * _NSConcreteStackBlock[32]; +BLOCK_EXPORT void * _NSConcreteMallocBlock[32]; +BLOCK_EXPORT void * _NSConcreteAutoBlock[32]; +BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; +BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; +BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; + + +/* the intercept routines that must be used under GC */ +BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), + void (*setHasRefcount)(const void *, const bool), + void (*gc_assign_strong)(void *, void **), + void (*gc_assign_weak)(const void *, void *), + void (*gc_memmove)(void *, void *, unsigned long)); + +/* earlier version, now simply transitional */ +BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), + void (*setHasRefcount)(const void *, const bool), + void (*gc_assign_strong)(void *, void **), + void (*gc_assign_weak)(const void *, void *)); + +BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), + void (*release)(const void *)); + +/* make a collectable GC heap based Block. Not useful under non-GC. */ +BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); + +/* thread-unsafe diagnostic */ +BLOCK_EXPORT const char *_Block_dump(const void *block); + + +/* Obsolete */ + +/* first layout */ +struct Block_basic { + void *isa; + int Block_flags; /* int32_t */ + int Block_size; /* XXX should be packed into Block_flags */ + void (*Block_invoke)(void *); + void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ + void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ + /* long params[0]; // where const imports, __block storage references, etc. get laid down */ +}; + + +#if defined(__cplusplus) +} +#endif + + +#endif /* _BLOCK_PRIVATE_H_ */ diff --git a/src/include.new/FlexLexer.h b/src/include.new/FlexLexer.h new file mode 100644 index 0000000..bad4ce0 --- /dev/null +++ b/src/include.new/FlexLexer.h @@ -0,0 +1,206 @@ +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + int YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream* new_in = 0, + FLEX_STD ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif // FLEXLEXER_H + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex manual. +#define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); + virtual int yywrap(); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif // yyFlexLexer || ! yyFlexLexerOnce + diff --git a/src/include.new/_ctype.h b/src/include.new/_ctype.h new file mode 100644 index 0000000..8ed4b86 --- /dev/null +++ b/src/include.new/_ctype.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From @(#)ctype.h 8.4 (Berkeley) 1/21/94 + * From FreeBSD: src/include/ctype.h,v 1.27 2004/06/23 07:11:39 tjr Exp + * $FreeBSD: releng/10.2/include/_ctype.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef __CTYPE_H_ +#define __CTYPE_H_ + +#include +#include + +#define _CTYPE_A 0x00000100L /* Alpha */ +#define _CTYPE_C 0x00000200L /* Control */ +#define _CTYPE_D 0x00000400L /* Digit */ +#define _CTYPE_G 0x00000800L /* Graph */ +#define _CTYPE_L 0x00001000L /* Lower */ +#define _CTYPE_P 0x00002000L /* Punct */ +#define _CTYPE_S 0x00004000L /* Space */ +#define _CTYPE_U 0x00008000L /* Upper */ +#define _CTYPE_X 0x00010000L /* X digit */ +#define _CTYPE_B 0x00020000L /* Blank */ +#define _CTYPE_R 0x00040000L /* Print */ +#define _CTYPE_I 0x00080000L /* Ideogram */ +#define _CTYPE_T 0x00100000L /* Special */ +#define _CTYPE_Q 0x00200000L /* Phonogram */ +#define _CTYPE_SW0 0x20000000L /* 0 width character */ +#define _CTYPE_SW1 0x40000000L /* 1 width character */ +#define _CTYPE_SW2 0x80000000L /* 2 width character */ +#define _CTYPE_SW3 0xc0000000L /* 3 width character */ +#define _CTYPE_SWM 0xe0000000L /* Mask for screen width data */ +#define _CTYPE_SWS 30 /* Bits to shift to get width */ + +/* See comments in about __ct_rune_t. */ +__BEGIN_DECLS +unsigned long ___runetype(__ct_rune_t) __pure; +__ct_rune_t ___tolower(__ct_rune_t) __pure; +__ct_rune_t ___toupper(__ct_rune_t) __pure; +__END_DECLS + +/* + * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us + * to generate code for extern versions of all our inline functions. + */ +#ifdef _EXTERNALIZE_CTYPE_INLINES_ +#define _USE_CTYPE_INLINE_ +#define static +#define __inline +#endif + +extern int __mb_sb_limit; + +/* + * Use inline functions if we are allowed to and the compiler supports them. + */ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +#include + +static __inline int +__maskrune(__ct_rune_t _c, unsigned long _f) +{ + return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) : + _CurrentRuneLocale->__runetype[_c]) & _f; +} + +static __inline int +__sbmaskrune(__ct_rune_t _c, unsigned long _f) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? 0 : + _CurrentRuneLocale->__runetype[_c] & _f; +} + +static __inline int +__istype(__ct_rune_t _c, unsigned long _f) +{ + return (!!__maskrune(_c, _f)); +} + +static __inline int +__sbistype(__ct_rune_t _c, unsigned long _f) +{ + return (!!__sbmaskrune(_c, _f)); +} + +static __inline int +__isctype(__ct_rune_t _c, unsigned long _f) +{ + return (_c < 0 || _c >= 128) ? 0 : + !!(_DefaultRuneLocale.__runetype[_c] & _f); +} + +static __inline __ct_rune_t +__toupper(__ct_rune_t _c) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) : + _CurrentRuneLocale->__mapupper[_c]; +} + +static __inline __ct_rune_t +__sbtoupper(__ct_rune_t _c) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? _c : + _CurrentRuneLocale->__mapupper[_c]; +} + +static __inline __ct_rune_t +__tolower(__ct_rune_t _c) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) : + _CurrentRuneLocale->__maplower[_c]; +} + +static __inline __ct_rune_t +__sbtolower(__ct_rune_t _c) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? _c : + _CurrentRuneLocale->__maplower[_c]; +} + +static __inline int +__wcwidth(__ct_rune_t _c) +{ + unsigned int _x; + + if (_c == 0) + return (0); + _x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R); + if ((_x & _CTYPE_SWM) != 0) + return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); + return ((_x & _CTYPE_R) != 0 ? 1 : -1); +} + +#else /* not using inlines */ + +__BEGIN_DECLS +int __maskrune(__ct_rune_t, unsigned long); +int __sbmaskrune(__ct_rune_t, unsigned long); +int __istype(__ct_rune_t, unsigned long); +int __sbistype(__ct_rune_t, unsigned long); +int __isctype(__ct_rune_t, unsigned long); +__ct_rune_t __toupper(__ct_rune_t); +__ct_rune_t __sbtoupper(__ct_rune_t); +__ct_rune_t __tolower(__ct_rune_t); +__ct_rune_t __sbtolower(__ct_rune_t); +int __wcwidth(__ct_rune_t); +__END_DECLS +#endif /* using inlines */ + +#endif /* !__CTYPE_H_ */ diff --git a/src/include.new/_semaphore.h b/src/include.new/_semaphore.h new file mode 100644 index 0000000..b8a83b2 --- /dev/null +++ b/src/include.new/_semaphore.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2002 Alfred Perlstein + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/sys/sys/_semaphore.h 201546 2010-01-05 02:37:59Z davidxu $ + */ +#ifndef __SEMAPHORE_H_ +#define __SEMAPHORE_H_ + +typedef intptr_t semid_t; +struct timespec; + +#define SEM_VALUE_MAX __INT_MAX + +#ifndef _KERNEL + +__BEGIN_DECLS + +int ksem_close(semid_t id); +int ksem_post(semid_t id); +int ksem_wait(semid_t id); +int ksem_trywait(semid_t id); +int ksem_timedwait(semid_t id, const struct timespec *abstime); +int ksem_init(semid_t *idp, unsigned int value); +int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, + unsigned int value); +int ksem_unlink(const char *name); +int ksem_getvalue(semid_t id, int *val); +int ksem_destroy(semid_t id); + +__END_DECLS + +#endif /* !_KERNEL */ + +#endif /* __SEMAPHORE_H_ */ diff --git a/src/include.new/a.out.h b/src/include.new/a.out.h new file mode 100644 index 0000000..bf57968 --- /dev/null +++ b/src/include.new/a.out.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)a.out.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/10.2/include/a.out.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _AOUT_H_ +#define _AOUT_H_ + +#include +#include +#include +#include +#include + +#define _AOUT_INCLUDE_ +#include + +#endif /* !_AOUT_H_ */ diff --git a/src/include.new/aio.h b/src/include.new/aio.h new file mode 100644 index 0000000..75353a6 --- /dev/null +++ b/src/include.new/aio.h @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 1997 John S. Dyson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. John S. Dyson's name may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * DISCLAIMER: This code isn't warranted to do anything useful. Anything + * bad that happens because of using this software isn't the responsibility + * of the author. This software is distributed AS-IS. + * + * $FreeBSD: releng/10.2/sys/sys/aio.h 251526 2013-06-08 13:27:57Z glebius $ + */ + +#ifndef _SYS_AIO_H_ +#define _SYS_AIO_H_ + +#include +#include + +/* + * Returned by aio_cancel: + */ +#define AIO_CANCELED 0x1 +#define AIO_NOTCANCELED 0x2 +#define AIO_ALLDONE 0x3 + +/* + * LIO opcodes + */ +#define LIO_NOP 0x0 +#define LIO_WRITE 0x1 +#define LIO_READ 0x2 +#ifdef _KERNEL +#define LIO_SYNC 0x3 +#define LIO_MLOCK 0x4 +#endif + +/* + * LIO modes + */ +#define LIO_NOWAIT 0x0 +#define LIO_WAIT 0x1 + +/* + * Maximum number of allowed LIO operations + */ +#define AIO_LISTIO_MAX 16 + +/* + * Private members for aiocb -- don't access + * directly. + */ +struct __aiocb_private { + long status; + long error; + void *kernelinfo; +}; + +/* + * I/O control block + */ +typedef struct aiocb { + int aio_fildes; /* File descriptor */ + off_t aio_offset; /* File offset for I/O */ + volatile void *aio_buf; /* I/O buffer in process space */ + size_t aio_nbytes; /* Number of bytes for I/O */ + int __spare__[2]; + void *__spare2__; + int aio_lio_opcode; /* LIO opcode */ + int aio_reqprio; /* Request priority -- ignored */ + struct __aiocb_private _aiocb_private; + struct sigevent aio_sigevent; /* Signal to deliver */ +} aiocb_t; + +#ifndef _KERNEL + +struct timespec; + +__BEGIN_DECLS +/* + * Asynchronously read from a file + */ +int aio_read(struct aiocb *); + +/* + * Asynchronously write to file + */ +int aio_write(struct aiocb *); + +/* + * List I/O Asynchronously/synchronously read/write to/from file + * "lio_mode" specifies whether or not the I/O is synchronous. + * "acb_list" is an array of "nacb_listent" I/O control blocks. + * when all I/Os are complete, the optional signal "sig" is sent. + */ +int lio_listio(int, struct aiocb * const [], int, struct sigevent *); + +/* + * Get completion status + * returns EINPROGRESS until I/O is complete. + * this routine does not block. + */ +int aio_error(const struct aiocb *); + +/* + * Finish up I/O, releasing I/O resources and returns the value + * that would have been associated with a synchronous I/O request. + * This routine must be called once and only once for each + * I/O control block who has had I/O associated with it. + */ +ssize_t aio_return(struct aiocb *); + +/* + * Cancel I/O + */ +int aio_cancel(int, struct aiocb *); + +/* + * Suspend until all specified I/O or timeout is complete. + */ +int aio_suspend(const struct aiocb * const[], int, const struct timespec *); + +/* + * Asynchronous mlock + */ +int aio_mlock(struct aiocb *); + +#ifdef __BSD_VISIBLE +int aio_waitcomplete(struct aiocb **, struct timespec *); +#endif + +int aio_fsync(int op, struct aiocb *aiocbp); +__END_DECLS + +#else + +/* Forward declarations for prototypes below. */ +struct socket; +struct sockbuf; + +extern void (*aio_swake)(struct socket *, struct sockbuf *); + +#endif + +#endif diff --git a/src/include.new/alias.h b/src/include.new/alias.h new file mode 100644 index 0000000..9559561 --- /dev/null +++ b/src/include.new/alias.h @@ -0,0 +1,238 @@ +/* lint -save -library Flexelint comment for external headers */ + +/*- + * Copyright (c) 2001 Charles Mott + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/sys/netinet/libalias/alias.h 223080 2011-06-14 13:35:24Z ae $ + */ + +/* + * Alias.h defines the outside world interfaces for the packet aliasing + * software. + * + * This software is placed into the public domain with no restrictions on its + * distribution. + */ + +#ifndef _ALIAS_H_ +#define _ALIAS_H_ + +#include +#include +#include + +#define LIBALIAS_BUF_SIZE 128 +#ifdef _KERNEL +/* + * The kernel version of libalias does not support these features. + */ +#define NO_FW_PUNCH +#define NO_USE_SOCKETS +#endif + +/* + * The external interface to libalias, the packet aliasing engine. + * + * There are two sets of functions: + * + * PacketAlias*() the old API which doesn't take an instance pointer + * and therefore can only have one packet engine at a time. + * + * LibAlias*() the new API which takes as first argument a pointer to + * the instance of the packet aliasing engine. + * + * The functions otherwise correspond to each other one for one, except + * for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were + * were misnamed in the old API. + */ + +/* + * The instance structure + */ +struct libalias; + +/* + * An anonymous structure, a pointer to which is returned from + * PacketAliasRedirectAddr(), PacketAliasRedirectPort() or + * PacketAliasRedirectProto(), passed to PacketAliasAddServer(), + * and freed by PacketAliasRedirectDelete(). + */ +struct alias_link; + +/* Initialization and control functions. */ +struct libalias *LibAliasInit(struct libalias *); +void LibAliasSetAddress(struct libalias *, struct in_addr _addr); +void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num); +void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port); +unsigned int + LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask); +void LibAliasUninit(struct libalias *); + +/* Packet Handling functions. */ +int LibAliasIn (struct libalias *, char *_ptr, int _maxpacketsize); +int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize); +int LibAliasOutTry(struct libalias *, char *_ptr, int _maxpacketsize, int _create); +int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize); + +/* Port and address redirection functions. */ + +int +LibAliasAddServer(struct libalias *, struct alias_link *_lnk, + struct in_addr _addr, unsigned short _port); +struct alias_link * +LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr, + struct in_addr _alias_addr); +int LibAliasRedirectDynamic(struct libalias *, struct alias_link *_lnk); +void LibAliasRedirectDelete(struct libalias *, struct alias_link *_lnk); +struct alias_link * +LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr, + unsigned short _src_port, struct in_addr _dst_addr, + unsigned short _dst_port, struct in_addr _alias_addr, + unsigned short _alias_port, unsigned char _proto); +struct alias_link * +LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr, + struct in_addr _dst_addr, struct in_addr _alias_addr, + unsigned char _proto); + +/* Fragment Handling functions. */ +void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment); +char *LibAliasGetFragment(struct libalias *, char *_ptr); +int LibAliasSaveFragment(struct libalias *, char *_ptr); + +/* Miscellaneous functions. */ +int LibAliasCheckNewLink(struct libalias *); +unsigned short + LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes); +void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr); + +/* Transparent proxying routines. */ +int LibAliasProxyRule(struct libalias *, const char *_cmd); + +/* Module handling API */ +int LibAliasLoadModule(char *); +int LibAliasUnLoadAllModule(void); +int LibAliasRefreshModules(void); + +/* Mbuf helper function. */ +struct mbuf *m_megapullup(struct mbuf *, int); + +/* + * Mode flags and other constants. + */ + + +/* Mode flags, set using PacketAliasSetMode() */ + +/* + * If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log + * every time a link is created or deleted. This is useful for debugging. + */ +#define PKT_ALIAS_LOG 0x01 + +/* + * If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp, + * telnet or web servers will be prevented by the aliasing mechanism. + */ +#define PKT_ALIAS_DENY_INCOMING 0x02 + +/* + * If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from the + * same port as they originated on. This allows e.g. rsh to work *99% of the + * time*, but _not_ 100% (it will be slightly flakey instead of not working + * at all). This mode bit is set by PacketAliasInit(), so it is a default + * mode of operation. + */ +#define PKT_ALIAS_SAME_PORTS 0x04 + +/* + * If PKT_ALIAS_USE_SOCKETS is set, then when partially specified links (e.g. + * destination port and/or address is zero), the packet aliasing engine will + * attempt to allocate a socket for the aliasing port it chooses. This will + * avoid interference with the host machine. Fully specified links do not + * require this. This bit is set after a call to PacketAliasInit(), so it is + * a default mode of operation. + */ +#ifndef NO_USE_SOCKETS +#define PKT_ALIAS_USE_SOCKETS 0x08 +#endif +/*- + * If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with + * unregistered source addresses will be aliased. Private + * addresses are those in the following ranges: + * + * 10.0.0.0 -> 10.255.255.255 + * 172.16.0.0 -> 172.31.255.255 + * 192.168.0.0 -> 192.168.255.255 + */ +#define PKT_ALIAS_UNREGISTERED_ONLY 0x10 + +/* + * If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic + * aliasing links will be reset whenever PacketAliasSetAddress() changes the + * default aliasing address. If the default aliasing address is left + * unchanged by this function call, then the table of dynamic aliasing links + * will be left intact. This bit is set after a call to PacketAliasInit(). + */ +#define PKT_ALIAS_RESET_ON_ADDR_CHANGE 0x20 + +/* + * If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only + * transparent proxying is performed. + */ +#define PKT_ALIAS_PROXY_ONLY 0x40 + +/* + * If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn() and + * PacketAliasOut() are reversed. + */ +#define PKT_ALIAS_REVERSE 0x80 + +#ifndef NO_FW_PUNCH +/* + * If PKT_ALIAS_PUNCH_FW is set, active FTP and IRC DCC connections will + * create a 'hole' in the firewall to allow the transfers to work. The + * ipfw rule number that the hole is created with is controlled by + * PacketAliasSetFWBase(). The hole will be attached to that + * particular alias_link, so when the link goes away the hole is deleted. + */ +#define PKT_ALIAS_PUNCH_FW 0x100 +#endif + +/* + * If PKT_ALIAS_SKIP_GLOBAL is set, nat instance is not checked for matching + * states in 'ipfw nat global' rule. + */ +#define PKT_ALIAS_SKIP_GLOBAL 0x200 + +/* Function return codes. */ +#define PKT_ALIAS_ERROR -1 +#define PKT_ALIAS_OK 1 +#define PKT_ALIAS_IGNORED 2 +#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3 +#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4 + +#endif /* !_ALIAS_H_ */ + +/* lint -restore */ diff --git a/src/include.new/altq/altq.h b/src/include.new/altq/altq.h new file mode 100644 index 0000000..b6220d9 --- /dev/null +++ b/src/include.new/altq/altq.h @@ -0,0 +1,204 @@ +/* $FreeBSD: releng/10.2/sys/contrib/altq/altq/altq.h 130368 2004-06-12 00:57:20Z mlaier $ */ +/* $KAME: altq.h,v 1.10 2003/07/10 12:07:47 kjc Exp $ */ + +/* + * Copyright (C) 1998-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _ALTQ_ALTQ_H_ +#define _ALTQ_ALTQ_H_ + +#if 0 +/* + * allow altq-3 (altqd(8) and /dev/altq) to coexist with the new pf-based altq. + * altq3 is mainly for research experiments. pf-based altq is for daily use. + */ +#define ALTQ3_COMPAT /* for compatibility with altq-3 */ +#define ALTQ3_CLFIER_COMPAT /* for compatibility with altq-3 classifier */ +#endif + +#ifdef ALTQ3_COMPAT +#include +#include +#include +#include + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#endif /* ALTQ3_COMPAT */ + +/* altq discipline type */ +#define ALTQT_NONE 0 /* reserved */ +#define ALTQT_CBQ 1 /* cbq */ +#define ALTQT_WFQ 2 /* wfq */ +#define ALTQT_AFMAP 3 /* afmap */ +#define ALTQT_FIFOQ 4 /* fifoq */ +#define ALTQT_RED 5 /* red */ +#define ALTQT_RIO 6 /* rio */ +#define ALTQT_LOCALQ 7 /* local use */ +#define ALTQT_HFSC 8 /* hfsc */ +#define ALTQT_CDNR 9 /* traffic conditioner */ +#define ALTQT_BLUE 10 /* blue */ +#define ALTQT_PRIQ 11 /* priority queue */ +#define ALTQT_JOBS 12 /* JoBS */ +#define ALTQT_MAX 13 /* should be max discipline type + 1 */ + +#ifdef ALTQ3_COMPAT +struct altqreq { + char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ + u_long arg; /* request-specific argument */ +}; +#endif + +/* simple token backet meter profile */ +struct tb_profile { + u_int rate; /* rate in bit-per-sec */ + u_int depth; /* depth in bytes */ +}; + +#ifdef ALTQ3_COMPAT +struct tbrreq { + char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct tb_profile tb_prof; /* token bucket profile */ +}; + +#ifdef ALTQ3_CLFIER_COMPAT +/* + * common network flow info structure + */ +struct flowinfo { + u_char fi_len; /* total length */ + u_char fi_family; /* address family */ + u_int8_t fi_data[46]; /* actually longer; address family + specific flow info. */ +}; + +/* + * flow info structure for internet protocol family. + * (currently this is the only protocol family supported) + */ +struct flowinfo_in { + u_char fi_len; /* sizeof(struct flowinfo_in) */ + u_char fi_family; /* AF_INET */ + u_int8_t fi_proto; /* IPPROTO_XXX */ + u_int8_t fi_tos; /* type-of-service */ + struct in_addr fi_dst; /* dest address */ + struct in_addr fi_src; /* src address */ + u_int16_t fi_dport; /* dest port */ + u_int16_t fi_sport; /* src port */ + uint32_t fi_gpi; /* generalized port id for ipsec */ + u_int8_t _pad[28]; /* make the size equal to + flowinfo_in6 */ +}; + +#ifdef SIN6_LEN +struct flowinfo_in6 { + u_char fi6_len; /* sizeof(struct flowinfo_in6) */ + u_char fi6_family; /* AF_INET6 */ + u_int8_t fi6_proto; /* IPPROTO_XXX */ + u_int8_t fi6_tclass; /* traffic class */ + uint32_t fi6_flowlabel; /* ipv6 flowlabel */ + u_int16_t fi6_dport; /* dest port */ + u_int16_t fi6_sport; /* src port */ + uint32_t fi6_gpi; /* generalized port id */ + struct in6_addr fi6_dst; /* dest address */ + struct in6_addr fi6_src; /* src address */ +}; +#endif /* INET6 */ + +/* + * flow filters for AF_INET and AF_INET6 + */ +struct flow_filter { + int ff_ruleno; + struct flowinfo_in ff_flow; + struct { + struct in_addr mask_dst; + struct in_addr mask_src; + u_int8_t mask_tos; + u_int8_t _pad[3]; + } ff_mask; + u_int8_t _pad2[24]; /* make the size equal to flow_filter6 */ +}; + +#ifdef SIN6_LEN +struct flow_filter6 { + int ff_ruleno; + struct flowinfo_in6 ff_flow6; + struct { + struct in6_addr mask6_dst; + struct in6_addr mask6_src; + u_int8_t mask6_tclass; + u_int8_t _pad[3]; + } ff_mask6; +}; +#endif /* INET6 */ +#endif /* ALTQ3_CLFIER_COMPAT */ +#endif /* ALTQ3_COMPAT */ + +/* + * generic packet counter + */ +struct pktcntr { + u_int64_t packets; + u_int64_t bytes; +}; + +#define PKTCNTR_ADD(cntr, len) \ + do { (cntr)->packets++; (cntr)->bytes += len; } while (/*CONSTCOND*/ 0) + +#ifdef ALTQ3_COMPAT +/* + * altq related ioctls + */ +#define ALTQGTYPE _IOWR('q', 0, struct altqreq) /* get queue type */ +#if 0 +/* + * these ioctls are currently discipline-specific but could be shared + * in the future. + */ +#define ALTQATTACH _IOW('q', 1, struct altqreq) /* attach discipline */ +#define ALTQDETACH _IOW('q', 2, struct altqreq) /* detach discipline */ +#define ALTQENABLE _IOW('q', 3, struct altqreq) /* enable discipline */ +#define ALTQDISABLE _IOW('q', 4, struct altqreq) /* disable discipline*/ +#define ALTQCLEAR _IOW('q', 5, struct altqreq) /* (re)initialize */ +#define ALTQCONFIG _IOWR('q', 6, struct altqreq) /* set config params */ +#define ALTQADDCLASS _IOWR('q', 7, struct altqreq) /* add a class */ +#define ALTQMODCLASS _IOWR('q', 8, struct altqreq) /* modify a class */ +#define ALTQDELCLASS _IOWR('q', 9, struct altqreq) /* delete a class */ +#define ALTQADDFILTER _IOWR('q', 10, struct altqreq) /* add a filter */ +#define ALTQDELFILTER _IOWR('q', 11, struct altqreq) /* delete a filter */ +#define ALTQGETSTATS _IOWR('q', 12, struct altqreq) /* get statistics */ +#define ALTQGETCNTR _IOWR('q', 13, struct altqreq) /* get a pkt counter */ +#endif /* 0 */ +#define ALTQTBRSET _IOW('q', 14, struct tbrreq) /* set tb regulator */ +#define ALTQTBRGET _IOWR('q', 15, struct tbrreq) /* get tb regulator */ +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL +#include +#endif + +#endif /* _ALTQ_ALTQ_H_ */ diff --git a/src/include.new/altq/altq_cbq.h b/src/include.new/altq/altq_cbq.h new file mode 100644 index 0000000..723bebb --- /dev/null +++ b/src/include.new/altq/altq_cbq.h @@ -0,0 +1,221 @@ +/* $KAME: altq_cbq.h,v 1.12 2003/10/03 05:05:15 kjc Exp $ */ + +/* + * Copyright (c) Sun Microsystems, Inc. 1993-1998 All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the SMCC Technology + * Development Group at Sun Microsystems, Inc. + * + * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE + * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is + * provided "as is" without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this software. + */ + +#ifndef _ALTQ_ALTQ_CBQ_H_ +#define _ALTQ_ALTQ_CBQ_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NULL_CLASS_HANDLE 0 + +/* class flags should be same as class flags in rm_class.h */ +#define CBQCLF_RED 0x0001 /* use RED */ +#define CBQCLF_ECN 0x0002 /* use RED/ECN */ +#define CBQCLF_RIO 0x0004 /* use RIO */ +#define CBQCLF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */ +#define CBQCLF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ +#define CBQCLF_BORROW 0x0020 /* borrow from parent */ + +/* class flags only for root class */ +#define CBQCLF_WRR 0x0100 /* weighted-round robin */ +#define CBQCLF_EFFICIENT 0x0200 /* work-conserving */ + +/* class flags for special classes */ +#define CBQCLF_ROOTCLASS 0x1000 /* root class */ +#define CBQCLF_DEFCLASS 0x2000 /* default class */ +#ifdef ALTQ3_COMPAT +#define CBQCLF_CTLCLASS 0x4000 /* control class */ +#endif +#define CBQCLF_CLASSMASK 0xf000 /* class mask */ + +#define CBQ_MAXQSIZE 200 +#define CBQ_MAXPRI RM_MAXPRIO + +typedef struct _cbq_class_stats_ { + uint32_t handle; + u_int depth; + + struct pktcntr xmit_cnt; /* packets sent in this class */ + struct pktcntr drop_cnt; /* dropped packets */ + u_int over; /* # times went over limit */ + u_int borrows; /* # times tried to borrow */ + u_int overactions; /* # times invoked overlimit action */ + u_int delays; /* # times invoked delay actions */ + + /* other static class parameters useful for debugging */ + int priority; + int maxidle; + int minidle; + int offtime; + int qmax; + int ns_per_byte; + int wrr_allot; + + int qcnt; /* # packets in queue */ + int avgidle; + + /* red and rio related info */ + int qtype; + struct redstats red[3]; +} class_stats_t; + +#ifdef ALTQ3_COMPAT +/* + * Define structures associated with IOCTLS for cbq. + */ + +/* + * Define the CBQ interface structure. This must be included in all + * IOCTL's such that the CBQ driver may find the appropriate CBQ module + * associated with the network interface to be affected. + */ +struct cbq_interface { + char cbq_ifacename[IFNAMSIZ]; +}; + +typedef struct cbq_class_spec { + u_int priority; + u_int nano_sec_per_byte; + u_int maxq; + u_int maxidle; + int minidle; + u_int offtime; + uint32_t parent_class_handle; + uint32_t borrow_class_handle; + + u_int pktsize; + int flags; +} cbq_class_spec_t; + +struct cbq_add_class { + struct cbq_interface cbq_iface; + + cbq_class_spec_t cbq_class; + uint32_t cbq_class_handle; +}; + +struct cbq_delete_class { + struct cbq_interface cbq_iface; + uint32_t cbq_class_handle; +}; + +struct cbq_modify_class { + struct cbq_interface cbq_iface; + + cbq_class_spec_t cbq_class; + uint32_t cbq_class_handle; +}; + +struct cbq_add_filter { + struct cbq_interface cbq_iface; + uint32_t cbq_class_handle; + struct flow_filter cbq_filter; + + u_long cbq_filter_handle; +}; + +struct cbq_delete_filter { + struct cbq_interface cbq_iface; + u_long cbq_filter_handle; +}; + +/* number of classes are returned in nclasses field */ +struct cbq_getstats { + struct cbq_interface iface; + int nclasses; + class_stats_t *stats; +}; + +/* + * Define IOCTLs for CBQ. + */ +#define CBQ_IF_ATTACH _IOW('Q', 1, struct cbq_interface) +#define CBQ_IF_DETACH _IOW('Q', 2, struct cbq_interface) +#define CBQ_ENABLE _IOW('Q', 3, struct cbq_interface) +#define CBQ_DISABLE _IOW('Q', 4, struct cbq_interface) +#define CBQ_CLEAR_HIERARCHY _IOW('Q', 5, struct cbq_interface) +#define CBQ_ADD_CLASS _IOWR('Q', 7, struct cbq_add_class) +#define CBQ_DEL_CLASS _IOW('Q', 8, struct cbq_delete_class) +#define CBQ_MODIFY_CLASS _IOWR('Q', 9, struct cbq_modify_class) +#define CBQ_ADD_FILTER _IOWR('Q', 10, struct cbq_add_filter) +#define CBQ_DEL_FILTER _IOW('Q', 11, struct cbq_delete_filter) +#define CBQ_GETSTATS _IOWR('Q', 12, struct cbq_getstats) +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL +/* + * Define macros only good for kernel drivers and modules. + */ +#define CBQ_WATCHDOG (hz / 20) +#define CBQ_TIMEOUT 10 +#define CBQ_LS_TIMEOUT (20 * hz / 1000) + +#define CBQ_MAX_CLASSES 256 + +#ifdef ALTQ3_COMPAT +#define CBQ_MAX_FILTERS 256 + +#define DISABLE 0x00 +#define ENABLE 0x01 +#endif /* ALTQ3_COMPAT */ + +/* + * Define State structures. + */ +typedef struct cbqstate { +#ifdef ALTQ3_COMPAT + struct cbqstate *cbq_next; +#endif + int cbq_qlen; /* # of packets in cbq */ + struct rm_class *cbq_class_tbl[CBQ_MAX_CLASSES]; + + struct rm_ifdat ifnp; + struct callout cbq_callout; /* for timeouts */ +#ifdef ALTQ3_CLFIER_COMPAT + struct acc_classifier cbq_classifier; +#endif +} cbq_state_t; + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_ALTQ_ALTQ_CBQ_H_ */ diff --git a/src/include.new/altq/altq_cdnr.h b/src/include.new/altq/altq_cdnr.h new file mode 100644 index 0000000..f22fec7 --- /dev/null +++ b/src/include.new/altq/altq_cdnr.h @@ -0,0 +1,335 @@ +/* $KAME: altq_cdnr.h,v 1.9 2003/07/10 12:07:48 kjc Exp $ */ + +/* + * Copyright (C) 1999-2002 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALTQ_ALTQ_CDNR_H_ +#define _ALTQ_ALTQ_CDNR_H_ + +#include + +/* + * traffic conditioner element types + */ +#define TCETYPE_NONE 0 +#define TCETYPE_TOP 1 /* top level conditioner */ +#define TCETYPE_ELEMENT 2 /* a simple tc element */ +#define TCETYPE_TBMETER 3 /* token bucket meter */ +#define TCETYPE_TRTCM 4 /* (two-rate) three color marker */ +#define TCETYPE_TSWTCM 5 /* time sliding window 3-color maker */ + +/* + * traffic conditioner action + */ +struct cdnr_block; + +struct tc_action { + int tca_code; /* e.g., TCACODE_PASS */ + /* tca_code dependent variable */ + union { + u_long un_value; /* template */ + u_int8_t un_dscp; /* diffserv code point */ + u_long un_handle; /* tc action handle */ + struct cdnr_block *un_next; /* next tc element block */ + } tca_un; +}; +#define tca_value tca_un.un_value +#define tca_dscp tca_un.un_dscp +#define tca_handle tca_un.un_handle +#define tca_next tca_un.un_next + +#define TCACODE_NONE 0 /* action is not set */ +#define TCACODE_PASS 1 /* pass this packet */ +#define TCACODE_DROP 2 /* discard this packet */ +#define TCACODE_RETURN 3 /* do not process this packet */ +#define TCACODE_MARK 4 /* mark dscp */ +#define TCACODE_HANDLE 5 /* take action specified by handle */ +#define TCACODE_NEXT 6 /* take action in the next tc element */ +#define TCACODE_MAX 6 + +#define CDNR_NULL_HANDLE 0 + +struct cdnr_interface { + char cdnr_ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */ +}; + +/* simple element operations */ +struct cdnr_add_element { + struct cdnr_interface iface; + struct tc_action action; + + u_long cdnr_handle; /* return value */ +}; + +struct cdnr_delete_element { + struct cdnr_interface iface; + u_long cdnr_handle; +}; + +/* token-bucket meter operations */ +struct cdnr_add_tbmeter { + struct cdnr_interface iface; + struct tb_profile profile; + struct tc_action in_action; + struct tc_action out_action; + + u_long cdnr_handle; /* return value */ +}; + +struct cdnr_modify_tbmeter { + struct cdnr_interface iface; + u_long cdnr_handle; + struct tb_profile profile; +}; + +struct cdnr_tbmeter_stats { + struct cdnr_interface iface; + u_long cdnr_handle; + struct pktcntr in_cnt; + struct pktcntr out_cnt; +}; + +/* two-rate three-color marker operations */ +struct cdnr_add_trtcm { + struct cdnr_interface iface; + struct tb_profile cmtd_profile; /* profile for committed tb */ + struct tb_profile peak_profile; /* profile for peak tb */ + struct tc_action green_action; /* action for green packets */ + struct tc_action yellow_action; /* action for yellow packets */ + struct tc_action red_action; /* action for red packets */ + int coloraware; /* color-aware/color-blind */ + + u_long cdnr_handle; /* return value */ +}; + +struct cdnr_modify_trtcm { + struct cdnr_interface iface; + u_long cdnr_handle; + struct tb_profile cmtd_profile; /* profile for committed tb */ + struct tb_profile peak_profile; /* profile for peak tb */ + int coloraware; /* color-aware/color-blind */ +}; + +struct cdnr_tcm_stats { + struct cdnr_interface iface; + u_long cdnr_handle; + struct pktcntr green_cnt; + struct pktcntr yellow_cnt; + struct pktcntr red_cnt; +}; + +/* time sliding window three-color marker operations */ +struct cdnr_add_tswtcm { + struct cdnr_interface iface; + uint32_t cmtd_rate; /* committed rate (bits/sec) */ + uint32_t peak_rate; /* peak rate (bits/sec) */ + uint32_t avg_interval; /* averaging interval (msec) */ + struct tc_action green_action; /* action for green packets */ + struct tc_action yellow_action; /* action for yellow packets */ + struct tc_action red_action; /* action for red packets */ + + u_long cdnr_handle; /* return value */ +}; + +struct cdnr_modify_tswtcm { + struct cdnr_interface iface; + u_long cdnr_handle; + uint32_t cmtd_rate; /* committed rate (bits/sec) */ + uint32_t peak_rate; /* peak rate (bits/sec) */ + uint32_t avg_interval; /* averaging interval (msec) */ +}; + +struct cdnr_add_filter { + struct cdnr_interface iface; + u_long cdnr_handle; +#ifdef ALTQ3_CLFIER_COMPAT + struct flow_filter filter; +#endif + u_long filter_handle; /* return value */ +}; + +struct cdnr_delete_filter { + struct cdnr_interface iface; + u_long filter_handle; +}; + +struct tce_stats { + u_long tce_handle; /* tc element handle */ + int tce_type; /* e.g., TCETYPE_ELEMENT */ + struct pktcntr tce_cnts[3]; /* tcm returns 3 counters */ +}; + +struct cdnr_get_stats { + struct cdnr_interface iface; + struct pktcntr cnts[TCACODE_MAX+1]; + + /* element stats */ + int nskip; /* skip # of elements */ + int nelements; /* # of element stats (WR) */ + struct tce_stats *tce_stats; /* pointer to stats array */ +}; + +#define CDNR_IF_ATTACH _IOW('Q', 1, struct cdnr_interface) +#define CDNR_IF_DETACH _IOW('Q', 2, struct cdnr_interface) +#define CDNR_ENABLE _IOW('Q', 3, struct cdnr_interface) +#define CDNR_DISABLE _IOW('Q', 4, struct cdnr_interface) +#define CDNR_ADD_FILTER _IOWR('Q', 10, struct cdnr_add_filter) +#define CDNR_DEL_FILTER _IOW('Q', 11, struct cdnr_delete_filter) +#define CDNR_GETSTATS _IOWR('Q', 12, struct cdnr_get_stats) +#define CDNR_ADD_ELEM _IOWR('Q', 30, struct cdnr_add_element) +#define CDNR_DEL_ELEM _IOW('Q', 31, struct cdnr_delete_element) +#define CDNR_ADD_TBM _IOWR('Q', 32, struct cdnr_add_tbmeter) +#define CDNR_MOD_TBM _IOW('Q', 33, struct cdnr_modify_tbmeter) +#define CDNR_TBM_STATS _IOWR('Q', 34, struct cdnr_tbmeter_stats) +#define CDNR_ADD_TCM _IOWR('Q', 35, struct cdnr_add_trtcm) +#define CDNR_MOD_TCM _IOWR('Q', 36, struct cdnr_modify_trtcm) +#define CDNR_TCM_STATS _IOWR('Q', 37, struct cdnr_tcm_stats) +#define CDNR_ADD_TSW _IOWR('Q', 38, struct cdnr_add_tswtcm) +#define CDNR_MOD_TSW _IOWR('Q', 39, struct cdnr_modify_tswtcm) + +#ifndef DSCP_EF +/* diffserve code points */ +#define DSCP_MASK 0xfc +#define DSCP_CUMASK 0x03 +#define DSCP_EF 0xb8 +#define DSCP_AF11 0x28 +#define DSCP_AF12 0x30 +#define DSCP_AF13 0x38 +#define DSCP_AF21 0x48 +#define DSCP_AF22 0x50 +#define DSCP_AF23 0x58 +#define DSCP_AF31 0x68 +#define DSCP_AF32 0x70 +#define DSCP_AF33 0x78 +#define DSCP_AF41 0x88 +#define DSCP_AF42 0x90 +#define DSCP_AF43 0x98 +#define AF_CLASSMASK 0xe0 +#define AF_DROPPRECMASK 0x18 +#endif + +#ifdef _KERNEL + +/* + * packet information passed to the input function of tc elements + */ +struct cdnr_pktinfo { + int pkt_len; /* packet length */ + u_int8_t pkt_dscp; /* diffserv code point */ +}; + +/* + * traffic conditioner control block common to all types of tc elements + */ +struct cdnr_block { + LIST_ENTRY(cdnr_block) cb_next; + int cb_len; /* size of this tc element */ + int cb_type; /* cdnr block type */ + int cb_ref; /* reference count of this element */ + u_long cb_handle; /* handle of this tc element */ + struct top_cdnr *cb_top; /* back pointer to top */ + struct tc_action cb_action; /* top level action for this tcb */ + struct tc_action *(*cb_input)(struct cdnr_block *, + struct cdnr_pktinfo *); +}; + +/* + * top level traffic conditioner structure for an interface + */ +struct top_cdnr { + struct cdnr_block tc_block; + + LIST_ENTRY(top_cdnr) tc_next; + struct ifaltq *tc_ifq; + + LIST_HEAD(, cdnr_block) tc_elements; +#ifdef ALTQ3_CLFIER_COMPAT + struct acc_classifier tc_classifier; +#endif + struct pktcntr tc_cnts[TCACODE_MAX+1]; +}; + +/* token bucket element */ +struct tbe { + u_int64_t rate; + u_int64_t depth; + + u_int64_t token; + u_int64_t filluptime; + u_int64_t last; +}; + +/* token bucket meter structure */ +struct tbmeter { + struct cdnr_block cdnrblk; /* conditioner block */ + struct tbe tb; /* token bucket */ + struct tc_action in_action; /* actions for IN/OUT */ + struct tc_action out_action; /* actions for IN/OUT */ + struct pktcntr in_cnt; /* statistics for IN/OUT */ + struct pktcntr out_cnt; /* statistics for IN/OUT */ +}; + +/* two-rate three-color marker structure */ +struct trtcm { + struct cdnr_block cdnrblk; /* conditioner block */ + struct tbe cmtd_tb; /* committed tb profile */ + struct tbe peak_tb; /* peak tb profile */ + struct tc_action green_action; + struct tc_action yellow_action; + struct tc_action red_action; + int coloraware; + u_int8_t green_dscp; + u_int8_t yellow_dscp; + u_int8_t red_dscp; + struct pktcntr green_cnt; + struct pktcntr yellow_cnt; + struct pktcntr red_cnt; +}; + +/* time sliding window three-color marker structure */ +struct tswtcm { + struct cdnr_block cdnrblk; /* conditioner block */ + + uint32_t avg_rate; /* average rate (bytes/sec) */ + u_int64_t t_front; /* timestamp of last update */ + + u_int64_t timewin; /* average interval */ + uint32_t cmtd_rate; /* committed target rate */ + uint32_t peak_rate; /* peak target rate */ + struct tc_action green_action; + struct tc_action yellow_action; + struct tc_action red_action; + u_int8_t green_dscp; + u_int8_t yellow_dscp; + u_int8_t red_dscp; + struct pktcntr green_cnt; + struct pktcntr yellow_cnt; + struct pktcntr red_cnt; +}; + +#endif /* _KERNEL */ + +#endif /* _ALTQ_ALTQ_CDNR_H_ */ diff --git a/src/include.new/altq/altq_classq.h b/src/include.new/altq/altq_classq.h new file mode 100644 index 0000000..dc5c646 --- /dev/null +++ b/src/include.new/altq/altq_classq.h @@ -0,0 +1,206 @@ +/* $KAME: altq_classq.h,v 1.6 2003/01/07 07:33:38 kjc Exp $ */ + +/* + * Copyright (c) 1991-1997 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Network Research + * Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * class queue definitions extracted from rm_class.h. + */ +#ifndef _ALTQ_ALTQ_CLASSQ_H_ +#define _ALTQ_ALTQ_CLASSQ_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Packet Queue types: RED or DROPHEAD. + */ +#define Q_DROPHEAD 0x00 +#define Q_RED 0x01 +#define Q_RIO 0x02 +#define Q_DROPTAIL 0x03 + +#ifdef _KERNEL + +/* + * Packet Queue structures and macros to manipulate them. + */ +struct _class_queue_ { + struct mbuf *tail_; /* Tail of packet queue */ + int qlen_; /* Queue length (in number of packets) */ + int qlim_; /* Queue limit (in number of packets*) */ + int qtype_; /* Queue type */ +}; + +typedef struct _class_queue_ class_queue_t; + +#define qtype(q) (q)->qtype_ /* Get queue type */ +#define qlimit(q) (q)->qlim_ /* Max packets to be queued */ +#define qlen(q) (q)->qlen_ /* Current queue length. */ +#define qtail(q) (q)->tail_ /* Tail of the queue */ +#define qhead(q) ((q)->tail_ ? (q)->tail_->m_nextpkt : NULL) + +#define qempty(q) ((q)->qlen_ == 0) /* Is the queue empty?? */ +#define q_is_red(q) ((q)->qtype_ == Q_RED) /* Is the queue a red queue */ +#define q_is_rio(q) ((q)->qtype_ == Q_RIO) /* Is the queue a rio queue */ +#define q_is_red_or_rio(q) ((q)->qtype_ == Q_RED || (q)->qtype_ == Q_RIO) + +#if !defined(__GNUC__) || defined(ALTQ_DEBUG) + +extern void _addq(class_queue_t *, struct mbuf *); +extern struct mbuf *_getq(class_queue_t *); +extern struct mbuf *_getq_tail(class_queue_t *); +extern struct mbuf *_getq_random(class_queue_t *); +extern void _removeq(class_queue_t *, struct mbuf *); +extern void _flushq(class_queue_t *); + +#else /* __GNUC__ && !ALTQ_DEBUG */ +/* + * inlined versions + */ +static __inline void +_addq(class_queue_t *q, struct mbuf *m) +{ + struct mbuf *m0; + + if ((m0 = qtail(q)) != NULL) + m->m_nextpkt = m0->m_nextpkt; + else + m0 = m; + m0->m_nextpkt = m; + qtail(q) = m; + qlen(q)++; +} + +static __inline struct mbuf * +_getq(class_queue_t *q) +{ + struct mbuf *m, *m0; + + if ((m = qtail(q)) == NULL) + return (NULL); + if ((m0 = m->m_nextpkt) != m) + m->m_nextpkt = m0->m_nextpkt; + else + qtail(q) = NULL; + qlen(q)--; + m0->m_nextpkt = NULL; + return (m0); +} + +/* drop a packet at the tail of the queue */ +static __inline struct mbuf * +_getq_tail(class_queue_t *q) +{ + struct mbuf *m, *m0, *prev; + + if ((m = m0 = qtail(q)) == NULL) + return NULL; + do { + prev = m0; + m0 = m0->m_nextpkt; + } while (m0 != m); + prev->m_nextpkt = m->m_nextpkt; + if (prev == m) + qtail(q) = NULL; + else + qtail(q) = prev; + qlen(q)--; + m->m_nextpkt = NULL; + return (m); +} + +/* randomly select a packet in the queue */ +static __inline struct mbuf * +_getq_random(class_queue_t *q) +{ + struct mbuf *m; + int i, n; + + if ((m = qtail(q)) == NULL) + return NULL; + if (m->m_nextpkt == m) + qtail(q) = NULL; + else { + struct mbuf *prev = NULL; + + n = random() % qlen(q) + 1; + for (i = 0; i < n; i++) { + prev = m; + m = m->m_nextpkt; + } + prev->m_nextpkt = m->m_nextpkt; + if (m == qtail(q)) + qtail(q) = prev; + } + qlen(q)--; + m->m_nextpkt = NULL; + return (m); +} + +static __inline void +_removeq(class_queue_t *q, struct mbuf *m) +{ + struct mbuf *m0, *prev; + + m0 = qtail(q); + do { + prev = m0; + m0 = m0->m_nextpkt; + } while (m0 != m); + prev->m_nextpkt = m->m_nextpkt; + if (prev == m) + qtail(q) = NULL; + else if (qtail(q) == m) + qtail(q) = prev; + qlen(q)--; +} + +static __inline void +_flushq(class_queue_t *q) +{ + struct mbuf *m; + + while ((m = _getq(q)) != NULL) + m_freem(m); +} + +#endif /* __GNUC__ && !ALTQ_DEBUG */ + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ALTQ_ALTQ_CLASSQ_H_ */ diff --git a/src/include.new/altq/altq_hfsc.h b/src/include.new/altq/altq_hfsc.h new file mode 100644 index 0000000..f343477 --- /dev/null +++ b/src/include.new/altq/altq_hfsc.h @@ -0,0 +1,310 @@ +/* $KAME: altq_hfsc.h,v 1.12 2003/12/05 05:40:46 kjc Exp $ */ + +/* + * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation is hereby granted (including for commercial or + * for-profit use), provided that both the copyright notice and this + * permission notice appear in all copies of the software, derivative + * works, or modified versions, and any portions thereof. + * + * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF + * WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS + * SOFTWARE IN ITS ``AS IS'' CONDITION, AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Carnegie Mellon encourages (but does not require) users of this + * software to return any improvements or extensions that they make, + * and to grant Carnegie Mellon the rights to redistribute these + * changes without encumbrance. + */ +#ifndef _ALTQ_ALTQ_HFSC_H_ +#define _ALTQ_ALTQ_HFSC_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct service_curve { + u_int m1; /* slope of the first segment in bits/sec */ + u_int d; /* the x-projection of the first segment in msec */ + u_int m2; /* slope of the second segment in bits/sec */ +}; + +/* special class handles */ +#define HFSC_NULLCLASS_HANDLE 0 +#define HFSC_MAX_CLASSES 64 + +/* hfsc class flags */ +#define HFCF_RED 0x0001 /* use RED */ +#define HFCF_ECN 0x0002 /* use RED/ECN */ +#define HFCF_RIO 0x0004 /* use RIO */ +#define HFCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ +#define HFCF_DEFAULTCLASS 0x1000 /* default class */ + +/* service curve types */ +#define HFSC_REALTIMESC 1 +#define HFSC_LINKSHARINGSC 2 +#define HFSC_UPPERLIMITSC 4 +#define HFSC_DEFAULTSC (HFSC_REALTIMESC|HFSC_LINKSHARINGSC) + +struct hfsc_classstats { + u_int class_id; + uint32_t class_handle; + struct service_curve rsc; + struct service_curve fsc; + struct service_curve usc; /* upper limit service curve */ + + u_int64_t total; /* total work in bytes */ + u_int64_t cumul; /* cumulative work in bytes + done by real-time criteria */ + u_int64_t d; /* deadline */ + u_int64_t e; /* eligible time */ + u_int64_t vt; /* virtual time */ + u_int64_t f; /* fit time for upper-limit */ + + /* info helpful for debugging */ + u_int64_t initvt; /* init virtual time */ + u_int64_t vtoff; /* cl_vt_ipoff */ + u_int64_t cvtmax; /* cl_maxvt */ + u_int64_t myf; /* cl_myf */ + u_int64_t cfmin; /* cl_mincf */ + u_int64_t cvtmin; /* cl_mincvt */ + u_int64_t myfadj; /* cl_myfadj */ + u_int64_t vtadj; /* cl_vtadj */ + u_int64_t cur_time; + uint32_t machclk_freq; + + u_int qlength; + u_int qlimit; + struct pktcntr xmit_cnt; + struct pktcntr drop_cnt; + u_int period; + + u_int vtperiod; /* vt period sequence no */ + u_int parentperiod; /* parent's vt period seqno */ + int nactive; /* number of active children */ + + /* red and rio related info */ + int qtype; + struct redstats red[3]; +}; + +#ifdef ALTQ3_COMPAT +struct hfsc_interface { + char hfsc_ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */ +}; + +struct hfsc_attach { + struct hfsc_interface iface; + u_int bandwidth; /* link bandwidth in bits/sec */ +}; + +struct hfsc_add_class { + struct hfsc_interface iface; + uint32_t parent_handle; + struct service_curve service_curve; + int qlimit; + int flags; + + uint32_t class_handle; /* return value */ +}; + +struct hfsc_delete_class { + struct hfsc_interface iface; + uint32_t class_handle; +}; + +struct hfsc_modify_class { + struct hfsc_interface iface; + uint32_t class_handle; + struct service_curve service_curve; + int sctype; +}; + +struct hfsc_add_filter { + struct hfsc_interface iface; + uint32_t class_handle; + struct flow_filter filter; + + u_long filter_handle; /* return value */ +}; + +struct hfsc_delete_filter { + struct hfsc_interface iface; + u_long filter_handle; +}; + +struct hfsc_class_stats { + struct hfsc_interface iface; + int nskip; /* skip # of classes */ + int nclasses; /* # of class stats (WR) */ + u_int64_t cur_time; /* current time */ + uint32_t machclk_freq; /* machine clock frequency */ + u_int hif_classes; /* # of classes in the tree */ + u_int hif_packets; /* # of packets in the tree */ + struct hfsc_classstats *stats; /* pointer to stats array */ +}; + +#define HFSC_IF_ATTACH _IOW('Q', 1, struct hfsc_attach) +#define HFSC_IF_DETACH _IOW('Q', 2, struct hfsc_interface) +#define HFSC_ENABLE _IOW('Q', 3, struct hfsc_interface) +#define HFSC_DISABLE _IOW('Q', 4, struct hfsc_interface) +#define HFSC_CLEAR_HIERARCHY _IOW('Q', 5, struct hfsc_interface) +#define HFSC_ADD_CLASS _IOWR('Q', 7, struct hfsc_add_class) +#define HFSC_DEL_CLASS _IOW('Q', 8, struct hfsc_delete_class) +#define HFSC_MOD_CLASS _IOW('Q', 9, struct hfsc_modify_class) +#define HFSC_ADD_FILTER _IOWR('Q', 10, struct hfsc_add_filter) +#define HFSC_DEL_FILTER _IOW('Q', 11, struct hfsc_delete_filter) +#define HFSC_GETSTATS _IOWR('Q', 12, struct hfsc_class_stats) +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL +/* + * kernel internal service curve representation + * coordinates are given by 64 bit unsigned integers. + * x-axis: unit is clock count. for the intel x86 architecture, + * the raw Pentium TSC (Timestamp Counter) value is used. + * virtual time is also calculated in this time scale. + * y-axis: unit is byte. + * + * the service curve parameters are converted to the internal + * representation. + * the slope values are scaled to avoid overflow. + * the inverse slope values as well as the y-projection of the 1st + * segment are kept in order to to avoid 64-bit divide operations + * that are expensive on 32-bit architectures. + * + * note: Intel Pentium TSC never wraps around in several thousands of years. + * x-axis doesn't wrap around for 1089 years with 1GHz clock. + * y-axis doesn't wrap around for 4358 years with 1Gbps bandwidth. + */ + +/* kernel internal representation of a service curve */ +struct internal_sc { + u_int64_t sm1; /* scaled slope of the 1st segment */ + u_int64_t ism1; /* scaled inverse-slope of the 1st segment */ + u_int64_t dx; /* the x-projection of the 1st segment */ + u_int64_t dy; /* the y-projection of the 1st segment */ + u_int64_t sm2; /* scaled slope of the 2nd segment */ + u_int64_t ism2; /* scaled inverse-slope of the 2nd segment */ +}; + +/* runtime service curve */ +struct runtime_sc { + u_int64_t x; /* current starting position on x-axis */ + u_int64_t y; /* current starting position on x-axis */ + u_int64_t sm1; /* scaled slope of the 1st segment */ + u_int64_t ism1; /* scaled inverse-slope of the 1st segment */ + u_int64_t dx; /* the x-projection of the 1st segment */ + u_int64_t dy; /* the y-projection of the 1st segment */ + u_int64_t sm2; /* scaled slope of the 2nd segment */ + u_int64_t ism2; /* scaled inverse-slope of the 2nd segment */ +}; + +struct hfsc_class { + u_int cl_id; /* class id (just for debug) */ + uint32_t cl_handle; /* class handle */ + struct hfsc_if *cl_hif; /* back pointer to struct hfsc_if */ + int cl_flags; /* misc flags */ + + struct hfsc_class *cl_parent; /* parent class */ + struct hfsc_class *cl_siblings; /* sibling classes */ + struct hfsc_class *cl_children; /* child classes */ + + class_queue_t *cl_q; /* class queue structure */ + struct red *cl_red; /* RED state */ + struct altq_pktattr *cl_pktattr; /* saved header used by ECN */ + + u_int64_t cl_total; /* total work in bytes */ + u_int64_t cl_cumul; /* cumulative work in bytes + done by real-time criteria */ + u_int64_t cl_d; /* deadline */ + u_int64_t cl_e; /* eligible time */ + u_int64_t cl_vt; /* virtual time */ + u_int64_t cl_f; /* time when this class will fit for + link-sharing, max(myf, cfmin) */ + u_int64_t cl_myf; /* my fit-time (as calculated from this + class's own upperlimit curve) */ + u_int64_t cl_myfadj; /* my fit-time adjustment + (to cancel history dependence) */ + u_int64_t cl_cfmin; /* earliest children's fit-time (used + with cl_myf to obtain cl_f) */ + u_int64_t cl_cvtmin; /* minimal virtual time among the + children fit for link-sharing + (monotonic within a period) */ + u_int64_t cl_vtadj; /* intra-period cumulative vt + adjustment */ + u_int64_t cl_vtoff; /* inter-period cumulative vt offset */ + u_int64_t cl_cvtmax; /* max child's vt in the last period */ + + u_int64_t cl_initvt; /* init virtual time (for debugging) */ + + struct internal_sc *cl_rsc; /* internal real-time service curve */ + struct internal_sc *cl_fsc; /* internal fair service curve */ + struct internal_sc *cl_usc; /* internal upperlimit service curve */ + struct runtime_sc cl_deadline; /* deadline curve */ + struct runtime_sc cl_eligible; /* eligible curve */ + struct runtime_sc cl_virtual; /* virtual curve */ + struct runtime_sc cl_ulimit; /* upperlimit curve */ + + u_int cl_vtperiod; /* vt period sequence no */ + u_int cl_parentperiod; /* parent's vt period seqno */ + int cl_nactive; /* number of active children */ + + TAILQ_HEAD(acthead, hfsc_class) cl_actc; /* active children list */ + TAILQ_ENTRY(hfsc_class) cl_actlist; /* active children list entry */ + TAILQ_ENTRY(hfsc_class) cl_ellist; /* eligible list entry */ + + struct { + struct pktcntr xmit_cnt; + struct pktcntr drop_cnt; + u_int period; + } cl_stats; +}; + +/* + * hfsc interface state + */ +struct hfsc_if { + struct hfsc_if *hif_next; /* interface state list */ + struct ifaltq *hif_ifq; /* backpointer to ifaltq */ + struct hfsc_class *hif_rootclass; /* root class */ + struct hfsc_class *hif_defaultclass; /* default class */ + struct hfsc_class *hif_class_tbl[HFSC_MAX_CLASSES]; + struct hfsc_class *hif_pollcache; /* cache for poll operation */ + + u_int hif_classes; /* # of classes in the tree */ + u_int hif_packets; /* # of packets in the tree */ + u_int hif_classid; /* class id sequence number */ + + TAILQ_HEAD(elighead, hfsc_class) hif_eligible; /* eligible list */ + +#ifdef ALTQ3_CLFIER_COMPAT + struct acc_classifier hif_classifier; +#endif +}; + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ALTQ_ALTQ_HFSC_H_ */ diff --git a/src/include.new/altq/altq_priq.h b/src/include.new/altq/altq_priq.h new file mode 100644 index 0000000..2851702 --- /dev/null +++ b/src/include.new/altq/altq_priq.h @@ -0,0 +1,170 @@ +/* $KAME: altq_priq.h,v 1.7 2003/10/03 05:05:15 kjc Exp $ */ +/* + * Copyright (C) 2000-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALTQ_ALTQ_PRIQ_H_ +#define _ALTQ_ALTQ_PRIQ_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PRIQ_MAXPRI 16 /* upper limit of the number of priorities */ + +#ifdef ALTQ3_COMPAT +struct priq_interface { + char ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */ + u_long arg; /* request-specific argument */ +}; + +struct priq_add_class { + struct priq_interface iface; + int pri; /* priority (0 is the lowest) */ + int qlimit; /* queue size limit */ + int flags; /* misc flags (see below) */ + + uint32_t class_handle; /* return value */ +}; +#endif /* ALTQ3_COMPAT */ + +/* priq class flags */ +#define PRCF_RED 0x0001 /* use RED */ +#define PRCF_ECN 0x0002 /* use RED/ECN */ +#define PRCF_RIO 0x0004 /* use RIO */ +#define PRCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ +#define PRCF_DEFAULTCLASS 0x1000 /* default class */ + +/* special class handles */ +#define PRIQ_NULLCLASS_HANDLE 0 + +#ifdef ALTQ3_COMPAT +struct priq_delete_class { + struct priq_interface iface; + uint32_t class_handle; +}; + +struct priq_modify_class { + struct priq_interface iface; + uint32_t class_handle; + int pri; + int qlimit; + int flags; +}; + +struct priq_add_filter { + struct priq_interface iface; + uint32_t class_handle; + struct flow_filter filter; + + u_long filter_handle; /* return value */ +}; + +struct priq_delete_filter { + struct priq_interface iface; + u_long filter_handle; +}; +#endif /* ALTQ3_COMPAT */ + +struct priq_classstats { + uint32_t class_handle; + + u_int qlength; + u_int qlimit; + u_int period; + struct pktcntr xmitcnt; /* transmitted packet counter */ + struct pktcntr dropcnt; /* dropped packet counter */ + + /* red and rio related info */ + int qtype; + struct redstats red[3]; /* rio has 3 red stats */ +}; + +#ifdef ALTQ3_COMPAT +struct priq_class_stats { + struct priq_interface iface; + int maxpri; /* in/out */ + + struct priq_classstats *stats; /* pointer to stats array */ +}; + +#define PRIQ_IF_ATTACH _IOW('Q', 1, struct priq_interface) +#define PRIQ_IF_DETACH _IOW('Q', 2, struct priq_interface) +#define PRIQ_ENABLE _IOW('Q', 3, struct priq_interface) +#define PRIQ_DISABLE _IOW('Q', 4, struct priq_interface) +#define PRIQ_CLEAR _IOW('Q', 5, struct priq_interface) +#define PRIQ_ADD_CLASS _IOWR('Q', 7, struct priq_add_class) +#define PRIQ_DEL_CLASS _IOW('Q', 8, struct priq_delete_class) +#define PRIQ_MOD_CLASS _IOW('Q', 9, struct priq_modify_class) +#define PRIQ_ADD_FILTER _IOWR('Q', 10, struct priq_add_filter) +#define PRIQ_DEL_FILTER _IOW('Q', 11, struct priq_delete_filter) +#define PRIQ_GETSTATS _IOWR('Q', 12, struct priq_class_stats) + +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL + +struct priq_class { + uint32_t cl_handle; /* class handle */ + class_queue_t *cl_q; /* class queue structure */ + struct red *cl_red; /* RED state */ + int cl_pri; /* priority */ + int cl_flags; /* class flags */ + struct priq_if *cl_pif; /* back pointer to pif */ + struct altq_pktattr *cl_pktattr; /* saved header used by ECN */ + + /* statistics */ + u_int cl_period; /* backlog period */ + struct pktcntr cl_xmitcnt; /* transmitted packet counter */ + struct pktcntr cl_dropcnt; /* dropped packet counter */ +}; + +/* + * priq interface state + */ +struct priq_if { + struct priq_if *pif_next; /* interface state list */ + struct ifaltq *pif_ifq; /* backpointer to ifaltq */ + u_int pif_bandwidth; /* link bandwidth in bps */ + int pif_maxpri; /* max priority in use */ + struct priq_class *pif_default; /* default class */ + struct priq_class *pif_classes[PRIQ_MAXPRI]; /* classes */ +#ifdef ALTQ3_CLFIER_COMPAT + struct acc_classifier pif_classifier; /* classifier */ +#endif +}; + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ALTQ_ALTQ_PRIQ_H_ */ diff --git a/src/include.new/altq/altq_red.h b/src/include.new/altq/altq_red.h new file mode 100644 index 0000000..dc8ea0a --- /dev/null +++ b/src/include.new/altq/altq_red.h @@ -0,0 +1,198 @@ +/* $KAME: altq_red.h,v 1.8 2003/07/10 12:07:49 kjc Exp $ */ + +/* + * Copyright (C) 1997-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALTQ_ALTQ_RED_H_ +#define _ALTQ_ALTQ_RED_H_ + +#include + +#ifdef ALTQ3_COMPAT +struct red_interface { + char red_ifname[IFNAMSIZ]; +}; + +struct red_stats { + struct red_interface iface; + int q_len; + int q_avg; + + struct pktcntr xmit_cnt; + struct pktcntr drop_cnt; + u_int drop_forced; + u_int drop_unforced; + u_int marked_packets; + + /* static red parameters */ + int q_limit; + int weight; + int inv_pmax; + int th_min; + int th_max; + + /* flowvalve related stuff */ + u_int fv_flows; + u_int fv_pass; + u_int fv_predrop; + u_int fv_alloc; + u_int fv_escape; +}; + +struct red_conf { + struct red_interface iface; + int red_weight; /* weight for EWMA */ + int red_inv_pmax; /* inverse of max drop probability */ + int red_thmin; /* red min threshold */ + int red_thmax; /* red max threshold */ + int red_limit; /* max queue length */ + int red_pkttime; /* average packet time in usec */ + int red_flags; /* see below */ +}; +#endif /* ALTQ3_COMPAT */ + +/* red flags */ +#define REDF_ECN4 0x01 /* use packet marking for IPv4 packets */ +#define REDF_ECN6 0x02 /* use packet marking for IPv6 packets */ +#define REDF_ECN (REDF_ECN4 | REDF_ECN6) +#define REDF_FLOWVALVE 0x04 /* use flowvalve (aka penalty-box) */ + +/* + * simpler versions of red parameters and statistics used by other + * disciplines (e.g., CBQ) + */ +struct redparams { + int th_min; /* red min threshold */ + int th_max; /* red max threshold */ + int inv_pmax; /* inverse of max drop probability */ +}; + +struct redstats { + int q_avg; + struct pktcntr xmit_cnt; + struct pktcntr drop_cnt; + u_int drop_forced; + u_int drop_unforced; + u_int marked_packets; +}; + +#ifdef ALTQ3_COMPAT +/* + * IOCTLs for RED + */ +#define RED_IF_ATTACH _IOW('Q', 1, struct red_interface) +#define RED_IF_DETACH _IOW('Q', 2, struct red_interface) +#define RED_ENABLE _IOW('Q', 3, struct red_interface) +#define RED_DISABLE _IOW('Q', 4, struct red_interface) +#define RED_CONFIG _IOWR('Q', 6, struct red_conf) +#define RED_GETSTATS _IOWR('Q', 12, struct red_stats) +#define RED_SETDEFAULTS _IOW('Q', 30, struct redparams) +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL + +#ifdef ALTQ3_COMPAT +struct flowvalve; +#endif + +/* weight table structure for idle time calibration */ +struct wtab { + struct wtab *w_next; + int w_weight; + int w_param_max; + int w_refcount; + int32_t w_tab[32]; +}; + +typedef struct red { + int red_pkttime; /* average packet time in micro sec + used for idle calibration */ + int red_flags; /* red flags */ + + /* red parameters */ + int red_weight; /* weight for EWMA */ + int red_inv_pmax; /* inverse of max drop probability */ + int red_thmin; /* red min threshold */ + int red_thmax; /* red max threshold */ + + /* variables for internal use */ + int red_wshift; /* log(red_weight) */ + int red_thmin_s; /* th_min scaled by avgshift */ + int red_thmax_s; /* th_max scaled by avgshift */ + int red_probd; /* drop probability denominator */ + + int red_avg; /* queue len avg scaled by avgshift */ + int red_count; /* packet count since last dropped/ + marked packet */ + int red_idle; /* queue was empty */ + int red_old; /* avg is above th_min */ + struct wtab *red_wtab; /* weight table */ + struct timeval red_last; /* time when the queue becomes idle */ + +#ifdef ALTQ3_COMPAT + struct flowvalve *red_flowvalve; /* flowvalve state */ +#endif + + struct { + struct pktcntr xmit_cnt; + struct pktcntr drop_cnt; + u_int drop_forced; + u_int drop_unforced; + u_int marked_packets; + } red_stats; +} red_t; + +#ifdef ALTQ3_COMPAT +typedef struct red_queue { + struct red_queue *rq_next; /* next red_state in the list */ + struct ifaltq *rq_ifq; /* backpointer to ifaltq */ + + class_queue_t *rq_q; + + red_t *rq_red; +} red_queue_t; +#endif /* ALTQ3_COMPAT */ + +/* red drop types */ +#define DTYPE_NODROP 0 /* no drop */ +#define DTYPE_FORCED 1 /* a "forced" drop */ +#define DTYPE_EARLY 2 /* an "unforced" (early) drop */ + +extern red_t *red_alloc(int, int, int, int, int, int); +extern void red_destroy(red_t *); +extern void red_getstats(red_t *, struct redstats *); +extern int red_addq(red_t *, class_queue_t *, struct mbuf *, + struct altq_pktattr *); +extern struct mbuf *red_getq(red_t *, class_queue_t *); +extern int drop_early(int, int, int); +extern int mark_ecn(struct mbuf *, struct altq_pktattr *, int); +extern struct wtab *wtab_alloc(int); +extern int wtab_destroy(struct wtab *); +extern int32_t pow_w(struct wtab *, int); + +#endif /* _KERNEL */ + +#endif /* _ALTQ_ALTQ_RED_H_ */ diff --git a/src/include.new/altq/altq_rio.h b/src/include.new/altq/altq_rio.h new file mode 100644 index 0000000..83210f2 --- /dev/null +++ b/src/include.new/altq/altq_rio.h @@ -0,0 +1,144 @@ +/* $KAME: altq_rio.h,v 1.9 2003/07/10 12:07:49 kjc Exp $ */ + +/* + * Copyright (C) 1998-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALTQ_ALTQ_RIO_H_ +#define _ALTQ_ALTQ_RIO_H_ + +#include + +/* + * RIO: RED with IN/OUT bit + * (extended to support more than 2 drop precedence values) + */ +#define RIO_NDROPPREC 3 /* number of drop precedence values */ + +#ifdef ALTQ3_COMPAT +struct rio_interface { + char rio_ifname[IFNAMSIZ]; +}; + +struct rio_stats { + struct rio_interface iface; + int q_len[RIO_NDROPPREC]; + struct redstats q_stats[RIO_NDROPPREC]; + + /* static red parameters */ + int q_limit; + int weight; + int flags; + struct redparams q_params[RIO_NDROPPREC]; +}; + +struct rio_conf { + struct rio_interface iface; + struct redparams q_params[RIO_NDROPPREC]; + int rio_weight; /* weight for EWMA */ + int rio_limit; /* max queue length */ + int rio_pkttime; /* average packet time in usec */ + int rio_flags; /* see below */ +}; +#endif /* ALTQ3_COMPAT */ + +/* rio flags */ +#define RIOF_ECN4 0x01 /* use packet marking for IPv4 packets */ +#define RIOF_ECN6 0x02 /* use packet marking for IPv6 packets */ +#define RIOF_ECN (RIOF_ECN4 | RIOF_ECN6) +#define RIOF_CLEARDSCP 0x200 /* clear diffserv codepoint */ + +#ifdef ALTQ3_COMPAT +/* + * IOCTLs for RIO + */ +#define RIO_IF_ATTACH _IOW('Q', 1, struct rio_interface) +#define RIO_IF_DETACH _IOW('Q', 2, struct rio_interface) +#define RIO_ENABLE _IOW('Q', 3, struct rio_interface) +#define RIO_DISABLE _IOW('Q', 4, struct rio_interface) +#define RIO_CONFIG _IOWR('Q', 6, struct rio_conf) +#define RIO_GETSTATS _IOWR('Q', 12, struct rio_stats) +#define RIO_SETDEFAULTS _IOW('Q', 30, struct redparams[RIO_NDROPPREC]) +#endif /* ALTQ3_COMPAT */ + +#ifdef _KERNEL + +typedef struct rio { + /* per drop precedence structure */ + struct dropprec_state { + /* red parameters */ + int inv_pmax; /* inverse of max drop probability */ + int th_min; /* red min threshold */ + int th_max; /* red max threshold */ + + /* variables for internal use */ + int th_min_s; /* th_min scaled by avgshift */ + int th_max_s; /* th_max scaled by avgshift */ + int probd; /* drop probability denominator */ + + int qlen; /* queue length */ + int avg; /* (scaled) queue length average */ + int count; /* packet count since the last dropped/ + marked packet */ + int idle; /* queue was empty */ + int old; /* avg is above th_min */ + struct timeval last; /* timestamp when queue becomes idle */ + } rio_precstate[RIO_NDROPPREC]; + + int rio_wshift; /* log(red_weight) */ + int rio_weight; /* weight for EWMA */ + struct wtab *rio_wtab; /* weight table */ + + int rio_pkttime; /* average packet time in micro sec + used for idle calibration */ + int rio_flags; /* rio flags */ + + u_int8_t rio_codepoint; /* codepoint value to tag packets */ + u_int8_t rio_codepointmask; /* codepoint mask bits */ + + struct redstats q_stats[RIO_NDROPPREC]; /* statistics */ +} rio_t; + +#ifdef ALTQ3_COMPAT +typedef struct rio_queue { + struct rio_queue *rq_next; /* next red_state in the list */ + struct ifaltq *rq_ifq; /* backpointer to ifaltq */ + + class_queue_t *rq_q; + + rio_t *rq_rio; +} rio_queue_t; +#endif /* ALTQ3_COMPAT */ + +extern rio_t *rio_alloc(int, struct redparams *, int, int); +extern void rio_destroy(rio_t *); +extern void rio_getstats(rio_t *, struct redstats *); +extern int rio_addq(rio_t *, class_queue_t *, struct mbuf *, + struct altq_pktattr *); +extern struct mbuf *rio_getq(rio_t *, class_queue_t *); + +#endif /* _KERNEL */ + +#endif /* _ALTQ_ALTQ_RIO_H_ */ diff --git a/src/include.new/altq/altq_rmclass.h b/src/include.new/altq/altq_rmclass.h new file mode 100644 index 0000000..cf0ddf4 --- /dev/null +++ b/src/include.new/altq/altq_rmclass.h @@ -0,0 +1,266 @@ +/* $KAME: altq_rmclass.h,v 1.10 2003/08/20 23:30:23 itojun Exp $ */ + +/* + * Copyright (c) 1991-1997 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Network Research + * Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALTQ_ALTQ_RMCLASS_H_ +#define _ALTQ_ALTQ_RMCLASS_H_ + +#include + +/* #pragma ident "@(#)rm_class.h 1.20 97/10/23 SMI" */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RM_MAXPRIO 8 /* Max priority */ + +#ifdef _KERNEL + +typedef struct mbuf mbuf_t; +typedef struct rm_ifdat rm_ifdat_t; +typedef struct rm_class rm_class_t; + +struct red; + +/* + * Macros for dealing with time values. We assume all times are + * 'timevals'. `microtime' is used to get the best available clock + * resolution. If `microtime' *doesn't* return a value that's about + * ten times smaller than the average packet time on the fastest + * link that will use these routines, a slightly different clock + * scheme than this one should be used. + * (Bias due to truncation error in this scheme will overestimate utilization + * and discriminate against high bandwidth classes. To remove this bias an + * integrator needs to be added. The simplest integrator uses a history of + * 10 * avg.packet.time / min.tick.time packet completion entries. This is + * straight forward to add but we don't want to pay the extra memory + * traffic to maintain it if it's not necessary (occasionally a vendor + * accidentally builds a workstation with a decent clock - e.g., Sun & HP).) + */ + +#define RM_GETTIME(now) microtime(&now) + +#define TV_LT(a, b) (((a)->tv_sec < (b)->tv_sec) || \ + (((a)->tv_usec < (b)->tv_usec) && ((a)->tv_sec <= (b)->tv_sec))) + +#define TV_DELTA(a, b, delta) { \ + register int xxs; \ + \ + delta = (a)->tv_usec - (b)->tv_usec; \ + if ((xxs = (a)->tv_sec - (b)->tv_sec)) { \ + switch (xxs) { \ + default: \ + /* if (xxs < 0) \ + printf("rm_class: bogus time values\n"); */ \ + delta = 0; \ + /* fall through */ \ + case 2: \ + delta += 1000000; \ + /* fall through */ \ + case 1: \ + delta += 1000000; \ + break; \ + } \ + } \ +} + +#define TV_ADD_DELTA(a, delta, res) { \ + register int xxus = (a)->tv_usec + (delta); \ + \ + (res)->tv_sec = (a)->tv_sec; \ + while (xxus >= 1000000) { \ + ++((res)->tv_sec); \ + xxus -= 1000000; \ + } \ + (res)->tv_usec = xxus; \ +} + +#define RM_TIMEOUT 2 /* 1 Clock tick. */ + +#if 1 +#define RM_MAXQUEUED 1 /* this isn't used in ALTQ/CBQ */ +#else +#define RM_MAXQUEUED 16 /* Max number of packets downstream of CBQ */ +#endif +#define RM_MAXQUEUE 64 /* Max queue length */ +#define RM_FILTER_GAIN 5 /* log2 of gain, e.g., 5 => 31/32 */ +#define RM_POWER (1 << RM_FILTER_GAIN) +#define RM_MAXDEPTH 32 +#define RM_NS_PER_SEC (1000000000) + +typedef struct _rm_class_stats_ { + u_int handle; + u_int depth; + + struct pktcntr xmit_cnt; /* packets sent in this class */ + struct pktcntr drop_cnt; /* dropped packets */ + u_int over; /* # times went over limit */ + u_int borrows; /* # times tried to borrow */ + u_int overactions; /* # times invoked overlimit action */ + u_int delays; /* # times invoked delay actions */ +} rm_class_stats_t; + +/* + * CBQ Class state structure + */ +struct rm_class { + class_queue_t *q_; /* Queue of packets */ + rm_ifdat_t *ifdat_; + int pri_; /* Class priority. */ + int depth_; /* Class depth */ + u_int ns_per_byte_; /* NanoSeconds per byte. */ + u_int maxrate_; /* Bytes per second for this class. */ + u_int allotment_; /* Fraction of link bandwidth. */ + u_int w_allotment_; /* Weighted allotment for WRR */ + int bytes_alloc_; /* Allocation for round of WRR */ + + int avgidle_; + int maxidle_; + int minidle_; + int offtime_; + int sleeping_; /* != 0 if delaying */ + int qthresh_; /* Queue threshold for formal link sharing */ + int leaf_; /* Note whether leaf class or not.*/ + + rm_class_t *children_; /* Children of this class */ + rm_class_t *next_; /* Next pointer, used if child */ + + rm_class_t *peer_; /* Peer class */ + rm_class_t *borrow_; /* Borrow class */ + rm_class_t *parent_; /* Parent class */ + + void (*overlimit)(struct rm_class *, struct rm_class *); + void (*drop)(struct rm_class *); /* Class drop action. */ + + struct red *red_; /* RED state pointer */ + struct altq_pktattr *pktattr_; /* saved hdr used by RED/ECN */ + int flags_; + + int last_pkttime_; /* saved pkt_time */ + struct timeval undertime_; /* time can next send */ + struct timeval last_; /* time last packet sent */ + struct timeval overtime_; + struct callout callout_; /* for timeout() calls */ + + rm_class_stats_t stats_; /* Class Statistics */ +}; + +/* + * CBQ Interface state + */ +struct rm_ifdat { + int queued_; /* # pkts queued downstream */ + int efficient_; /* Link Efficency bit */ + int wrr_; /* Enable Weighted Round-Robin */ + u_long ns_per_byte_; /* Link byte speed. */ + int maxqueued_; /* Max packets to queue */ + int maxpkt_; /* Max packet size. */ + int qi_; /* In/out pointers for downstream */ + int qo_; /* packets */ + + /* + * Active class state and WRR state. + */ + rm_class_t *active_[RM_MAXPRIO]; /* Active cl's in each pri */ + int na_[RM_MAXPRIO]; /* # of active cl's in a pri */ + int num_[RM_MAXPRIO]; /* # of cl's per pri */ + int alloc_[RM_MAXPRIO]; /* Byte Allocation */ + u_long M_[RM_MAXPRIO]; /* WRR weights. */ + + /* + * Network Interface/Solaris Queue state pointer. + */ + struct ifaltq *ifq_; + rm_class_t *default_; /* Default Pkt class, BE */ + rm_class_t *root_; /* Root Link class. */ + rm_class_t *ctl_; /* Control Traffic class. */ + void (*restart)(struct ifaltq *); /* Restart routine. */ + + /* + * Current packet downstream packet state and dynamic state. + */ + rm_class_t *borrowed_[RM_MAXQUEUED]; /* Class borrowed last */ + rm_class_t *class_[RM_MAXQUEUED]; /* class sending */ + int curlen_[RM_MAXQUEUED]; /* Current pktlen */ + struct timeval now_[RM_MAXQUEUED]; /* Current packet time. */ + int is_overlimit_[RM_MAXQUEUED];/* Current packet time. */ + + int cutoff_; /* Cut-off depth for borrowing */ + + struct timeval ifnow_; /* expected xmit completion time */ +#if 1 /* ALTQ4PPP */ + int maxiftime_; /* max delay inside interface */ +#endif + rm_class_t *pollcache_; /* cached rm_class by poll operation */ +}; + +/* flags for rmc_init and rmc_newclass */ +/* class flags */ +#define RMCF_RED 0x0001 +#define RMCF_ECN 0x0002 +#define RMCF_RIO 0x0004 +#define RMCF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */ +#define RMCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ + +/* flags for rmc_init */ +#define RMCF_WRR 0x0100 +#define RMCF_EFFICIENT 0x0200 + +#define is_a_parent_class(cl) ((cl)->children_ != NULL) + +extern rm_class_t *rmc_newclass(int, struct rm_ifdat *, u_int, + void (*)(struct rm_class *, struct rm_class *), + int, struct rm_class *, struct rm_class *, + u_int, int, u_int, int, int); +extern void rmc_delete_class(struct rm_ifdat *, struct rm_class *); +extern int rmc_modclass(struct rm_class *, u_int, int, + u_int, int, u_int, int); +extern void rmc_init(struct ifaltq *, struct rm_ifdat *, u_int, + void (*)(struct ifaltq *), + int, int, u_int, int, u_int, int); +extern int rmc_queue_packet(struct rm_class *, mbuf_t *); +extern mbuf_t *rmc_dequeue_next(struct rm_ifdat *, int); +extern void rmc_update_class_util(struct rm_ifdat *); +extern void rmc_delay_action(struct rm_class *, struct rm_class *); +extern void rmc_dropall(struct rm_class *); +extern int rmc_get_weight(struct rm_ifdat *, int); + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ALTQ_ALTQ_RMCLASS_H_ */ diff --git a/src/include.new/altq/altq_rmclass_debug.h b/src/include.new/altq/altq_rmclass_debug.h new file mode 100644 index 0000000..8f471b2 --- /dev/null +++ b/src/include.new/altq/altq_rmclass_debug.h @@ -0,0 +1,112 @@ +/* $KAME: altq_rmclass_debug.h,v 1.3 2002/11/29 04:36:24 kjc Exp $ */ + +/* + * Copyright (c) Sun Microsystems, Inc. 1998 All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the SMCC Technology + * Development Group at Sun Microsystems, Inc. + * + * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE + * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is + * provided "as is" without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this software. + */ + +#ifndef _ALTQ_ALTQ_RMCLASS_DEBUG_H_ +#define _ALTQ_ALTQ_RMCLASS_DEBUG_H_ + +/* #pragma ident "@(#)rm_class_debug.h 1.7 98/05/04 SMI" */ + +/* + * Cbq debugging macros + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CBQ_TRACE +#ifndef NCBQTRACE +#define NCBQTRACE (16 * 1024) +#endif + +/* + * To view the trace output, using adb, type: + * adb -k /dev/ksyms /dev/mem , then type + * cbqtrace_count/D to get the count, then type + * cbqtrace_buffer,0tcount/Dp4C" "Xn + * This will dump the trace buffer from 0 to count. + */ +/* + * in ALTQ, "call cbqtrace_dump(N)" from DDB to display 20 events + * from Nth event in the circular buffer. + */ + +struct cbqtrace { + int count; + int function; /* address of function */ + int trace_action; /* descriptive 4 characters */ + int object; /* object operated on */ +}; + +extern struct cbqtrace cbqtrace_buffer[]; +extern struct cbqtrace *cbqtrace_ptr; +extern int cbqtrace_count; + +#define CBQTRACEINIT() { \ + if (cbqtrace_ptr == NULL) \ + cbqtrace_ptr = cbqtrace_buffer; \ + else { \ + cbqtrace_ptr = cbqtrace_buffer; \ + bzero((void *)cbqtrace_ptr, sizeof(cbqtrace_buffer)); \ + cbqtrace_count = 0; \ + } \ +} + +#define LOCK_TRACE() splimp() +#define UNLOCK_TRACE(x) splx(x) + +#define CBQTRACE(func, act, obj) { \ + int __s = LOCK_TRACE(); \ + int *_p = &cbqtrace_ptr->count; \ + *_p++ = ++cbqtrace_count; \ + *_p++ = (int)(func); \ + *_p++ = (int)(act); \ + *_p++ = (int)(obj); \ + if ((struct cbqtrace *)(void *)_p >= &cbqtrace_buffer[NCBQTRACE])\ + cbqtrace_ptr = cbqtrace_buffer; \ + else \ + cbqtrace_ptr = (struct cbqtrace *)(void *)_p; \ + UNLOCK_TRACE(__s); \ + } +#else + +/* If no tracing, define no-ops */ +#define CBQTRACEINIT() +#define CBQTRACE(a, b, c) + +#endif /* !CBQ_TRACE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ALTQ_ALTQ_RMCLASS_DEBUG_H_ */ diff --git a/src/include.new/altq/altq_var.h b/src/include.new/altq/altq_var.h new file mode 100644 index 0000000..75f9c8b --- /dev/null +++ b/src/include.new/altq/altq_var.h @@ -0,0 +1,261 @@ +/* $FreeBSD: releng/10.2/sys/contrib/altq/altq/altq_var.h 219457 2011-03-10 18:49:15Z jkim $ */ +/* $KAME: altq_var.h,v 1.16 2003/10/03 05:05:15 kjc Exp $ */ + +/* + * Copyright (C) 1998-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _ALTQ_ALTQ_VAR_H_ +#define _ALTQ_ALTQ_VAR_H_ + +#ifdef _KERNEL + +#include +#include +#include + +#ifdef ALTQ3_CLFIER_COMPAT +/* + * filter structure for altq common classifier + */ +struct acc_filter { + LIST_ENTRY(acc_filter) f_chain; + void *f_class; /* pointer to the class */ + u_long f_handle; /* filter id */ + uint32_t f_fbmask; /* filter bitmask */ + struct flow_filter f_filter; /* filter value */ +}; + +/* + * XXX ACC_FILTER_TABLESIZE can't be larger than 2048 unless we fix + * the handle assignment. + */ +#define ACC_FILTER_TABLESIZE (256+1) +#define ACC_FILTER_MASK (ACC_FILTER_TABLESIZE - 2) +#define ACC_WILDCARD_INDEX (ACC_FILTER_TABLESIZE - 1) +#ifdef __GNUC__ +#define ACC_GET_HASH_INDEX(addr) \ + ({int x = (addr) + ((addr) >> 16); (x + (x >> 8)) & ACC_FILTER_MASK;}) +#else +#define ACC_GET_HASH_INDEX(addr) \ + (((addr) + ((addr) >> 8) + ((addr) >> 16) + ((addr) >> 24)) \ + & ACC_FILTER_MASK) +#endif +#define ACC_GET_HINDEX(handle) ((handle) >> 20) + +#if (__FreeBSD_version > 500000) +#define ACC_LOCK_INIT(ac) mtx_init(&(ac)->acc_mtx, "classifier", MTX_DEF) +#define ACC_LOCK_DESTROY(ac) mtx_destroy(&(ac)->acc_mtx) +#define ACC_LOCK(ac) mtx_lock(&(ac)->acc_mtx) +#define ACC_UNLOCK(ac) mtx_unlock(&(ac)->acc_mtx) +#else +#define ACC_LOCK_INIT(ac) +#define ACC_LOCK_DESTROY(ac) +#define ACC_LOCK(ac) +#define ACC_UNLOCK(ac) +#endif + +struct acc_classifier { + uint32_t acc_fbmask; + LIST_HEAD(filt, acc_filter) acc_filters[ACC_FILTER_TABLESIZE]; + +#if (__FreeBSD_version > 500000) + struct mtx acc_mtx; +#endif +}; + +/* + * flowinfo mask bits used by classifier + */ +/* for ipv4 */ +#define FIMB4_PROTO 0x0001 +#define FIMB4_TOS 0x0002 +#define FIMB4_DADDR 0x0004 +#define FIMB4_SADDR 0x0008 +#define FIMB4_DPORT 0x0010 +#define FIMB4_SPORT 0x0020 +#define FIMB4_GPI 0x0040 +#define FIMB4_ALL 0x007f +/* for ipv6 */ +#define FIMB6_PROTO 0x0100 +#define FIMB6_TCLASS 0x0200 +#define FIMB6_DADDR 0x0400 +#define FIMB6_SADDR 0x0800 +#define FIMB6_DPORT 0x1000 +#define FIMB6_SPORT 0x2000 +#define FIMB6_GPI 0x4000 +#define FIMB6_FLABEL 0x8000 +#define FIMB6_ALL 0xff00 + +#define FIMB_ALL (FIMB4_ALL|FIMB6_ALL) + +#define FIMB4_PORTS (FIMB4_DPORT|FIMB4_SPORT|FIMB4_GPI) +#define FIMB6_PORTS (FIMB6_DPORT|FIMB6_SPORT|FIMB6_GPI) +#endif /* ALTQ3_CLFIER_COMPAT */ + +/* + * machine dependent clock + * a 64bit high resolution time counter. + */ +extern int machclk_usepcc; +extern uint32_t machclk_freq; +extern uint32_t machclk_per_tick; +extern void init_machclk(void); +extern u_int64_t read_machclk(void); + +/* + * debug support + */ +#ifdef ALTQ_DEBUG +#ifdef __STDC__ +#define ASSERT(e) ((e) ? (void)0 : altq_assert(__FILE__, __LINE__, #e)) +#else /* PCC */ +#define ASSERT(e) ((e) ? (void)0 : altq_assert(__FILE__, __LINE__, "e")) +#endif +#else +#define ASSERT(e) ((void)0) +#endif + +/* + * misc stuff for compatibility + */ +/* ioctl cmd type */ +typedef u_long ioctlcmd_t; + +/* + * queue macros: + * the interface of TAILQ_LAST macro changed after the introduction + * of softupdate. redefine it here to make it work with pre-2.2.7. + */ +#undef TAILQ_LAST +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#ifndef TAILQ_EMPTY +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) +#endif +#ifndef TAILQ_FOREACH +#define TAILQ_FOREACH(var, head, field) \ + for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) +#endif + +/* macro for timeout/untimeout */ +#if (__FreeBSD_version > 300000) || defined(__NetBSD__) +/* use callout */ +#include + +#if (__FreeBSD_version > 500000) +#define CALLOUT_INIT(c) callout_init((c), 0) +#else +#define CALLOUT_INIT(c) callout_init((c)) +#endif +#define CALLOUT_RESET(c,t,f,a) callout_reset((c),(t),(f),(a)) +#define CALLOUT_STOP(c) callout_stop((c)) +#if !defined(CALLOUT_INITIALIZER) && (__FreeBSD_version < 600000) +#define CALLOUT_INITIALIZER { { { NULL } }, 0, NULL, NULL, 0 } +#endif +#elif defined(__OpenBSD__) +#include +/* callout structure as a wrapper of struct timeout */ +struct callout { + struct timeout c_to; +}; +#define CALLOUT_INIT(c) do { bzero((c), sizeof(*(c))); } while (/*CONSTCOND*/ 0) +#define CALLOUT_RESET(c,t,f,a) do { if (!timeout_initialized(&(c)->c_to)) \ + timeout_set(&(c)->c_to, (f), (a)); \ + timeout_add(&(c)->c_to, (t)); } while (/*CONSTCOND*/ 0) +#define CALLOUT_STOP(c) timeout_del(&(c)->c_to) +#define CALLOUT_INITIALIZER { { { NULL }, NULL, NULL, 0, 0 } } +#else +/* use old-style timeout/untimeout */ +/* dummy callout structure */ +struct callout { + void *c_arg; /* function argument */ + void (*c_func)(void *); /* functiuon to call */ +}; +#define CALLOUT_INIT(c) do { bzero((c), sizeof(*(c))); } while (/*CONSTCOND*/ 0) +#define CALLOUT_RESET(c,t,f,a) do { (c)->c_arg = (a); \ + (c)->c_func = (f); \ + timeout((f),(a),(t)); } while (/*CONSTCOND*/ 0) +#define CALLOUT_STOP(c) untimeout((c)->c_func,(c)->c_arg) +#define CALLOUT_INITIALIZER { NULL, NULL } +#endif +#if !defined(__FreeBSD__) +typedef void (timeout_t)(void *); +#endif + +#define m_pktlen(m) ((m)->m_pkthdr.len) + +struct ifnet; struct mbuf; +struct pf_altq; +#ifdef ALTQ3_CLFIER_COMPAT +struct flowinfo; +#endif + +void *altq_lookup(char *, int); +#ifdef ALTQ3_CLFIER_COMPAT +int altq_extractflow(struct mbuf *, int, struct flowinfo *, uint32_t); +int acc_add_filter(struct acc_classifier *, struct flow_filter *, + void *, u_long *); +int acc_delete_filter(struct acc_classifier *, u_long); +int acc_discard_filters(struct acc_classifier *, void *, int); +void *acc_classify(void *, struct mbuf *, int); +#endif +u_int8_t read_dsfield(struct mbuf *, struct altq_pktattr *); +void write_dsfield(struct mbuf *, struct altq_pktattr *, u_int8_t); +void altq_assert(const char *, int, const char *); +int tbr_set(struct ifaltq *, struct tb_profile *); +int tbr_get(struct ifaltq *, struct tb_profile *); + +int altq_pfattach(struct pf_altq *); +int altq_pfdetach(struct pf_altq *); +int altq_add(struct pf_altq *); +int altq_remove(struct pf_altq *); +int altq_add_queue(struct pf_altq *); +int altq_remove_queue(struct pf_altq *); +int altq_getqstats(struct pf_altq *, void *, int *); + +int cbq_pfattach(struct pf_altq *); +int cbq_add_altq(struct pf_altq *); +int cbq_remove_altq(struct pf_altq *); +int cbq_add_queue(struct pf_altq *); +int cbq_remove_queue(struct pf_altq *); +int cbq_getqstats(struct pf_altq *, void *, int *); + +int priq_pfattach(struct pf_altq *); +int priq_add_altq(struct pf_altq *); +int priq_remove_altq(struct pf_altq *); +int priq_add_queue(struct pf_altq *); +int priq_remove_queue(struct pf_altq *); +int priq_getqstats(struct pf_altq *, void *, int *); + +int hfsc_pfattach(struct pf_altq *); +int hfsc_add_altq(struct pf_altq *); +int hfsc_remove_altq(struct pf_altq *); +int hfsc_add_queue(struct pf_altq *); +int hfsc_remove_queue(struct pf_altq *); +int hfsc_getqstats(struct pf_altq *, void *, int *); + +#endif /* _KERNEL */ +#endif /* _ALTQ_ALTQ_VAR_H_ */ diff --git a/src/include.new/altq/altqconf.h b/src/include.new/altq/altqconf.h new file mode 100644 index 0000000..4d3921c --- /dev/null +++ b/src/include.new/altq/altqconf.h @@ -0,0 +1,29 @@ +/* $OpenBSD: altqconf.h,v 1.1 2001/06/27 05:28:36 kjc Exp $ */ +/* $NetBSD: altqconf.h,v 1.2 2001/05/30 11:57:16 mrg Exp $ */ + +#if defined(_KERNEL_OPT) || defined(__OpenBSD__) + +#if defined(_KERNEL_OPT) +#include "opt_altq_enabled.h" +#endif + +#include + +#ifdef ALTQ +#define NALTQ 1 +#else +#define NALTQ 0 +#endif + +cdev_decl(altq); + +#ifdef __OpenBSD__ +#define cdev_altq_init(c,n) { \ + dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \ + (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ + (dev_type_stop((*))) enodev, 0, (dev_type_select((*))) enodev, \ + (dev_type_mmap((*))) enodev } +#else +#define cdev_altq_init(x,y) cdev__oci_init(x,y) +#endif +#endif /* defined(_KERNEL_OPT) || defined(__OpenBSD__) */ diff --git a/src/include.new/altq/if_altq.h b/src/include.new/altq/if_altq.h new file mode 100644 index 0000000..0b71eaf --- /dev/null +++ b/src/include.new/altq/if_altq.h @@ -0,0 +1,191 @@ +/* $FreeBSD: releng/10.2/sys/contrib/altq/altq/if_altq.h 219457 2011-03-10 18:49:15Z jkim $ */ +/* $KAME: if_altq.h,v 1.12 2005/04/13 03:44:25 suz Exp $ */ + +/* + * Copyright (C) 1997-2003 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _ALTQ_IF_ALTQ_H_ +#define _ALTQ_IF_ALTQ_H_ + +#ifdef __FreeBSD__ +#include /* XXX */ +#include /* XXX */ +#include /* XXX */ +#endif + +#ifdef _KERNEL_OPT +#include +#endif + +struct altq_pktattr; struct tb_regulator; struct top_cdnr; + +/* + * Structure defining a queue for a network interface. + */ +struct ifaltq { + /* fields compatible with struct ifqueue */ + struct mbuf *ifq_head; + struct mbuf *ifq_tail; + int ifq_len; + int ifq_maxlen; + int ifq_drops; +#ifdef __FreeBSD__ + struct mtx ifq_mtx; +#endif + + /* driver owned queue (used for bulk dequeue and prepend) UNLOCKED */ + struct mbuf *ifq_drv_head; + struct mbuf *ifq_drv_tail; + int ifq_drv_len; + int ifq_drv_maxlen; + + /* alternate queueing related fields */ + int altq_type; /* discipline type */ + int altq_flags; /* flags (e.g. ready, in-use) */ + void *altq_disc; /* for discipline-specific use */ + struct ifnet *altq_ifp; /* back pointer to interface */ + + int (*altq_enqueue)(struct ifaltq *, struct mbuf *, + struct altq_pktattr *); + struct mbuf *(*altq_dequeue)(struct ifaltq *, int); + int (*altq_request)(struct ifaltq *, int, void *); + + /* classifier fields */ + void *altq_clfier; /* classifier-specific use */ + void *(*altq_classify)(void *, struct mbuf *, int); + + /* token bucket regulator */ + struct tb_regulator *altq_tbr; + + /* input traffic conditioner (doesn't belong to the output queue...) */ + struct top_cdnr *altq_cdnr; +}; + + +#ifdef _KERNEL + +/* + * packet attributes used by queueing disciplines. + * pattr_class is a discipline-dependent scheduling class that is + * set by a classifier. + * pattr_hdr and pattr_af may be used by a discipline to access + * the header within a mbuf. (e.g. ECN needs to update the CE bit) + * note that pattr_hdr could be stale after m_pullup, though link + * layer output routines usually don't use m_pullup. link-level + * compression also invalidates these fields. thus, pattr_hdr needs + * to be verified when a discipline touches the header. + */ +struct altq_pktattr { + void *pattr_class; /* sched class set by classifier */ + int pattr_af; /* address family */ + caddr_t pattr_hdr; /* saved header position in mbuf */ +}; + +/* + * mbuf tag to carry a queue id (and hints for ECN). + */ +struct altq_tag { + uint32_t qid; /* queue id */ + /* hints for ecn */ + int af; /* address family */ + void *hdr; /* saved header position in mbuf */ +}; + +/* + * a token-bucket regulator limits the rate that a network driver can + * dequeue packets from the output queue. + * modern cards are able to buffer a large amount of packets and dequeue + * too many packets at a time. this bursty dequeue behavior makes it + * impossible to schedule packets by queueing disciplines. + * a token-bucket is used to control the burst size in a device + * independent manner. + */ +struct tb_regulator { + int64_t tbr_rate; /* (scaled) token bucket rate */ + int64_t tbr_depth; /* (scaled) token bucket depth */ + + int64_t tbr_token; /* (scaled) current token */ + int64_t tbr_filluptime; /* (scaled) time to fill up bucket */ + u_int64_t tbr_last; /* last time token was updated */ + + int tbr_lastop; /* last dequeue operation type + needed for poll-and-dequeue */ +}; + +/* if_altqflags */ +#define ALTQF_READY 0x01 /* driver supports alternate queueing */ +#define ALTQF_ENABLED 0x02 /* altq is in use */ +#define ALTQF_CLASSIFY 0x04 /* classify packets */ +#define ALTQF_CNDTNING 0x08 /* altq traffic conditioning is enabled */ +#define ALTQF_DRIVER1 0x40 /* driver specific */ + +/* if_altqflags set internally only: */ +#define ALTQF_CANTCHANGE (ALTQF_READY) + +/* altq_dequeue 2nd arg */ +#define ALTDQ_REMOVE 1 /* dequeue mbuf from the queue */ +#define ALTDQ_POLL 2 /* don't dequeue mbuf from the queue */ + +/* altq request types (currently only purge is defined) */ +#define ALTRQ_PURGE 1 /* purge all packets */ + +#define ALTQ_IS_READY(ifq) ((ifq)->altq_flags & ALTQF_READY) +#define ALTQ_IS_ENABLED(ifq) ((ifq)->altq_flags & ALTQF_ENABLED) +#define ALTQ_NEEDS_CLASSIFY(ifq) ((ifq)->altq_flags & ALTQF_CLASSIFY) +#define ALTQ_IS_CNDTNING(ifq) ((ifq)->altq_flags & ALTQF_CNDTNING) + +#define ALTQ_SET_CNDTNING(ifq) ((ifq)->altq_flags |= ALTQF_CNDTNING) +#define ALTQ_CLEAR_CNDTNING(ifq) ((ifq)->altq_flags &= ~ALTQF_CNDTNING) +#define ALTQ_IS_ATTACHED(ifq) ((ifq)->altq_disc != NULL) + +#define ALTQ_ENQUEUE(ifq, m, pa, err) \ + (err) = (*(ifq)->altq_enqueue)((ifq),(m),(pa)) +#define ALTQ_DEQUEUE(ifq, m) \ + (m) = (*(ifq)->altq_dequeue)((ifq), ALTDQ_REMOVE) +#define ALTQ_POLL(ifq, m) \ + (m) = (*(ifq)->altq_dequeue)((ifq), ALTDQ_POLL) +#define ALTQ_PURGE(ifq) \ + (void)(*(ifq)->altq_request)((ifq), ALTRQ_PURGE, (void *)0) +#define ALTQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) +#define TBR_IS_ENABLED(ifq) ((ifq)->altq_tbr != NULL) + +extern int altq_attach(struct ifaltq *, int, void *, + int (*)(struct ifaltq *, struct mbuf *, + struct altq_pktattr *), + struct mbuf *(*)(struct ifaltq *, int), + int (*)(struct ifaltq *, int, void *), + void *, + void *(*)(void *, struct mbuf *, int)); +extern int altq_detach(struct ifaltq *); +extern int altq_enable(struct ifaltq *); +extern int altq_disable(struct ifaltq *); +extern struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int); +extern int (*altq_input)(struct mbuf *, int); +#if 0 /* ALTQ3_CLFIER_COMPAT */ +void altq_etherclassify(struct ifaltq *, struct mbuf *, struct altq_pktattr *); +#endif +#endif /* _KERNEL */ + +#endif /* _ALTQ_IF_ALTQ_H_ */ diff --git a/src/include.new/ar.h b/src/include.new/ar.h new file mode 100644 index 0000000..c86a563 --- /dev/null +++ b/src/include.new/ar.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * This code is derived from software contributed to Berkeley by + * Hugh Smith at The University of Guelph. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ar.h 8.2 (Berkeley) 1/21/94 + * + * $FreeBSD: releng/10.2/include/ar.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _AR_H_ +#define _AR_H_ + +#include + +/* Pre-4BSD archives had these magic numbers in them. */ +#define OARMAG1 0177555 +#define OARMAG2 0177545 + +#define ARMAG "!\n" /* ar "magic number" */ +#define SARMAG 8 /* strlen(ARMAG); */ + +#define AR_EFMT1 "#1/" /* extended format #1 */ + +struct ar_hdr { + char ar_name[16]; /* name */ + char ar_date[12]; /* modification time */ + char ar_uid[6]; /* user id */ + char ar_gid[6]; /* group id */ + char ar_mode[8]; /* octal file permissions */ + char ar_size[10]; /* size in bytes */ +#define ARFMAG "`\n" + char ar_fmag[2]; /* consistency check */ +} __packed; + +#endif /* !_AR_H_ */ diff --git a/src/include.new/archive.h b/src/include.new/archive.h new file mode 100644 index 0000000..db34904 --- /dev/null +++ b/src/include.new/archive.h @@ -0,0 +1,1040 @@ +/*- + * Copyright (c) 2003-2010 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/contrib/libarchive/libarchive/archive.h 248616 2013-03-22 13:36:03Z mm $ + */ + +#ifndef ARCHIVE_H_INCLUDED +#define ARCHIVE_H_INCLUDED + +#include +#include /* for wchar_t */ +#include /* For FILE * */ + +/* + * Note: archive.h is for use outside of libarchive; the configuration + * headers (config.h, archive_platform.h, etc.) are purely internal. + * Do NOT use HAVE_XXX configuration macros to control the behavior of + * this header! If you must conditionalize, use predefined compiler and/or + * platform macros. + */ +#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560 +# include +#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) +# include +#endif + +/* Get appropriate definitions of standard POSIX-style types. */ +/* These should match the types used in 'struct stat' */ +#if defined(_WIN32) && !defined(__CYGWIN__) +# define __LA_INT64_T __int64 +# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_) +# define __LA_SSIZE_T ssize_t +# elif defined(_WIN64) +# define __LA_SSIZE_T __int64 +# else +# define __LA_SSIZE_T long +# endif +#else +# include /* ssize_t */ +# if defined(_SCO_DS) +# define __LA_INT64_T long long +# else +# define __LA_INT64_T int64_t +# endif +# define __LA_SSIZE_T ssize_t +#endif + +/* + * On Windows, define LIBARCHIVE_STATIC if you're building or using a + * .lib. The default here assumes you're building a DLL. Only + * libarchive source should ever define __LIBARCHIVE_BUILD. + */ +#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC) +# ifdef __LIBARCHIVE_BUILD +# ifdef __GNUC__ +# define __LA_DECL __attribute__((dllexport)) extern +# else +# define __LA_DECL __declspec(dllexport) +# endif +# else +# ifdef __GNUC__ +# define __LA_DECL +# else +# define __LA_DECL __declspec(dllimport) +# endif +# endif +#else +/* Static libraries or non-Windows needs no special declaration. */ +# define __LA_DECL +#endif + +#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__) +#define __LA_PRINTF(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#else +#define __LA_PRINTF(fmtarg, firstvararg) /* nothing */ +#endif + +#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1 +# define __LA_DEPRECATED __attribute__((deprecated)) +#else +# define __LA_DEPRECATED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The version number is provided as both a macro and a function. + * The macro identifies the installed header; the function identifies + * the library version (which may not be the same if you're using a + * dynamically-linked version of the library). Of course, if the + * header and library are very different, you should expect some + * strangeness. Don't do that. + */ + +/* + * The version number is expressed as a single integer that makes it + * easy to compare versions at build time: for version a.b.c, the + * version number is printf("%d%03d%03d",a,b,c). For example, if you + * know your application requires version 2.12.108 or later, you can + * assert that ARCHIVE_VERSION_NUMBER >= 2012108. + */ +/* Note: Compiler will complain if this does not match archive_entry.h! */ +#define ARCHIVE_VERSION_NUMBER 3001002 +__LA_DECL int archive_version_number(void); + +/* + * Textual name/version of the library, useful for version displays. + */ +#define ARCHIVE_VERSION_STRING "libarchive 3.1.2" +__LA_DECL const char * archive_version_string(void); + +/* Declare our basic types. */ +struct archive; +struct archive_entry; + +/* + * Error codes: Use archive_errno() and archive_error_string() + * to retrieve details. Unless specified otherwise, all functions + * that return 'int' use these codes. + */ +#define ARCHIVE_EOF 1 /* Found end of archive. */ +#define ARCHIVE_OK 0 /* Operation was successful. */ +#define ARCHIVE_RETRY (-10) /* Retry might succeed. */ +#define ARCHIVE_WARN (-20) /* Partial success. */ +/* For example, if write_header "fails", then you can't push data. */ +#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */ +/* But if write_header is "fatal," then this archive is dead and useless. */ +#define ARCHIVE_FATAL (-30) /* No more operations are possible. */ + +/* + * As far as possible, archive_errno returns standard platform errno codes. + * Of course, the details vary by platform, so the actual definitions + * here are stored in "archive_platform.h". The symbols are listed here + * for reference; as a rule, clients should not need to know the exact + * platform-dependent error code. + */ +/* Unrecognized or invalid file format. */ +/* #define ARCHIVE_ERRNO_FILE_FORMAT */ +/* Illegal usage of the library. */ +/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */ +/* Unknown or unclassified error. */ +/* #define ARCHIVE_ERRNO_MISC */ + +/* + * Callbacks are invoked to automatically read/skip/write/open/close the + * archive. You can provide your own for complex tasks (like breaking + * archives across multiple tapes) or use standard ones built into the + * library. + */ + +/* Returns pointer and size of next block of data from archive. */ +typedef __LA_SSIZE_T archive_read_callback(struct archive *, + void *_client_data, const void **_buffer); + +/* Skips at most request bytes from archive and returns the skipped amount. + * This may skip fewer bytes than requested; it may even skip zero bytes. + * If you do skip fewer bytes than requested, libarchive will invoke your + * read callback and discard data as necessary to make up the full skip. + */ +typedef __LA_INT64_T archive_skip_callback(struct archive *, + void *_client_data, __LA_INT64_T request); + +/* Seeks to specified location in the file and returns the position. + * Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h. + * Return ARCHIVE_FATAL if the seek fails for any reason. + */ +typedef __LA_INT64_T archive_seek_callback(struct archive *, + void *_client_data, __LA_INT64_T offset, int whence); + +/* Returns size actually written, zero on EOF, -1 on error. */ +typedef __LA_SSIZE_T archive_write_callback(struct archive *, + void *_client_data, + const void *_buffer, size_t _length); + +typedef int archive_open_callback(struct archive *, void *_client_data); + +typedef int archive_close_callback(struct archive *, void *_client_data); + +/* Switches from one client data object to the next/prev client data object. + * This is useful for reading from different data blocks such as a set of files + * that make up one large file. + */ +typedef int archive_switch_callback(struct archive *, void *_client_data1, + void *_client_data2); + +/* + * Codes to identify various stream filters. + */ +#define ARCHIVE_FILTER_NONE 0 +#define ARCHIVE_FILTER_GZIP 1 +#define ARCHIVE_FILTER_BZIP2 2 +#define ARCHIVE_FILTER_COMPRESS 3 +#define ARCHIVE_FILTER_PROGRAM 4 +#define ARCHIVE_FILTER_LZMA 5 +#define ARCHIVE_FILTER_XZ 6 +#define ARCHIVE_FILTER_UU 7 +#define ARCHIVE_FILTER_RPM 8 +#define ARCHIVE_FILTER_LZIP 9 +#define ARCHIVE_FILTER_LRZIP 10 +#define ARCHIVE_FILTER_LZOP 11 +#define ARCHIVE_FILTER_GRZIP 12 + +#if ARCHIVE_VERSION_NUMBER < 4000000 +#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE +#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP +#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2 +#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS +#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM +#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA +#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ +#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU +#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM +#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP +#define ARCHIVE_COMPRESSION_LRZIP ARCHIVE_FILTER_LRZIP +#endif + +/* + * Codes returned by archive_format. + * + * Top 16 bits identifies the format family (e.g., "tar"); lower + * 16 bits indicate the variant. This is updated by read_next_header. + * Note that the lower 16 bits will often vary from entry to entry. + * In some cases, this variation occurs as libarchive learns more about + * the archive (for example, later entries might utilize extensions that + * weren't necessary earlier in the archive; in this case, libarchive + * will change the format code to indicate the extended format that + * was used). In other cases, it's because different tools have + * modified the archive and so different parts of the archive + * actually have slightly different formats. (Both tar and cpio store + * format codes in each entry, so it is quite possible for each + * entry to be in a different format.) + */ +#define ARCHIVE_FORMAT_BASE_MASK 0xff0000 +#define ARCHIVE_FORMAT_CPIO 0x10000 +#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1) +#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2) +#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3) +#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4) +#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5) +#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6) +#define ARCHIVE_FORMAT_SHAR 0x20000 +#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1) +#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2) +#define ARCHIVE_FORMAT_TAR 0x30000 +#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1) +#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2) +#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3) +#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4) +#define ARCHIVE_FORMAT_ISO9660 0x40000 +#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1) +#define ARCHIVE_FORMAT_ZIP 0x50000 +#define ARCHIVE_FORMAT_EMPTY 0x60000 +#define ARCHIVE_FORMAT_AR 0x70000 +#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1) +#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2) +#define ARCHIVE_FORMAT_MTREE 0x80000 +#define ARCHIVE_FORMAT_RAW 0x90000 +#define ARCHIVE_FORMAT_XAR 0xA0000 +#define ARCHIVE_FORMAT_LHA 0xB0000 +#define ARCHIVE_FORMAT_CAB 0xC0000 +#define ARCHIVE_FORMAT_RAR 0xD0000 +#define ARCHIVE_FORMAT_7ZIP 0xE0000 + +/*- + * Basic outline for reading an archive: + * 1) Ask archive_read_new for an archive reader object. + * 2) Update any global properties as appropriate. + * In particular, you'll certainly want to call appropriate + * archive_read_support_XXX functions. + * 3) Call archive_read_open_XXX to open the archive + * 4) Repeatedly call archive_read_next_header to get information about + * successive archive entries. Call archive_read_data to extract + * data for entries of interest. + * 5) Call archive_read_finish to end processing. + */ +__LA_DECL struct archive *archive_read_new(void); + +/* + * The archive_read_support_XXX calls enable auto-detect for this + * archive handle. They also link in the necessary support code. + * For example, if you don't want bzlib linked in, don't invoke + * support_compression_bzip2(). The "all" functions provide the + * obvious shorthand. + */ + +#if ARCHIVE_VERSION_NUMBER < 4000000 +__LA_DECL int archive_read_support_compression_all(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_bzip2(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_compress(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_gzip(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_lzip(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_lzma(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_none(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_program(struct archive *, + const char *command) __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_program_signature + (struct archive *, const char *, + const void * /* match */, size_t) __LA_DEPRECATED; + +__LA_DECL int archive_read_support_compression_rpm(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_uu(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_read_support_compression_xz(struct archive *) + __LA_DEPRECATED; +#endif + +__LA_DECL int archive_read_support_filter_all(struct archive *); +__LA_DECL int archive_read_support_filter_bzip2(struct archive *); +__LA_DECL int archive_read_support_filter_compress(struct archive *); +__LA_DECL int archive_read_support_filter_gzip(struct archive *); +__LA_DECL int archive_read_support_filter_grzip(struct archive *); +__LA_DECL int archive_read_support_filter_lrzip(struct archive *); +__LA_DECL int archive_read_support_filter_lzip(struct archive *); +__LA_DECL int archive_read_support_filter_lzma(struct archive *); +__LA_DECL int archive_read_support_filter_lzop(struct archive *); +__LA_DECL int archive_read_support_filter_none(struct archive *); +__LA_DECL int archive_read_support_filter_program(struct archive *, + const char *command); +__LA_DECL int archive_read_support_filter_program_signature + (struct archive *, const char * /* cmd */, + const void * /* match */, size_t); +__LA_DECL int archive_read_support_filter_rpm(struct archive *); +__LA_DECL int archive_read_support_filter_uu(struct archive *); +__LA_DECL int archive_read_support_filter_xz(struct archive *); + +__LA_DECL int archive_read_support_format_7zip(struct archive *); +__LA_DECL int archive_read_support_format_all(struct archive *); +__LA_DECL int archive_read_support_format_ar(struct archive *); +__LA_DECL int archive_read_support_format_by_code(struct archive *, int); +__LA_DECL int archive_read_support_format_cab(struct archive *); +__LA_DECL int archive_read_support_format_cpio(struct archive *); +__LA_DECL int archive_read_support_format_empty(struct archive *); +__LA_DECL int archive_read_support_format_gnutar(struct archive *); +__LA_DECL int archive_read_support_format_iso9660(struct archive *); +__LA_DECL int archive_read_support_format_lha(struct archive *); +__LA_DECL int archive_read_support_format_mtree(struct archive *); +__LA_DECL int archive_read_support_format_rar(struct archive *); +__LA_DECL int archive_read_support_format_raw(struct archive *); +__LA_DECL int archive_read_support_format_tar(struct archive *); +__LA_DECL int archive_read_support_format_xar(struct archive *); +__LA_DECL int archive_read_support_format_zip(struct archive *); + +/* Functions to manually set the format and filters to be used. This is + * useful to bypass the bidding process when the format and filters to use + * is known in advance. + */ +__LA_DECL int archive_read_set_format(struct archive *, int); +__LA_DECL int archive_read_append_filter(struct archive *, int); +__LA_DECL int archive_read_append_filter_program(struct archive *, + const char *); +__LA_DECL int archive_read_append_filter_program_signature + (struct archive *, const char *, const void * /* match */, size_t); + +/* Set various callbacks. */ +__LA_DECL int archive_read_set_open_callback(struct archive *, + archive_open_callback *); +__LA_DECL int archive_read_set_read_callback(struct archive *, + archive_read_callback *); +__LA_DECL int archive_read_set_seek_callback(struct archive *, + archive_seek_callback *); +__LA_DECL int archive_read_set_skip_callback(struct archive *, + archive_skip_callback *); +__LA_DECL int archive_read_set_close_callback(struct archive *, + archive_close_callback *); +/* Callback used to switch between one data object to the next */ +__LA_DECL int archive_read_set_switch_callback(struct archive *, + archive_switch_callback *); + +/* This sets the first data object. */ +__LA_DECL int archive_read_set_callback_data(struct archive *, void *); +/* This sets data object at specified index */ +__LA_DECL int archive_read_set_callback_data2(struct archive *, void *, + unsigned int); +/* This adds a data object at the specified index. */ +__LA_DECL int archive_read_add_callback_data(struct archive *, void *, + unsigned int); +/* This appends a data object to the end of list */ +__LA_DECL int archive_read_append_callback_data(struct archive *, void *); +/* This prepends a data object to the beginning of list */ +__LA_DECL int archive_read_prepend_callback_data(struct archive *, void *); + +/* Opening freezes the callbacks. */ +__LA_DECL int archive_read_open1(struct archive *); + +/* Convenience wrappers around the above. */ +__LA_DECL int archive_read_open(struct archive *, void *_client_data, + archive_open_callback *, archive_read_callback *, + archive_close_callback *); +__LA_DECL int archive_read_open2(struct archive *, void *_client_data, + archive_open_callback *, archive_read_callback *, + archive_skip_callback *, archive_close_callback *); + +/* + * A variety of shortcuts that invoke archive_read_open() with + * canned callbacks suitable for common situations. The ones that + * accept a block size handle tape blocking correctly. + */ +/* Use this if you know the filename. Note: NULL indicates stdin. */ +__LA_DECL int archive_read_open_filename(struct archive *, + const char *_filename, size_t _block_size); +/* Use this for reading multivolume files by filenames. + * NOTE: Must be NULL terminated. Sorting is NOT done. */ +__LA_DECL int archive_read_open_filenames(struct archive *, + const char **_filenames, size_t _block_size); +__LA_DECL int archive_read_open_filename_w(struct archive *, + const wchar_t *_filename, size_t _block_size); +/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */ +__LA_DECL int archive_read_open_file(struct archive *, + const char *_filename, size_t _block_size) __LA_DEPRECATED; +/* Read an archive that's stored in memory. */ +__LA_DECL int archive_read_open_memory(struct archive *, + void * buff, size_t size); +/* A more involved version that is only used for internal testing. */ +__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff, + size_t size, size_t read_size); +/* Read an archive that's already open, using the file descriptor. */ +__LA_DECL int archive_read_open_fd(struct archive *, int _fd, + size_t _block_size); +/* Read an archive that's already open, using a FILE *. */ +/* Note: DO NOT use this with tape drives. */ +__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file); + +/* Parses and returns next entry header. */ +__LA_DECL int archive_read_next_header(struct archive *, + struct archive_entry **); + +/* Parses and returns next entry header using the archive_entry passed in */ +__LA_DECL int archive_read_next_header2(struct archive *, + struct archive_entry *); + +/* + * Retrieve the byte offset in UNCOMPRESSED data where last-read + * header started. + */ +__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *); + +/* Read data from the body of an entry. Similar to read(2). */ +__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *, + void *, size_t); + +/* Seek within the body of an entry. Similar to lseek(2). */ +__LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int); + +/* + * A zero-copy version of archive_read_data that also exposes the file offset + * of each returned block. Note that the client has no way to specify + * the desired size of the block. The API does guarantee that offsets will + * be strictly increasing and that returned blocks will not overlap. + */ +__LA_DECL int archive_read_data_block(struct archive *a, + const void **buff, size_t *size, __LA_INT64_T *offset); + +/*- + * Some convenience functions that are built on archive_read_data: + * 'skip': skips entire entry + * 'into_buffer': writes data into memory buffer that you provide + * 'into_fd': writes data to specified filedes + */ +__LA_DECL int archive_read_data_skip(struct archive *); +__LA_DECL int archive_read_data_into_fd(struct archive *, int fd); + +/* + * Set read options. + */ +/* Apply option to the format only. */ +__LA_DECL int archive_read_set_format_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option to the filter only. */ +__LA_DECL int archive_read_set_filter_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option to both the format and the filter. */ +__LA_DECL int archive_read_set_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option string to both the format and the filter. */ +__LA_DECL int archive_read_set_options(struct archive *_a, + const char *opts); + +/*- + * Convenience function to recreate the current entry (whose header + * has just been read) on disk. + * + * This does quite a bit more than just copy data to disk. It also: + * - Creates intermediate directories as required. + * - Manages directory permissions: non-writable directories will + * be initially created with write permission enabled; when the + * archive is closed, dir permissions are edited to the values specified + * in the archive. + * - Checks hardlinks: hardlinks will not be extracted unless the + * linked-to file was also extracted within the same session. (TODO) + */ + +/* The "flags" argument selects optional behavior, 'OR' the flags you want. */ + +/* Default: Do not try to set owner/group. */ +#define ARCHIVE_EXTRACT_OWNER (0x0001) +/* Default: Do obey umask, do not restore SUID/SGID/SVTX bits. */ +#define ARCHIVE_EXTRACT_PERM (0x0002) +/* Default: Do not restore mtime/atime. */ +#define ARCHIVE_EXTRACT_TIME (0x0004) +/* Default: Replace existing files. */ +#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008) +/* Default: Try create first, unlink only if create fails with EEXIST. */ +#define ARCHIVE_EXTRACT_UNLINK (0x0010) +/* Default: Do not restore ACLs. */ +#define ARCHIVE_EXTRACT_ACL (0x0020) +/* Default: Do not restore fflags. */ +#define ARCHIVE_EXTRACT_FFLAGS (0x0040) +/* Default: Do not restore xattrs. */ +#define ARCHIVE_EXTRACT_XATTR (0x0080) +/* Default: Do not try to guard against extracts redirected by symlinks. */ +/* Note: With ARCHIVE_EXTRACT_UNLINK, will remove any intermediate symlink. */ +#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100) +/* Default: Do not reject entries with '..' as path elements. */ +#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200) +/* Default: Create parent directories as needed. */ +#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400) +/* Default: Overwrite files, even if one on disk is newer. */ +#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800) +/* Detect blocks of 0 and write holes instead. */ +#define ARCHIVE_EXTRACT_SPARSE (0x1000) +/* Default: Do not restore Mac extended metadata. */ +/* This has no effect except on Mac OS. */ +#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000) +/* Default: Use HFS+ compression if it was compressed. */ +/* This has no effect except on Mac OS v10.6 or later. */ +#define ARCHIVE_EXTRACT_NO_HFS_COMPRESSION (0x4000) +/* Default: Do not use HFS+ compression if it was not compressed. */ +/* This has no effect except on Mac OS v10.6 or later. */ +#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000) + +__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, + int flags); +__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *, + struct archive * /* dest */); +__LA_DECL void archive_read_extract_set_progress_callback(struct archive *, + void (*_progress_func)(void *), void *_user_data); + +/* Record the dev/ino of a file that will not be written. This is + * generally set to the dev/ino of the archive being read. */ +__LA_DECL void archive_read_extract_set_skip_file(struct archive *, + __LA_INT64_T, __LA_INT64_T); + +/* Close the file and release most resources. */ +__LA_DECL int archive_read_close(struct archive *); +/* Release all resources and destroy the object. */ +/* Note that archive_read_free will call archive_read_close for you. */ +__LA_DECL int archive_read_free(struct archive *); +#if ARCHIVE_VERSION_NUMBER < 4000000 +/* Synonym for archive_read_free() for backwards compatibility. */ +__LA_DECL int archive_read_finish(struct archive *) __LA_DEPRECATED; +#endif + +/*- + * To create an archive: + * 1) Ask archive_write_new for an archive writer object. + * 2) Set any global properties. In particular, you should set + * the compression and format to use. + * 3) Call archive_write_open to open the file (most people + * will use archive_write_open_file or archive_write_open_fd, + * which provide convenient canned I/O callbacks for you). + * 4) For each entry: + * - construct an appropriate struct archive_entry structure + * - archive_write_header to write the header + * - archive_write_data to write the entry data + * 5) archive_write_close to close the output + * 6) archive_write_free to cleanup the writer and release resources + */ +__LA_DECL struct archive *archive_write_new(void); +__LA_DECL int archive_write_set_bytes_per_block(struct archive *, + int bytes_per_block); +__LA_DECL int archive_write_get_bytes_per_block(struct archive *); +/* XXX This is badly misnamed; suggestions appreciated. XXX */ +__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *, + int bytes_in_last_block); +__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *); + +/* The dev/ino of a file that won't be archived. This is used + * to avoid recursively adding an archive to itself. */ +__LA_DECL int archive_write_set_skip_file(struct archive *, + __LA_INT64_T, __LA_INT64_T); + +#if ARCHIVE_VERSION_NUMBER < 4000000 +__LA_DECL int archive_write_set_compression_bzip2(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_compress(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_gzip(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_lzip(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_lzma(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_none(struct archive *) + __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_program(struct archive *, + const char *cmd) __LA_DEPRECATED; +__LA_DECL int archive_write_set_compression_xz(struct archive *) + __LA_DEPRECATED; +#endif + +/* A convenience function to set the filter based on the code. */ +__LA_DECL int archive_write_add_filter(struct archive *, int filter_code); +__LA_DECL int archive_write_add_filter_by_name(struct archive *, + const char *name); +__LA_DECL int archive_write_add_filter_b64encode(struct archive *); +__LA_DECL int archive_write_add_filter_bzip2(struct archive *); +__LA_DECL int archive_write_add_filter_compress(struct archive *); +__LA_DECL int archive_write_add_filter_grzip(struct archive *); +__LA_DECL int archive_write_add_filter_gzip(struct archive *); +__LA_DECL int archive_write_add_filter_lrzip(struct archive *); +__LA_DECL int archive_write_add_filter_lzip(struct archive *); +__LA_DECL int archive_write_add_filter_lzma(struct archive *); +__LA_DECL int archive_write_add_filter_lzop(struct archive *); +__LA_DECL int archive_write_add_filter_none(struct archive *); +__LA_DECL int archive_write_add_filter_program(struct archive *, + const char *cmd); +__LA_DECL int archive_write_add_filter_uuencode(struct archive *); +__LA_DECL int archive_write_add_filter_xz(struct archive *); + + +/* A convenience function to set the format based on the code or name. */ +__LA_DECL int archive_write_set_format(struct archive *, int format_code); +__LA_DECL int archive_write_set_format_by_name(struct archive *, + const char *name); +/* To minimize link pollution, use one or more of the following. */ +__LA_DECL int archive_write_set_format_7zip(struct archive *); +__LA_DECL int archive_write_set_format_ar_bsd(struct archive *); +__LA_DECL int archive_write_set_format_ar_svr4(struct archive *); +__LA_DECL int archive_write_set_format_cpio(struct archive *); +__LA_DECL int archive_write_set_format_cpio_newc(struct archive *); +__LA_DECL int archive_write_set_format_gnutar(struct archive *); +__LA_DECL int archive_write_set_format_iso9660(struct archive *); +__LA_DECL int archive_write_set_format_mtree(struct archive *); +__LA_DECL int archive_write_set_format_mtree_classic(struct archive *); +/* TODO: int archive_write_set_format_old_tar(struct archive *); */ +__LA_DECL int archive_write_set_format_pax(struct archive *); +__LA_DECL int archive_write_set_format_pax_restricted(struct archive *); +__LA_DECL int archive_write_set_format_shar(struct archive *); +__LA_DECL int archive_write_set_format_shar_dump(struct archive *); +__LA_DECL int archive_write_set_format_ustar(struct archive *); +__LA_DECL int archive_write_set_format_v7tar(struct archive *); +__LA_DECL int archive_write_set_format_xar(struct archive *); +__LA_DECL int archive_write_set_format_zip(struct archive *); +__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *); +__LA_DECL int archive_write_zip_set_compression_store(struct archive *); +__LA_DECL int archive_write_open(struct archive *, void *, + archive_open_callback *, archive_write_callback *, + archive_close_callback *); +__LA_DECL int archive_write_open_fd(struct archive *, int _fd); +__LA_DECL int archive_write_open_filename(struct archive *, const char *_file); +__LA_DECL int archive_write_open_filename_w(struct archive *, + const wchar_t *_file); +/* A deprecated synonym for archive_write_open_filename() */ +__LA_DECL int archive_write_open_file(struct archive *, const char *_file) + __LA_DEPRECATED; +__LA_DECL int archive_write_open_FILE(struct archive *, FILE *); +/* _buffSize is the size of the buffer, _used refers to a variable that + * will be updated after each write into the buffer. */ +__LA_DECL int archive_write_open_memory(struct archive *, + void *_buffer, size_t _buffSize, size_t *_used); + +/* + * Note that the library will truncate writes beyond the size provided + * to archive_write_header or pad if the provided data is short. + */ +__LA_DECL int archive_write_header(struct archive *, + struct archive_entry *); +__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *, + const void *, size_t); + +/* This interface is currently only available for archive_write_disk handles. */ +__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *, + const void *, size_t, __LA_INT64_T); + +__LA_DECL int archive_write_finish_entry(struct archive *); +__LA_DECL int archive_write_close(struct archive *); +/* Marks the archive as FATAL so that a subsequent free() operation + * won't try to close() cleanly. Provides a fast abort capability + * when the client discovers that things have gone wrong. */ +__LA_DECL int archive_write_fail(struct archive *); +/* This can fail if the archive wasn't already closed, in which case + * archive_write_free() will implicitly call archive_write_close(). */ +__LA_DECL int archive_write_free(struct archive *); +#if ARCHIVE_VERSION_NUMBER < 4000000 +/* Synonym for archive_write_free() for backwards compatibility. */ +__LA_DECL int archive_write_finish(struct archive *) __LA_DEPRECATED; +#endif + +/* + * Set write options. + */ +/* Apply option to the format only. */ +__LA_DECL int archive_write_set_format_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option to the filter only. */ +__LA_DECL int archive_write_set_filter_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option to both the format and the filter. */ +__LA_DECL int archive_write_set_option(struct archive *_a, + const char *m, const char *o, + const char *v); +/* Apply option string to both the format and the filter. */ +__LA_DECL int archive_write_set_options(struct archive *_a, + const char *opts); + +/*- + * ARCHIVE_WRITE_DISK API + * + * To create objects on disk: + * 1) Ask archive_write_disk_new for a new archive_write_disk object. + * 2) Set any global properties. In particular, you probably + * want to set the options. + * 3) For each entry: + * - construct an appropriate struct archive_entry structure + * - archive_write_header to create the file/dir/etc on disk + * - archive_write_data to write the entry data + * 4) archive_write_free to cleanup the writer and release resources + * + * In particular, you can use this in conjunction with archive_read() + * to pull entries out of an archive and create them on disk. + */ +__LA_DECL struct archive *archive_write_disk_new(void); +/* This file will not be overwritten. */ +__LA_DECL int archive_write_disk_set_skip_file(struct archive *, + __LA_INT64_T, __LA_INT64_T); +/* Set flags to control how the next item gets created. + * This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */ +__LA_DECL int archive_write_disk_set_options(struct archive *, + int flags); +/* + * The lookup functions are given uname/uid (or gname/gid) pairs and + * return a uid (gid) suitable for this system. These are used for + * restoring ownership and for setting ACLs. The default functions + * are naive, they just return the uid/gid. These are small, so reasonable + * for applications that don't need to preserve ownership; they + * are probably also appropriate for applications that are doing + * same-system backup and restore. + */ +/* + * The "standard" lookup functions use common system calls to lookup + * the uname/gname, falling back to the uid/gid if the names can't be + * found. They cache lookups and are reasonably fast, but can be very + * large, so they are not used unless you ask for them. In + * particular, these match the specifications of POSIX "pax" and old + * POSIX "tar". + */ +__LA_DECL int archive_write_disk_set_standard_lookup(struct archive *); +/* + * If neither the default (naive) nor the standard (big) functions suit + * your needs, you can write your own and register them. Be sure to + * include a cleanup function if you have allocated private data. + */ +__LA_DECL int archive_write_disk_set_group_lookup(struct archive *, + void * /* private_data */, + __LA_INT64_T (*)(void *, const char *, __LA_INT64_T), + void (* /* cleanup */)(void *)); +__LA_DECL int archive_write_disk_set_user_lookup(struct archive *, + void * /* private_data */, + __LA_INT64_T (*)(void *, const char *, __LA_INT64_T), + void (* /* cleanup */)(void *)); +__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T); +__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T); + +/* + * ARCHIVE_READ_DISK API + * + * This is still evolving and somewhat experimental. + */ +__LA_DECL struct archive *archive_read_disk_new(void); +/* The names for symlink modes here correspond to an old BSD + * command-line argument convention: -L, -P, -H */ +/* Follow all symlinks. */ +__LA_DECL int archive_read_disk_set_symlink_logical(struct archive *); +/* Follow no symlinks. */ +__LA_DECL int archive_read_disk_set_symlink_physical(struct archive *); +/* Follow symlink initially, then not. */ +__LA_DECL int archive_read_disk_set_symlink_hybrid(struct archive *); +/* TODO: Handle Linux stat32/stat64 ugliness. */ +__LA_DECL int archive_read_disk_entry_from_file(struct archive *, + struct archive_entry *, int /* fd */, const struct stat *); +/* Look up gname for gid or uname for uid. */ +/* Default implementations are very, very stupid. */ +__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_INT64_T); +__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_INT64_T); +/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the + * results for performance. */ +__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *); +/* You can install your own lookups if you like. */ +__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *, + void * /* private_data */, + const char *(* /* lookup_fn */)(void *, __LA_INT64_T), + void (* /* cleanup_fn */)(void *)); +__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *, + void * /* private_data */, + const char *(* /* lookup_fn */)(void *, __LA_INT64_T), + void (* /* cleanup_fn */)(void *)); +/* Start traversal. */ +__LA_DECL int archive_read_disk_open(struct archive *, const char *); +__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *); +/* + * Request that current entry be visited. If you invoke it on every + * directory, you'll get a physical traversal. This is ignored if the + * current entry isn't a directory or a link to a directory. So, if + * you invoke this on every returned path, you'll get a full logical + * traversal. + */ +__LA_DECL int archive_read_disk_descend(struct archive *); +__LA_DECL int archive_read_disk_can_descend(struct archive *); +__LA_DECL int archive_read_disk_current_filesystem(struct archive *); +__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *); +__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *); +/* Request that the access time of the entry visited by travesal be restored. */ +__LA_DECL int archive_read_disk_set_atime_restored(struct archive *); +/* + * Set behavior. The "flags" argument selects optional behavior. + */ +/* Request that the access time of the entry visited by travesal be restored. + * This is the same as archive_read_disk_set_atime_restored. */ +#define ARCHIVE_READDISK_RESTORE_ATIME (0x0001) +/* Default: Do not skip an entry which has nodump flags. */ +#define ARCHIVE_READDISK_HONOR_NODUMP (0x0002) +/* Default: Skip a mac resource fork file whose prefix is "._" because of + * using copyfile. */ +#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004) +/* Default: Do not traverse mount points. */ +#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008) + +__LA_DECL int archive_read_disk_set_behavior(struct archive *, + int flags); + +/* + * Set archive_match object that will be used in archive_read_disk to + * know whether an entry should be skipped. The callback function + * _excluded_func will be invoked when an entry is skipped by the result + * of archive_match. + */ +__LA_DECL int archive_read_disk_set_matching(struct archive *, + struct archive *_matching, void (*_excluded_func) + (struct archive *, void *, struct archive_entry *), + void *_client_data); +__LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *, + int (*_metadata_filter_func)(struct archive *, void *, + struct archive_entry *), void *_client_data); + +/* + * Accessor functions to read/set various information in + * the struct archive object: + */ + +/* Number of filters in the current filter pipeline. */ +/* Filter #0 is the one closest to the format, -1 is a synonym for the + * last filter, which is always the pseudo-filter that wraps the + * client callbacks. */ +__LA_DECL int archive_filter_count(struct archive *); +__LA_DECL __LA_INT64_T archive_filter_bytes(struct archive *, int); +__LA_DECL int archive_filter_code(struct archive *, int); +__LA_DECL const char * archive_filter_name(struct archive *, int); + +#if ARCHIVE_VERSION_NUMBER < 4000000 +/* These don't properly handle multiple filters, so are deprecated and + * will eventually be removed. */ +/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */ +__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *) + __LA_DEPRECATED; +/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */ +__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *) + __LA_DEPRECATED; +/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */ +__LA_DECL const char *archive_compression_name(struct archive *) + __LA_DEPRECATED; +/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */ +__LA_DECL int archive_compression(struct archive *) + __LA_DEPRECATED; +#endif + +__LA_DECL int archive_errno(struct archive *); +__LA_DECL const char *archive_error_string(struct archive *); +__LA_DECL const char *archive_format_name(struct archive *); +__LA_DECL int archive_format(struct archive *); +__LA_DECL void archive_clear_error(struct archive *); +__LA_DECL void archive_set_error(struct archive *, int _err, + const char *fmt, ...) __LA_PRINTF(3, 4); +__LA_DECL void archive_copy_error(struct archive *dest, + struct archive *src); +__LA_DECL int archive_file_count(struct archive *); + +/* + * ARCHIVE_MATCH API + */ +__LA_DECL struct archive *archive_match_new(void); +__LA_DECL int archive_match_free(struct archive *); + +/* + * Test if archive_entry is excluded. + * This is a convenience function. This is the same as calling all + * archive_match_path_excluded, archive_match_time_excluded + * and archive_match_owner_excluded. + */ +__LA_DECL int archive_match_excluded(struct archive *, + struct archive_entry *); + +/* + * Test if pathname is excluded. The conditions are set by following functions. + */ +__LA_DECL int archive_match_path_excluded(struct archive *, + struct archive_entry *); +/* Add exclusion pathname pattern. */ +__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *); +__LA_DECL int archive_match_exclude_pattern_w(struct archive *, + const wchar_t *); +/* Add exclusion pathname pattern from file. */ +__LA_DECL int archive_match_exclude_pattern_from_file(struct archive *, + const char *, int _nullSeparator); +__LA_DECL int archive_match_exclude_pattern_from_file_w(struct archive *, + const wchar_t *, int _nullSeparator); +/* Add inclusion pathname pattern. */ +__LA_DECL int archive_match_include_pattern(struct archive *, const char *); +__LA_DECL int archive_match_include_pattern_w(struct archive *, + const wchar_t *); +/* Add inclusion pathname pattern from file. */ +__LA_DECL int archive_match_include_pattern_from_file(struct archive *, + const char *, int _nullSeparator); +__LA_DECL int archive_match_include_pattern_from_file_w(struct archive *, + const wchar_t *, int _nullSeparator); +/* + * How to get statistic information for inclusion patterns. + */ +/* Return the amount number of unmatched inclusion patterns. */ +__LA_DECL int archive_match_path_unmatched_inclusions(struct archive *); +/* Return the pattern of unmatched inclusion with ARCHIVE_OK. + * Return ARCHIVE_EOF if there is no inclusion pattern. */ +__LA_DECL int archive_match_path_unmatched_inclusions_next( + struct archive *, const char **); +__LA_DECL int archive_match_path_unmatched_inclusions_next_w( + struct archive *, const wchar_t **); + +/* + * Test if a file is excluded by its time stamp. + * The conditions are set by following functions. + */ +__LA_DECL int archive_match_time_excluded(struct archive *, + struct archive_entry *); + +/* + * Flags to tell a matching type of time stamps. These are used for + * following functinos. + */ +/* Time flag: mtime to be tested. */ +#define ARCHIVE_MATCH_MTIME (0x0100) +/* Time flag: ctime to be tested. */ +#define ARCHIVE_MATCH_CTIME (0x0200) +/* Comparison flag: Match the time if it is newer than. */ +#define ARCHIVE_MATCH_NEWER (0x0001) +/* Comparison flag: Match the time if it is older than. */ +#define ARCHIVE_MATCH_OLDER (0x0002) +/* Comparison flag: Match the time if it is equal to. */ +#define ARCHIVE_MATCH_EQUAL (0x0010) +/* Set inclusion time. */ +__LA_DECL int archive_match_include_time(struct archive *, int _flag, + time_t _sec, long _nsec); +/* Set inclusion time by a date string. */ +__LA_DECL int archive_match_include_date(struct archive *, int _flag, + const char *_datestr); +__LA_DECL int archive_match_include_date_w(struct archive *, int _flag, + const wchar_t *_datestr); +/* Set inclusion time by a particluar file. */ +__LA_DECL int archive_match_include_file_time(struct archive *, + int _flag, const char *_pathname); +__LA_DECL int archive_match_include_file_time_w(struct archive *, + int _flag, const wchar_t *_pathname); +/* Add exclusion entry. */ +__LA_DECL int archive_match_exclude_entry(struct archive *, + int _flag, struct archive_entry *); + +/* + * Test if a file is excluded by its uid ,gid, uname or gname. + * The conditions are set by following functions. + */ +__LA_DECL int archive_match_owner_excluded(struct archive *, + struct archive_entry *); +/* Add inclusion uid, gid, uname and gname. */ +__LA_DECL int archive_match_include_uid(struct archive *, __LA_INT64_T); +__LA_DECL int archive_match_include_gid(struct archive *, __LA_INT64_T); +__LA_DECL int archive_match_include_uname(struct archive *, const char *); +__LA_DECL int archive_match_include_uname_w(struct archive *, + const wchar_t *); +__LA_DECL int archive_match_include_gname(struct archive *, const char *); +__LA_DECL int archive_match_include_gname_w(struct archive *, + const wchar_t *); + +#ifdef __cplusplus +} +#endif + +/* These are meaningless outside of this header. */ +#undef __LA_DECL + +/* These need to remain defined because they're used in the + * callback type definitions. XXX Fix this. This is ugly. XXX */ +/* #undef __LA_INT64_T */ +/* #undef __LA_SSIZE_T */ + +#endif /* !ARCHIVE_H_INCLUDED */ diff --git a/src/include.new/archive_entry.h b/src/include.new/archive_entry.h new file mode 100644 index 0000000..a67371c --- /dev/null +++ b/src/include.new/archive_entry.h @@ -0,0 +1,615 @@ +/*- + * Copyright (c) 2003-2008 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/contrib/libarchive/libarchive/archive_entry.h 248616 2013-03-22 13:36:03Z mm $ + */ + +#ifndef ARCHIVE_ENTRY_H_INCLUDED +#define ARCHIVE_ENTRY_H_INCLUDED + +/* Note: Compiler will complain if this does not match archive.h! */ +#define ARCHIVE_VERSION_NUMBER 3001002 + +/* + * Note: archive_entry.h is for use outside of libarchive; the + * configuration headers (config.h, archive_platform.h, etc.) are + * purely internal. Do NOT use HAVE_XXX configuration macros to + * control the behavior of this header! If you must conditionalize, + * use predefined compiler and/or platform macros. + */ + +#include +#include /* for wchar_t */ +#include + +#if defined(_WIN32) && !defined(__CYGWIN__) +#include +#endif + +/* Get a suitable 64-bit integer type. */ +#if defined(_WIN32) && !defined(__CYGWIN__) +# define __LA_INT64_T __int64 +#else +#include +# if defined(_SCO_DS) +# define __LA_INT64_T long long +# else +# define __LA_INT64_T int64_t +# endif +#endif + +/* Get a suitable definition for mode_t */ +#if ARCHIVE_VERSION_NUMBER >= 3999000 +/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */ +# define __LA_MODE_T int +#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) +# define __LA_MODE_T unsigned short +#else +# define __LA_MODE_T mode_t +#endif + +/* + * On Windows, define LIBARCHIVE_STATIC if you're building or using a + * .lib. The default here assumes you're building a DLL. Only + * libarchive source should ever define __LIBARCHIVE_BUILD. + */ +#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC) +# ifdef __LIBARCHIVE_BUILD +# ifdef __GNUC__ +# define __LA_DECL __attribute__((dllexport)) extern +# else +# define __LA_DECL __declspec(dllexport) +# endif +# else +# ifdef __GNUC__ +# define __LA_DECL +# else +# define __LA_DECL __declspec(dllimport) +# endif +# endif +#else +/* Static libraries on all platforms and shared libraries on non-Windows. */ +# define __LA_DECL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Description of an archive entry. + * + * You can think of this as "struct stat" with some text fields added in. + * + * TODO: Add "comment", "charset", and possibly other entries that are + * supported by "pax interchange" format. However, GNU, ustar, cpio, + * and other variants don't support these features, so they're not an + * excruciatingly high priority right now. + * + * TODO: "pax interchange" format allows essentially arbitrary + * key/value attributes to be attached to any entry. Supporting + * such extensions may make this library useful for special + * applications (e.g., a package manager could attach special + * package-management attributes to each entry). + */ +struct archive; +struct archive_entry; + +/* + * File-type constants. These are returned from archive_entry_filetype() + * and passed to archive_entry_set_filetype(). + * + * These values match S_XXX defines on every platform I've checked, + * including Windows, AIX, Linux, Solaris, and BSD. They're + * (re)defined here because platforms generally don't define the ones + * they don't support. For example, Windows doesn't define S_IFLNK or + * S_IFBLK. Instead of having a mass of conditional logic and system + * checks to define any S_XXX values that aren't supported locally, + * I've just defined a new set of such constants so that + * libarchive-based applications can manipulate and identify archive + * entries properly even if the hosting platform can't store them on + * disk. + * + * These values are also used directly within some portable formats, + * such as cpio. If you find a platform that varies from these, the + * correct solution is to leave these alone and translate from these + * portable values to platform-native values when entries are read from + * or written to disk. + */ +/* + * In libarchive 4.0, we can drop the casts here. + * They're needed to work around Borland C's broken mode_t. + */ +#define AE_IFMT ((__LA_MODE_T)0170000) +#define AE_IFREG ((__LA_MODE_T)0100000) +#define AE_IFLNK ((__LA_MODE_T)0120000) +#define AE_IFSOCK ((__LA_MODE_T)0140000) +#define AE_IFCHR ((__LA_MODE_T)0020000) +#define AE_IFBLK ((__LA_MODE_T)0060000) +#define AE_IFDIR ((__LA_MODE_T)0040000) +#define AE_IFIFO ((__LA_MODE_T)0010000) + +/* + * Basic object manipulation + */ + +__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *); +/* The 'clone' function does a deep copy; all of the strings are copied too. */ +__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *); +__LA_DECL void archive_entry_free(struct archive_entry *); +__LA_DECL struct archive_entry *archive_entry_new(void); + +/* + * This form of archive_entry_new2() will pull character-set + * conversion information from the specified archive handle. The + * older archive_entry_new(void) form is equivalent to calling + * archive_entry_new2(NULL) and will result in the use of an internal + * default character-set conversion. + */ +__LA_DECL struct archive_entry *archive_entry_new2(struct archive *); + +/* + * Retrieve fields from an archive_entry. + * + * There are a number of implicit conversions among these fields. For + * example, if a regular string field is set and you read the _w wide + * character field, the entry will implicitly convert narrow-to-wide + * using the current locale. Similarly, dev values are automatically + * updated when you write devmajor or devminor and vice versa. + * + * In addition, fields can be "set" or "unset." Unset string fields + * return NULL, non-string fields have _is_set() functions to test + * whether they've been set. You can "unset" a string field by + * assigning NULL; non-string fields have _unset() functions to + * unset them. + * + * Note: There is one ambiguity in the above; string fields will + * also return NULL when implicit character set conversions fail. + * This is usually what you want. + */ +__LA_DECL time_t archive_entry_atime(struct archive_entry *); +__LA_DECL long archive_entry_atime_nsec(struct archive_entry *); +__LA_DECL int archive_entry_atime_is_set(struct archive_entry *); +__LA_DECL time_t archive_entry_birthtime(struct archive_entry *); +__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *); +__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *); +__LA_DECL time_t archive_entry_ctime(struct archive_entry *); +__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *); +__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *); +__LA_DECL dev_t archive_entry_dev(struct archive_entry *); +__LA_DECL int archive_entry_dev_is_set(struct archive_entry *); +__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *); +__LA_DECL dev_t archive_entry_devminor(struct archive_entry *); +__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *); +__LA_DECL void archive_entry_fflags(struct archive_entry *, + unsigned long * /* set */, + unsigned long * /* clear */); +__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *); +__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *); +__LA_DECL const char *archive_entry_gname(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *); +__LA_DECL const char *archive_entry_hardlink(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *); +__LA_DECL __LA_INT64_T archive_entry_ino(struct archive_entry *); +__LA_DECL __LA_INT64_T archive_entry_ino64(struct archive_entry *); +__LA_DECL int archive_entry_ino_is_set(struct archive_entry *); +__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *); +__LA_DECL time_t archive_entry_mtime(struct archive_entry *); +__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *); +__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *); +__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *); +__LA_DECL const char *archive_entry_pathname(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *); +__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *); +__LA_DECL dev_t archive_entry_rdev(struct archive_entry *); +__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *); +__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *); +__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *); +__LA_DECL __LA_INT64_T archive_entry_size(struct archive_entry *); +__LA_DECL int archive_entry_size_is_set(struct archive_entry *); +__LA_DECL const char *archive_entry_strmode(struct archive_entry *); +__LA_DECL const char *archive_entry_symlink(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *); +__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *); +__LA_DECL const char *archive_entry_uname(struct archive_entry *); +__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *); + +/* + * Set fields in an archive_entry. + * + * Note: Before libarchive 2.4, there were 'set' and 'copy' versions + * of the string setters. 'copy' copied the actual string, 'set' just + * stored the pointer. In libarchive 2.4 and later, strings are + * always copied. + */ + +__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long); +__LA_DECL void archive_entry_unset_atime(struct archive_entry *); +#if defined(_WIN32) && !defined(__CYGWIN__) +__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *); +#endif +__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long); +__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *); +__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long); +__LA_DECL void archive_entry_unset_ctime(struct archive_entry *); +__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int); +__LA_DECL void archive_entry_set_fflags(struct archive_entry *, + unsigned long /* set */, unsigned long /* clear */); +/* Returns pointer to start of first invalid token, or NULL if none. */ +/* Note that all recognized tokens are processed, regardless. */ +__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *, + const char *); +__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *, + const wchar_t *); +__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_T); +__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *); +__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *); +__LA_DECL void archive_entry_set_ino(struct archive_entry *, __LA_INT64_T); +__LA_DECL void archive_entry_set_ino64(struct archive_entry *, __LA_INT64_T); +__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *); +__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T); +__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long); +__LA_DECL void archive_entry_unset_mtime(struct archive_entry *); +__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int); +__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *); +__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T); +__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t); +__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_T); +__LA_DECL void archive_entry_unset_size(struct archive_entry *); +__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *); +__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *); +__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_INT64_T); +__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *); +__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *); +__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *); +/* + * Routines to bulk copy fields to/from a platform-native "struct + * stat." Libarchive used to just store a struct stat inside of each + * archive_entry object, but this created issues when trying to + * manipulate archives on systems different than the ones they were + * created on. + * + * TODO: On Linux and other LFS systems, provide both stat32 and + * stat64 versions of these functions and all of the macro glue so + * that archive_entry_stat is magically defined to + * archive_entry_stat32 or archive_entry_stat64 as appropriate. + */ +__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *); +__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *); + +/* + * Storage for Mac OS-specific AppleDouble metadata information. + * Apple-format tar files store a separate binary blob containing + * encoded metadata with ACL, extended attributes, etc. + * This provides a place to store that blob. + */ + +__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *); +__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t); + +/* + * ACL routines. This used to simply store and return text-format ACL + * strings, but that proved insufficient for a number of reasons: + * = clients need control over uname/uid and gname/gid mappings + * = there are many different ACL text formats + * = would like to be able to read/convert archives containing ACLs + * on platforms that lack ACL libraries + * + * This last point, in particular, forces me to implement a reasonably + * complete set of ACL support routines. + */ + +/* + * Permission bits. + */ +#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001 +#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002 +#define ARCHIVE_ENTRY_ACL_READ 0x00000004 +#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008 +#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008 +#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010 +#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010 +#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020 +#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020 +#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040 +#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080 +#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100 +#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200 +#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400 +#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800 +#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000 +#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000 +#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000 +#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000 + +#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \ + (ARCHIVE_ENTRY_ACL_EXECUTE \ + | ARCHIVE_ENTRY_ACL_WRITE \ + | ARCHIVE_ENTRY_ACL_READ) + +#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \ + (ARCHIVE_ENTRY_ACL_EXECUTE \ + | ARCHIVE_ENTRY_ACL_READ_DATA \ + | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \ + | ARCHIVE_ENTRY_ACL_WRITE_DATA \ + | ARCHIVE_ENTRY_ACL_ADD_FILE \ + | ARCHIVE_ENTRY_ACL_APPEND_DATA \ + | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \ + | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \ + | ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \ + | ARCHIVE_ENTRY_ACL_DELETE_CHILD \ + | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \ + | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \ + | ARCHIVE_ENTRY_ACL_DELETE \ + | ARCHIVE_ENTRY_ACL_READ_ACL \ + | ARCHIVE_ENTRY_ACL_WRITE_ACL \ + | ARCHIVE_ENTRY_ACL_WRITE_OWNER \ + | ARCHIVE_ENTRY_ACL_SYNCHRONIZE) + +/* + * Inheritance values (NFS4 ACLs only); included in permset. + */ +#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000 +#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000 +#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000 +#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000 +#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000 +#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000 + +#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \ + (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \ + | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \ + | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \ + | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \ + | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \ + | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS) + +/* We need to be able to specify combinations of these. */ +#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */ +#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */ +#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */ +#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */ +#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */ +#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */ +#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \ + | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) +#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \ + | ARCHIVE_ENTRY_ACL_TYPE_DENY \ + | ARCHIVE_ENTRY_ACL_TYPE_AUDIT \ + | ARCHIVE_ENTRY_ACL_TYPE_ALARM) + +/* Tag values mimic POSIX.1e */ +#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */ +#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */ +#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */ +#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */ +#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */ +#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */ +#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */ + +/* + * Set the ACL by clearing it and adding entries one at a time. + * Unlike the POSIX.1e ACL routines, you must specify the type + * (access/default) for each entry. Internally, the ACL data is just + * a soup of entries. API calls here allow you to retrieve just the + * entries of interest. This design (which goes against the spirit of + * POSIX.1e) is useful for handling archive formats that combine + * default and access information in a single ACL list. + */ +__LA_DECL void archive_entry_acl_clear(struct archive_entry *); +__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *, + int /* type */, int /* permset */, int /* tag */, + int /* qual */, const char * /* name */); +__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *, + int /* type */, int /* permset */, int /* tag */, + int /* qual */, const wchar_t * /* name */); + +/* + * To retrieve the ACL, first "reset", then repeatedly ask for the + * "next" entry. The want_type parameter allows you to request only + * certain types of entries. + */ +__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */); +__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */, + int * /* type */, int * /* permset */, int * /* tag */, + int * /* qual */, const char ** /* name */); +__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */, + int * /* type */, int * /* permset */, int * /* tag */, + int * /* qual */, const wchar_t ** /* name */); + +/* + * Construct a text-format ACL. The flags argument is a bitmask that + * can include any of the following: + * + * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries. + * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries. + * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries. + * ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in + * each ACL entry. ('star' introduced this for POSIX.1e, this flag + * also applies to NFS4.) + * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each + * default ACL entry, as used in old Solaris ACLs. + */ +#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024 +#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048 +__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *, + int /* flags */); +__LA_DECL const char *archive_entry_acl_text(struct archive_entry *, + int /* flags */); + +/* Return a count of entries matching 'want_type' */ +__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */); + +/* Return an opaque ACL object. */ +/* There's not yet anything clients can actually do with this... */ +struct archive_acl; +__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *); + +/* + * extended attributes + */ + +__LA_DECL void archive_entry_xattr_clear(struct archive_entry *); +__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *, + const char * /* name */, const void * /* value */, + size_t /* size */); + +/* + * To retrieve the xattr list, first "reset", then repeatedly ask for the + * "next" entry. + */ + +__LA_DECL int archive_entry_xattr_count(struct archive_entry *); +__LA_DECL int archive_entry_xattr_reset(struct archive_entry *); +__LA_DECL int archive_entry_xattr_next(struct archive_entry *, + const char ** /* name */, const void ** /* value */, size_t *); + +/* + * sparse + */ + +__LA_DECL void archive_entry_sparse_clear(struct archive_entry *); +__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *, + __LA_INT64_T /* offset */, __LA_INT64_T /* length */); + +/* + * To retrieve the xattr list, first "reset", then repeatedly ask for the + * "next" entry. + */ + +__LA_DECL int archive_entry_sparse_count(struct archive_entry *); +__LA_DECL int archive_entry_sparse_reset(struct archive_entry *); +__LA_DECL int archive_entry_sparse_next(struct archive_entry *, + __LA_INT64_T * /* offset */, __LA_INT64_T * /* length */); + +/* + * Utility to match up hardlinks. + * + * The 'struct archive_entry_linkresolver' is a cache of archive entries + * for files with multiple links. Here's how to use it: + * 1. Create a lookup object with archive_entry_linkresolver_new() + * 2. Tell it the archive format you're using. + * 3. Hand each archive_entry to archive_entry_linkify(). + * That function will return 0, 1, or 2 entries that should + * be written. + * 4. Call archive_entry_linkify(resolver, NULL) until + * no more entries are returned. + * 5. Call archive_entry_linkresolver_free(resolver) to free resources. + * + * The entries returned have their hardlink and size fields updated + * appropriately. If an entry is passed in that does not refer to + * a file with multiple links, it is returned unchanged. The intention + * is that you should be able to simply filter all entries through + * this machine. + * + * To make things more efficient, be sure that each entry has a valid + * nlinks value. The hardlink cache uses this to track when all links + * have been found. If the nlinks value is zero, it will keep every + * name in the cache indefinitely, which can use a lot of memory. + * + * Note that archive_entry_size() is reset to zero if the file + * body should not be written to the archive. Pay attention! + */ +struct archive_entry_linkresolver; + +/* + * There are three different strategies for marking hardlinks. + * The descriptions below name them after the best-known + * formats that rely on each strategy: + * + * "Old cpio" is the simplest, it always returns any entry unmodified. + * As far as I know, only cpio formats use this. Old cpio archives + * store every link with the full body; the onus is on the dearchiver + * to detect and properly link the files as they are restored. + * "tar" is also pretty simple; it caches a copy the first time it sees + * any link. Subsequent appearances are modified to be hardlink + * references to the first one without any body. Used by all tar + * formats, although the newest tar formats permit the "old cpio" strategy + * as well. This strategy is very simple for the dearchiver, + * and reasonably straightforward for the archiver. + * "new cpio" is trickier. It stores the body only with the last + * occurrence. The complication is that we might not + * see every link to a particular file in a single session, so + * there's no easy way to know when we've seen the last occurrence. + * The solution here is to queue one link until we see the next. + * At the end of the session, you can enumerate any remaining + * entries by calling archive_entry_linkify(NULL) and store those + * bodies. If you have a file with three links l1, l2, and l3, + * you'll get the following behavior if you see all three links: + * linkify(l1) => NULL (the resolver stores l1 internally) + * linkify(l2) => l1 (resolver stores l2, you write l1) + * linkify(l3) => l2, l3 (all links seen, you can write both). + * If you only see l1 and l2, you'll get this behavior: + * linkify(l1) => NULL + * linkify(l2) => l1 + * linkify(NULL) => l2 (at end, you retrieve remaining links) + * As the name suggests, this strategy is used by newer cpio variants. + * It's noticeably more complex for the archiver, slightly more complex + * for the dearchiver than the tar strategy, but makes it straightforward + * to restore a file using any link by simply continuing to scan until + * you see a link that is stored with a body. In contrast, the tar + * strategy requires you to rescan the archive from the beginning to + * correctly extract an arbitrary link. + */ + +__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void); +__LA_DECL void archive_entry_linkresolver_set_strategy( + struct archive_entry_linkresolver *, int /* format_code */); +__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *); +__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *, + struct archive_entry **, struct archive_entry **); +__LA_DECL struct archive_entry *archive_entry_partial_links( + struct archive_entry_linkresolver *res, unsigned int *links); + +#ifdef __cplusplus +} +#endif + +/* This is meaningless outside of this header. */ +#undef __LA_DECL + +#endif /* !ARCHIVE_ENTRY_H_INCLUDED */ diff --git a/src/include.new/arpa/ftp.h b/src/include.new/arpa/ftp.h new file mode 100644 index 0000000..1d8d977 --- /dev/null +++ b/src/include.new/arpa/ftp.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1983, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ftp.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/10.2/include/arpa/ftp.h 203965 2010-02-16 19:46:46Z imp $ + */ + +#ifndef _ARPA_FTP_H_ +#define _ARPA_FTP_H_ + +/* Definitions for FTP; see RFC-765. */ + +/* + * Reply codes. + */ +#define PRELIM 1 /* positive preliminary */ +#define COMPLETE 2 /* positive completion */ +#define CONTINUE 3 /* positive intermediate */ +#define TRANSIENT 4 /* transient negative completion */ +#define ERROR 5 /* permanent negative completion */ + +/* + * Type codes + */ +#define TYPE_A 1 /* ASCII */ +#define TYPE_E 2 /* EBCDIC */ +#define TYPE_I 3 /* image */ +#define TYPE_L 4 /* local byte size */ + +#ifdef FTP_NAMES +char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" }; +#endif + +/* + * Form codes + */ +#define FORM_N 1 /* non-print */ +#define FORM_T 2 /* telnet format effectors */ +#define FORM_C 3 /* carriage control (ASA) */ +#ifdef FTP_NAMES +char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" }; +#endif + +/* + * Structure codes + */ +#define STRU_F 1 /* file (no record structure) */ +#define STRU_R 2 /* record structure */ +#define STRU_P 3 /* page structure */ +#ifdef FTP_NAMES +char *strunames[] = {"0", "File", "Record", "Page" }; +#endif + +/* + * Mode types + */ +#define MODE_S 1 /* stream */ +#define MODE_B 2 /* block */ +#define MODE_C 3 /* compressed */ +#ifdef FTP_NAMES +char *modenames[] = {"0", "Stream", "Block", "Compressed" }; +#endif + +/* + * Record Tokens + */ +#define REC_ESC '\377' /* Record-mode Escape */ +#define REC_EOR '\001' /* Record-mode End-of-Record */ +#define REC_EOF '\002' /* Record-mode End-of-File */ + +/* + * Block Header + */ +#define BLK_EOR 0x80 /* Block is End-of-Record */ +#define BLK_EOF 0x40 /* Block is End-of-File */ +#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */ +#define BLK_RESTART 0x10 /* Block is Restart Marker */ + +#define BLK_BYTECOUNT 2 /* Bytes in this block */ + +#endif /* !_FTP_H_ */ diff --git a/src/include.new/arpa/inet.h b/src/include.new/arpa/inet.h new file mode 100644 index 0000000..7086a4a --- /dev/null +++ b/src/include.new/arpa/inet.h @@ -0,0 +1,178 @@ +/* + * ++Copyright++ 1983, 1993 + * - + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/*% + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + * $Id: inet.h 103 2016-01-12 05:32:24Z reddawg $ + * $FreeBSD: releng/10.2/include/arpa/inet.h 270838 2014-08-30 10:16:25Z ume $ + */ + +#ifndef _ARPA_INET_H_ +#define _ARPA_INET_H_ + +/* External definitions for functions in inet(3). */ + +#include +#include + +/* Required for byteorder(3) functions. */ +#include + +#define INET_ADDRSTRLEN 16 +#define INET6_ADDRSTRLEN 46 + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _IN_ADDR_T_DECLARED +typedef uint32_t in_addr_t; +#define _IN_ADDR_T_DECLARED +#endif + +#ifndef _IN_PORT_T_DECLARED +typedef uint16_t in_port_t; +#define _IN_PORT_T_DECLARED +#endif + +#if __BSD_VISIBLE +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif +#endif + +/* + * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by + * POSIX.1-2001. + */ +#ifndef _SOCKLEN_T_DECLARED +typedef __socklen_t socklen_t; +#define _SOCKLEN_T_DECLARED +#endif + +#ifndef _STRUCT_IN_ADDR_DECLARED +struct in_addr { + in_addr_t s_addr; +}; +#define _STRUCT_IN_ADDR_DECLARED +#endif + +/* XXX all new diversions!! argh!! */ +#if __BSD_VISIBLE +#define inet_addr __inet_addr +#define inet_aton __inet_aton +#define inet_lnaof __inet_lnaof +#define inet_makeaddr __inet_makeaddr +#define inet_neta __inet_neta +#define inet_netof __inet_netof +#define inet_network __inet_network +#define inet_net_ntop __inet_net_ntop +#define inet_net_pton __inet_net_pton +#define inet_cidr_ntop __inet_cidr_ntop +#define inet_cidr_pton __inet_cidr_pton +#define inet_ntoa __inet_ntoa +#define inet_ntoa_r __inet_ntoa_r +#define inet_pton __inet_pton +#define inet_ntop __inet_ntop +#define inet_nsap_addr __inet_nsap_addr +#define inet_nsap_ntoa __inet_nsap_ntoa +#endif /* __BSD_VISIBLE */ + +__BEGIN_DECLS +#ifndef _BYTEORDER_PROTOTYPED +#define _BYTEORDER_PROTOTYPED +uint32_t htonl(uint32_t); +uint16_t htons(uint16_t); +uint32_t ntohl(uint32_t); +uint16_t ntohs(uint16_t); +#endif + +in_addr_t inet_addr(const char *); +/*const*/ char *inet_ntoa(struct in_addr); +const char *inet_ntop(int, const void * __restrict, char * __restrict, + socklen_t); +int inet_pton(int, const char * __restrict, void * __restrict); + +#if __BSD_VISIBLE +int inet_aton(const char *, struct in_addr *); +in_addr_t inet_lnaof(struct in_addr); +struct in_addr inet_makeaddr(in_addr_t, in_addr_t); +char * inet_neta(in_addr_t, char *, size_t); +in_addr_t inet_netof(struct in_addr); +in_addr_t inet_network(const char *); +char *inet_net_ntop(int, const void *, int, char *, size_t); +int inet_net_pton(int, const char *, void *, size_t); +char *inet_ntoa_r(struct in_addr, char *buf, socklen_t size); +char *inet_cidr_ntop(int, const void *, int, char *, size_t); +int inet_cidr_pton(int, const char *, void *, int *); +unsigned inet_nsap_addr(const char *, unsigned char *, int); +char *inet_nsap_ntoa(int, const unsigned char *, char *); +#endif /* __BSD_VISIBLE */ +__END_DECLS + +#ifndef _BYTEORDER_FUNC_DEFINED +#define _BYTEORDER_FUNC_DEFINED +#define htonl(x) __htonl(x) +#define htons(x) __htons(x) +#define ntohl(x) __ntohl(x) +#define ntohs(x) __ntohs(x) +#endif + +#endif /* !_ARPA_INET_H_ */ + +/*! \file */ diff --git a/src/include.new/arpa/nameser.h b/src/include.new/arpa/nameser.h new file mode 100644 index 0000000..fb22cf6 --- /dev/null +++ b/src/include.new/arpa/nameser.h @@ -0,0 +1,680 @@ +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 1983, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id: nameser.h 103 2016-01-12 05:32:24Z reddawg $ + * $FreeBSD: releng/10.2/include/arpa/nameser.h 270838 2014-08-30 10:16:25Z ume $ + */ + +#ifndef _ARPA_NAMESER_H_ +#define _ARPA_NAMESER_H_ + +/*! \file */ + +#define BIND_4_COMPAT + +#include +#include +#include + +/*% + * Revision information. This is the release date in YYYYMMDD format. + * It can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not + * compare for equality; rather, use it to determine whether your libbind.a + * contains a new enough lib/nameser/ to support the feature you need. + */ + +#define __NAMESER 20090302 /*%< New interface version stamp. */ +/* + * Define constants based on RFC0883, RFC1034, RFC 1035 + */ +#define NS_PACKETSZ 512 /*%< default UDP packet size */ +#define NS_MAXDNAME 1025 /*%< maximum domain name (presentation format)*/ +#define NS_MAXMSG 65535 /*%< maximum message size */ +#define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ +#define NS_MAXLABEL 63 /*%< maximum length of domain label */ +#define NS_MAXLABELS 128 /*%< theoretical max #/labels per domain name */ +#define NS_MAXNNAME 256 /*%< maximum uncompressed (binary) domain name*/ +#define NS_MAXPADDR (sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") +#define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ +#define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ +#define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ +#define NS_INT32SZ 4 /*%< #/bytes of data in a uint32_t */ +#define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ +#define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ +#define NS_INADDRSZ 4 /*%< IPv4 T_A */ +#define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ +#define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ +#define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ +/* + * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() + * in synch with it. + */ +typedef enum __ns_sect { + ns_s_qd = 0, /*%< Query: Question. */ + ns_s_zn = 0, /*%< Update: Zone. */ + ns_s_an = 1, /*%< Query: Answer. */ + ns_s_pr = 1, /*%< Update: Prerequisites. */ + ns_s_ns = 2, /*%< Query: Name servers. */ + ns_s_ud = 2, /*%< Update: Update. */ + ns_s_ar = 3, /*%< Query|Update: Additional records. */ + ns_s_max = 4 +} ns_sect; + +/*% + * Network name (compressed or not) type. Equivilent to a pointer when used + * in a function prototype. Can be const'd. + */ +typedef u_char ns_nname[NS_MAXNNAME]; +typedef const u_char *ns_nname_ct; +typedef u_char *ns_nname_t; + +struct ns_namemap { ns_nname_ct base; int len; }; +typedef struct ns_namemap *ns_namemap_t; +typedef const struct ns_namemap *ns_namemap_ct; + +/*% + * This is a message handle. It is caller allocated and has no dynamic data. + * This structure is intended to be opaque to all but ns_parse.c, thus the + * leading _'s on the member names. Use the accessor functions, not the _'s. + */ +typedef struct __ns_msg { + const u_char *_msg, *_eom; + u_int16_t _id, _flags, _counts[ns_s_max]; + const u_char *_sections[ns_s_max]; + ns_sect _sect; + int _rrnum; + const u_char *_msg_ptr; +} ns_msg; + +/* + * This is a newmsg handle, used when constructing new messages with + * ns_newmsg_init, et al. + */ +struct ns_newmsg { + ns_msg msg; + const u_char *dnptrs[25]; + const u_char **lastdnptr; +}; +typedef struct ns_newmsg ns_newmsg; + +/* Private data structure - do not use from outside library. */ +struct _ns_flagdata { int mask, shift; }; +extern struct _ns_flagdata _ns_flagdata[]; + +/* Accessor macros - this is part of the public interface. */ + +#define ns_msg_id(handle) ((handle)._id + 0) +#define ns_msg_base(handle) ((handle)._msg + 0) +#define ns_msg_end(handle) ((handle)._eom + 0) +#define ns_msg_size(handle) ((handle)._eom - (handle)._msg) +#define ns_msg_count(handle, section) ((handle)._counts[section] + 0) + +/*% + * This is a parsed record. It is caller allocated and has no dynamic data. + */ +typedef struct __ns_rr { + char name[NS_MAXDNAME]; + u_int16_t type; + u_int16_t rr_class; + uint32_t ttl; + u_int16_t rdlength; + const u_char * rdata; +} ns_rr; + +/* + * Same thing, but using uncompressed network binary names, and real C types. + */ +typedef struct __ns_rr2 { + ns_nname nname; + size_t nnamel; + int type; + int rr_class; + u_int ttl; + int rdlength; + const u_char * rdata; +} ns_rr2; + +/* Accessor macros - this is part of the public interface. */ +#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") +#define ns_rr_nname(rr) ((const ns_nname_t)(rr).nname) +#define ns_rr_nnamel(rr) ((rr).nnamel + 0) +#define ns_rr_type(rr) ((ns_type)((rr).type + 0)) +#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) +#define ns_rr_ttl(rr) ((rr).ttl + 0) +#define ns_rr_rdlen(rr) ((rr).rdlength + 0) +#define ns_rr_rdata(rr) ((rr).rdata + 0) + +/*% + * These don't have to be in the same order as in the packet flags word, + * and they can even overlap in some cases, but they will need to be kept + * in synch with ns_parse.c:ns_flagdata[]. + */ +typedef enum __ns_flag { + ns_f_qr, /*%< Question/Response. */ + ns_f_opcode, /*%< Operation code. */ + ns_f_aa, /*%< Authoritative Answer. */ + ns_f_tc, /*%< Truncation occurred. */ + ns_f_rd, /*%< Recursion Desired. */ + ns_f_ra, /*%< Recursion Available. */ + ns_f_z, /*%< MBZ. */ + ns_f_ad, /*%< Authentic Data (DNSSEC). */ + ns_f_cd, /*%< Checking Disabled (DNSSEC). */ + ns_f_rcode, /*%< Response code. */ + ns_f_max +} ns_flag; + +/*% + * Currently defined opcodes. + */ +typedef enum __ns_opcode { + ns_o_query = 0, /*%< Standard query. */ + ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ + ns_o_status = 2, /*%< Name server status query (unsupported). */ + /* Opcode 3 is undefined/reserved. */ + ns_o_notify = 4, /*%< Zone change notification. */ + ns_o_update = 5, /*%< Zone update message. */ + ns_o_max = 6 +} ns_opcode; + +/*% + * Currently defined response codes. + */ +typedef enum __ns_rcode { + ns_r_noerror = 0, /*%< No error occurred. */ + ns_r_formerr = 1, /*%< Format error. */ + ns_r_servfail = 2, /*%< Server failure. */ + ns_r_nxdomain = 3, /*%< Name error. */ + ns_r_notimpl = 4, /*%< Unimplemented. */ + ns_r_refused = 5, /*%< Operation refused. */ + /* these are for BIND_UPDATE */ + ns_r_yxdomain = 6, /*%< Name exists */ + ns_r_yxrrset = 7, /*%< RRset exists */ + ns_r_nxrrset = 8, /*%< RRset does not exist */ + ns_r_notauth = 9, /*%< Not authoritative for zone */ + ns_r_notzone = 10, /*%< Zone of record different from zone section */ + ns_r_max = 11, + /* The following are EDNS extended rcodes */ + ns_r_badvers = 16, + /* The following are TSIG errors */ + ns_r_badsig = 16, + ns_r_badkey = 17, + ns_r_badtime = 18 +} ns_rcode; + +/* BIND_UPDATE */ +typedef enum __ns_update_operation { + ns_uop_delete = 0, + ns_uop_add = 1, + ns_uop_max = 2 +} ns_update_operation; + +/*% + * This structure is used for TSIG authenticated messages + */ +struct ns_tsig_key { + char name[NS_MAXDNAME], alg[NS_MAXDNAME]; + unsigned char *data; + int len; +}; +typedef struct ns_tsig_key ns_tsig_key; + +/*% + * This structure is used for TSIG authenticated TCP messages + */ +struct ns_tcp_tsig_state { + int counter; + struct dst_key *key; + void *ctx; + unsigned char sig[NS_PACKETSZ]; + int siglen; +}; +typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; + +#define NS_TSIG_FUDGE 300 +#define NS_TSIG_TCP_COUNT 100 +#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT" + +#define NS_TSIG_ERROR_NO_TSIG -10 +#define NS_TSIG_ERROR_NO_SPACE -11 +#define NS_TSIG_ERROR_FORMERR -12 + +/*% + * Currently defined type values for resources and queries. + */ +typedef enum __ns_type { + ns_t_invalid = 0, /*%< Cookie. */ + ns_t_a = 1, /*%< Host address. */ + ns_t_ns = 2, /*%< Authoritative server. */ + ns_t_md = 3, /*%< Mail destination. */ + ns_t_mf = 4, /*%< Mail forwarder. */ + ns_t_cname = 5, /*%< Canonical name. */ + ns_t_soa = 6, /*%< Start of authority zone. */ + ns_t_mb = 7, /*%< Mailbox domain name. */ + ns_t_mg = 8, /*%< Mail group member. */ + ns_t_mr = 9, /*%< Mail rename name. */ + ns_t_null = 10, /*%< Null resource record. */ + ns_t_wks = 11, /*%< Well known service. */ + ns_t_ptr = 12, /*%< Domain name pointer. */ + ns_t_hinfo = 13, /*%< Host information. */ + ns_t_minfo = 14, /*%< Mailbox information. */ + ns_t_mx = 15, /*%< Mail routing information. */ + ns_t_txt = 16, /*%< Text strings. */ + ns_t_rp = 17, /*%< Responsible person. */ + ns_t_afsdb = 18, /*%< AFS cell database. */ + ns_t_x25 = 19, /*%< X_25 calling address. */ + ns_t_isdn = 20, /*%< ISDN calling address. */ + ns_t_rt = 21, /*%< Router. */ + ns_t_nsap = 22, /*%< NSAP address. */ + ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ + ns_t_sig = 24, /*%< Security signature. */ + ns_t_key = 25, /*%< Security key. */ + ns_t_px = 26, /*%< X.400 mail mapping. */ + ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ + ns_t_aaaa = 28, /*%< IPv6 Address. */ + ns_t_loc = 29, /*%< Location Information. */ + ns_t_nxt = 30, /*%< Next domain (security). */ + ns_t_eid = 31, /*%< Endpoint identifier. */ + ns_t_nimloc = 32, /*%< Nimrod Locator. */ + ns_t_srv = 33, /*%< Server Selection. */ + ns_t_atma = 34, /*%< ATM Address */ + ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ + ns_t_kx = 36, /*%< Key Exchange */ + ns_t_cert = 37, /*%< Certification record */ + ns_t_a6 = 38, /*%< IPv6 address (experimental) */ + ns_t_dname = 39, /*%< Non-terminal DNAME */ + ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ + ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ + ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ + ns_t_ds = 43, /*%< Delegation Signer */ + ns_t_sshfp = 44, /*%< SSH Fingerprint */ + ns_t_ipseckey = 45, /*%< IPSEC Key */ + ns_t_rrsig = 46, /*%< RRset Signature */ + ns_t_nsec = 47, /*%< Negative security */ + ns_t_dnskey = 48, /*%< DNS Key */ + ns_t_dhcid = 49, /*%< Dynamic host configuratin identifier */ + ns_t_nsec3 = 50, /*%< Negative security type 3 */ + ns_t_nsec3param = 51, /*%< Negative security type 3 parameters */ + ns_t_hip = 55, /*%< Host Identity Protocol */ + ns_t_spf = 99, /*%< Sender Policy Framework */ + ns_t_tkey = 249, /*%< Transaction key */ + ns_t_tsig = 250, /*%< Transaction signature. */ + ns_t_ixfr = 251, /*%< Incremental zone transfer. */ + ns_t_axfr = 252, /*%< Transfer zone of authority. */ + ns_t_mailb = 253, /*%< Transfer mailbox records. */ + ns_t_maila = 254, /*%< Transfer mail agent records. */ + ns_t_any = 255, /*%< Wildcard match. */ + ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ + ns_t_dlv = 32769, /*%< DNSSEC look-aside validatation. */ + ns_t_max = 65536 +} ns_type; + +/* Exclusively a QTYPE? (not also an RTYPE) */ +#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \ + (t) == ns_t_mailb || (t) == ns_t_maila) +/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */ +#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt) +/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */ +#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t)) +#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr) +#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ + (t) == ns_t_zxfr) + +/*% + * Values for class field + */ +typedef enum __ns_class { + ns_c_invalid = 0, /*%< Cookie. */ + ns_c_in = 1, /*%< Internet. */ + ns_c_2 = 2, /*%< unallocated/unsupported. */ + ns_c_chaos = 3, /*%< MIT Chaos-net. */ + ns_c_hs = 4, /*%< MIT Hesiod. */ + /* Query class values which do not appear in resource records */ + ns_c_none = 254, /*%< for prereq. sections in update requests */ + ns_c_any = 255, /*%< Wildcard match. */ + ns_c_max = 65536 +} ns_class; + +/* DNSSEC constants. */ + +typedef enum __ns_key_types { + ns_kt_rsa = 1, /*%< key type RSA/MD5 */ + ns_kt_dh = 2, /*%< Diffie Hellman */ + ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ + ns_kt_private = 254 /*%< Private key type starts with OID */ +} ns_key_types; + +typedef enum __ns_cert_types { + cert_t_pkix = 1, /*%< PKIX (X.509v3) */ + cert_t_spki = 2, /*%< SPKI */ + cert_t_pgp = 3, /*%< PGP */ + cert_t_url = 253, /*%< URL private type */ + cert_t_oid = 254 /*%< OID private type */ +} ns_cert_types; + +/* Flags field of the KEY RR rdata. */ +#define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ +#define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ +#define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ +#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ +#define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ +/* The type bits can also be interpreted independently, as single bits: */ +#define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ +#define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ +#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ +#define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ +#define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ +#define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ +#define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ +#define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ +#define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ +#define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ +#define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ +#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ + NS_KEY_RESERVED4 | \ + NS_KEY_RESERVED5 | \ + NS_KEY_RESERVED8 | \ + NS_KEY_RESERVED9 | \ + NS_KEY_RESERVED10 | \ + NS_KEY_RESERVED11 ) +#define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ +/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ +#define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ +#define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ +#define NS_ALG_DSA 3 /*%< DSA KEY */ +#define NS_ALG_DSS NS_ALG_DSA +#define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ +#define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ +/* Protocol values */ +/* value 0 is reserved */ +#define NS_KEY_PROT_TLS 1 +#define NS_KEY_PROT_EMAIL 2 +#define NS_KEY_PROT_DNSSEC 3 +#define NS_KEY_PROT_IPSEC 4 +#define NS_KEY_PROT_ANY 255 + +/* Signatures */ +#define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ +#define NS_MD5RSA_MAX_BITS 4096 + /* Total of binary mod and exp */ +#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) + /* Max length of text sig block */ +#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4) +#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8) +#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8) + +#define NS_DSA_SIG_SIZE 41 +#define NS_DSA_MIN_SIZE 213 +#define NS_DSA_MAX_BYTES 405 + +/* Offsets into SIG record rdata to find various values */ +#define NS_SIG_TYPE 0 /*%< Type flags */ +#define NS_SIG_ALG 2 /*%< Algorithm */ +#define NS_SIG_LABELS 3 /*%< How many labels in name */ +#define NS_SIG_OTTL 4 /*%< Original TTL */ +#define NS_SIG_EXPIR 8 /*%< Expiration time */ +#define NS_SIG_SIGNED 12 /*%< Signature time */ +#define NS_SIG_FOOT 16 /*%< Key footprint */ +#define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ +/* How RR types are represented as bit-flags in NXT records */ +#define NS_NXT_BITS 8 +#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_MAX 127 + +/*% + * EDNS0 extended flags and option codes, host order. + */ +#define NS_OPT_DNSSEC_OK 0x8000U +#define NS_OPT_NSID 3 + +/*% + * Inline versions of get/put short/long. Pointer is advanced. + */ +#define NS_GET16(s, cp) do { \ + register const u_char *t_cp = (const u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += NS_INT16SZ; \ +} while (0) + +#define NS_GET32(l, cp) do { \ + register const u_char *t_cp = (const u_char *)(cp); \ + (l) = ((uint32_t)t_cp[0] << 24) \ + | ((uint32_t)t_cp[1] << 16) \ + | ((uint32_t)t_cp[2] << 8) \ + | ((uint32_t)t_cp[3]) \ + ; \ + (cp) += NS_INT32SZ; \ +} while (0) + +#define NS_PUT16(s, cp) do { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += NS_INT16SZ; \ +} while (0) + +#define NS_PUT32(l, cp) do { \ + register uint32_t t_l = (uint32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += NS_INT32SZ; \ +} while (0) + +/*% + * ANSI C identifier hiding for bind's lib/nameser. + */ +#define ns_msg_getflag __ns_msg_getflag +#define ns_get16 __ns_get16 +#define ns_get32 __ns_get32 +#define ns_put16 __ns_put16 +#define ns_put32 __ns_put32 +#define ns_initparse __ns_initparse +#define ns_skiprr __ns_skiprr +#define ns_parserr __ns_parserr +#define ns_parserr2 __ns_parserr2 +#define ns_sprintrr __ns_sprintrr +#define ns_sprintrrf __ns_sprintrrf +#define ns_format_ttl __ns_format_ttl +#define ns_parse_ttl __ns_parse_ttl +#if 0 +#define ns_datetosecs __ns_datetosecs +#endif +#define ns_name_ntol __ns_name_ntol +#define ns_name_ntop __ns_name_ntop +#define ns_name_pton __ns_name_pton +#define ns_name_pton2 __ns_name_pton2 +#define ns_name_unpack __ns_name_unpack +#define ns_name_unpack2 __ns_name_unpack2 +#define ns_name_pack __ns_name_pack +#define ns_name_compress __ns_name_compress +#define ns_name_uncompress __ns_name_uncompress +#define ns_name_skip __ns_name_skip +#define ns_name_rollback __ns_name_rollback +#define ns_name_length __ns_name_length +#define ns_name_eq __ns_name_eq +#define ns_name_owned __ns_name_owned +#define ns_name_map __ns_name_map +#define ns_name_labels __ns_name_labels +#if 0 +#define ns_sign __ns_sign +#define ns_sign2 __ns_sign2 +#define ns_sign_tcp __ns_sign_tcp +#define ns_sign_tcp2 __ns_sign_tcp2 +#define ns_sign_tcp_init __ns_sign_tcp_init +#define ns_find_tsig __ns_find_tsig +#define ns_verify __ns_verify +#define ns_verify_tcp __ns_verify_tcp +#define ns_verify_tcp_init __ns_verify_tcp_init +#endif +#define ns_samedomain __ns_samedomain +#if 0 +#define ns_subdomain __ns_subdomain +#endif +#define ns_makecanon __ns_makecanon +#define ns_samename __ns_samename +#define ns_newmsg_init __ns_newmsg_init +#define ns_newmsg_copy __ns_newmsg_copy +#define ns_newmsg_id __ns_newmsg_id +#define ns_newmsg_flag __ns_newmsg_flag +#define ns_newmsg_q __ns_newmsg_q +#define ns_newmsg_rr __ns_newmsg_rr +#define ns_newmsg_done __ns_newmsg_done +#define ns_rdata_unpack __ns_rdata_unpack +#define ns_rdata_equal __ns_rdata_equal +#define ns_rdata_refers __ns_rdata_refers + +__BEGIN_DECLS +int ns_msg_getflag(ns_msg, int); +u_int ns_get16(const u_char *); +u_long ns_get32(const u_char *); +void ns_put16(u_int, u_char *); +void ns_put32(u_long, u_char *); +int ns_initparse(const u_char *, int, ns_msg *); +int ns_skiprr(const u_char *, const u_char *, ns_sect, int); +int ns_parserr(ns_msg *, ns_sect, int, ns_rr *); +int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *); +int ns_sprintrr(const ns_msg *, const ns_rr *, + const char *, const char *, char *, size_t); +int ns_sprintrrf(const u_char *, size_t, const char *, + ns_class, ns_type, u_long, const u_char *, + size_t, const char *, const char *, + char *, size_t); +int ns_format_ttl(u_long, char *, size_t); +int ns_parse_ttl(const char *, u_long *); +#if 0 +uint32_t ns_datetosecs(const char *cp, int *errp); +#endif +int ns_name_ntol(const u_char *, u_char *, size_t); +int ns_name_ntop(const u_char *, char *, size_t); +int ns_name_pton(const char *, u_char *, size_t); +int ns_name_pton2(const char *, u_char *, size_t, size_t *); +int ns_name_unpack(const u_char *, const u_char *, + const u_char *, u_char *, size_t); +int ns_name_unpack2(const u_char *, const u_char *, + const u_char *, u_char *, size_t, + size_t *); +int ns_name_pack(const u_char *, u_char *, int, + const u_char **, const u_char **); +int ns_name_uncompress(const u_char *, const u_char *, + const u_char *, char *, size_t); +int ns_name_compress(const char *, u_char *, size_t, + const u_char **, const u_char **); +int ns_name_skip(const u_char **, const u_char *); +void ns_name_rollback(const u_char *, const u_char **, + const u_char **); +ssize_t ns_name_length(ns_nname_ct, size_t); +int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t); +int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int); +int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int); +int ns_name_labels(ns_nname_ct, size_t); +#if 0 +int ns_sign(u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t); +int ns_sign2(u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t, + u_char **, u_char **); +int ns_sign_tcp(u_char *, int *, int, int, + ns_tcp_tsig_state *, int); +int ns_sign_tcp2(u_char *, int *, int, int, + ns_tcp_tsig_state *, int, + u_char **, u_char **); +int ns_sign_tcp_init(void *, const u_char *, int, + ns_tcp_tsig_state *); +u_char *ns_find_tsig(u_char *, u_char *); +int ns_verify(u_char *, int *, void *, + const u_char *, int, u_char *, int *, + time_t *, int); +int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int); +int ns_verify_tcp_init(void *, const u_char *, int, + ns_tcp_tsig_state *); +#endif +int ns_samedomain(const char *, const char *); +#if 0 +int ns_subdomain(const char *, const char *); +#endif +int ns_makecanon(const char *, char *, size_t); +int ns_samename(const char *, const char *); +int ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *); +int ns_newmsg_copy(ns_newmsg *, ns_msg *); +void ns_newmsg_id(ns_newmsg *handle, u_int16_t id); +void ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value); +int ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname, + ns_type qtype, ns_class qclass); +int ns_newmsg_rr(ns_newmsg *handle, ns_sect sect, + ns_nname_ct name, ns_type type, + ns_class rr_class, uint32_t ttl, + u_int16_t rdlen, const u_char *rdata); +size_t ns_newmsg_done(ns_newmsg *handle); +ssize_t ns_rdata_unpack(const u_char *, const u_char *, ns_type, + const u_char *, size_t, u_char *, size_t); +int ns_rdata_equal(ns_type, + const u_char *, size_t, + const u_char *, size_t); +int ns_rdata_refers(ns_type, + const u_char *, size_t, + const u_char *); +__END_DECLS + +#ifdef BIND_4_COMPAT +#include +#endif + +#endif /* !_ARPA_NAMESER_H_ */ +/*! \file */ diff --git a/src/include.new/arpa/nameser_compat.h b/src/include.new/arpa/nameser_compat.h new file mode 100644 index 0000000..2be8233 --- /dev/null +++ b/src/include.new/arpa/nameser_compat.h @@ -0,0 +1,199 @@ +/* Copyright (c) 1983, 1989 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*% + * from nameser.h 8.1 (Berkeley) 6/2/93 + * $Id: nameser_compat.h 103 2016-01-12 05:32:24Z reddawg $ + * $FreeBSD: releng/10.2/include/arpa/nameser_compat.h 270838 2014-08-30 10:16:25Z ume $ + */ + +#ifndef _ARPA_NAMESER_COMPAT_ +#define _ARPA_NAMESER_COMPAT_ + +#define __BIND 19950621 /*%< (DEAD) interface version stamp. */ + +#include + +#if !defined(_BYTE_ORDER) || \ + (_BYTE_ORDER != _BIG_ENDIAN && _BYTE_ORDER != _LITTLE_ENDIAN && \ + _BYTE_ORDER != _PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ +#error "Undefined or invalid _BYTE_ORDER"; +#endif + +/*% + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /*%< query identification number */ +#if _BYTE_ORDER == _BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /*%< response flag */ + unsigned opcode: 4; /*%< purpose of message */ + unsigned aa: 1; /*%< authoritative answer */ + unsigned tc: 1; /*%< truncated message */ + unsigned rd: 1; /*%< recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /*%< recursion available */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned rcode :4; /*%< response code */ +#endif +#if _BYTE_ORDER == _LITTLE_ENDIAN || _BYTE_ORDER == _PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /*%< recursion desired */ + unsigned tc :1; /*%< truncated message */ + unsigned aa :1; /*%< authoritative answer */ + unsigned opcode :4; /*%< purpose of message */ + unsigned qr :1; /*%< response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /*%< response code */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /*%< recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /*%< number of question entries */ + unsigned ancount :16; /*%< number of answer entries */ + unsigned nscount :16; /*%< number of authority entries */ + unsigned arcount :16; /*%< number of resource entries */ +} HEADER; + +#define PACKETSZ NS_PACKETSZ +#define MAXDNAME NS_MAXDNAME +#define MAXCDNAME NS_MAXCDNAME +#define MAXLABEL NS_MAXLABEL +#define HFIXEDSZ NS_HFIXEDSZ +#define QFIXEDSZ NS_QFIXEDSZ +#define RRFIXEDSZ NS_RRFIXEDSZ +#define INT32SZ NS_INT32SZ +#define INT16SZ NS_INT16SZ +#define INT8SZ NS_INT8SZ +#define INADDRSZ NS_INADDRSZ +#define IN6ADDRSZ NS_IN6ADDRSZ +#define INDIR_MASK NS_CMPRSFLGS +#define NAMESERVER_PORT NS_DEFAULTPORT + +#define S_ZONE ns_s_zn +#define S_PREREQ ns_s_pr +#define S_UPDATE ns_s_ud +#define S_ADDT ns_s_ar + +#define QUERY ns_o_query +#define IQUERY ns_o_iquery +#define STATUS ns_o_status +#define NS_NOTIFY_OP ns_o_notify +#define NS_UPDATE_OP ns_o_update + +#define NOERROR ns_r_noerror +#define FORMERR ns_r_formerr +#define SERVFAIL ns_r_servfail +#define NXDOMAIN ns_r_nxdomain +#define NOTIMP ns_r_notimpl +#define REFUSED ns_r_refused +#define YXDOMAIN ns_r_yxdomain +#define YXRRSET ns_r_yxrrset +#define NXRRSET ns_r_nxrrset +#define NOTAUTH ns_r_notauth +#define NOTZONE ns_r_notzone +/*#define BADSIG ns_r_badsig*/ +/*#define BADKEY ns_r_badkey*/ +/*#define BADTIME ns_r_badtime*/ + + +#define DELETE ns_uop_delete +#define ADD ns_uop_add + +#define T_A ns_t_a +#define T_NS ns_t_ns +#define T_MD ns_t_md +#define T_MF ns_t_mf +#define T_CNAME ns_t_cname +#define T_SOA ns_t_soa +#define T_MB ns_t_mb +#define T_MG ns_t_mg +#define T_MR ns_t_mr +#define T_NULL ns_t_null +#define T_WKS ns_t_wks +#define T_PTR ns_t_ptr +#define T_HINFO ns_t_hinfo +#define T_MINFO ns_t_minfo +#define T_MX ns_t_mx +#define T_TXT ns_t_txt +#define T_RP ns_t_rp +#define T_AFSDB ns_t_afsdb +#define T_X25 ns_t_x25 +#define T_ISDN ns_t_isdn +#define T_RT ns_t_rt +#define T_NSAP ns_t_nsap +#define T_NSAP_PTR ns_t_nsap_ptr +#define T_SIG ns_t_sig +#define T_KEY ns_t_key +#define T_PX ns_t_px +#define T_GPOS ns_t_gpos +#define T_AAAA ns_t_aaaa +#define T_LOC ns_t_loc +#define T_NXT ns_t_nxt +#define T_EID ns_t_eid +#define T_NIMLOC ns_t_nimloc +#define T_SRV ns_t_srv +#define T_ATMA ns_t_atma +#define T_NAPTR ns_t_naptr +#define T_A6 ns_t_a6 +#define T_OPT ns_t_opt +#define T_TSIG ns_t_tsig +#define T_IXFR ns_t_ixfr +#define T_AXFR ns_t_axfr +#define T_MAILB ns_t_mailb +#define T_MAILA ns_t_maila +#define T_ANY ns_t_any + +#define C_IN ns_c_in +#define C_CHAOS ns_c_chaos +#define C_HS ns_c_hs +/* BIND_UPDATE */ +#define C_NONE ns_c_none +#define C_ANY ns_c_any + +#define GETSHORT NS_GET16 +#define GETLONG NS_GET32 +#define PUTSHORT NS_PUT16 +#define PUTLONG NS_PUT32 + +#endif /* _ARPA_NAMESER_COMPAT_ */ +/*! \file */ diff --git a/src/include.new/arpa/telnet.h b/src/include.new/arpa/telnet.h new file mode 100644 index 0000000..bf01736 --- /dev/null +++ b/src/include.new/arpa/telnet.h @@ -0,0 +1,348 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + * $FreeBSD: releng/10.2/contrib/telnet/arpa/telnet.h 275508 2014-12-05 12:23:29Z ngie $ + */ + +#ifndef _ARPA_TELNET_H_ +#define _ARPA_TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +const char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", + 0 +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_TN3270E 40 /* RFC2355 - TN3270 Enhancements */ +#define TELOPT_CHARSET 42 /* RFC2066 - Charset */ +#define TELOPT_COMPORT 44 /* RFC2217 - Com Port Control */ +#define TELOPT_KERMIT 47 /* RFC2840 - Kermit */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + +#define COMPORT_SET_BAUDRATE 1 /* RFC2217 - Com Port Set Baud Rate */ + +#define NTELOPTS (1+TELOPT_KERMIT) +#ifdef TELOPTS +const char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", "TN3270E", "XAUTH", "CHARSET", + "RSP", "COM-PORT", "SLE", "STARTTLS", "KERMIT", + 0 +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_KERMIT +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 +#define SLC_MCL 19 +#define SLC_MCR 20 +#define SLC_MCWL 21 +#define SLC_MCWR 22 +#define SLC_MCBOL 23 +#define SLC_MCEOL 24 +#define SLC_INSRT 25 +#define SLC_OVER 26 +#define SLC_ECR 27 +#define SLC_EWR 28 +#define SLC_EBOL 29 +#define SLC_EEOL 30 + +#define NSLC 30 + +/* + * For backwards compatibility, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \ + "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \ + "MCEOL", "INSRT", "OVER", "ECR", "EWR", \ + "EBOL", "EEOL", \ + 0 + +#ifdef SLC_NAMES +const char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_SRA 6 +#define AUTHTYPE_CNT 7 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +const char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", NULL, "SRA", + 0 +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you end encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +const char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0 +}; +const char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", + 0 +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* !_TELNET_H_ */ diff --git a/src/include.new/arpa/tftp.h b/src/include.new/arpa/tftp.h new file mode 100644 index 0000000..1c18e6c --- /dev/null +++ b/src/include.new/arpa/tftp.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/10.2/include/arpa/tftp.h 250887 2013-05-21 21:20:10Z ed $ + */ + +#ifndef _ARPA_TFTP_H_ +#define _ARPA_TFTP_H_ + +#include + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define ERROR 05 /* error code */ +#define OACK 06 /* option acknowledgement */ + +struct tftphdr { + unsigned short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + unsigned short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } __packed th_u; + char th_data[1]; /* data or error string */ +} __packed; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ +#define EOPTNEG 8 /* option negotiation failed */ + +#endif /* !_TFTP_H_ */ diff --git a/src/include.new/asn1-common.h b/src/include.new/asn1-common.h new file mode 100644 index 0000000..4083ebc --- /dev/null +++ b/src/include.new/asn1-common.h @@ -0,0 +1,79 @@ +/* $Id$ */ + +#include +#include +#include + +#ifndef __asn1_common_definitions__ +#define __asn1_common_definitions__ + +typedef struct heim_integer { + size_t length; + void *data; + int negative; +} heim_integer; + +typedef struct heim_octet_string { + size_t length; + void *data; +} heim_octet_string; + +typedef char *heim_general_string; +typedef char *heim_utf8_string; +typedef struct heim_octet_string heim_printable_string; +typedef struct heim_octet_string heim_ia5_string; + +typedef struct heim_bmp_string { + size_t length; + uint16_t *data; +} heim_bmp_string; + +typedef struct heim_universal_string { + size_t length; + uint32_t *data; +} heim_universal_string; + +typedef char *heim_visible_string; + +typedef struct heim_oid { + size_t length; + unsigned *components; +} heim_oid; + +typedef struct heim_bit_string { + size_t length; + void *data; +} heim_bit_string; + +typedef struct heim_octet_string heim_any; +typedef struct heim_octet_string heim_any_set; + +#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \ + do { \ + (BL) = length_##T((S)); \ + (B) = malloc((BL)); \ + if((B) == NULL) { \ + (R) = ENOMEM; \ + } else { \ + (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ + (S), (L)); \ + if((R) != 0) { \ + free((B)); \ + (B) = NULL; \ + } \ + } \ + } while (0) + +#ifdef _WIN32 +#ifndef ASN1_LIB +#define ASN1EXP __declspec(dllimport) +#else +#define ASN1EXP +#endif +#define ASN1CALL __stdcall +#else +#define ASN1EXP +#define ASN1CALL +#endif + +#endif diff --git a/src/include.new/asn1_err.h b/src/include.new/asn1_err.h new file mode 100644 index 0000000..8bd812b --- /dev/null +++ b/src/include.new/asn1_err.h @@ -0,0 +1,40 @@ +/* Generated from /usr/src/kerberos5/lib/libasn1/../../../crypto/heimdal/lib/asn1/asn1_err.et */ +/* $Id: asn1_err.h 103 2016-01-12 05:32:24Z reddawg $ */ + +#ifndef __asn1_err_h__ +#define __asn1_err_h__ + +struct et_list; + +void initialize_asn1_error_table_r(struct et_list **); + +void initialize_asn1_error_table(void); +#define init_asn1_err_tbl initialize_asn1_error_table + +typedef enum asn1_error_number{ + ASN1_BAD_TIMEFORMAT = 1859794432, + ASN1_MISSING_FIELD = 1859794433, + ASN1_MISPLACED_FIELD = 1859794434, + ASN1_TYPE_MISMATCH = 1859794435, + ASN1_OVERFLOW = 1859794436, + ASN1_OVERRUN = 1859794437, + ASN1_BAD_ID = 1859794438, + ASN1_BAD_LENGTH = 1859794439, + ASN1_BAD_FORMAT = 1859794440, + ASN1_PARSE_ERROR = 1859794441, + ASN1_EXTRA_DATA = 1859794442, + ASN1_BAD_CHARACTER = 1859794443, + ASN1_MIN_CONSTRAINT = 1859794444, + ASN1_MAX_CONSTRAINT = 1859794445, + ASN1_EXACT_CONSTRAINT = 1859794446, + ASN1_INDEF_OVERRUN = 1859794447, + ASN1_INDEF_UNDERRUN = 1859794448, + ASN1_GOT_BER = 1859794449, + ASN1_INDEF_EXTRA_DATA = 1859794450 +} asn1_error_number; + +#define ERROR_TABLE_BASE_asn1 1859794432 + +#define COM_ERR_BINDDOMAIN_asn1 "heim_com_err1859794432" + +#endif /* __asn1_err_h__ */ diff --git a/src/include.new/assert.h b/src/include.new/assert.h new file mode 100644 index 0000000..d1d3d7a --- /dev/null +++ b/src/include.new/assert.h @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)assert.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: releng/10.2/include/assert.h 228955 2011-12-29 14:41:17Z ed $ + */ + +#include + +/* + * Unlike other ANSI header files, may usefully be included + * multiple times, with and without NDEBUG defined. + */ + +#undef assert +#undef _assert + +#ifdef NDEBUG +#define assert(e) ((void)0) +#define _assert(e) ((void)0) +#else +#define _assert(e) assert(e) + +#define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \ + __LINE__, #e)) +#endif /* NDEBUG */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +/* + * Static assertions. In principle we could define static_assert for + * C++ older than C++11, but this breaks if _Static_assert is + * implemented as a macro. + * + * C++ template parameters may contain commas, even if not enclosed in + * parentheses, causing the _Static_assert macro to be invoked with more + * than two parameters. + */ +#if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus) +#define static_assert _Static_assert +#endif + +__BEGIN_DECLS +void __assert(const char *, const char *, int, const char *) __dead2; +__END_DECLS + +#endif /* !_ASSERT_H_ */ diff --git a/src/include.new/base64.h b/src/include.new/base64.h new file mode 100644 index 0000000..dfae4c1 --- /dev/null +++ b/src/include.new/base64.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#ifndef _BASE64_H_ +#define _BASE64_H_ + +#ifndef ROKEN_LIB_FUNCTION +#ifdef _WIN32 +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl +#else +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL +#endif +#endif + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +base64_encode(const void *, int, char **); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +base64_decode(const char *, void *); + +#endif diff --git a/src/include.new/bitstring.h b/src/include.new/bitstring.h new file mode 100644 index 0000000..5c99a98 --- /dev/null +++ b/src/include.new/bitstring.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2003 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/include/bitstring.h 116306 2003-06-13 19:40:13Z phk $ + */ + +#ifndef _BITSTRING_H_ +#define _BITSTRING_H_ + +#include + +#endif /* _BITSTRING_H_ */ + diff --git a/src/include.new/bluetooth.h b/src/include.new/bluetooth.h new file mode 100644 index 0000000..1db5d22 --- /dev/null +++ b/src/include.new/bluetooth.h @@ -0,0 +1,216 @@ +/* + * bluetooth.h + */ + +/*- + * Copyright (c) 2001-2009 Maksim Yevmenkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: bluetooth.h 103 2016-01-12 05:32:24Z reddawg $ + * $FreeBSD: releng/10.2/lib/libbluetooth/bluetooth.h 213042 2010-09-22 23:41:02Z emax $ + */ + +#ifndef _BLUETOOTH_H_ +#define _BLUETOOTH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/* + * Linux BlueZ compatibility + */ + +#define bacmp(ba1, ba2) memcmp((ba1), (ba2), sizeof(bdaddr_t)) +#define bacpy(dst, src) memcpy((dst), (src), sizeof(bdaddr_t)) +#define ba2str(ba, str) bt_ntoa((ba), (str)) +#define str2ba(str, ba) (bt_aton((str), (ba)) == 1? 0 : -1) +#define htobs(d) htole16(d) +#define htobl(d) htole32(d) +#define btohs(d) le16toh(d) +#define btohl(d) le32toh(d) + +/* + * Interface to the outside world + */ + +struct hostent * bt_gethostbyname (char const *name); +struct hostent * bt_gethostbyaddr (char const *addr, int len, int type); +struct hostent * bt_gethostent (void); +void bt_sethostent (int stayopen); +void bt_endhostent (void); + +struct protoent * bt_getprotobyname (char const *name); +struct protoent * bt_getprotobynumber (int proto); +struct protoent * bt_getprotoent (void); +void bt_setprotoent (int stayopen); +void bt_endprotoent (void); + +char const * bt_ntoa (bdaddr_t const *ba, char *str); +int bt_aton (char const *str, bdaddr_t *ba); + +/* bt_devXXXX() functions (inspired by NetBSD) */ +int bt_devaddr (char const *devname, bdaddr_t *addr); +int bt_devname (char *devname, bdaddr_t const *addr); + +/* + * Bluetooth HCI functions + */ + +#define HCI_DEVMAX 32 /* arbitrary */ +#define HCI_DEVNAME_SIZE NG_NODESIZ +#define HCI_DEVFEATURES_SIZE NG_HCI_FEATURES_SIZE + +struct bt_devinfo +{ + char devname[HCI_DEVNAME_SIZE]; + + uint32_t state; /* device/implementation specific */ + + bdaddr_t bdaddr; + uint16_t _reserved0; + + uint8_t features[HCI_DEVFEATURES_SIZE]; + + /* buffer info */ + uint16_t _reserved1; + uint16_t cmd_free; + uint16_t sco_size; + uint16_t sco_pkts; + uint16_t sco_free; + uint16_t acl_size; + uint16_t acl_pkts; + uint16_t acl_free; + + /* stats */ + uint32_t cmd_sent; + uint32_t evnt_recv; + uint32_t acl_recv; + uint32_t acl_sent; + uint32_t sco_recv; + uint32_t sco_sent; + uint32_t bytes_recv; + uint32_t bytes_sent; + + /* misc/specific */ + uint16_t link_policy_info; + uint16_t packet_type_info; + uint16_t role_switch_info; + uint16_t debug; + + uint8_t _padding[20]; /* leave space for future additions */ +}; + +struct bt_devreq +{ + uint16_t opcode; + uint8_t event; + void *cparam; + size_t clen; + void *rparam; + size_t rlen; +}; + +struct bt_devfilter { + bitstr_t bit_decl(packet_mask, 8); + bitstr_t bit_decl(event_mask, 256); +}; + +struct bt_devinquiry { + bdaddr_t bdaddr; + uint8_t pscan_rep_mode; + uint8_t pscan_period_mode; + uint8_t dev_class[3]; + uint16_t clock_offset; + int8_t rssi; + uint8_t data[240]; +}; + +typedef int (bt_devenum_cb_t)(int, struct bt_devinfo const *, void *); + +int bt_devopen (char const *devname); +int bt_devclose(int s); +int bt_devsend (int s, uint16_t opcode, void *param, size_t plen); +ssize_t bt_devrecv (int s, void *buf, size_t size, time_t to); +int bt_devreq (int s, struct bt_devreq *r, time_t to); +int bt_devfilter(int s, struct bt_devfilter const *newp, + struct bt_devfilter *oldp); +void bt_devfilter_pkt_set(struct bt_devfilter *filter, uint8_t type); +void bt_devfilter_pkt_clr(struct bt_devfilter *filter, uint8_t type); +int bt_devfilter_pkt_tst(struct bt_devfilter const *filter, uint8_t type); +void bt_devfilter_evt_set(struct bt_devfilter *filter, uint8_t event); +void bt_devfilter_evt_clr(struct bt_devfilter *filter, uint8_t event); +int bt_devfilter_evt_tst(struct bt_devfilter const *filter, uint8_t event); +int bt_devinquiry(char const *devname, time_t length, int num_rsp, + struct bt_devinquiry **ii); +int bt_devinfo (struct bt_devinfo *di); +int bt_devenum (bt_devenum_cb_t *cb, void *arg); + +/* + * bdaddr utility functions (from NetBSD) + */ + +static __inline int +bdaddr_same(const bdaddr_t *a, const bdaddr_t *b) +{ + return (a->b[0] == b->b[0] && a->b[1] == b->b[1] && + a->b[2] == b->b[2] && a->b[3] == b->b[3] && + a->b[4] == b->b[4] && a->b[5] == b->b[5]); +} + +static __inline int +bdaddr_any(const bdaddr_t *a) +{ + return (a->b[0] == 0 && a->b[1] == 0 && a->b[2] == 0 && + a->b[3] == 0 && a->b[4] == 0 && a->b[5] == 0); +} + +static __inline void +bdaddr_copy(bdaddr_t *d, const bdaddr_t *s) +{ + d->b[0] = s->b[0]; + d->b[1] = s->b[1]; + d->b[2] = s->b[2]; + d->b[3] = s->b[3]; + d->b[4] = s->b[4]; + d->b[5] = s->b[5]; +} + +__END_DECLS + +#endif /* ndef _BLUETOOTH_H_ */ + diff --git a/src/include.new/bsdxml.h b/src/include.new/bsdxml.h new file mode 100644 index 0000000..2f56665 --- /dev/null +++ b/src/include.new/bsdxml.h @@ -0,0 +1,1039 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file src/contrib/expat/COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + + +#include +#include "bsdxml_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +#ifdef XML_ATTR_INFO +/* Source file byte offsets for the start and end of attribute names and values. + The value indices are exclusive of surrounding quotes; thus in a UTF-8 source + file an attribute value of "blah" will yield: + info->valueEnd - info->valueStart = 4 bytes. +*/ +typedef struct { + XML_Index nameStart; /* Offset to beginning of the attribute name. */ + XML_Index nameEnd; /* Offset after the attribute name's last byte. */ + XML_Index valueStart; /* Offset to beginning of the attribute value. */ + XML_Index valueEnd; /* Offset after the attribute value's last byte. */ +} XML_AttrInfo; + +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs + passed in last call to the XML_StartElementHandler that were specified + in the start-tag rather than defaulted. Each attribute/value pair counts + as 1; thus the number of entries in the array is + XML_GetSpecifiedAttributeCount(parser) / 2. +*/ +XMLPARSEAPI(const XML_AttrInfo *) +XML_GetAttributeInfo(XML_Parser parser); +#endif + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. +*/ +XMLPARSEAPI(int) +XML_SetHashSalt(XML_Parser parser, + unsigned long hash_salt); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE, + XML_FEATURE_ATTR_INFO + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 1 +#define XML_MICRO_VERSION 0 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/src/include.new/bsdxml_external.h b/src/include.new/bsdxml_external.h new file mode 100644 index 0000000..2c03284 --- /dev/null +++ b/src/include.new/bsdxml_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/src/include.new/bsm/audit.h b/src/include.new/bsm/audit.h new file mode 100644 index 0000000..853d2b7 --- /dev/null +++ b/src/include.new/bsm/audit.h @@ -0,0 +1,328 @@ +/*- + * Copyright (c) 2005-2009 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#10 + * $FreeBSD: releng/10.2/sys/bsm/audit.h 195740 2009-07-17 14:02:20Z rwatson $ + */ + +#ifndef _BSM_AUDIT_H +#define _BSM_AUDIT_H + +#include +#include + +#define AUDIT_RECORD_MAGIC 0x828a0f1b +#define MAX_AUDIT_RECORDS 20 +#define MAXAUDITDATA (0x8000 - 1) +#define MAX_AUDIT_RECORD_SIZE MAXAUDITDATA +#define MIN_AUDIT_FILE_SIZE (512 * 1024) + +/* + * Minimum noumber of free blocks on the filesystem containing the audit + * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0 + * as the kernel does an unsigned compare, plus we want to leave a few blocks + * free so userspace can terminate the log, etc. + */ +#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 + +/* + * Triggers for the audit daemon. + */ +#define AUDIT_TRIGGER_MIN 1 +#define AUDIT_TRIGGER_LOW_SPACE 1 /* Below low watermark. */ +#define AUDIT_TRIGGER_ROTATE_KERNEL 2 /* Kernel requests rotate. */ +#define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */ +#define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */ +#define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */ +#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */ +#define AUDIT_TRIGGER_INITIALIZE 7 /* User initialize of auditd. */ +#define AUDIT_TRIGGER_EXPIRE_TRAILS 8 /* User expiration of trails. */ +#define AUDIT_TRIGGER_MAX 8 + +/* + * The special device filename (FreeBSD). + */ +#define AUDITDEV_FILENAME "audit" +#define AUDIT_TRIGGER_FILE ("/dev/" AUDITDEV_FILENAME) + +/* + * Pre-defined audit IDs + */ +#define AU_DEFAUDITID (uid_t)(-1) +#define AU_DEFAUDITSID 0 +#define AU_ASSIGN_ASID -1 + +/* + * IPC types. + */ +#define AT_IPC_MSG ((u_char)1) /* Message IPC id. */ +#define AT_IPC_SEM ((u_char)2) /* Semaphore IPC id. */ +#define AT_IPC_SHM ((u_char)3) /* Shared mem IPC id. */ + +/* + * Audit conditions. + */ +#define AUC_UNSET 0 +#define AUC_AUDITING 1 +#define AUC_NOAUDIT 2 +#define AUC_DISABLED -1 + +/* + * auditon(2) commands. + */ +#define A_OLDGETPOLICY 2 +#define A_OLDSETPOLICY 3 +#define A_GETKMASK 4 +#define A_SETKMASK 5 +#define A_OLDGETQCTRL 6 +#define A_OLDSETQCTRL 7 +#define A_GETCWD 8 +#define A_GETCAR 9 +#define A_GETSTAT 12 +#define A_SETSTAT 13 +#define A_SETUMASK 14 +#define A_SETSMASK 15 +#define A_OLDGETCOND 20 +#define A_OLDSETCOND 21 +#define A_GETCLASS 22 +#define A_SETCLASS 23 +#define A_GETPINFO 24 +#define A_SETPMASK 25 +#define A_SETFSIZE 26 +#define A_GETFSIZE 27 +#define A_GETPINFO_ADDR 28 +#define A_GETKAUDIT 29 +#define A_SETKAUDIT 30 +#define A_SENDTRIGGER 31 +#define A_GETSINFO_ADDR 32 +#define A_GETPOLICY 33 +#define A_SETPOLICY 34 +#define A_GETQCTRL 35 +#define A_SETQCTRL 36 +#define A_GETCOND 37 +#define A_SETCOND 38 + +/* + * Audit policy controls. + */ +#define AUDIT_CNT 0x0001 +#define AUDIT_AHLT 0x0002 +#define AUDIT_ARGV 0x0004 +#define AUDIT_ARGE 0x0008 +#define AUDIT_SEQ 0x0010 +#define AUDIT_WINDATA 0x0020 +#define AUDIT_USER 0x0040 +#define AUDIT_GROUP 0x0080 +#define AUDIT_TRAIL 0x0100 +#define AUDIT_PATH 0x0200 +#define AUDIT_SCNT 0x0400 +#define AUDIT_PUBLIC 0x0800 +#define AUDIT_ZONENAME 0x1000 +#define AUDIT_PERZONE 0x2000 + +/* + * Default audit queue control parameters. + */ +#define AQ_HIWATER 100 +#define AQ_MAXHIGH 10000 +#define AQ_LOWATER 10 +#define AQ_BUFSZ MAXAUDITDATA +#define AQ_MAXBUFSZ 1048576 + +/* + * Default minimum percentage free space on file system. + */ +#define AU_FS_MINFREE 20 + +/* + * Type definitions used indicating the length of variable length addresses + * in tokens containing addresses, such as header fields. + */ +#define AU_IPv4 4 +#define AU_IPv6 16 + +__BEGIN_DECLS + +typedef uid_t au_id_t; +typedef pid_t au_asid_t; +typedef u_int16_t au_event_t; +typedef u_int16_t au_emod_t; +typedef uint32_t au_class_t; +typedef u_int64_t au_asflgs_t __attribute__ ((aligned (8))); + +struct au_tid { + dev_t port; + uint32_t machine; +}; +typedef struct au_tid au_tid_t; + +struct au_tid_addr { + dev_t at_port; + uint32_t at_type; + uint32_t at_addr[4]; +}; +typedef struct au_tid_addr au_tid_addr_t; + +struct au_mask { + unsigned int am_success; /* Success bits. */ + unsigned int am_failure; /* Failure bits. */ +}; +typedef struct au_mask au_mask_t; + +struct auditinfo { + au_id_t ai_auid; /* Audit user ID. */ + au_mask_t ai_mask; /* Audit masks. */ + au_tid_t ai_termid; /* Terminal ID. */ + au_asid_t ai_asid; /* Audit session ID. */ +}; +typedef struct auditinfo auditinfo_t; + +struct auditinfo_addr { + au_id_t ai_auid; /* Audit user ID. */ + au_mask_t ai_mask; /* Audit masks. */ + au_tid_addr_t ai_termid; /* Terminal ID. */ + au_asid_t ai_asid; /* Audit session ID. */ + au_asflgs_t ai_flags; /* Audit session flags. */ +}; +typedef struct auditinfo_addr auditinfo_addr_t; + +struct auditpinfo { + pid_t ap_pid; /* ID of target process. */ + au_id_t ap_auid; /* Audit user ID. */ + au_mask_t ap_mask; /* Audit masks. */ + au_tid_t ap_termid; /* Terminal ID. */ + au_asid_t ap_asid; /* Audit session ID. */ +}; +typedef struct auditpinfo auditpinfo_t; + +struct auditpinfo_addr { + pid_t ap_pid; /* ID of target process. */ + au_id_t ap_auid; /* Audit user ID. */ + au_mask_t ap_mask; /* Audit masks. */ + au_tid_addr_t ap_termid; /* Terminal ID. */ + au_asid_t ap_asid; /* Audit session ID. */ + au_asflgs_t ap_flags; /* Audit session flags. */ +}; +typedef struct auditpinfo_addr auditpinfo_addr_t; + +struct au_session { + auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */ + au_mask_t as_mask; /* Process Audit Masks. */ +}; +typedef struct au_session au_session_t; + +/* + * Contents of token_t are opaque outside of libbsm. + */ +typedef struct au_token token_t; + +/* + * Kernel audit queue control parameters: + * Default: Maximum: + * aq_hiwater: AQ_HIWATER (100) AQ_MAXHIGH (10000) + * aq_lowater: AQ_LOWATER (10) +mach_port_name_t audit_session_self(void); +au_asid_t audit_session_join(mach_port_name_t port); +#endif /* __APPLE_API_PRIVATE */ + +#endif /* defined(_KERNEL) || defined(KERNEL) */ + +__END_DECLS + +#endif /* !_BSM_AUDIT_H */ diff --git a/src/include.new/bsm/audit_domain.h b/src/include.new/bsm/audit_domain.h new file mode 100644 index 0000000..1332e94 --- /dev/null +++ b/src/include.new/bsm/audit_domain.h @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2008 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_domain.h#2 + * $FreeBSD: releng/10.2/sys/bsm/audit_domain.h 191273 2009-04-19 16:17:13Z rwatson $ + */ + +#ifndef _BSM_AUDIT_DOMAIN_H_ +#define _BSM_AUDIT_DOMAIN_H_ + +/* + * BSM protocol domain constants - protocol domains defined in Solaris. + */ +#define BSM_PF_UNSPEC 0 +#define BSM_PF_LOCAL 1 +#define BSM_PF_INET 2 +#define BSM_PF_IMPLINK 3 +#define BSM_PF_PUP 4 +#define BSM_PF_CHAOS 5 +#define BSM_PF_NS 6 +#define BSM_PF_NBS 7 /* Solaris-specific. */ +#define BSM_PF_ECMA 8 +#define BSM_PF_DATAKIT 9 +#define BSM_PF_CCITT 10 +#define BSM_PF_SNA 11 +#define BSM_PF_DECnet 12 +#define BSM_PF_DLI 13 +#define BSM_PF_LAT 14 +#define BSM_PF_HYLINK 15 +#define BSM_PF_APPLETALK 16 +#define BSM_PF_NIT 17 /* Solaris-specific. */ +#define BSM_PF_802 18 /* Solaris-specific. */ +#define BSM_PF_OSI 19 +#define BSM_PF_X25 20 /* Solaris/Linux-specific. */ +#define BSM_PF_OSINET 21 /* Solaris-specific. */ +#define BSM_PF_GOSIP 22 /* Solaris-specific. */ +#define BSM_PF_IPX 23 +#define BSM_PF_ROUTE 24 +#define BSM_PF_LINK 25 +#define BSM_PF_INET6 26 +#define BSM_PF_KEY 27 +#define BSM_PF_NCA 28 /* Solaris-specific. */ +#define BSM_PF_POLICY 29 /* Solaris-specific. */ +#define BSM_PF_INET_OFFLOAD 30 /* Solaris-specific. */ + +/* + * BSM protocol domain constants - protocol domains not defined in Solaris. + */ +#define BSM_PF_NETBIOS 500 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_ISO 501 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_XTP 502 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_COIP 503 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_CNT 504 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_RTIP 505 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_SIP 506 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_PIP 507 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_ISDN 508 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_E164 509 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_NATM 510 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_ATM 511 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_NETGRAPH 512 /* FreeBSD/Darwin-specific. */ +#define BSM_PF_SLOW 513 /* FreeBSD-specific. */ +#define BSM_PF_SCLUSTER 514 /* FreeBSD-specific. */ +#define BSM_PF_ARP 515 /* FreeBSD-specific. */ +#define BSM_PF_BLUETOOTH 516 /* FreeBSD-specific. */ + /* 517: unallocated. */ +#define BSM_PF_AX25 518 /* Linux-specific. */ +#define BSM_PF_ROSE 519 /* Linux-specific. */ +#define BSM_PF_NETBEUI 520 /* Linux-specific. */ +#define BSM_PF_SECURITY 521 /* Linux-specific. */ +#define BSM_PF_PACKET 522 /* Linux-specific. */ +#define BSM_PF_ASH 523 /* Linux-specific. */ +#define BSM_PF_ECONET 524 /* Linux-specific. */ +#define BSM_PF_ATMSVC 525 /* Linux-specific. */ +#define BSM_PF_IRDA 526 /* Linux-specific. */ +#define BSM_PF_PPPOX 527 /* Linux-specific. */ +#define BSM_PF_WANPIPE 528 /* Linux-specific. */ +#define BSM_PF_LLC 529 /* Linux-specific. */ +#define BSM_PF_CAN 530 /* Linux-specific. */ +#define BSM_PF_TIPC 531 /* Linux-specific. */ +#define BSM_PF_IUCV 532 /* Linux-specific. */ +#define BSM_PF_RXRPC 533 /* Linux-specific. */ +#define BSM_PF_PHONET 534 /* Linux-specific. */ + +/* + * Used when there is no mapping from a local to BSM protocol domain. + */ +#define BSM_PF_UNKNOWN 700 /* OpenBSM-specific. */ + +#endif /* !_BSM_AUDIT_DOMAIN_H_ */ diff --git a/src/include.new/bsm/audit_errno.h b/src/include.new/bsm/audit_errno.h new file mode 100644 index 0000000..661320f --- /dev/null +++ b/src/include.new/bsm/audit_errno.h @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2008 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_errno.h#7 + * $FreeBSD: releng/10.2/sys/bsm/audit_errno.h 243751 2012-12-01 13:46:37Z rwatson $ + */ + +#ifndef _BSM_AUDIT_ERRNO_H_ +#define _BSM_AUDIT_ERRNO_H_ + +/* + * For the purposes of portable encoding, we convert between local error + * numbers and Solaris error numbers (as well as some extensions for error + * numbers that don't exist in Solaris). Although the first 35 or so + * constants are the same across all OS's, we don't handle that in any + * special way. + * + * When adding constants here, also add them to bsm_errno.c. + */ +#define BSM_ERRNO_ESUCCESS 0 +#define BSM_ERRNO_EPERM 1 +#define BSM_ERRNO_ENOENT 2 +#define BSM_ERRNO_ESRCH 3 +#define BSM_ERRNO_EINTR 4 +#define BSM_ERRNO_EIO 5 +#define BSM_ERRNO_ENXIO 6 +#define BSM_ERRNO_E2BIG 7 +#define BSM_ERRNO_ENOEXEC 8 +#define BSM_ERRNO_EBADF 9 +#define BSM_ERRNO_ECHILD 10 +#define BSM_ERRNO_EAGAIN 11 +#define BSM_ERRNO_ENOMEM 12 +#define BSM_ERRNO_EACCES 13 +#define BSM_ERRNO_EFAULT 14 +#define BSM_ERRNO_ENOTBLK 15 +#define BSM_ERRNO_EBUSY 16 +#define BSM_ERRNO_EEXIST 17 +#define BSM_ERRNO_EXDEV 18 +#define BSM_ERRNO_ENODEV 19 +#define BSM_ERRNO_ENOTDIR 20 +#define BSM_ERRNO_EISDIR 21 +#define BSM_ERRNO_EINVAL 22 +#define BSM_ERRNO_ENFILE 23 +#define BSM_ERRNO_EMFILE 24 +#define BSM_ERRNO_ENOTTY 25 +#define BSM_ERRNO_ETXTBSY 26 +#define BSM_ERRNO_EFBIG 27 +#define BSM_ERRNO_ENOSPC 28 +#define BSM_ERRNO_ESPIPE 29 +#define BSM_ERRNO_EROFS 30 +#define BSM_ERRNO_EMLINK 31 +#define BSM_ERRNO_EPIPE 32 +#define BSM_ERRNO_EDOM 33 +#define BSM_ERRNO_ERANGE 34 +#define BSM_ERRNO_ENOMSG 35 +#define BSM_ERRNO_EIDRM 36 +#define BSM_ERRNO_ECHRNG 37 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EL2NSYNC 38 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EL3HLT 39 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EL3RST 40 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELNRNG 41 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EUNATCH 42 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOCSI 43 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EL2HLT 44 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EDEADLK 45 +#define BSM_ERRNO_ENOLCK 46 +#define BSM_ERRNO_ECANCELED 47 +#define BSM_ERRNO_ENOTSUP 48 +#define BSM_ERRNO_EDQUOT 49 +#define BSM_ERRNO_EBADE 50 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EBADR 51 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EXFULL 52 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOANO 53 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EBADRQC 54 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EBADSLT 55 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EDEADLOCK 56 /* Solaris-specific. */ +#define BSM_ERRNO_EBFONT 57 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EOWNERDEAD 58 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOTRECOVERABLE 59 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOSTR 60 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ERRNO_ENODATA 61 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ERRNO_ETIME 62 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ERRNO_ENOSR 63 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ERRNO_ENONET 64 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOPKG 65 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EREMOTE 66 +#define BSM_ERRNO_ENOLINK 67 +#define BSM_ERRNO_EADV 68 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ESRMNT 69 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ECOMM 70 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EPROTO 71 +#define BSM_ERRNO_ELOCKUNMAPPED 72 /* Solaris-specific. */ +#define BSM_ERRNO_ENOTACTIVE 73 /* Solaris-specific. */ +#define BSM_ERRNO_EMULTIHOP 74 +#define BSM_ERRNO_EBADMSG 77 +#define BSM_ERRNO_ENAMETOOLONG 78 +#define BSM_ERRNO_EOVERFLOW 79 +#define BSM_ERRNO_ENOTUNIQ 80 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EBADFD 81 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EREMCHG 82 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELIBACC 83 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELIBBAD 84 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELIBSCN 85 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELIBMAX 86 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ELIBEXEC 87 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_EILSEQ 88 +#define BSM_ERRNO_ENOSYS 89 +#define BSM_ERRNO_ELOOP 90 +#define BSM_ERRNO_ERESTART 91 +#define BSM_ERRNO_ESTRPIPE 92 /* Solaris/Linux-specific. */ +#define BSM_ERRNO_ENOTEMPTY 93 +#define BSM_ERRNO_EUSERS 94 +#define BSM_ERRNO_ENOTSOCK 95 +#define BSM_ERRNO_EDESTADDRREQ 96 +#define BSM_ERRNO_EMSGSIZE 97 +#define BSM_ERRNO_EPROTOTYPE 98 +#define BSM_ERRNO_ENOPROTOOPT 99 +#define BSM_ERRNO_EPROTONOSUPPORT 120 +#define BSM_ERRNO_ESOCKTNOSUPPORT 121 +#define BSM_ERRNO_EOPNOTSUPP 122 +#define BSM_ERRNO_EPFNOSUPPORT 123 +#define BSM_ERRNO_EAFNOSUPPORT 124 +#define BSM_ERRNO_EADDRINUSE 125 +#define BSM_ERRNO_EADDRNOTAVAIL 126 +#define BSM_ERRNO_ENETDOWN 127 +#define BSM_ERRNO_ENETUNREACH 128 +#define BSM_ERRNO_ENETRESET 129 +#define BSM_ERRNO_ECONNABORTED 130 +#define BSM_ERRNO_ECONNRESET 131 +#define BSM_ERRNO_ENOBUFS 132 +#define BSM_ERRNO_EISCONN 133 +#define BSM_ERRNO_ENOTCONN 134 +#define BSM_ERRNO_ESHUTDOWN 143 +#define BSM_ERRNO_ETOOMANYREFS 144 +#define BSM_ERRNO_ETIMEDOUT 145 +#define BSM_ERRNO_ECONNREFUSED 146 +#define BSM_ERRNO_EHOSTDOWN 147 +#define BSM_ERRNO_EHOSTUNREACH 148 +#define BSM_ERRNO_EALREADY 149 +#define BSM_ERRNO_EINPROGRESS 150 +#define BSM_ERRNO_ESTALE 151 + +/* + * OpenBSM constants for error numbers not defined in Solaris. In the event + * that these errors are added to Solaris, we will deprecate the OpenBSM + * numbers in the same way we do for audit event constants. + * + * ELAST doesn't get a constant in the BSM space. + */ +#define BSM_ERRNO_EPROCLIM 190 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EBADRPC 191 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_ERPCMISMATCH 192 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EPROGUNAVAIL 193 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EPROGMISMATCH 194 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EPROCUNAVAIL 195 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EFTYPE 196 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EAUTH 197 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_ENEEDAUTH 198 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_ENOATTR 199 /* FreeBSD/Darwin-specific. */ +#define BSM_ERRNO_EDOOFUS 200 /* FreeBSD-specific. */ +#define BSM_ERRNO_EJUSTRETURN 201 /* FreeBSD-specific. */ +#define BSM_ERRNO_ENOIOCTL 202 /* FreeBSD-specific. */ +#define BSM_ERRNO_EDIRIOCTL 203 /* FreeBSD-specific. */ +#define BSM_ERRNO_EPWROFF 204 /* Darwin-specific. */ +#define BSM_ERRNO_EDEVERR 205 /* Darwin-specific. */ +#define BSM_ERRNO_EBADEXEC 206 /* Darwin-specific. */ +#define BSM_ERRNO_EBADARCH 207 /* Darwin-specific. */ +#define BSM_ERRNO_ESHLIBVERS 208 /* Darwin-specific. */ +#define BSM_ERRNO_EBADMACHO 209 /* Darwin-specific. */ +#define BSM_ERRNO_EPOLICY 210 /* Darwin-specific. */ +#define BSM_ERRNO_EDOTDOT 211 /* Linux-specific. */ +#define BSM_ERRNO_EUCLEAN 212 /* Linux-specific. */ +#define BSM_ERRNO_ENOTNAM 213 /* Linux(Xenix?)-specific. */ +#define BSM_ERRNO_ENAVAIL 214 /* Linux(Xenix?)-specific. */ +#define BSM_ERRNO_EISNAM 215 /* Linux(Xenix?)-specific. */ +#define BSM_ERRNO_EREMOTEIO 216 /* Linux-specific. */ +#define BSM_ERRNO_ENOMEDIUM 217 /* Linux-specific. */ +#define BSM_ERRNO_EMEDIUMTYPE 218 /* Linux-specific. */ +#define BSM_ERRNO_ENOKEY 219 /* Linux-specific. */ +#define BSM_ERRNO_EKEYEXPIRED 220 /* Linux-specific. */ +#define BSM_ERRNO_EKEYREVOKED 221 /* Linux-specific. */ +#define BSM_ERRNO_EKEYREJECTED 222 /* Linux-specific. */ +#define BSM_ERRNO_ENOTCAPABLE 223 /* FreeBSD-specific. */ +#define BSM_ERRNO_ECAPMODE 224 /* FreeBSD-specific. */ + +/* + * In the event that OpenBSM doesn't have a file representation of a local + * error number, use this. + */ +#define BSM_ERRNO_UNKNOWN 250 /* OpenBSM-specific. */ + +#endif /* !_BSM_AUDIT_ERRNO_H_ */ diff --git a/src/include.new/bsm/audit_fcntl.h b/src/include.new/bsm/audit_fcntl.h new file mode 100644 index 0000000..7922410 --- /dev/null +++ b/src/include.new/bsm/audit_fcntl.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2009 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_fcntl.h#2 + * $FreeBSD: releng/10.2/sys/bsm/audit_fcntl.h 191147 2009-04-16 20:17:32Z rwatson $ + */ + +#ifndef _BSM_AUDIT_FCNTL_H_ +#define _BSM_AUDIT_FCNTL_H_ + +/* + * Shared and Solaris-specific: (0-99). + */ +#define BSM_F_DUPFD 0 +#define BSM_F_GETFD 1 +#define BSM_F_SETFD 2 +#define BSM_F_GETFL 3 +#define BSM_F_SETFL 4 +#define BSM_F_O_GETLK 5 /* Solaris-specific. */ +#define BSM_F_SETLK 6 +#define BSM_F_SETLKW 7 +#define BSM_F_CHKFL 8 /* Solaris-specific. */ +#define BSM_F_DUP2FD 9 /* FreeBSD/Solaris-specific. */ +#define BSM_F_ALLOCSP 10 /* Solaris-specific. */ +#define BSM_F_FREESP 11 /* Solaris-specific. */ + +#define BSM_F_ISSTREAM 13 /* Solaris-specific. */ +#define BSM_F_GETLK 14 +#define BSM_F_PRIV 15 /* Solaris-specific. */ +#define BSM_F_NPRIV 16 /* Solaris-specific. */ +#define BSM_F_QUOTACTL 17 /* Solaris-specific. */ +#define BSM_F_BLOCKS 18 /* Solaris-specific. */ +#define BSM_F_BLKSIZE 19 /* Solaris-specific. */ + +#define BSM_F_GETOWN 23 +#define BSM_F_SETOWN 24 +#define BSM_F_REVOKE 25 /* Solaris-specific. */ +#define BSM_F_HASREMOTELOCKS 26 /* Solaris-specific. */ +#define BSM_F_FREESP64 27 /* Solaris-specific. */ +#define BSM_F_ALLOCSP64 28 /* Solaris-specific. */ + +#define BSM_F_GETLK64 33 /* Solaris-specific. */ +#define BSM_F_SETLK64 34 /* Solaris-specific. */ +#define BSM_F_SETLKW64 35 /* Solaris-specific. */ + +#define BSM_F_SHARE 40 /* Solaris-specific. */ +#define BSM_F_UNSHARE 41 /* Solaris-specific. */ +#define BSM_F_SETLK_NBMAND 42 /* Solaris-specific. */ +#define BSM_F_SHARE_NBMAND 43 /* Solaris-specific. */ +#define BSM_F_SETLK64_NBMAND 44 /* Solaris-specific. */ +#define BSM_F_GETXFL 45 /* Solaris-specific. */ +#define BSM_F_BADFD 46 /* Solaris-specific. */ + +/* + * FreeBSD-specific (100-199). + */ +#define BSM_F_OGETLK 107 /* FreeBSD-specific. */ +#define BSM_F_OSETLK 108 /* FreeBSD-specific. */ +#define BSM_F_OSETLKW 109 /* FreeBSD-specific. */ + +#define BSM_F_SETLK_REMOTE 114 /* FreeBSD-specific. */ + +/* + * Linux-specific (200-299). + */ +#define BSM_F_SETSIG 210 /* Linux-specific. */ +#define BSM_F_GETSIG 211 /* Linux-specific. */ + +/* + * Darwin-specific (300-399). + */ +#define BSM_F_CHKCLEAN 341 /* Darwin-specific. */ +#define BSM_F_PREALLOCATE 342 /* Darwin-specific. */ +#define BSM_F_SETSIZE 343 /* Darwin-specific. */ +#define BSM_F_RDADVISE 344 /* Darwin-specific. */ +#define BSM_F_RDAHEAD 345 /* Darwin-specific. */ +#define BSM_F_READBOOTSTRAP 346 /* Darwin-specific. */ +#define BSM_F_WRITEBOOTSTRAP 347 /* Darwin-specific. */ +#define BSM_F_NOCACHE 348 /* Darwin-specific. */ +#define BSM_F_LOG2PHYS 349 /* Darwin-specific. */ +#define BSM_F_GETPATH 350 /* Darwin-specific. */ +#define BSM_F_FULLFSYNC 351 /* Darwin-specific. */ +#define BSM_F_PATHPKG_CHECK 352 /* Darwin-specific. */ +#define BSM_F_FREEZE_FS 353 /* Darwin-specific. */ +#define BSM_F_THAW_FS 354 /* Darwin-specific. */ +#define BSM_F_GLOBAL_NOCACHE 355 /* Darwin-specific. */ +#define BSM_F_OPENFROM 356 /* Darwin-specific. */ +#define BSM_F_UNLINKFROM 357 /* Darwin-specific. */ +#define BSM_F_CHECK_OPENEVT 358 /* Darwin-specific. */ +#define BSM_F_ADDSIGS 359 /* Darwin-specific. */ +#define BSM_F_MARKDEPENDENCY 360 /* Darwin-specific. */ + +/* + * Darwin file system specific (400-499). + */ +#define BSM_F_FS_SPECIFIC_0 400 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_1 401 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_2 402 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_3 403 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_4 404 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_5 405 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_6 406 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_7 407 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_8 408 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_9 409 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_10 410 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_11 411 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_12 412 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_13 413 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_14 414 /* Darwin-fs-specific. */ +#define BSM_F_FS_SPECIFIC_15 415 /* Darwin-fs-specific. */ + + +#define BSM_F_UNKNOWN 0xFFFF + +#endif /* !_BSM_AUDIT_FCNTL_H_ */ diff --git a/src/include.new/bsm/audit_internal.h b/src/include.new/bsm/audit_internal.h new file mode 100644 index 0000000..61fc712 --- /dev/null +++ b/src/include.new/bsm/audit_internal.h @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2005-2008 Apple Inc. + * Copyright (c) 2005 SPARTA, Inc. + * All rights reserved. + * + * This code was developed in part by Robert N. M. Watson, Senior Principal + * Scientist, SPARTA, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#6 + * $FreeBSD: releng/10.2/sys/bsm/audit_internal.h 243751 2012-12-01 13:46:37Z rwatson $ + */ + +#ifndef _AUDIT_INTERNAL_H +#define _AUDIT_INTERNAL_H + +#if defined(__linux__) && !defined(__unused) +#define __unused +#endif + +/* + * audit_internal.h contains private interfaces that are shared by user space + * and the kernel for the purposes of assembling audit records. Applications + * should not include this file or use the APIs found within, or it may be + * broken with future releases of OpenBSM, which may delete, modify, or + * otherwise break these interfaces or the assumptions they rely on. + */ +struct au_token { + u_char *t_data; + size_t len; + TAILQ_ENTRY(au_token) tokens; +}; + +struct au_record { + char used; /* Record currently in use? */ + int desc; /* Descriptor for record. */ + TAILQ_HEAD(, au_token) token_q; /* Queue of BSM tokens. */ + u_char *data; + size_t len; + LIST_ENTRY(au_record) au_rec_q; +}; +typedef struct au_record au_record_t; + + +/* + * We could determined the header and trailer sizes by defining appropriate + * structures. We hold off that approach until we have a consistent way of + * using structures for all tokens. This is not straightforward since these + * token structures may contain pointers of whose contents we do not know the + * size (e.g text tokens). + */ +#define AUDIT_HEADER_EX_SIZE(a) ((a)->ai_termid.at_type+18+sizeof(uint32_t)) +#define AUDIT_HEADER_SIZE 18 +#define MAX_AUDIT_HEADER_SIZE (5*sizeof(uint32_t)+18) +#define AUDIT_TRAILER_SIZE 7 + +/* + * BSM token streams store fields in big endian byte order, so as to be + * portable; when encoding and decoding, we must convert byte orders for + * typed values. + */ +#define ADD_U_CHAR(loc, val) \ + do { \ + *(loc) = (val); \ + (loc) += sizeof(u_char); \ + } while(0) + + +#define ADD_U_INT16(loc, val) \ + do { \ + be16enc((loc), (val)); \ + (loc) += sizeof(u_int16_t); \ + } while(0) + +#define ADD_U_INT32(loc, val) \ + do { \ + be32enc((loc), (val)); \ + (loc) += sizeof(uint32_t); \ + } while(0) + +#define ADD_U_INT64(loc, val) \ + do { \ + be64enc((loc), (val)); \ + (loc) += sizeof(u_int64_t); \ + } while(0) + +#define ADD_MEM(loc, data, size) \ + do { \ + memcpy((loc), (data), (size)); \ + (loc) += size; \ + } while(0) + +#define ADD_STRING(loc, data, size) ADD_MEM(loc, data, size) + +#endif /* !_AUDIT_INTERNAL_H_ */ diff --git a/src/include.new/bsm/audit_kevents.h b/src/include.new/bsm/audit_kevents.h new file mode 100644 index 0000000..b132e64 --- /dev/null +++ b/src/include.new/bsm/audit_kevents.h @@ -0,0 +1,809 @@ +/*- + * Copyright (c) 2005-2009 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#7 + * $FreeBSD: releng/10.2/sys/bsm/audit_kevents.h 255219 2013-09-05 00:09:56Z pjd $ + */ + +#ifndef _BSM_AUDIT_KEVENTS_H_ +#define _BSM_AUDIT_KEVENTS_H_ + +/* + * The reserved event numbers for kernel events are 1...2047 and 43001..44900. + */ +#define AUE_IS_A_KEVENT(e) (((e) > 0 && (e) < 2048) || \ + ((e) > 43000 && (e) < 45000)) + +/* + * Values marked as AUE_NULL are not required to be audited as per CAPP. + * + * Some conflicts exist in the assignment of name to event number mappings + * between BSM implementations. In general, we prefer the OpenSolaris + * definition as we consider Solaris BSM to be authoritative. _DARWIN_ has + * been inserted for the Darwin variants. If necessary, other tags will be + * added in the future. + */ +#define AUE_NULL 0 +#define AUE_EXIT 1 +#define AUE_FORK 2 +#define AUE_FORKALL AUE_FORK /* Solaris-specific. */ +#define AUE_OPEN 3 +#define AUE_CREAT 4 +#define AUE_LINK 5 +#define AUE_UNLINK 6 +#define AUE_DELETE AUE_UNLINK /* Darwin-specific. */ +#define AUE_EXEC 7 +#define AUE_CHDIR 8 +#define AUE_MKNOD 9 +#define AUE_CHMOD 10 +#define AUE_CHOWN 11 +#define AUE_UMOUNT 12 +#define AUE_JUNK 13 /* Solaris-specific. */ +#define AUE_ACCESS 14 +#define AUE_KILL 15 +#define AUE_STAT 16 +#define AUE_LSTAT 17 +#define AUE_ACCT 18 +#define AUE_MCTL 19 /* Solaris-specific. */ +#define AUE_REBOOT 20 /* XXX: Darwin conflict. */ +#define AUE_SYMLINK 21 +#define AUE_READLINK 22 +#define AUE_EXECVE 23 +#define AUE_CHROOT 24 +#define AUE_VFORK 25 +#define AUE_SETGROUPS 26 +#define AUE_SETPGRP 27 +#define AUE_SWAPON 28 +#define AUE_SETHOSTNAME 29 /* XXX: Darwin conflict. */ +#define AUE_FCNTL 30 +#define AUE_SETPRIORITY 31 /* XXX: Darwin conflict. */ +#define AUE_CONNECT 32 +#define AUE_ACCEPT 33 +#define AUE_BIND 34 +#define AUE_SETSOCKOPT 35 +#define AUE_VTRACE 36 /* Solaris-specific. */ +#define AUE_SETTIMEOFDAY 37 /* XXX: Darwin conflict. */ +#define AUE_FCHOWN 38 +#define AUE_FCHMOD 39 +#define AUE_SETREUID 40 +#define AUE_SETREGID 41 +#define AUE_RENAME 42 +#define AUE_TRUNCATE 43 /* XXX: Darwin conflict. */ +#define AUE_FTRUNCATE 44 /* XXX: Darwin conflict. */ +#define AUE_FLOCK 45 /* XXX: Darwin conflict. */ +#define AUE_SHUTDOWN 46 +#define AUE_MKDIR 47 +#define AUE_RMDIR 48 +#define AUE_UTIMES 49 +#define AUE_ADJTIME 50 +#define AUE_SETRLIMIT 51 +#define AUE_KILLPG 52 +#define AUE_NFS_SVC 53 /* XXX: Darwin conflict. */ +#define AUE_STATFS 54 +#define AUE_FSTATFS 55 +#define AUE_UNMOUNT 56 /* XXX: Darwin conflict. */ +#define AUE_ASYNC_DAEMON 57 +#define AUE_NFS_GETFH 58 /* XXX: Darwin conflict. */ +#define AUE_SETDOMAINNAME 59 +#define AUE_QUOTACTL 60 /* XXX: Darwin conflict. */ +#define AUE_EXPORTFS 61 +#define AUE_MOUNT 62 +#define AUE_SEMSYS 63 +#define AUE_MSGSYS 64 +#define AUE_SHMSYS 65 +#define AUE_BSMSYS 66 /* Solaris-specific. */ +#define AUE_RFSSYS 67 /* Solaris-specific. */ +#define AUE_FCHDIR 68 +#define AUE_FCHROOT 69 +#define AUE_VPIXSYS 70 /* Solaris-specific. */ +#define AUE_PATHCONF 71 +#define AUE_OPEN_R 72 +#define AUE_OPEN_RC 73 +#define AUE_OPEN_RT 74 +#define AUE_OPEN_RTC 75 +#define AUE_OPEN_W 76 +#define AUE_OPEN_WC 77 +#define AUE_OPEN_WT 78 +#define AUE_OPEN_WTC 79 +#define AUE_OPEN_RW 80 +#define AUE_OPEN_RWC 81 +#define AUE_OPEN_RWT 82 +#define AUE_OPEN_RWTC 83 +#define AUE_MSGCTL 84 +#define AUE_MSGCTL_RMID 85 +#define AUE_MSGCTL_SET 86 +#define AUE_MSGCTL_STAT 87 +#define AUE_MSGGET 88 +#define AUE_MSGRCV 89 +#define AUE_MSGSND 90 +#define AUE_SHMCTL 91 +#define AUE_SHMCTL_RMID 92 +#define AUE_SHMCTL_SET 93 +#define AUE_SHMCTL_STAT 94 +#define AUE_SHMGET 95 +#define AUE_SHMAT 96 +#define AUE_SHMDT 97 +#define AUE_SEMCTL 98 +#define AUE_SEMCTL_RMID 99 +#define AUE_SEMCTL_SET 100 +#define AUE_SEMCTL_STAT 101 +#define AUE_SEMCTL_GETNCNT 102 +#define AUE_SEMCTL_GETPID 103 +#define AUE_SEMCTL_GETVAL 104 +#define AUE_SEMCTL_GETALL 105 +#define AUE_SEMCTL_GETZCNT 106 +#define AUE_SEMCTL_SETVAL 107 +#define AUE_SEMCTL_SETALL 108 +#define AUE_SEMGET 109 +#define AUE_SEMOP 110 +#define AUE_CORE 111 /* Solaris-specific, currently. */ +#define AUE_CLOSE 112 +#define AUE_SYSTEMBOOT 113 /* Solaris-specific. */ +#define AUE_ASYNC_DAEMON_EXIT 114 /* Solaris-specific. */ +#define AUE_NFSSVC_EXIT 115 /* Solaris-specific. */ +#define AUE_WRITEL 128 /* Solaris-specific. */ +#define AUE_WRITEVL 129 /* Solaris-specific. */ +#define AUE_GETAUID 130 +#define AUE_SETAUID 131 +#define AUE_GETAUDIT 132 +#define AUE_SETAUDIT 133 +#define AUE_GETUSERAUDIT 134 /* Solaris-specific. */ +#define AUE_SETUSERAUDIT 135 /* Solaris-specific. */ +#define AUE_AUDITSVC 136 /* Solaris-specific. */ +#define AUE_AUDITUSER 137 /* Solaris-specific. */ +#define AUE_AUDITON 138 +#define AUE_AUDITON_GTERMID 139 /* Solaris-specific. */ +#define AUE_AUDITON_STERMID 140 /* Solaris-specific. */ +#define AUE_AUDITON_GPOLICY 141 +#define AUE_AUDITON_SPOLICY 142 +#define AUE_AUDITON_GQCTRL 145 +#define AUE_AUDITON_SQCTRL 146 +#define AUE_GETKERNSTATE 147 /* Solaris-specific. */ +#define AUE_SETKERNSTATE 148 /* Solaris-specific. */ +#define AUE_GETPORTAUDIT 149 /* Solaris-specific. */ +#define AUE_AUDITSTAT 150 /* Solaris-specific. */ +#define AUE_REVOKE 151 +#define AUE_MAC 152 /* Solaris-specific. */ +#define AUE_ENTERPROM 153 /* Solaris-specific. */ +#define AUE_EXITPROM 154 /* Solaris-specific. */ +#define AUE_IFLOAT 155 /* Solaris-specific. */ +#define AUE_PFLOAT 156 /* Solaris-specific. */ +#define AUE_UPRIV 157 /* Solaris-specific. */ +#define AUE_IOCTL 158 +#define AUE_SOCKET 183 +#define AUE_SENDTO 184 +#define AUE_PIPE 185 +#define AUE_SOCKETPAIR 186 /* XXX: Darwin conflict. */ +#define AUE_SEND 187 +#define AUE_SENDMSG 188 +#define AUE_RECV 189 +#define AUE_RECVMSG 190 +#define AUE_RECVFROM 191 +#define AUE_READ 192 +#define AUE_GETDENTS 193 +#define AUE_LSEEK 194 +#define AUE_WRITE 195 +#define AUE_WRITEV 196 +#define AUE_NFS 197 /* Solaris-specific. */ +#define AUE_READV 198 +#define AUE_OSTAT 199 /* Solaris-specific. */ +#define AUE_SETUID 200 /* XXXRW: Solaris old setuid? */ +#define AUE_STIME 201 /* XXXRW: Solaris old stime? */ +#define AUE_UTIME 202 /* XXXRW: Solaris old utime? */ +#define AUE_NICE 203 /* XXXRW: Solaris old nice? */ +#define AUE_OSETPGRP 204 /* Solaris-specific. */ +#define AUE_SETGID 205 +#define AUE_READL 206 /* Solaris-specific. */ +#define AUE_READVL 207 /* Solaris-specific. */ +#define AUE_FSTAT 208 +#define AUE_DUP2 209 +#define AUE_MMAP 210 +#define AUE_AUDIT 211 +#define AUE_PRIOCNTLSYS 212 /* Solaris-specific. */ +#define AUE_MUNMAP 213 +#define AUE_SETEGID 214 +#define AUE_SETEUID 215 +#define AUE_PUTMSG 216 /* Solaris-specific. */ +#define AUE_GETMSG 217 /* Solaris-specific. */ +#define AUE_PUTPMSG 218 /* Solaris-specific. */ +#define AUE_GETPMSG 219 /* Solaris-specific. */ +#define AUE_AUDITSYS 220 /* Solaris-specific. */ +#define AUE_AUDITON_GETKMASK 221 +#define AUE_AUDITON_SETKMASK 222 +#define AUE_AUDITON_GETCWD 223 +#define AUE_AUDITON_GETCAR 224 +#define AUE_AUDITON_GETSTAT 225 +#define AUE_AUDITON_SETSTAT 226 +#define AUE_AUDITON_SETUMASK 227 +#define AUE_AUDITON_SETSMASK 228 +#define AUE_AUDITON_GETCOND 229 +#define AUE_AUDITON_SETCOND 230 +#define AUE_AUDITON_GETCLASS 231 +#define AUE_AUDITON_SETCLASS 232 +#define AUE_FUSERS 233 /* Solaris-specific; also UTSSYS? */ +#define AUE_STATVFS 234 +#define AUE_XSTAT 235 /* Solaris-specific. */ +#define AUE_LXSTAT 236 /* Solaris-specific. */ +#define AUE_LCHOWN 237 +#define AUE_MEMCNTL 238 /* Solaris-specific. */ +#define AUE_SYSINFO 239 /* Solaris-specific. */ +#define AUE_XMKNOD 240 /* Solaris-specific. */ +#define AUE_FORK1 241 +#define AUE_MODCTL 242 /* Solaris-specific. */ +#define AUE_MODLOAD 243 +#define AUE_MODUNLOAD 244 +#define AUE_MODCONFIG 245 /* Solaris-specific. */ +#define AUE_MODADDMAJ 246 /* Solaris-specific. */ +#define AUE_SOCKACCEPT 247 /* Solaris-specific. */ +#define AUE_SOCKCONNECT 248 /* Solaris-specific. */ +#define AUE_SOCKSEND 249 /* Solaris-specific. */ +#define AUE_SOCKRECEIVE 250 /* Solaris-specific. */ +#define AUE_ACLSET 251 +#define AUE_FACLSET 252 +#define AUE_DOORFS 253 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_CALL 254 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_RETURN 255 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_CREATE 256 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_REVOKE 257 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_INFO 258 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_CRED 259 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_BIND 260 /* Solaris-specific. */ +#define AUE_DOORFS_DOOR_UNBIND 261 /* Solaris-specific. */ +#define AUE_P_ONLINE 262 /* Solaris-specific. */ +#define AUE_PROCESSOR_BIND 263 /* Solaris-specific. */ +#define AUE_INST_SYNC 264 /* Solaris-specific. */ +#define AUE_SOCKCONFIG 265 /* Solaris-specific. */ +#define AUE_SETAUDIT_ADDR 266 +#define AUE_GETAUDIT_ADDR 267 +#define AUE_UMOUNT2 268 /* Solaris-specific. */ +#define AUE_FSAT 269 /* Solaris-specific. */ +#define AUE_OPENAT_R 270 +#define AUE_OPENAT_RC 271 +#define AUE_OPENAT_RT 272 +#define AUE_OPENAT_RTC 273 +#define AUE_OPENAT_W 274 +#define AUE_OPENAT_WC 275 +#define AUE_OPENAT_WT 276 +#define AUE_OPENAT_WTC 277 +#define AUE_OPENAT_RW 278 +#define AUE_OPENAT_RWC 279 +#define AUE_OPENAT_RWT 280 +#define AUE_OPENAT_RWTC 281 +#define AUE_RENAMEAT 282 +#define AUE_FSTATAT 283 +#define AUE_FCHOWNAT 284 +#define AUE_FUTIMESAT 285 +#define AUE_UNLINKAT 286 +#define AUE_CLOCK_SETTIME 287 +#define AUE_NTP_ADJTIME 288 +#define AUE_SETPPRIV 289 /* Solaris-specific. */ +#define AUE_MODDEVPLCY 290 /* Solaris-specific. */ +#define AUE_MODADDPRIV 291 /* Solaris-specific. */ +#define AUE_CRYPTOADM 292 /* Solaris-specific. */ +#define AUE_CONFIGKSSL 293 /* Solaris-specific. */ +#define AUE_BRANDSYS 294 /* Solaris-specific. */ +#define AUE_PF_POLICY_ADDRULE 295 /* Solaris-specific. */ +#define AUE_PF_POLICY_DELRULE 296 /* Solaris-specific. */ +#define AUE_PF_POLICY_CLONE 297 /* Solaris-specific. */ +#define AUE_PF_POLICY_FLIP 298 /* Solaris-specific. */ +#define AUE_PF_POLICY_FLUSH 299 /* Solaris-specific. */ +#define AUE_PF_POLICY_ALGS 300 /* Solaris-specific. */ +#define AUE_PORTFS 301 /* Solaris-specific. */ + +/* + * Events added for Apple Darwin that potentially collide with future Solaris + * BSM events. These are assigned AUE_DARWIN prefixes, and are deprecated in + * new trails. Systems generating these events should switch to the new + * identifiers that avoid colliding with the Solaris identifier space. + */ +#define AUE_DARWIN_GETFSSTAT 301 +#define AUE_DARWIN_PTRACE 302 +#define AUE_DARWIN_CHFLAGS 303 +#define AUE_DARWIN_FCHFLAGS 304 +#define AUE_DARWIN_PROFILE 305 +#define AUE_DARWIN_KTRACE 306 +#define AUE_DARWIN_SETLOGIN 307 +#define AUE_DARWIN_REBOOT 308 +#define AUE_DARWIN_REVOKE 309 +#define AUE_DARWIN_UMASK 310 +#define AUE_DARWIN_MPROTECT 311 +#define AUE_DARWIN_SETPRIORITY 312 +#define AUE_DARWIN_SETTIMEOFDAY 313 +#define AUE_DARWIN_FLOCK 314 +#define AUE_DARWIN_MKFIFO 315 +#define AUE_DARWIN_POLL 316 +#define AUE_DARWIN_SOCKETPAIR 317 +#define AUE_DARWIN_FUTIMES 318 +#define AUE_DARWIN_SETSID 319 +#define AUE_DARWIN_SETPRIVEXEC 320 /* Darwin-specific. */ +#define AUE_DARWIN_NFSSVC 321 +#define AUE_DARWIN_GETFH 322 +#define AUE_DARWIN_QUOTACTL 323 +#define AUE_DARWIN_ADDPROFILE 324 /* Darwin-specific. */ +#define AUE_DARWIN_KDEBUGTRACE 325 /* Darwin-specific. */ +#define AUE_DARWIN_KDBUGTRACE AUE_KDEBUGTRACE +#define AUE_DARWIN_FSTAT 326 +#define AUE_DARWIN_FPATHCONF 327 +#define AUE_DARWIN_GETDIRENTRIES 328 +#define AUE_DARWIN_TRUNCATE 329 +#define AUE_DARWIN_FTRUNCATE 330 +#define AUE_DARWIN_SYSCTL 331 +#define AUE_DARWIN_MLOCK 332 +#define AUE_DARWIN_MUNLOCK 333 +#define AUE_DARWIN_UNDELETE 334 +#define AUE_DARWIN_GETATTRLIST 335 /* Darwin-specific. */ +#define AUE_DARWIN_SETATTRLIST 336 /* Darwin-specific. */ +#define AUE_DARWIN_GETDIRENTRIESATTR 337 /* Darwin-specific. */ +#define AUE_DARWIN_EXCHANGEDATA 338 /* Darwin-specific. */ +#define AUE_DARWIN_SEARCHFS 339 /* Darwin-specific. */ +#define AUE_DARWIN_MINHERIT 340 +#define AUE_DARWIN_SEMCONFIG 341 +#define AUE_DARWIN_SEMOPEN 342 +#define AUE_DARWIN_SEMCLOSE 343 +#define AUE_DARWIN_SEMUNLINK 344 +#define AUE_DARWIN_SHMOPEN 345 +#define AUE_DARWIN_SHMUNLINK 346 +#define AUE_DARWIN_LOADSHFILE 347 /* Darwin-specific. */ +#define AUE_DARWIN_RESETSHFILE 348 /* Darwin-specific. */ +#define AUE_DARWIN_NEWSYSTEMSHREG 349 /* Darwin-specific. */ +#define AUE_DARWIN_PTHREADKILL 350 /* Darwin-specific. */ +#define AUE_DARWIN_PTHREADSIGMASK 351 /* Darwin-specific. */ +#define AUE_DARWIN_AUDITCTL 352 +#define AUE_DARWIN_RFORK 353 +#define AUE_DARWIN_LCHMOD 354 +#define AUE_DARWIN_SWAPOFF 355 +#define AUE_DARWIN_INITPROCESS 356 /* Darwin-specific. */ +#define AUE_DARWIN_MAPFD 357 /* Darwin-specific. */ +#define AUE_DARWIN_TASKFORPID 358 /* Darwin-specific. */ +#define AUE_DARWIN_PIDFORTASK 359 /* Darwin-specific. */ +#define AUE_DARWIN_SYSCTL_NONADMIN 360 +#define AUE_DARWIN_COPYFILE 361 /* Darwin-specific. */ + +/* + * Audit event identifiers added as part of OpenBSM, generally corresponding + * to events in FreeBSD, Darwin, and Linux that were not present in Solaris. + * These often duplicate events added to the Solaris set by Darwin, but use + * event identifiers in a higher range in order to avoid colliding with + * future Solaris additions. + * + * If an event in this section is later added to Solaris, we prefer the + * Solaris event identifier, and add _OPENBSM_ to the OpenBSM-specific + * identifier so that old trails can still be processed, but new trails use + * the Solaris identifier. + */ +#define AUE_GETFSSTAT 43001 +#define AUE_PTRACE 43002 +#define AUE_CHFLAGS 43003 +#define AUE_FCHFLAGS 43004 +#define AUE_PROFILE 43005 +#define AUE_KTRACE 43006 +#define AUE_SETLOGIN 43007 +#define AUE_OPENBSM_REVOKE 43008 /* Solaris event now preferred. */ +#define AUE_UMASK 43009 +#define AUE_MPROTECT 43010 +#define AUE_MKFIFO 43011 +#define AUE_POLL 43012 +#define AUE_FUTIMES 43013 +#define AUE_SETSID 43014 +#define AUE_SETPRIVEXEC 43015 /* Darwin-specific. */ +#define AUE_ADDPROFILE 43016 /* Darwin-specific. */ +#define AUE_KDEBUGTRACE 43017 /* Darwin-specific. */ +#define AUE_KDBUGTRACE AUE_KDEBUGTRACE +#define AUE_OPENBSM_FSTAT 43018 /* Solaris event now preferred. */ +#define AUE_FPATHCONF 43019 +#define AUE_GETDIRENTRIES 43020 +#define AUE_SYSCTL 43021 +#define AUE_MLOCK 43022 +#define AUE_MUNLOCK 43023 +#define AUE_UNDELETE 43024 +#define AUE_GETATTRLIST 43025 /* Darwin-specific. */ +#define AUE_SETATTRLIST 43026 /* Darwin-specific. */ +#define AUE_GETDIRENTRIESATTR 43027 /* Darwin-specific. */ +#define AUE_EXCHANGEDATA 43028 /* Darwin-specific. */ +#define AUE_SEARCHFS 43029 /* Darwin-specific. */ +#define AUE_MINHERIT 43030 +#define AUE_SEMCONFIG 43031 +#define AUE_SEMOPEN 43032 +#define AUE_SEMCLOSE 43033 +#define AUE_SEMUNLINK 43034 +#define AUE_SHMOPEN 43035 +#define AUE_SHMUNLINK 43036 +#define AUE_LOADSHFILE 43037 /* Darwin-specific. */ +#define AUE_RESETSHFILE 43038 /* Darwin-specific. */ +#define AUE_NEWSYSTEMSHREG 43039 /* Darwin-specific. */ +#define AUE_PTHREADKILL 43040 /* Darwin-specific. */ +#define AUE_PTHREADSIGMASK 43041 /* Darwin-specific. */ +#define AUE_AUDITCTL 43042 +#define AUE_RFORK 43043 +#define AUE_LCHMOD 43044 +#define AUE_SWAPOFF 43045 +#define AUE_INITPROCESS 43046 /* Darwin-specific. */ +#define AUE_MAPFD 43047 /* Darwin-specific. */ +#define AUE_TASKFORPID 43048 /* Darwin-specific. */ +#define AUE_PIDFORTASK 43049 /* Darwin-specific. */ +#define AUE_SYSCTL_NONADMIN 43050 +#define AUE_COPYFILE 43051 /* Darwin-specific. */ + +/* + * Events added to OpenBSM for FreeBSD and Linux; may also be used by Darwin + * in the future. + */ +#define AUE_LUTIMES 43052 +#define AUE_LCHFLAGS 43053 /* FreeBSD-specific. */ +#define AUE_SENDFILE 43054 /* BSD/Linux-specific. */ +#define AUE_USELIB 43055 /* Linux-specific. */ +#define AUE_GETRESUID 43056 +#define AUE_SETRESUID 43057 +#define AUE_GETRESGID 43058 +#define AUE_SETRESGID 43059 +#define AUE_WAIT4 43060 /* FreeBSD-specific. */ +#define AUE_LGETFH 43061 /* FreeBSD-specific. */ +#define AUE_FHSTATFS 43062 /* FreeBSD-specific. */ +#define AUE_FHOPEN 43063 /* FreeBSD-specific. */ +#define AUE_FHSTAT 43064 /* FreeBSD-specific. */ +#define AUE_JAIL 43065 /* FreeBSD-specific. */ +#define AUE_EACCESS 43066 /* FreeBSD-specific. */ +#define AUE_KQUEUE 43067 /* FreeBSD-specific. */ +#define AUE_KEVENT 43068 /* FreeBSD-specific. */ +#define AUE_FSYNC 43069 +#define AUE_NMOUNT 43070 /* FreeBSD-specific. */ +#define AUE_BDFLUSH 43071 /* Linux-specific. */ +#define AUE_SETFSUID 43072 /* Linux-specific. */ +#define AUE_SETFSGID 43073 /* Linux-specific. */ +#define AUE_PERSONALITY 43074 /* Linux-specific. */ +#define AUE_SCHED_GETSCHEDULER 43075 /* POSIX.1b. */ +#define AUE_SCHED_SETSCHEDULER 43076 /* POSIX.1b. */ +#define AUE_PRCTL 43077 /* Linux-specific. */ +#define AUE_GETCWD 43078 /* FreeBSD/Linux-specific. */ +#define AUE_CAPGET 43079 /* Linux-specific. */ +#define AUE_CAPSET 43080 /* Linux-specific. */ +#define AUE_PIVOT_ROOT 43081 /* Linux-specific. */ +#define AUE_RTPRIO 43082 /* FreeBSD-specific. */ +#define AUE_SCHED_GETPARAM 43083 /* POSIX.1b. */ +#define AUE_SCHED_SETPARAM 43084 /* POSIX.1b. */ +#define AUE_SCHED_GET_PRIORITY_MAX 43085 /* POSIX.1b. */ +#define AUE_SCHED_GET_PRIORITY_MIN 43086 /* POSIX.1b. */ +#define AUE_SCHED_RR_GET_INTERVAL 43087 /* POSIX.1b. */ +#define AUE_ACL_GET_FILE 43088 /* FreeBSD. */ +#define AUE_ACL_SET_FILE 43089 /* FreeBSD. */ +#define AUE_ACL_GET_FD 43090 /* FreeBSD. */ +#define AUE_ACL_SET_FD 43091 /* FreeBSD. */ +#define AUE_ACL_DELETE_FILE 43092 /* FreeBSD. */ +#define AUE_ACL_DELETE_FD 43093 /* FreeBSD. */ +#define AUE_ACL_CHECK_FILE 43094 /* FreeBSD. */ +#define AUE_ACL_CHECK_FD 43095 /* FreeBSD. */ +#define AUE_ACL_GET_LINK 43096 /* FreeBSD. */ +#define AUE_ACL_SET_LINK 43097 /* FreeBSD. */ +#define AUE_ACL_DELETE_LINK 43098 /* FreeBSD. */ +#define AUE_ACL_CHECK_LINK 43099 /* FreeBSD. */ +#define AUE_SYSARCH 43100 /* FreeBSD. */ +#define AUE_EXTATTRCTL 43101 /* FreeBSD. */ +#define AUE_EXTATTR_GET_FILE 43102 /* FreeBSD. */ +#define AUE_EXTATTR_SET_FILE 43103 /* FreeBSD. */ +#define AUE_EXTATTR_LIST_FILE 43104 /* FreeBSD. */ +#define AUE_EXTATTR_DELETE_FILE 43105 /* FreeBSD. */ +#define AUE_EXTATTR_GET_FD 43106 /* FreeBSD. */ +#define AUE_EXTATTR_SET_FD 43107 /* FreeBSD. */ +#define AUE_EXTATTR_LIST_FD 43108 /* FreeBSD. */ +#define AUE_EXTATTR_DELETE_FD 43109 /* FreeBSD. */ +#define AUE_EXTATTR_GET_LINK 43110 /* FreeBSD. */ +#define AUE_EXTATTR_SET_LINK 43111 /* FreeBSD. */ +#define AUE_EXTATTR_LIST_LINK 43112 /* FreeBSD. */ +#define AUE_EXTATTR_DELETE_LINK 43113 /* FreeBSD. */ +#define AUE_KENV 43114 /* FreeBSD. */ +#define AUE_JAIL_ATTACH 43115 /* FreeBSD. */ +#define AUE_SYSCTL_WRITE 43116 /* FreeBSD. */ +#define AUE_IOPERM 43117 /* Linux. */ +#define AUE_READDIR 43118 /* Linux. */ +#define AUE_IOPL 43119 /* Linux. */ +#define AUE_VM86 43120 /* Linux. */ +#define AUE_MAC_GET_PROC 43121 /* FreeBSD/Darwin. */ +#define AUE_MAC_SET_PROC 43122 /* FreeBSD/Darwin. */ +#define AUE_MAC_GET_FD 43123 /* FreeBSD/Darwin. */ +#define AUE_MAC_GET_FILE 43124 /* FreeBSD/Darwin. */ +#define AUE_MAC_SET_FD 43125 /* FreeBSD/Darwin. */ +#define AUE_MAC_SET_FILE 43126 /* FreeBSD/Darwin. */ +#define AUE_MAC_SYSCALL 43127 /* FreeBSD. */ +#define AUE_MAC_GET_PID 43128 /* FreeBSD/Darwin. */ +#define AUE_MAC_GET_LINK 43129 /* FreeBSD/Darwin. */ +#define AUE_MAC_SET_LINK 43130 /* FreeBSD/Darwin. */ +#define AUE_MAC_EXECVE 43131 /* FreeBSD/Darwin. */ +#define AUE_GETPATH_FROMFD 43132 /* FreeBSD. */ +#define AUE_GETPATH_FROMADDR 43133 /* FreeBSD. */ +#define AUE_MQ_OPEN 43134 /* FreeBSD. */ +#define AUE_MQ_SETATTR 43135 /* FreeBSD. */ +#define AUE_MQ_TIMEDRECEIVE 43136 /* FreeBSD. */ +#define AUE_MQ_TIMEDSEND 43137 /* FreeBSD. */ +#define AUE_MQ_NOTIFY 43138 /* FreeBSD. */ +#define AUE_MQ_UNLINK 43139 /* FreeBSD. */ +#define AUE_LISTEN 43140 /* FreeBSD/Darwin/Linux. */ +#define AUE_MLOCKALL 43141 /* FreeBSD. */ +#define AUE_MUNLOCKALL 43142 /* FreeBSD. */ +#define AUE_CLOSEFROM 43143 /* FreeBSD. */ +#define AUE_FEXECVE 43144 /* FreeBSD. */ +#define AUE_FACCESSAT 43145 /* FreeBSD. */ +#define AUE_FCHMODAT 43146 /* FreeBSD. */ +#define AUE_LINKAT 43147 /* FreeBSD. */ +#define AUE_MKDIRAT 43148 /* FreeBSD. */ +#define AUE_MKFIFOAT 43149 /* FreeBSD. */ +#define AUE_MKNODAT 43150 /* FreeBSD. */ +#define AUE_READLINKAT 43151 /* FreeBSD. */ +#define AUE_SYMLINKAT 43152 /* FreeBSD. */ +#define AUE_MAC_GETFSSTAT 43153 /* Darwin. */ +#define AUE_MAC_GET_MOUNT 43154 /* Darwin. */ +#define AUE_MAC_GET_LCID 43155 /* Darwin. */ +#define AUE_MAC_GET_LCTX 43156 /* Darwin. */ +#define AUE_MAC_SET_LCTX 43157 /* Darwin. */ +#define AUE_MAC_MOUNT 43158 /* Darwin. */ +#define AUE_GETLCID 43159 /* Darwin. */ +#define AUE_SETLCID 43160 /* Darwin. */ +#define AUE_TASKNAMEFORPID 43161 /* Darwin. */ +#define AUE_ACCESS_EXTENDED 43162 /* Darwin. */ +#define AUE_CHMOD_EXTENDED 43163 /* Darwin. */ +#define AUE_FCHMOD_EXTENDED 43164 /* Darwin. */ +#define AUE_FSTAT_EXTENDED 43165 /* Darwin. */ +#define AUE_LSTAT_EXTENDED 43166 /* Darwin. */ +#define AUE_MKDIR_EXTENDED 43167 /* Darwin. */ +#define AUE_MKFIFO_EXTENDED 43168 /* Darwin. */ +#define AUE_OPEN_EXTENDED 43169 /* Darwin. */ +#define AUE_OPEN_EXTENDED_R 43170 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RC 43171 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RT 43172 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RTC 43173 /* Darwin. */ +#define AUE_OPEN_EXTENDED_W 43174 /* Darwin. */ +#define AUE_OPEN_EXTENDED_WC 43175 /* Darwin. */ +#define AUE_OPEN_EXTENDED_WT 43176 /* Darwin. */ +#define AUE_OPEN_EXTENDED_WTC 43177 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RW 43178 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RWC 43179 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RWT 43180 /* Darwin. */ +#define AUE_OPEN_EXTENDED_RWTC 43181 /* Darwin. */ +#define AUE_STAT_EXTENDED 43182 /* Darwin. */ +#define AUE_UMASK_EXTENDED 43183 /* Darwin. */ +#define AUE_OPENAT 43184 /* FreeBSD. */ +#define AUE_POSIX_OPENPT 43185 /* FreeBSD. */ +#define AUE_CAP_NEW 43186 /* TrustedBSD. */ +#define AUE_CAP_RIGHTS_GET 43187 /* TrustedBSD. */ +#define AUE_CAP_GETRIGHTS AUE_CAP_RIGHTS_GET +#define AUE_CAP_ENTER 43188 /* TrustedBSD. */ +#define AUE_CAP_GETMODE 43189 /* TrustedBSD. */ +#define AUE_POSIX_SPAWN 43190 /* Darwin. */ +#define AUE_FSGETPATH 43191 /* Darwin. */ +#define AUE_PREAD 43192 /* Darwin/FreeBSD. */ +#define AUE_PWRITE 43193 /* Darwin/FreeBSD. */ +#define AUE_FSCTL 43194 /* Darwin. */ +#define AUE_FFSCTL 43195 /* Darwin. */ +#define AUE_LPATHCONF 43196 /* FreeBSD. */ +#define AUE_PDFORK 43197 /* FreeBSD. */ +#define AUE_PDKILL 43198 /* FreeBSD. */ +#define AUE_PDGETPID 43199 /* FreeBSD. */ +#define AUE_PDWAIT 43200 /* FreeBSD. */ +#define AUE_WAIT6 43201 /* FreeBSD. */ +#define AUE_CAP_RIGHTS_LIMIT 43202 /* TrustedBSD. */ +#define AUE_CAP_IOCTLS_LIMIT 43203 /* TrustedBSD. */ +#define AUE_CAP_IOCTLS_GET 43204 /* TrustedBSD. */ +#define AUE_CAP_FCNTLS_LIMIT 43205 /* TrustedBSD. */ +#define AUE_CAP_FCNTLS_GET 43206 /* TrustedBSD. */ +#define AUE_BINDAT 43207 /* TrustedBSD. */ +#define AUE_CONNECTAT 43208 /* TrustedBSD. */ +#define AUE_CHFLAGSAT 43209 /* FreeBSD-specific. */ + +/* + * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the + * normal Solaris BSM identifiers. _O_ refers to it being an old, or compat + * interface. In most cases, Darwin has never implemented these system calls + * but picked up the fields in their system call table from their FreeBSD + * import. Happily, these have different names than the AUE_O* definitions + * in Solaris BSM. + */ +#define AUE_O_CREAT AUE_OPEN_RWTC /* Darwin */ +#define AUE_O_EXECVE AUE_NULL /* Darwin */ +#define AUE_O_SBREAK AUE_NULL /* Darwin */ +#define AUE_O_LSEEK AUE_NULL /* Darwin */ +#define AUE_O_MOUNT AUE_NULL /* Darwin */ +#define AUE_O_UMOUNT AUE_NULL /* Darwin */ +#define AUE_O_STAT AUE_STAT /* Darwin */ +#define AUE_O_LSTAT AUE_LSTAT /* Darwin */ +#define AUE_O_FSTAT AUE_FSTAT /* Darwin */ +#define AUE_O_GETPAGESIZE AUE_NULL /* Darwin */ +#define AUE_O_VREAD AUE_NULL /* Darwin */ +#define AUE_O_VWRITE AUE_NULL /* Darwin */ +#define AUE_O_MMAP AUE_MMAP /* Darwin */ +#define AUE_O_VADVISE AUE_NULL /* Darwin */ +#define AUE_O_VHANGUP AUE_NULL /* Darwin */ +#define AUE_O_VLIMIT AUE_NULL /* Darwin */ +#define AUE_O_WAIT AUE_NULL /* Darwin */ +#define AUE_O_GETHOSTNAME AUE_NULL /* Darwin */ +#define AUE_O_SETHOSTNAME AUE_SYSCTL /* Darwin */ +#define AUE_O_GETDOPT AUE_NULL /* Darwin */ +#define AUE_O_SETDOPT AUE_NULL /* Darwin */ +#define AUE_O_ACCEPT AUE_NULL /* Darwin */ +#define AUE_O_SEND AUE_SENDMSG /* Darwin */ +#define AUE_O_RECV AUE_RECVMSG /* Darwin */ +#define AUE_O_VTIMES AUE_NULL /* Darwin */ +#define AUE_O_SIGVEC AUE_NULL /* Darwin */ +#define AUE_O_SIGBLOCK AUE_NULL /* Darwin */ +#define AUE_O_SIGSETMASK AUE_NULL /* Darwin */ +#define AUE_O_SIGSTACK AUE_NULL /* Darwin */ +#define AUE_O_RECVMSG AUE_RECVMSG /* Darwin */ +#define AUE_O_SENDMSG AUE_SENDMSG /* Darwin */ +#define AUE_O_VTRACE AUE_NULL /* Darwin */ +#define AUE_O_RESUBA AUE_NULL /* Darwin */ +#define AUE_O_RECVFROM AUE_RECVFROM /* Darwin */ +#define AUE_O_SETREUID AUE_SETREUID /* Darwin */ +#define AUE_O_SETREGID AUE_SETREGID /* Darwin */ +#define AUE_O_GETDIRENTRIES AUE_GETDIRENTRIES /* Darwin */ +#define AUE_O_TRUNCATE AUE_TRUNCATE /* Darwin */ +#define AUE_O_FTRUNCATE AUE_FTRUNCATE /* Darwin */ +#define AUE_O_GETPEERNAME AUE_NULL /* Darwin */ +#define AUE_O_GETHOSTID AUE_NULL /* Darwin */ +#define AUE_O_SETHOSTID AUE_NULL /* Darwin */ +#define AUE_O_GETRLIMIT AUE_NULL /* Darwin */ +#define AUE_O_SETRLIMIT AUE_SETRLIMIT /* Darwin */ +#define AUE_O_KILLPG AUE_KILL /* Darwin */ +#define AUE_O_SETQUOTA AUE_NULL /* Darwin */ +#define AUE_O_QUOTA AUE_NULL /* Darwin */ +#define AUE_O_GETSOCKNAME AUE_NULL /* Darwin */ +#define AUE_O_GETDIREENTRIES AUE_GETDIREENTRIES /* Darwin */ +#define AUE_O_ASYNCDAEMON AUE_NULL /* Darwin */ +#define AUE_O_GETDOMAINNAME AUE_NULL /* Darwin */ +#define AUE_O_SETDOMAINNAME AUE_SYSCTL /* Darwin */ +#define AUE_O_PCFS_MOUNT AUE_NULL /* Darwin */ +#define AUE_O_EXPORTFS AUE_NULL /* Darwin */ +#define AUE_O_USTATE AUE_NULL /* Darwin */ +#define AUE_O_WAIT3 AUE_NULL /* Darwin */ +#define AUE_O_RPAUSE AUE_NULL /* Darwin */ +#define AUE_O_GETDENTS AUE_NULL /* Darwin */ + +/* + * Possible desired future values based on review of BSD/Darwin system calls. + */ +#define AUE_ATGETMSG AUE_NULL +#define AUE_ATPUTMSG AUE_NULL +#define AUE_ATSOCKET AUE_NULL +#define AUE_ATPGETREQ AUE_NULL +#define AUE_ATPGETRSP AUE_NULL +#define AUE_ATPSNDREQ AUE_NULL +#define AUE_ATPSNDRSP AUE_NULL +#define AUE_BSDTHREADCREATE AUE_NULL +#define AUE_BSDTHREADTERMINATE AUE_NULL +#define AUE_BSDTHREADREGISTER AUE_NULL +#define AUE_CHUD AUE_NULL +#define AUE_CSOPS AUE_NULL +#define AUE_DUP AUE_NULL +#define AUE_FDATASYNC AUE_NULL +#define AUE_FGETATTRLIST AUE_NULL +#define AUE_FGETXATTR AUE_NULL +#define AUE_FLISTXATTR AUE_NULL +#define AUE_FREMOVEXATTR AUE_NULL +#define AUE_FSETATTRLIST AUE_NULL +#define AUE_FSETXATTR AUE_NULL +#define AUE_FSTATFS64 AUE_NULL +#define AUE_FSTATV AUE_NULL +#define AUE_FSTAT64 AUE_NULL +#define AUE_FSTAT64_EXTENDED AUE_NULL +#define AUE_GCCONTROL AUE_NULL +#define AUE_GETDIRENTRIES64 AUE_NULL +#define AUE_GETDTABLESIZE AUE_NULL +#define AUE_GETEGID AUE_NULL +#define AUE_GETEUID AUE_NULL +#define AUE_GETFSSTAT64 AUE_NULL +#define AUE_GETGID AUE_NULL +#define AUE_GETGROUPS AUE_NULL +#define AUE_GETITIMER AUE_NULL +#define AUE_GETLOGIN AUE_NULL +#define AUE_GETPEERNAME AUE_NULL +#define AUE_GETPGID AUE_NULL +#define AUE_GETPGRP AUE_NULL +#define AUE_GETPID AUE_NULL +#define AUE_GETPPID AUE_NULL +#define AUE_GETPRIORITY AUE_NULL +#define AUE_GETRLIMIT AUE_NULL +#define AUE_GETRUSAGE AUE_NULL +#define AUE_GETSGROUPS AUE_NULL +#define AUE_GETSID AUE_NULL +#define AUE_GETSOCKNAME AUE_NULL +#define AUE_GETTIMEOFDAY AUE_NULL +#define AUE_GETTID AUE_NULL +#define AUE_GETUID AUE_NULL +#define AUE_GETSOCKOPT AUE_NULL +#define AUE_GETWGROUPS AUE_NULL +#define AUE_GETXATTR AUE_NULL +#define AUE_IDENTITYSVC AUE_NULL +#define AUE_INITGROUPS AUE_NULL +#define AUE_IOPOLICYSYS AUE_NULL +#define AUE_ISSETUGID AUE_NULL +#define AUE_LIOLISTIO AUE_NULL +#define AUE_LISTXATTR AUE_NULL +#define AUE_LSTATV AUE_NULL +#define AUE_LSTAT64 AUE_NULL +#define AUE_LSTAT64_EXTENDED AUE_NULL +#define AUE_MADVISE AUE_NULL +#define AUE_MINCORE AUE_NULL +#define AUE_MKCOMPLEX AUE_NULL +#define AUE_MODWATCH AUE_NULL +#define AUE_MSGCL AUE_NULL +#define AUE_MSYNC AUE_NULL +#define AUE_PREADV AUE_NULL +#define AUE_PROCINFO AUE_NULL +#define AUE_PTHREADCANCELED AUE_NULL +#define AUE_PTHREADCHDIR AUE_NULL +#define AUE_PTHREADCONDBROADCAST AUE_NULL +#define AUE_PTHREADCONDDESTORY AUE_NULL +#define AUE_PTHREADCONDINIT AUE_NULL +#define AUE_PTHREADCONDSIGNAL AUE_NULL +#define AUE_PTHREADCONDWAIT AUE_NULL +#define AUE_PTHREADFCHDIR AUE_NULL +#define AUE_PTHREADMARK AUE_NULL +#define AUE_PTHREADMUTEXDESTROY AUE_NULL +#define AUE_PTHREADMUTEXINIT AUE_NULL +#define AUE_PTHREADMUTEXTRYLOCK AUE_NULL +#define AUE_PTHREADMUTEXUNLOCK AUE_NULL +#define AUE_PWRITEV AUE_NULL +#define AUE_REMOVEXATTR AUE_NULL +#define AUE_SBRK AUE_NULL +#define AUE_SELECT AUE_NULL +#define AUE_SEMDESTROY AUE_NULL +#define AUE_SEMGETVALUE AUE_NULL +#define AUE_SEMINIT AUE_NULL +#define AUE_SEMPOST AUE_NULL +#define AUE_SEMTRYWAIT AUE_NULL +#define AUE_SEMWAIT AUE_NULL +#define AUE_SEMWAITSIGNAL AUE_NULL +#define AUE_SETITIMER AUE_NULL +#define AUE_SETSGROUPS AUE_NULL +#define AUE_SETTID AUE_NULL +#define AUE_SETTIDWITHPID AUE_NULL +#define AUE_SETWGROUPS AUE_NULL +#define AUE_SETXATTR AUE_NULL +#define AUE_SHAREDREGIONCHECK AUE_NULL +#define AUE_SHAREDREGIONMAP AUE_NULL +#define AUE_SIGACTION AUE_NULL +#define AUE_SIGALTSTACK AUE_NULL +#define AUE_SIGPENDING AUE_NULL +#define AUE_SIGPROCMASK AUE_NULL +#define AUE_SIGRETURN AUE_NULL +#define AUE_SIGSUSPEND AUE_NULL +#define AUE_SIGWAIT AUE_NULL +#define AUE_SSTK AUE_NULL +#define AUE_STACKSNAPSHOT AUE_NULL +#define AUE_STATFS64 AUE_NULL +#define AUE_STATV AUE_NULL +#define AUE_STAT64 AUE_NULL +#define AUE_STAT64_EXTENDED AUE_NULL +#define AUE_SYNC AUE_NULL +#define AUE_SYSCALL AUE_NULL +#define AUE_TABLE AUE_NULL +#define AUE_VMPRESSUREMONITOR AUE_NULL +#define AUE_WAITEVENT AUE_NULL +#define AUE_WAITID AUE_NULL +#define AUE_WATCHEVENT AUE_NULL +#define AUE_WORKQOPEN AUE_NULL +#define AUE_WORKQOPS AUE_NULL + +#endif /* !_BSM_AUDIT_KEVENTS_H_ */ diff --git a/src/include.new/bsm/audit_record.h b/src/include.new/bsm/audit_record.h new file mode 100644 index 0000000..c2fc3b6 --- /dev/null +++ b/src/include.new/bsm/audit_record.h @@ -0,0 +1,305 @@ +/*- + * Copyright (c) 2005-2009 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#10 + * $FreeBSD: releng/10.2/sys/bsm/audit_record.h 255219 2013-09-05 00:09:56Z pjd $ + */ + +#ifndef _BSM_AUDIT_RECORD_H_ +#define _BSM_AUDIT_RECORD_H_ + +#include /* struct timeval */ +#include /* cap_rights_t */ + +/* + * Token type identifiers. + */ +#define AUT_INVALID 0x00 +#define AUT_OTHER_FILE32 0x11 +#define AUT_OHEADER 0x12 +#define AUT_TRAILER 0x13 +#define AUT_HEADER32 0x14 +#define AUT_HEADER32_EX 0x15 +#define AUT_DATA 0x21 +#define AUT_IPC 0x22 +#define AUT_PATH 0x23 +#define AUT_SUBJECT32 0x24 +#define AUT_XATPATH 0x25 +#define AUT_PROCESS32 0x26 +#define AUT_RETURN32 0x27 +#define AUT_TEXT 0x28 +#define AUT_OPAQUE 0x29 +#define AUT_IN_ADDR 0x2a +#define AUT_IP 0x2b +#define AUT_IPORT 0x2c +#define AUT_ARG32 0x2d +#define AUT_SOCKET 0x2e +#define AUT_SEQ 0x2f +#define AUT_ACL 0x30 +#define AUT_ATTR 0x31 +#define AUT_IPC_PERM 0x32 +#define AUT_LABEL 0x33 +#define AUT_GROUPS 0x34 +#define AUT_ACE 0x35 +#define AUT_PRIV 0x38 +#define AUT_UPRIV 0x39 +#define AUT_LIAISON 0x3a +#define AUT_NEWGROUPS 0x3b +#define AUT_EXEC_ARGS 0x3c +#define AUT_EXEC_ENV 0x3d +#define AUT_ATTR32 0x3e +#define AUT_UNAUTH 0x3f +#define AUT_XATOM 0x40 +#define AUT_XOBJ 0x41 +#define AUT_XPROTO 0x42 +#define AUT_XSELECT 0x43 +#define AUT_XCOLORMAP 0x44 +#define AUT_XCURSOR 0x45 +#define AUT_XFONT 0x46 +#define AUT_XGC 0x47 +#define AUT_XPIXMAP 0x48 +#define AUT_XPROPERTY 0x49 +#define AUT_XWINDOW 0x4a +#define AUT_XCLIENT 0x4b +#define AUT_CMD 0x51 +#define AUT_EXIT 0x52 +#define AUT_ZONENAME 0x60 +#define AUT_HOST 0x70 +#define AUT_ARG64 0x71 +#define AUT_RETURN64 0x72 +#define AUT_ATTR64 0x73 +#define AUT_HEADER64 0x74 +#define AUT_SUBJECT64 0x75 +#define AUT_PROCESS64 0x77 +#define AUT_OTHER_FILE64 0x78 +#define AUT_HEADER64_EX 0x79 +#define AUT_SUBJECT32_EX 0x7a +#define AUT_PROCESS32_EX 0x7b +#define AUT_SUBJECT64_EX 0x7c +#define AUT_PROCESS64_EX 0x7d +#define AUT_IN_ADDR_EX 0x7e +#define AUT_SOCKET_EX 0x7f + +/* + * Pre-64-bit BSM, 32-bit tokens weren't explicitly named as '32'. We have + * compatibility defines. + */ +#define AUT_HEADER AUT_HEADER32 +#define AUT_ARG AUT_ARG32 +#define AUT_RETURN AUT_RETURN32 +#define AUT_SUBJECT AUT_SUBJECT32 +#define AUT_PROCESS AUT_PROCESS32 +#define AUT_OTHER_FILE AUT_OTHER_FILE32 + +/* + * The values for the following token ids are not defined by BSM. + * + * XXXRW: Not sure how to handle these in OpenBSM yet, but I'll give them + * names more consistent with Sun's BSM. These originally came from Apple's + * BSM. + */ +#define AUT_SOCKINET32 0x80 /* XXX */ +#define AUT_SOCKINET128 0x81 /* XXX */ +#define AUT_SOCKUNIX 0x82 /* XXX */ + +#define AUT_RIGHTS 0x83 + +/* print values for the arbitrary token */ +#define AUP_BINARY 0 +#define AUP_OCTAL 1 +#define AUP_DECIMAL 2 +#define AUP_HEX 3 +#define AUP_STRING 4 + +/* data-types for the arbitrary token */ +#define AUR_BYTE 0 +#define AUR_CHAR AUR_BYTE +#define AUR_SHORT 1 +#define AUR_INT32 2 +#define AUR_INT AUR_INT32 +#define AUR_INT64 3 + +/* ... and their sizes */ +#define AUR_BYTE_SIZE sizeof(u_char) +#define AUR_CHAR_SIZE AUR_BYTE_SIZE +#define AUR_SHORT_SIZE sizeof(uint16_t) +#define AUR_INT32_SIZE sizeof(uint32_t) +#define AUR_INT_SIZE AUR_INT32_SIZE +#define AUR_INT64_SIZE sizeof(uint64_t) + +/* Modifiers for the header token */ +#define PAD_NOTATTR 0x4000 /* nonattributable event */ +#define PAD_FAILURE 0x8000 /* fail audit event */ + +#define AUDIT_MAX_GROUPS 16 + +/* + * A number of BSM versions are floating around and defined. Here are + * constants for them. OpenBSM uses the same token types, etc, used in the + * Solaris BSM version, but has a separate version number in order to + * identify a potentially different event identifier name space. + */ +#define AUDIT_HEADER_VERSION_OLDDARWIN 1 /* In retrospect, a mistake. */ +#define AUDIT_HEADER_VERSION_SOLARIS 2 +#define AUDIT_HEADER_VERSION_TSOL25 3 +#define AUDIT_HEADER_VERSION_TSOL 4 +#define AUDIT_HEADER_VERSION_OPENBSM10 10 +#define AUDIT_HEADER_VERSION_OPENBSM11 11 +#define AUDIT_HEADER_VERSION_OPENBSM AUDIT_HEADER_VERSION_OPENBSM11 + +#define AUT_TRAILER_MAGIC 0xb105 + +/* BSM library calls */ + +__BEGIN_DECLS + +struct in_addr; +struct in6_addr; +struct ip; +struct ipc_perm; +struct kevent; +struct sockaddr; +struct sockaddr_in; +struct sockaddr_in6; +struct sockaddr_un; +#if defined(_KERNEL) || defined(KERNEL) +struct vnode_au_info; +#endif + +int au_open(void); +int au_write(int d, token_t *m); +int au_close(int d, int keep, short event); +int au_close_buffer(int d, short event, u_char *buffer, size_t *buflen); +int au_close_token(token_t *tok, u_char *buffer, size_t *buflen); + +token_t *au_to_file(const char *file, struct timeval tm); + +token_t *au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm); +token_t *au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm, struct auditinfo_addr *aia); +token_t *au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm); +#if !defined(KERNEL) && !defined(_KERNEL) +token_t *au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod); +token_t *au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod); +token_t *au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod); +token_t *au_to_header64(int rec_size, au_event_t e_type, au_emod_t e_mod); +token_t *au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod); +#endif + +token_t *au_to_me(void); +token_t *au_to_arg(char n, const char *text, uint32_t v); +token_t *au_to_arg32(char n, const char *text, uint32_t v); +token_t *au_to_arg64(char n, const char *text, uint64_t v); + +#if defined(_KERNEL) || defined(KERNEL) +token_t *au_to_attr(struct vnode_au_info *vni); +token_t *au_to_attr32(struct vnode_au_info *vni); +token_t *au_to_attr64(struct vnode_au_info *vni); +#endif + +token_t *au_to_data(char unit_print, char unit_type, char unit_count, + const char *p); +token_t *au_to_exit(int retval, int err); +token_t *au_to_groups(int *groups); +token_t *au_to_newgroups(uint16_t n, gid_t *groups); +token_t *au_to_in_addr(struct in_addr *internet_addr); +token_t *au_to_in_addr_ex(struct in6_addr *internet_addr); +token_t *au_to_ip(struct ip *ip); +token_t *au_to_ipc(char type, int id); +token_t *au_to_ipc_perm(struct ipc_perm *perm); +token_t *au_to_iport(uint16_t iport); +token_t *au_to_opaque(const char *data, uint16_t bytes); +token_t *au_to_path(const char *path); +token_t *au_to_privset(char *privtypestr, char *privstr); +token_t *au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, + uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, + au_tid_addr_t *tid); +token_t *au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_rights(cap_rights_t *rightsp); +token_t *au_to_return(char status, uint32_t ret); +token_t *au_to_return32(char status, uint32_t ret); +token_t *au_to_return64(char status, uint64_t ret); +token_t *au_to_seq(long audit_count); +token_t *au_to_socket_ex(u_short so_domain, u_short so_type, + struct sockaddr *sa_local, struct sockaddr *sa_remote); +token_t *au_to_sock_inet(struct sockaddr_in *so); +token_t *au_to_sock_inet32(struct sockaddr_in *so); +token_t *au_to_sock_inet128(struct sockaddr_in6 *so); +token_t *au_to_sock_unix(struct sockaddr_un *so); +token_t *au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid); +token_t *au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +#if defined(_KERNEL) || defined(KERNEL) +token_t *au_to_exec_args(char *args, int argc); +token_t *au_to_exec_env(char *envs, int envc); +#else +token_t *au_to_exec_args(char **argv); +token_t *au_to_exec_env(char **envp); +#endif +token_t *au_to_text(const char *text); +token_t *au_to_kevent(struct kevent *kev); +token_t *au_to_trailer(int rec_size); +token_t *au_to_upriv(char sorf, char *priv); +token_t *au_to_zonename(const char *zonename); + +/* + * BSM library routines for converting between local and BSM constant spaces. + */ +int au_bsm_to_domain(u_short bsm_domain, int *local_domainp); +int au_bsm_to_errno(u_char bsm_error, int *errorp); +int au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp); +int au_bsm_to_socket_type(u_short bsm_socket_type, + int *local_socket_typep); +u_short au_domain_to_bsm(int local_domain); +u_char au_errno_to_bsm(int local_errno); +u_short au_fcntl_cmd_to_bsm(int local_fcntl_command); +u_short au_socket_type_to_bsm(int local_socket_type); + +__END_DECLS + +#endif /* ! _BSM_AUDIT_RECORD_H_ */ diff --git a/src/include.new/bsm/audit_socket_type.h b/src/include.new/bsm/audit_socket_type.h new file mode 100644 index 0000000..b932e10 --- /dev/null +++ b/src/include.new/bsm/audit_socket_type.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2008 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_socket_type.h#1 + * $FreeBSD: releng/10.2/sys/bsm/audit_socket_type.h 187214 2009-01-14 10:44:16Z rwatson $ + */ + +#ifndef _BSM_AUDIT_SOCKET_TYPE_H_ +#define _BSM_AUDIT_SOCKET_TYPE_H_ + +/* + * BSM socket type constants. + */ +#define BSM_SOCK_DGRAM 1 +#define BSM_SOCK_STREAM 2 +#define BSM_SOCK_RAW 4 +#define BSM_SOCK_RDM 5 +#define BSM_SOCK_SEQPACKET 6 + +#define BSM_SOCK_UNKNOWN 500 + +#endif /* !_BSM_AUDIT_SOCKET_TYPE_H_ */ diff --git a/src/include.new/bsm/audit_uevents.h b/src/include.new/bsm/audit_uevents.h new file mode 100644 index 0000000..f71797b --- /dev/null +++ b/src/include.new/bsm/audit_uevents.h @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 2004-2008 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit_uevents.h#11 $ + */ + +#ifndef _BSM_AUDIT_UEVENTS_H_ +#define _BSM_AUDIT_UEVENTS_H_ + +/* + * Solaris userspace events. + */ +#define AUE_at_create 6144 +#define AUE_at_delete 6145 +#define AUE_at_perm 6146 +#define AUE_cron_invoke 6147 +#define AUE_crontab_create 6148 +#define AUE_crontab_delete 6149 +#define AUE_crontab_perm 6150 +#define AUE_inetd_connect 6151 +#define AUE_login 6152 +#define AUE_logout 6153 +#define AUE_telnet 6154 +#define AUE_rlogin 6155 +#define AUE_mountd_mount 6156 +#define AUE_mountd_umount 6157 +#define AUE_rshd 6158 +#define AUE_su 6159 +#define AUE_halt 6160 +#define AUE_reboot 6161 +#define AUE_rexecd 6162 +#define AUE_passwd 6163 +#define AUE_rexd 6164 +#define AUE_ftpd 6165 +#define AUE_init 6166 +#define AUE_uadmin 6167 +#define AUE_shutdown 6168 +#define AUE_poweroff 6169 +#define AUE_crontab_mod 6170 +#define AUE_ftpd_logout 6171 +#define AUE_ssh 6172 +#define AUE_role_login 6173 +#define AUE_prof_cmd 6180 +#define AUE_filesystem_add 6181 +#define AUE_filesystem_delete 6182 +#define AUE_filesystem_modify 6183 +#define AUE_allocate_succ 6200 +#define AUE_allocate_fail 6201 +#define AUE_deallocate_succ 6202 +#define AUE_deallocate_fail 6203 +#define AUE_listdevice_succ 6205 +#define AUE_listdevice_fail 6206 +#define AUE_create_user 6207 +#define AUE_modify_user 6208 +#define AUE_delete_user 6209 +#define AUE_disable_user 6210 +#define AUE_enable_user 6211 +#define AUE_newgrp_login 6212 +#define AUE_admin_authentication 6213 +#define AUE_kadmind_auth 6214 +#define AUE_kadmind_unauth 6215 +#define AUE_krb5kdc_as_req 6216 +#define AUE_krb5kdc_tgs_req 6217 +#define AUE_krb5kdc_tgs_req_2ndtktmm 6218 +#define AUE_krb5kdc_tgs_req_alt_tgt 6219 + +/* + * Historic Darwin use of the low event numbering space, which collided with + * the Solaris event space. Now obsoleted and new, higher, event numbers + * assigned to make it easier to interpret Solaris events using the OpenBSM + * tools. + */ +#define AUE_DARWIN_audit_startup 6171 +#define AUE_DARWIN_audit_shutdown 6172 +#define AUE_DARWIN_sudo 6300 +#define AUE_DARWIN_modify_password 6501 +#define AUE_DARWIN_create_group 6511 +#define AUE_DARWIN_delete_group 6512 +#define AUE_DARWIN_modify_group 6513 +#define AUE_DARWIN_add_to_group 6514 +#define AUE_DARWIN_remove_from_group 6515 +#define AUE_DARWIN_revoke_obj 6521 +#define AUE_DARWIN_lw_login 6600 +#define AUE_DARWIN_lw_logout 6601 +#define AUE_DARWIN_auth_user 7000 +#define AUE_DARWIN_ssconn 7001 +#define AUE_DARWIN_ssauthorize 7002 +#define AUE_DARWIN_ssauthint 7003 + +/* + * Historic/third-party appliation allocations of event idenfiers. + */ +#define AUE_openssh 32800 + +/* + * OpenBSM-managed application event space. + */ +#define AUE_audit_startup 45000 /* Darwin-specific. */ +#define AUE_audit_shutdown 45001 /* Darwin-specific. */ +#define AUE_modify_password 45014 /* Darwin-specific. */ +#define AUE_create_group 45015 /* Darwin-specific. */ +#define AUE_delete_group 45016 /* Darwin-specific. */ +#define AUE_modify_group 45017 /* Darwin-specific. */ +#define AUE_add_to_group 45018 /* Darwin-specific. */ +#define AUE_remove_from_group 45019 /* Darwin-specific. */ +#define AUE_revoke_obj 45020 /* Darwin-specific. */ +#define AUE_lw_login 45021 /* Darwin-specific. */ +#define AUE_lw_logout 45022 /* Darwin-specific. */ +#define AUE_auth_user 45023 /* Darwin-specific. */ +#define AUE_ssconn 45024 /* Darwin-specific. */ +#define AUE_ssauthorize 45025 /* Darwin-specific. */ +#define AUE_ssauthint 45026 /* Darwin-specific. */ +#define AUE_calife 45027 /* OpenBSM-allocated. */ +#define AUE_sudo 45028 /* OpenBSM-allocated. */ +#define AUE_audit_recovery 45029 /* OpenBSM-allocated. */ +#define AUE_ssauthmech 45030 /* Darwin-specific. */ + +#endif /* !_BSM_AUDIT_UEVENTS_H_ */ diff --git a/src/include.new/bsm/libbsm.h b/src/include.new/bsm/libbsm.h new file mode 100644 index 0000000..b678a23 --- /dev/null +++ b/src/include.new/bsm/libbsm.h @@ -0,0 +1,1342 @@ +/*- + * Copyright (c) 2004-2009 Apple Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#50 $ + */ + +#ifndef _LIBBSM_H_ +#define _LIBBSM_H_ + +/* + * NB: definitions, etc., marked with "OpenSSH compatibility" were introduced + * solely to allow OpenSSH to compile; Darwin/Apple code should not use them. + */ + +#include +#include + +#include /* Required for audit.h. */ +#include /* Required for clock_t on Linux. */ + +#include +#include + +#include + +#ifdef __APPLE__ +#include /* audit_token_t */ +#endif + +/* + * Size parsed token vectors for execve(2) arguments and environmental + * variables. Note: changing these sizes affects the ABI of the token + * structure, and as the token structure is often placed in the caller stack, + * this is undesirable. + */ +#define AUDIT_MAX_ARGS 128 +#define AUDIT_MAX_ENV 128 + +/* + * Arguments to au_preselect(3). + */ +#define AU_PRS_USECACHE 0 +#define AU_PRS_REREAD 1 + +#define AU_PRS_SUCCESS 1 +#define AU_PRS_FAILURE 2 +#define AU_PRS_BOTH (AU_PRS_SUCCESS|AU_PRS_FAILURE) + +#define AUDIT_EVENT_FILE "/etc/security/audit_event" +#define AUDIT_CLASS_FILE "/etc/security/audit_class" +#define AUDIT_CONTROL_FILE "/etc/security/audit_control" +#define AUDIT_USER_FILE "/etc/security/audit_user" + +#define DIR_CONTROL_ENTRY "dir" +#define DIST_CONTROL_ENTRY "dist" +#define FILESZ_CONTROL_ENTRY "filesz" +#define FLAGS_CONTROL_ENTRY "flags" +#define HOST_CONTROL_ENTRY "host" +#define MINFREE_CONTROL_ENTRY "minfree" +#define NA_CONTROL_ENTRY "naflags" +#define POLICY_CONTROL_ENTRY "policy" +#define EXPIRE_AFTER_CONTROL_ENTRY "expire-after" + +#define AU_CLASS_NAME_MAX 8 +#define AU_CLASS_DESC_MAX 72 +#define AU_EVENT_NAME_MAX 30 +#define AU_EVENT_DESC_MAX 50 +#define AU_USER_NAME_MAX 50 +#define AU_LINE_MAX 256 +#define MAX_AUDITSTRING_LEN 256 +#define BSM_TEXTBUFSZ MAX_AUDITSTRING_LEN /* OpenSSH compatibility */ + +/* + * Arguments to au_close(3). + */ +#define AU_TO_NO_WRITE 0 /* Abandon audit record. */ +#define AU_TO_WRITE 1 /* Commit audit record. */ + +/* + * Output format flags for au_print_flags_tok(). + */ +#define AU_OFLAG_NONE 0x0000 /* Default form. */ +#define AU_OFLAG_RAW 0x0001 /* Raw, numeric form. */ +#define AU_OFLAG_SHORT 0x0002 /* Short form. */ +#define AU_OFLAG_XML 0x0004 /* XML form. */ +#define AU_OFLAG_NORESOLVE 0x0008 /* No user/group name resolution. */ + +__BEGIN_DECLS +struct au_event_ent { + au_event_t ae_number; + char *ae_name; + char *ae_desc; + au_class_t ae_class; +}; +typedef struct au_event_ent au_event_ent_t; + +struct au_class_ent { + char *ac_name; + au_class_t ac_class; + char *ac_desc; +}; +typedef struct au_class_ent au_class_ent_t; + +struct au_user_ent { + char *au_name; + au_mask_t au_always; + au_mask_t au_never; +}; +typedef struct au_user_ent au_user_ent_t; +__END_DECLS + +#define ADD_TO_MASK(m, c, sel) do { \ + if (sel & AU_PRS_SUCCESS) \ + (m)->am_success |= c; \ + if (sel & AU_PRS_FAILURE) \ + (m)->am_failure |= c; \ +} while (0) + +#define SUB_FROM_MASK(m, c, sel) do { \ + if (sel & AU_PRS_SUCCESS) \ + (m)->am_success &= ((m)->am_success ^ c); \ + if (sel & AU_PRS_FAILURE) \ + (m)->am_failure &= ((m)->am_failure ^ c); \ +} while (0) + +#define ADDMASK(m, v) do { \ + (m)->am_success |= (v)->am_success; \ + (m)->am_failure |= (v)->am_failure; \ +} while(0) + +#define SUBMASK(m, v) do { \ + (m)->am_success &= ((m)->am_success ^ (v)->am_success); \ + (m)->am_failure &= ((m)->am_failure ^ (v)->am_failure); \ +} while(0) + +__BEGIN_DECLS + +typedef struct au_tid32 { + uint32_t port; + uint32_t addr; +} au_tid32_t; + +typedef struct au_tid64 { + u_int64_t port; + uint32_t addr; +} au_tid64_t; + +typedef struct au_tidaddr32 { + uint32_t port; + uint32_t type; + uint32_t addr[4]; +} au_tidaddr32_t; + +typedef struct au_tidaddr64 { + u_int64_t port; + uint32_t type; + uint32_t addr[4]; +} au_tidaddr64_t; + +/* + * argument # 1 byte + * argument value 4 bytes/8 bytes (32-bit/64-bit value) + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +typedef struct { + u_char no; + uint32_t val; + u_int16_t len; + char *text; +} au_arg32_t; + +typedef struct { + u_char no; + u_int64_t val; + u_int16_t len; + char *text; +} au_arg64_t; + +/* + * how to print 1 byte + * basic unit 1 byte + * unit count 1 byte + * data items (depends on basic unit) + */ +typedef struct { + u_char howtopr; + u_char bu; + u_char uc; + u_char *data; +} au_arb_t; + +/* + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +typedef struct { + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint32_t fsid; + u_int64_t nid; + uint32_t dev; +} au_attr32_t; + +typedef struct { + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint32_t fsid; + u_int64_t nid; + u_int64_t dev; +} au_attr64_t; + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +typedef struct { + uint32_t count; + char *text[AUDIT_MAX_ARGS]; +} au_execarg_t; + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +typedef struct { + uint32_t count; + char *text[AUDIT_MAX_ENV]; +} au_execenv_t; + +/* + * status 4 bytes + * return value 4 bytes + */ +typedef struct { + uint32_t status; + uint32_t ret; +} au_exit_t; + +/* + * seconds of time 4 bytes + * milliseconds of time 4 bytes + * file name length 2 bytes + * file pathname N bytes + 1 terminating NULL byte + */ +typedef struct { + uint32_t s; + uint32_t ms; + u_int16_t len; + char *name; +} au_file_t; + + +/* + * number groups 2 bytes + * group list N * 4 bytes + */ +typedef struct { + u_int16_t no; + uint32_t list[AUDIT_MAX_GROUPS]; +} au_groups_t; + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +typedef struct { + uint32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + uint32_t s; + uint32_t ms; +} au_header32_t; + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 1 byte (XXX: actually, 4 bytes) + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32/64-bits) + * nanoseconds of time 4 bytes/8 bytes (32/64-bits) + */ +typedef struct { + uint32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + uint32_t ad_type; + uint32_t addr[4]; + uint32_t s; + uint32_t ms; +} au_header32_ex_t; + +typedef struct { + uint32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + u_int64_t s; + u_int64_t ms; +} au_header64_t; + +typedef struct { + uint32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + uint32_t ad_type; + uint32_t addr[4]; + u_int64_t s; + u_int64_t ms; +} au_header64_ex_t; + +/* + * internet address 4 bytes + */ +typedef struct { + uint32_t addr; +} au_inaddr_t; + +/* + * type 4 bytes + * internet address 16 bytes + */ +typedef struct { + uint32_t type; + uint32_t addr[4]; +} au_inaddr_ex_t; + +/* + * version and ihl 1 byte + * type of service 1 byte + * length 2 bytes + * id 2 bytes + * offset 2 bytes + * ttl 1 byte + * protocol 1 byte + * checksum 2 bytes + * source address 4 bytes + * destination address 4 bytes + */ +typedef struct { + u_char version; + u_char tos; + u_int16_t len; + u_int16_t id; + u_int16_t offset; + u_char ttl; + u_char prot; + u_int16_t chksm; + uint32_t src; + uint32_t dest; +} au_ip_t; + +/* + * object ID type 1 byte + * object ID 4 bytes + */ +typedef struct { + u_char type; + uint32_t id; +} au_ipc_t; + +/* + * owner user ID 4 bytes + * owner group ID 4 bytes + * creator user ID 4 bytes + * creator group ID 4 bytes + * access mode 4 bytes + * slot sequence # 4 bytes + * key 4 bytes + */ +typedef struct { + uint32_t uid; + uint32_t gid; + uint32_t puid; + uint32_t pgid; + uint32_t mode; + uint32_t seq; + uint32_t key; +} au_ipcperm_t; + +/* + * port IP address 2 bytes + */ +typedef struct { + u_int16_t port; +} au_iport_t; + +/* + * length 2 bytes + * data length bytes + */ +typedef struct { + u_int16_t size; + char *data; +} au_opaque_t; + +/* + * path length 2 bytes + * path N bytes + 1 terminating NULL byte + */ +typedef struct { + u_int16_t len; + char *path; +} au_path_t; + +/* + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tid32_t tid; +} au_proc32_t; + +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tid64_t tid; +} au_proc64_t; + +/* + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * type 4 bytes + * machine address 16 bytes + */ +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tidaddr32_t tid; +} au_proc32ex_t; + +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tidaddr64_t tid; +} au_proc64ex_t; + +/* + * error status 1 byte + * return value 4 bytes/8 bytes (32-bit/64-bit value) + */ +typedef struct { + u_char status; + uint32_t ret; +} au_ret32_t; + +typedef struct { + u_char err; + u_int64_t val; +} au_ret64_t; + +/* + * sequence number 4 bytes + */ +typedef struct { + uint32_t seqno; +} au_seq_t; + +/* + * socket type 2 bytes + * local port 2 bytes + * local Internet address 4 bytes + * remote port 2 bytes + * remote Internet address 4 bytes + */ +typedef struct { + u_int16_t type; + u_int16_t l_port; + uint32_t l_addr; + u_int16_t r_port; + uint32_t r_addr; +} au_socket_t; + +/* + * socket type 2 bytes + * local port 2 bytes + * address type/length 4 bytes + * local Internet address 4 bytes/16 bytes (IPv4/IPv6 address) + * remote port 4 bytes + * address type/length 4 bytes + * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address) + */ +typedef struct { + u_int16_t domain; + u_int16_t type; + u_int16_t atype; + u_int16_t l_port; + uint32_t l_addr[4]; + uint32_t r_port; + uint32_t r_addr[4]; +} au_socket_ex32_t; + +/* + * socket family 2 bytes + * local port 2 bytes + * socket address 4 bytes/16 bytes (IPv4/IPv6 address) + */ +typedef struct { + u_int16_t family; + u_int16_t port; + uint32_t addr[4]; +} au_socketinet_ex32_t; + +typedef struct { + u_int16_t family; + u_int16_t port; + uint32_t addr; +} au_socketinet32_t; + +/* + * socket family 2 bytes + * path 104 bytes + */ +typedef struct { + u_int16_t family; + char path[104]; +} au_socketunix_t; + +/* + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tid32_t tid; +} au_subject32_t; + +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tid64_t tid; +} au_subject64_t; + +/* + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * type 4 bytes + * machine address 16 bytes + */ +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tidaddr32_t tid; +} au_subject32ex_t; + +typedef struct { + uint32_t auid; + uint32_t euid; + uint32_t egid; + uint32_t ruid; + uint32_t rgid; + uint32_t pid; + uint32_t sid; + au_tidaddr64_t tid; +} au_subject64ex_t; + +/* + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +typedef struct { + u_int16_t len; + char *text; +} au_text_t; + +/* + * upriv status 1 byte + * privstr len 2 bytes + * privstr N bytes + 1 (\0 byte) + */ +typedef struct { + u_int8_t sorf; + u_int16_t privstrlen; + char *priv; +} au_priv_t; + +/* +* privset +* privtstrlen 2 bytes +* privtstr N Bytes + 1 +* privstrlen 2 bytes +* privstr N Bytes + 1 +*/ +typedef struct { + u_int16_t privtstrlen; + char *privtstr; + u_int16_t privstrlen; + char *privstr; +} au_privset_t; + +/* + * zonename length 2 bytes + * zonename text N bytes + 1 NULL terminator + */ +typedef struct { + u_int16_t len; + char *zonename; +} au_zonename_t; + +typedef struct { + uint32_t ident; + u_int16_t filter; + u_int16_t flags; + uint32_t fflags; + uint32_t data; +} au_kevent_t; + +typedef struct { + u_int16_t length; + char *data; +} au_invalid_t; + +/* + * trailer magic number 2 bytes + * record byte count 4 bytes + */ +typedef struct { + u_int16_t magic; + uint32_t count; +} au_trailer_t; + +struct tokenstr { + u_char id; + u_char *data; + size_t len; + union { + au_arg32_t arg32; + au_arg64_t arg64; + au_arb_t arb; + au_attr32_t attr32; + au_attr64_t attr64; + au_execarg_t execarg; + au_execenv_t execenv; + au_exit_t exit; + au_file_t file; + au_groups_t grps; + au_header32_t hdr32; + au_header32_ex_t hdr32_ex; + au_header64_t hdr64; + au_header64_ex_t hdr64_ex; + au_inaddr_t inaddr; + au_inaddr_ex_t inaddr_ex; + au_ip_t ip; + au_ipc_t ipc; + au_ipcperm_t ipcperm; + au_iport_t iport; + au_opaque_t opaque; + au_path_t path; + au_proc32_t proc32; + au_proc32ex_t proc32_ex; + au_proc64_t proc64; + au_proc64ex_t proc64_ex; + au_ret32_t ret32; + au_ret64_t ret64; + au_seq_t seq; + au_socket_t socket; + au_socket_ex32_t socket_ex32; + au_socketinet_ex32_t sockinet_ex32; + au_socketunix_t sockunix; + au_subject32_t subj32; + au_subject32ex_t subj32_ex; + au_subject64_t subj64; + au_subject64ex_t subj64_ex; + au_text_t text; + au_kevent_t kevent; + au_invalid_t invalid; + au_trailer_t trail; + au_zonename_t zonename; + au_priv_t priv; + au_privset_t privset; + } tt; /* The token is one of the above types */ +}; + +typedef struct tokenstr tokenstr_t; + +int audit_submit(short au_event, au_id_t auid, + char status, int reterr, const char *fmt, ...); + +/* + * Functions relating to querying audit class information. + */ +void setauclass(void); +void endauclass(void); +struct au_class_ent *getauclassent(void); +struct au_class_ent *getauclassent_r(au_class_ent_t *class_int); +struct au_class_ent *getauclassnam(const char *name); +struct au_class_ent *getauclassnam_r(au_class_ent_t *class_int, + const char *name); +struct au_class_ent *getauclassnum(au_class_t class_number); +struct au_class_ent *getauclassnum_r(au_class_ent_t *class_int, + au_class_t class_number); + +/* + * Functions relating to querying audit control information. + */ +void setac(void); +void endac(void); +int getacdir(char *name, int len); +int getacdist(void); +int getacexpire(int *andflg, time_t *age, size_t *size); +int getacfilesz(size_t *size_val); +int getacflg(char *auditstr, int len); +int getachost(char *auditstr, size_t len); +int getacmin(int *min_val); +int getacna(char *auditstr, int len); +int getacpol(char *auditstr, size_t len); +int getauditflagsbin(char *auditstr, au_mask_t *masks); +int getauditflagschar(char *auditstr, au_mask_t *masks, + int verbose); +int au_preselect(au_event_t event, au_mask_t *mask_p, + int sorf, int flag); +ssize_t au_poltostr(int policy, size_t maxsize, char *buf); +int au_strtopol(const char *polstr, int *policy); + +/* + * Functions relating to querying audit event information. + */ +void setauevent(void); +void endauevent(void); +struct au_event_ent *getauevent(void); +struct au_event_ent *getauevent_r(struct au_event_ent *e); +struct au_event_ent *getauevnam(const char *name); +struct au_event_ent *getauevnam_r(struct au_event_ent *e, + const char *name); +struct au_event_ent *getauevnum(au_event_t event_number); +struct au_event_ent *getauevnum_r(struct au_event_ent *e, + au_event_t event_number); +au_event_t *getauevnonam(const char *event_name); +au_event_t *getauevnonam_r(au_event_t *ev, + const char *event_name); + +/* + * Functions relating to querying audit user information. + */ +void setauuser(void); +void endauuser(void); +struct au_user_ent *getauuserent(void); +struct au_user_ent *getauuserent_r(struct au_user_ent *u); +struct au_user_ent *getauusernam(const char *name); +struct au_user_ent *getauusernam_r(struct au_user_ent *u, + const char *name); +int au_user_mask(char *username, au_mask_t *mask_p); +int getfauditflags(au_mask_t *usremask, + au_mask_t *usrdmask, au_mask_t *lastmask); + +/* + * Functions for reading and printing records and tokens from audit trails. + */ +int au_read_rec(FILE *fp, u_char **buf); +int au_fetch_tok(tokenstr_t *tok, u_char *buf, int len); +//XXX The following interface has different prototype from BSM +void au_print_tok(FILE *outfp, tokenstr_t *tok, + char *del, char raw, char sfrm); +void au_print_flags_tok(FILE *outfp, tokenstr_t *tok, + char *del, int oflags); +void au_print_tok_xml(FILE *outfp, tokenstr_t *tok, + char *del, char raw, char sfrm); + +/* + * Functions relating to XML output. + */ +void au_print_xml_header(FILE *outfp); +void au_print_xml_footer(FILE *outfp); + +/* + * BSM library routines for converting between local and BSM constant spaces. + * (Note: some of these are replicated in audit_record.h for the benefit of + * the FreeBSD and Mac OS X kernels) + */ +int au_bsm_to_domain(u_short bsm_domain, int *local_domainp); +int au_bsm_to_errno(u_char bsm_error, int *errorp); +int au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp); +int au_bsm_to_socket_type(u_short bsm_socket_type, + int *local_socket_typep); +u_short au_domain_to_bsm(int local_domain); +u_char au_errno_to_bsm(int local_errno); +u_short au_fcntl_cmd_to_bsm(int local_fcntl_command); +u_short au_socket_type_to_bsm(int local_socket_type); + +const char *au_strerror(u_char bsm_error); +__END_DECLS + +/* + * The remaining APIs are associated with Apple's BSM implementation, in + * particular as relates to Mach IPC auditing and triggers passed via Mach + * IPC. + */ +#ifdef __APPLE__ +#include + +/************************************************************************** + ************************************************************************** + ** The following definitions, functions, etc., are NOT officially + ** supported: they may be changed or removed in the future. Do not use + ** them unless you are prepared to cope with that eventuality. + ************************************************************************** + **************************************************************************/ + +#ifdef __APPLE_API_PRIVATE +#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change" +#endif /* __APPLE_API_PRIVATE */ + +/* + * au_get_state() return values + * XXX use AUC_* values directly instead (); AUDIT_OFF and + * AUDIT_ON are deprecated and WILL be removed. + */ +#ifdef __APPLE_API_PRIVATE +#define AUDIT_OFF AUC_NOAUDIT +#define AUDIT_ON AUC_AUDITING +#endif /* __APPLE_API_PRIVATE */ +#endif /* !__APPLE__ */ + +/* + * Error return codes for audit_set_terminal_id(), audit_write() and its + * brethren. We have 255 (not including kAUNoErr) to play with. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +enum { + kAUNoErr = 0, + kAUBadParamErr = -66049, + kAUStatErr, + kAUSysctlErr, + kAUOpenErr, + kAUMakeSubjectTokErr, + kAUWriteSubjectTokErr, + kAUWriteCallerTokErr, + kAUMakeReturnTokErr, + kAUWriteReturnTokErr, + kAUCloseErr, + kAUMakeTextTokErr, + kAULastErr +}; + +#ifdef __APPLE__ +/* + * Error return codes for au_get_state() and/or its private support + * functions. These codes are designed to be compatible with the + * NOTIFY_STATUS_* codes defined in but non-overlapping. + * Any changes to notify(3) may cause these values to change in future. + * + * AU_UNIMPL should never happen unless you've changed your system software + * without rebooting. Shame on you. + */ +#ifdef __APPLE_API_PRIVATE +#define AU_UNIMPL NOTIFY_STATUS_FAILED + 1 /* audit unimplemented */ +#endif /* __APPLE_API_PRIVATE */ +#endif /* !__APPLE__ */ + +__BEGIN_DECLS +/* + * XXX This prototype should be in audit_record.h + * + * au_free_token() + * + * @summary - au_free_token() deallocates a token_t created by any of + * the au_to_*() BSM API functions. + * + * The BSM API generally manages deallocation of token_t objects. However, + * if au_write() is passed a bad audit descriptor, the token_t * parameter + * will be left untouched. In that case, the caller can deallocate the + * token_t using au_free_token() if desired. This is, in fact, what + * audit_write() does, in keeping with the existing memory management model + * of the BSM API. + * + * @param tok - A token_t * generated by one of the au_to_*() BSM API + * calls. For convenience, tok may be NULL, in which case + * au_free_token() returns immediately. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +void au_free_token(token_t *tok); + +/* + * Lightweight check to determine if auditing is enabled. If a client + * wants to use this to govern whether an entire series of audit calls + * should be made--as in the common case of a caller building a set of + * tokens, then writing them--it should cache the audit status in a local + * variable. This call always returns the current state of auditing. + * + * @return - AUC_AUDITING or AUC_NOAUDIT if no error occurred. + * Otherwise the function can return any of the errno values defined for + * setaudit(2), or AU_UNIMPL if audit does not appear to be supported by + * the system. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int au_get_state(void); + +/* + * Initialize the audit notification. If it has not already been initialized + * it will automatically on the first call of au_get_state(). + */ +uint32_t au_notify_initialize(void); + +/* + * Cancel audit notification and free the resources associated with it. + * Responsible code that no longer needs to use au_get_state() should call + * this. + */ +int au_notify_terminate(void); +__END_DECLS + +/* OpenSSH compatibility */ +int cannot_audit(int); + +__BEGIN_DECLS +/* + * audit_set_terminal_id() + * + * @summary - audit_set_terminal_id() fills in an au_tid_t struct, which is + * used in audit session initialization by processes like /usr/bin/login. + * + * @param tid - A pointer to an au_tid_t struct. + * + * @return - kAUNoErr on success; kAUBadParamErr if tid is NULL, kAUStatErr + * or kAUSysctlErr if one of the underlying system calls fails (a message + * is sent to the system log in those cases). + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_set_terminal_id(au_tid_t *tid); + +/* + * BEGIN au_write() WRAPPERS + * + * The following calls all wrap the existing BSM API. They use the + * provided subject information, if any, to construct the subject token + * required for every log message. They use the provided return/error + * value(s), if any, to construct the success/failure indication required + * for every log message. They only permit one "miscellaneous" token, + * which should contain the event-specific logging information mandated by + * CAPP. + * + * All these calls assume the caller has previously determined that + * auditing is enabled by calling au_get_state(). + */ + +/* + * audit_write() + * + * @summary - audit_write() is the basis for the other audit_write_*() + * calls. Performs a basic write of an audit record (subject, additional + * info, success/failure). Note that this call only permits logging one + * caller-specified token; clients needing to log more flexibly must use + * the existing BSM API (au_open(), et al.) directly. + * + * Note on memory management: audit_write() guarantees that the token_t *s + * passed to it will be deallocated whether or not the underlying write to + * the audit log succeeded. This addresses an inconsistency in the + * underlying BSM API in which token_t *s are usually but not always + * deallocated. + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param subject - A token_t * generated by au_to_subject(), + * au_to_subject32(), au_to_subject64(), or au_to_me(). If no subject is + * required, subject should be NULL. + * + * @param misctok - A token_t * generated by one of the au_to_*() BSM API + * calls. This should correspond to the additional information required by + * CAPP for the event being audited. If no additional information is + * required, misctok should be NULL. + * + * @param retval - The return value to be logged for this event. This + * should be 0 (zero) for success, otherwise the value is event-specific. + * + * @param errcode - Any error code associated with the return value (e.g., + * errno or h_errno). If there was no error, errcode should be 0 (zero). + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write(short event_code, token_t *subject, token_t *misctok, + char retval, int errcode); + +/* + * audit_write_success() + * + * @summary - audit_write_success() records an auditable event that did not + * encounter an error. The interface is designed to require as little + * direct use of the au_to_*() API as possible. It builds a subject token + * from the information passed in and uses that to invoke audit_write(). + * A subject, as defined by CAPP, is a process acting on the user's behalf. + * + * If the subject information is the same as the current process, use + * au_write_success_self(). + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param misctok - A token_t * generated by one of the au_to_*() BSM API + * calls. This should correspond to the additional information required by + * CAPP for the event being audited. If no additional information is + * required, misctok should be NULL. + * + * @param auid - The subject's audit ID. + * + * @param euid - The subject's effective user ID. + * + * @param egid - The subject's effective group ID. + * + * @param ruid - The subject's real user ID. + * + * @param rgid - The subject's real group ID. + * + * @param pid - The subject's process ID. + * + * @param sid - The subject's session ID. + * + * @param tid - The subject's terminal ID. + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write_success(short event_code, token_t *misctok, au_id_t auid, + uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, + au_asid_t sid, au_tid_t *tid); + +/* + * audit_write_success_self() + * + * @summary - Similar to audit_write_success(), but used when the subject + * (process) is owned and operated by the auditable user him/herself. + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param misctok - A token_t * generated by one of the au_to_*() BSM API + * calls. This should correspond to the additional information required by + * CAPP for the event being audited. If no additional information is + * required, misctok should be NULL. + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write_success_self(short event_code, token_t *misctok); + +/* + * audit_write_failure() + * + * @summary - audit_write_failure() records an auditable event that + * encountered an error. The interface is designed to require as little + * direct use of the au_to_*() API as possible. It builds a subject token + * from the information passed in and uses that to invoke audit_write(). + * A subject, as defined by CAPP, is a process acting on the user's behalf. + * + * If the subject information is the same as the current process, use + * au_write_failure_self(). + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param errmsg - A text message providing additional information about + * the event being audited. + * + * @param errret - A numerical value providing additional information about + * the error. This is intended to store the value of errno or h_errno if + * it's relevant. This can be 0 (zero) if no additional information is + * available. + * + * @param auid - The subject's audit ID. + * + * @param euid - The subject's effective user ID. + * + * @param egid - The subject's effective group ID. + * + * @param ruid - The subject's real user ID. + * + * @param rgid - The subject's real group ID. + * + * @param pid - The subject's process ID. + * + * @param sid - The subject's session ID. + * + * @param tid - The subject's terminal ID. + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write_failure(short event_code, char *errmsg, int errret, + au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, + pid_t pid, au_asid_t sid, au_tid_t *tid); + +/* + * audit_write_failure_self() + * + * @summary - Similar to audit_write_failure(), but used when the subject + * (process) is owned and operated by the auditable user him/herself. + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param errmsg - A text message providing additional information about + * the event being audited. + * + * @param errret - A numerical value providing additional information about + * the error. This is intended to store the value of errno or h_errno if + * it's relevant. This can be 0 (zero) if no additional information is + * available. + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write_failure_self(short event_code, char *errmsg, int errret); + +/* + * audit_write_failure_na() + * + * @summary - audit_write_failure_na() records errors during login. Such + * errors are implicitly non-attributable (i.e., not ascribable to any user). + * + * @param event_code - The code for the event being logged. This should + * be one of the AUE_ values in /usr/include/bsm/audit_uevents.h. + * + * @param errmsg - A text message providing additional information about + * the event being audited. + * + * @param errret - A numerical value providing additional information about + * the error. This is intended to store the value of errno or h_errno if + * it's relevant. This can be 0 (zero) if no additional information is + * available. + * + * @param euid - The subject's effective user ID. + * + * @param egid - The subject's effective group ID. + * + * @param pid - The subject's process ID. + * + * @param tid - The subject's terminal ID. + * + * @return - The status of the call: 0 (zero) on success, else one of the + * kAU*Err values defined above. + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +int audit_write_failure_na(short event_code, char *errmsg, int errret, + uid_t euid, gid_t egid, pid_t pid, au_tid_t *tid); + +/* END au_write() WRAPPERS */ + +#ifdef __APPLE__ +/* + * audit_token_to_au32() + * + * @summary - Extract information from an audit_token_t, used to identify + * Mach tasks and senders of Mach messages as subjects to the audit system. + * audit_tokent_to_au32() is the only method that should be used to parse + * an audit_token_t, since its internal representation may change over + * time. A pointer parameter may be NULL if that information is not + * needed. + * + * @param atoken - the audit token containing the desired information + * + * @param auidp - Pointer to a uid_t; on return will be set to the task or + * sender's audit user ID + * + * @param euidp - Pointer to a uid_t; on return will be set to the task or + * sender's effective user ID + * + * @param egidp - Pointer to a gid_t; on return will be set to the task or + * sender's effective group ID + * + * @param ruidp - Pointer to a uid_t; on return will be set to the task or + * sender's real user ID + * + * @param rgidp - Pointer to a gid_t; on return will be set to the task or + * sender's real group ID + * + * @param pidp - Pointer to a pid_t; on return will be set to the task or + * sender's process ID + * + * @param asidp - Pointer to an au_asid_t; on return will be set to the + * task or sender's audit session ID + * + * @param tidp - Pointer to an au_tid_t; on return will be set to the task + * or sender's terminal ID + * + * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. + */ +void audit_token_to_au32( + audit_token_t atoken, + uid_t *auidp, + uid_t *euidp, + gid_t *egidp, + uid_t *ruidp, + gid_t *rgidp, + pid_t *pidp, + au_asid_t *asidp, + au_tid_t *tidp); +#endif /* !__APPLE__ */ + +/* + * Wrapper functions to auditon(2). + */ +int audit_get_car(char *path, size_t sz); +int audit_get_class(au_evclass_map_t *evc_map, size_t sz); +int audit_set_class(au_evclass_map_t *evc_map, size_t sz); +int audit_get_cond(int *cond); +int audit_set_cond(int *cond); +int audit_get_cwd(char *path, size_t sz); +int audit_get_fsize(au_fstat_t *fstat, size_t sz); +int audit_set_fsize(au_fstat_t *fstat, size_t sz); +int audit_get_kmask(au_mask_t *kmask, size_t sz); +int audit_set_kmask(au_mask_t *kmask, size_t sz); +int audit_get_kaudit(auditinfo_addr_t *aia, size_t sz); +int audit_set_kaudit(auditinfo_addr_t *aia, size_t sz); +int audit_set_pmask(auditpinfo_t *api, size_t sz); +int audit_get_pinfo(auditpinfo_t *api, size_t sz); +int audit_get_pinfo_addr(auditpinfo_addr_t *apia, size_t sz); +int audit_get_policy(int *policy); +int audit_set_policy(int *policy); +int audit_get_qctrl(au_qctrl_t *qctrl, size_t sz); +int audit_set_qctrl(au_qctrl_t *qctrl, size_t sz); +int audit_get_sinfo_addr(auditinfo_addr_t *aia, size_t sz); +int audit_get_stat(au_stat_t *stats, size_t sz); +int audit_set_stat(au_stat_t *stats, size_t sz); +int audit_send_trigger(int *trigger); + +__END_DECLS + +#endif /* !_LIBBSM_H_ */ diff --git a/src/include.new/bsnmp/asn1.h b/src/include.new/bsnmp/asn1.h new file mode 100644 index 0000000..cf9a727 --- /dev/null +++ b/src/include.new/bsnmp/asn1.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/lib/asn1.h,v 1.20 2005/10/05 16:43:11 brandt_h Exp $ + * + * ASN.1 for SNMP + */ +#ifndef asn1_h_ +#define asn1_h_ + +#include + +struct asn_buf { + union { + u_char *ptr; + const u_char *cptr; + } asn_u; + size_t asn_len; +}; +#define asn_cptr asn_u.cptr +#define asn_ptr asn_u.ptr + +/* these restrictions are in the SMI */ +#define ASN_MAXID 0xffffffff +#define ASN_MAXOIDLEN 128 + +/* the string needed for this (with trailing zero) */ +#define ASN_OIDSTRLEN (ASN_MAXOIDLEN * (10 + 1) - 1 + 1) + +/* type of subidentifiers */ +typedef uint32_t asn_subid_t; + +struct asn_oid { + u_int len; + asn_subid_t subs[ASN_MAXOIDLEN]; +}; + +enum asn_err { + /* conversion was ok */ + ASN_ERR_OK = 0, + /* conversion failed and stopped */ + ASN_ERR_FAILED = 1 | 0x1000, + /* length field bad, value skipped */ + ASN_ERR_BADLEN = 2, + /* out of buffer, stopped */ + ASN_ERR_EOBUF = 3 | 0x1000, + /* length ok, but value is out of range */ + ASN_ERR_RANGE = 4, + /* not the expected tag, stopped */ + ASN_ERR_TAG = 5 | 0x1000, +}; +#define ASN_ERR_STOPPED(E) (((E) & 0x1000) != 0) + +/* type for the length field of encoded values. The length is restricted + * to 65535, but using uint16_t would give conversion warnings on gcc */ +typedef uint32_t asn_len_t; /* could be also uint16_t */ + +/* maximal length of a long length field without the length of the length */ +#define ASN_MAXLEN 65535 +#define ASN_MAXLENLEN 2 /* number of bytes in a length */ + +/* maximum size of an octet string as per SMIv2 */ +#define ASN_MAXOCTETSTRING 65535 + +extern void (*asn_error)(const struct asn_buf *, const char *, ...); + +enum asn_err asn_get_header(struct asn_buf *, u_char *, asn_len_t *); +enum asn_err asn_put_header(struct asn_buf *, u_char, asn_len_t); + +enum asn_err asn_put_temp_header(struct asn_buf *, u_char, u_char **); +enum asn_err asn_commit_header(struct asn_buf *, u_char *, size_t *); + +enum asn_err asn_get_integer_raw(struct asn_buf *, asn_len_t, int32_t *); +enum asn_err asn_get_integer(struct asn_buf *, int32_t *); +enum asn_err asn_put_integer(struct asn_buf *, int32_t); + +enum asn_err asn_get_octetstring_raw(struct asn_buf *, asn_len_t, u_char *, u_int *); +enum asn_err asn_get_octetstring(struct asn_buf *, u_char *, u_int *); +enum asn_err asn_put_octetstring(struct asn_buf *, const u_char *, u_int); + +enum asn_err asn_get_null_raw(struct asn_buf *b, asn_len_t); +enum asn_err asn_get_null(struct asn_buf *); +enum asn_err asn_put_null(struct asn_buf *); + +enum asn_err asn_put_exception(struct asn_buf *, u_int); + +enum asn_err asn_get_objid_raw(struct asn_buf *, asn_len_t, struct asn_oid *); +enum asn_err asn_get_objid(struct asn_buf *, struct asn_oid *); +enum asn_err asn_put_objid(struct asn_buf *, const struct asn_oid *); + +enum asn_err asn_get_sequence(struct asn_buf *, asn_len_t *); + +enum asn_err asn_get_ipaddress_raw(struct asn_buf *, asn_len_t, u_char *); +enum asn_err asn_get_ipaddress(struct asn_buf *, u_char *); +enum asn_err asn_put_ipaddress(struct asn_buf *, const u_char *); + +enum asn_err asn_get_uint32_raw(struct asn_buf *, asn_len_t, uint32_t *); +enum asn_err asn_put_uint32(struct asn_buf *, u_char, uint32_t); + +enum asn_err asn_get_counter64_raw(struct asn_buf *, asn_len_t, uint64_t *); +enum asn_err asn_put_counter64(struct asn_buf *, uint64_t); + +enum asn_err asn_get_timeticks(struct asn_buf *, uint32_t *); +enum asn_err asn_put_timeticks(struct asn_buf *, uint32_t); + +enum asn_err asn_skip(struct asn_buf *, asn_len_t); +enum asn_err asn_pad(struct asn_buf *, asn_len_t); + +/* + * Utility functions for OIDs + */ +/* get a sub-OID from the middle of another OID */ +void asn_slice_oid(struct asn_oid *, const struct asn_oid *, u_int, u_int); + +/* append an OID to another one */ +void asn_append_oid(struct asn_oid *, const struct asn_oid *); + +/* compare two OIDs */ +int asn_compare_oid(const struct asn_oid *, const struct asn_oid *); + +/* check whether the first is a suboid of the second one */ +int asn_is_suboid(const struct asn_oid *, const struct asn_oid *); + +/* format an OID into a user buffer of size ASN_OIDSTRLEN */ +char *asn_oid2str_r(const struct asn_oid *, char *); + +/* format an OID into a private static buffer */ +char *asn_oid2str(const struct asn_oid *); + +enum { + ASN_TYPE_BOOLEAN = 0x01, + ASN_TYPE_INTEGER = 0x02, + ASN_TYPE_BITSTRING = 0x03, + ASN_TYPE_OCTETSTRING = 0x04, + ASN_TYPE_NULL = 0x05, + ASN_TYPE_OBJID = 0x06, + ASN_TYPE_SEQUENCE = 0x10, + + ASN_TYPE_CONSTRUCTED = 0x20, + ASN_CLASS_UNIVERSAL = 0x00, + ASN_CLASS_APPLICATION = 0x40, + ASN_CLASS_CONTEXT = 0x80, + ASN_CLASS_PRIVATE = 0xc0, + ASN_TYPE_MASK = 0x1f, + + ASN_APP_IPADDRESS = 0x00, + ASN_APP_COUNTER = 0x01, + ASN_APP_GAUGE = 0x02, + ASN_APP_TIMETICKS = 0x03, + ASN_APP_OPAQUE = 0x04, /* not implemented */ + ASN_APP_COUNTER64 = 0x06, + + ASN_EXCEPT_NOSUCHOBJECT = 0x00, + ASN_EXCEPT_NOSUCHINSTANCE = 0x01, + ASN_EXCEPT_ENDOFMIBVIEW = 0x02, +}; + +#endif diff --git a/src/include.new/bsnmp/bridge_snmp.h b/src/include.new/bsnmp/bridge_snmp.h new file mode 100644 index 0000000..31d23fb --- /dev/null +++ b/src/include.new/bsnmp/bridge_snmp.h @@ -0,0 +1,357 @@ +/*- + * Copyright (c) 2006 Shteryana Shopova + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Bridge MIB implementation for SNMPd. + * + * $FreeBSD: releng/10.2/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h 171791 2007-08-08 19:27:50Z syrinx $ + */ + +#ifndef SNMP_BRIDGE_H +#define SNMP_BRIDGE_H + +#define SNMP_BRIDGE_ID_LEN 8 + +typedef uint8_t port_id[2]; +typedef u_char bridge_id[SNMP_BRIDGE_ID_LEN]; + +#define SNMP_BRIDGE_MAX_PRIORITY 65535 + +#define SNMP_BRIDGE_MIN_AGE_TIME 10 +#define SNMP_BRIDGE_MAX_AGE_TIME 1000000 + +#define SNMP_BRIDGE_MIN_TXHC 1 +#define SNMP_BRIDGE_MAX_TXHC 10 + +#define SNMP_BRIDGE_MIN_MAGE 600 +#define SNMP_BRIDGE_MAX_MAGE 4000 + +#define SNMP_BRIDGE_MIN_HTIME 100 +#define SNMP_BRIDGE_MAX_HTIME 1000 + +#define SNMP_BRIDGE_MIN_FDELAY 400 +#define SNMP_BRIDGE_MAX_FDELAY 3000 + +#define SNMP_PORT_PATHCOST_OBSOLETE 65535 +#define SNMP_PORT_MIN_PATHCOST 0 +#define SNMP_PORT_MAX_PATHCOST 200000000 +#define SNMP_PORT_PATHCOST_AUTO 0 + +#define SNMP_BRIDGE_DATA_MAXAGE 10 +#define SNMP_BRIDGE_DATA_MAXAGE_MIN 1 +#define SNMP_BRIDGE_DATA_MAXAGE_MAX 300 + +/* By default poll kernel data every 5 minutes. */ +#define SNMP_BRIDGE_POLL_INTERVAL (5 * 60) +#define SNMP_BRIDGE_POLL_INTERVAL_MIN 1 +#define SNMP_BRIDGE_POLL_INTERVAL_MAX 3600 + +/* Poll for a topology change once every 30 seconds. */ +#define SNMP_BRIDGE_TC_POLL_INTERVAL 30 + +struct bridge_if *bridge_get_default(void); + +void bridge_set_default(struct bridge_if *bif); + +const char *bridge_get_default_name(void); + +int bridge_get_data_maxage(void); + +/* + * Bridge Addresses Table. + */ +struct tp_entry { + uint32_t sysindex; /* The bridge if sysindex. */ + int32_t port_no; + enum TpFdbStatus status; + uint8_t tp_addr[ETHER_ADDR_LEN]; + uint8_t flags; + TAILQ_ENTRY(tp_entry) tp_e; +}; + +/* + * Bridge ports. + * The bridge port system interface index is used for a + * port number. Transparent bridging statistics and STP + * information for a port are also contained here. + */ +struct bridge_port { + /* dot1dBase subtree objects. */ + uint32_t sysindex; /* The bridge interface sysindex. */ + int32_t port_no; /* The bridge member system index. */ + int32_t if_idx; /* SNMP ifIndex from mibII. */ + int8_t span_enable; /* Span flag set - private MIB. */ + struct asn_oid circuit; /* Unused. */ + uint32_t dly_ex_drops; /* Drops on output. */ + uint32_t dly_mtu_drops; /* MTU exceeded drops. */ + int32_t status; /* The entry status. */ + enum TruthValue priv_set; /* The private flag. */ + + /* dot1dStp subtree objects. */ + int32_t path_cost; + int32_t priority; + int32_t design_cost; + uint32_t fwd_trans; + char p_name[IFNAMSIZ]; /* Not in BRIDGE-MIB. */ + enum StpPortState state; + enum dot1dStpPortEnable enable; + port_id design_port; + bridge_id design_root; + bridge_id design_bridge; + + /* rstpMib extensions. */ + int32_t admin_path_cost; + enum TruthValue proto_migr; + enum TruthValue admin_edge; + enum TruthValue oper_edge; + enum TruthValue oper_ptp; + enum StpPortAdminPointToPointType admin_ptp; + + /* dot1dTp subtree objects. */ + int32_t max_info; + int32_t in_frames; + int32_t out_frames; + int32_t in_drops; + + uint8_t flags; + TAILQ_ENTRY(bridge_port) b_p; +}; + +/* + * A bridge interface. + * The system interface index of the bridge is not required neither by the + * standard BRIDGE-MIB nor by the private BEGEMOT-BRIDGE-MIB, but is used + * as key for looking up the other info for this bridge. + */ +struct bridge_if { + /* dot1dBase subtree objects. */ + uint32_t sysindex; /* The system interface index. */ + int32_t num_ports; /* Number of ports. */ + enum BaseType br_type; /* Bridge type. */ + enum RowStatus if_status; /* Bridge status. */ + char bif_name[IFNAMSIZ]; /* Bridge interface name. */ + struct ether_addr br_addr; /* Bridge address. */ + struct bridge_port *f_bp; /* This bridge's first entry + * in the base ports TAILQ. */ + /* dot1dStp subtree objects. */ + int32_t priority; + int32_t root_cost; + int32_t root_port; + int32_t max_age; /* Current max age. */ + int32_t hello_time; /* Current hello time. */ + int32_t fwd_delay; /* Current forward delay. */ + int32_t hold_time; + int32_t bridge_max_age; /* Configured max age. */ + int32_t bridge_hello_time; /* Configured hello time. */ + int32_t bridge_fwd_delay; /* Configured forward delay. */ + int32_t tx_hold_count; + uint32_t top_changes; + enum dot1dStpVersion stp_version; + enum dot1dStpProtocolSpecification prot_spec; + struct timeval last_tc_time; + bridge_id design_root; + + /* dot1dTp subtree objects. */ + int32_t lrnt_drops; /* Dropped addresses. */ + int32_t age_time; /* Address entry timeout. */ + int32_t num_addrs; /* Current # of addresses in cache. */ + int32_t max_addrs; /* Max # of addresses in cache. */ + struct tp_entry *f_tpa; /* This bridge's first entry in + * the tp addresses TAILQ. */ + + time_t entry_age; + time_t ports_age; + time_t addrs_age; + TAILQ_ENTRY(bridge_if) b_if; +}; + +void bridge_ifs_fini(void); + +struct bridge_if *bridge_if_find_ifs(uint32_t sysindex); + +struct bridge_if *bridge_if_find_ifname(const char *b_name); + +const char *bridge_if_find_name(uint32_t sysindex); + +int bridge_compare_sysidx(uint32_t i1, uint32_t i2); + +int bridge_attach_newif(struct mibif *ifp); + +struct bridge_if *bridge_first_bif(void); + +struct bridge_if *bridge_next_bif(struct bridge_if *b_pr); + +void bridge_remove_bif(struct bridge_if *bif); + +void bridge_update_all_ports(void); + +void bridge_update_all_addrs(void); + +void bridge_update_all_ifs(void); + +void bridge_update_all(void *arg); + +void bridge_update_tc_time(void *arg); + +void bridge_ifs_dump(void); + +/* Bridge ports. */ +void bridge_ports_update_listage(void); + +void bridge_ports_fini(void); + +void bridge_members_free(struct bridge_if *bif); + +struct bridge_port *bridge_new_port(struct mibif *mif, struct bridge_if *bif); + +void bridge_port_remove(struct bridge_port *bp, struct bridge_if *bif); + +struct bridge_port *bridge_port_bif_first(struct bridge_if *bif); + +struct bridge_port *bridge_port_bif_next(struct bridge_port *bp); + +struct bridge_port *bridge_port_find(int32_t if_idx, struct bridge_if *bif); + +void bridge_port_getinfo_mibif(struct mibif *m_if, struct bridge_port *bp); + +int bridge_getinfo_bif_ports(struct bridge_if *bif); + +int bridge_update_memif(struct bridge_if *bif); + +void bridge_ports_dump(struct bridge_if *bif); + +/* Bridge addresses. */ +void bridge_addrs_update_listage(void); + +void bridge_addrs_fini(void); + +void bridge_addrs_free(struct bridge_if *bif); + +struct tp_entry *bridge_new_addrs(uint8_t *mac, struct bridge_if *bif); + +void bridge_addrs_remove(struct tp_entry *te, struct bridge_if *bif); + +struct tp_entry *bridge_addrs_find(uint8_t *mac, struct bridge_if *bif); + +struct tp_entry *bridge_addrs_bif_first(struct bridge_if *bif); + +struct tp_entry *bridge_addrs_bif_next(struct tp_entry *te); + +int bridge_getinfo_bif_addrs(struct bridge_if *bif); + +int bridge_update_addrs(struct bridge_if *bif); + +void bridge_addrs_dump(struct bridge_if *bif); + +/* Bridge PF. */ + +void bridge_pf_dump(void); + +/* System specific. */ + +/* Open the socket for the ioctls. */ +int bridge_ioctl_init(void); + +/* Load bridge kernel module. */ +int bridge_kmod_load(void); + +/* Get the bridge interface information. */ +int bridge_getinfo_bif(struct bridge_if *bif); + +/* Get the bridge interface STP parameters. */ +int bridge_get_op_param(struct bridge_if *bif); + +/* Set the bridge priority. */ +int bridge_set_priority(struct bridge_if *bif, int32_t priority); + +/* Set the bridge max age. */ +int bridge_set_maxage(struct bridge_if *bif, int32_t max_age); + +/* Set the bridge hello time.*/ +int bridge_set_hello_time(struct bridge_if *bif, int32_t hello_time); + +/* Set the bridge forward delay.*/ +int bridge_set_forward_delay(struct bridge_if *bif, int32_t fwd_delay); + +/* Set the bridge address cache max age. */ +int bridge_set_aging_time(struct bridge_if *bif, int32_t age_time); + +/* Set the max number of entries in the bridge address cache. */ +int bridge_set_max_cache(struct bridge_if *bif, int32_t max_cache); + +/* Set the bridge TX hold count. */ +int bridge_set_tx_hold_count(struct bridge_if *bif, int32_t tx_hc); + +/* Set the bridge STP protocol version. */ +int bridge_set_stp_version(struct bridge_if *bif, int32_t stp_proto); + +/* Set the bridge interface status to up/down. */ +int bridge_set_if_up(const char* b_name, int8_t up); + +/* Create a bridge interface. */ +int bridge_create(const char *b_name); + +/* Destroy a bridge interface. */ +int bridge_destroy(const char *b_name); + +/* Fetch the bridge mac address. */ +u_char *bridge_get_basemac(const char *bif_name, u_char *mac, size_t mlen); + +/* Set a bridge member priority. */ +int bridge_port_set_priority(const char *bif_name, struct bridge_port *bp, + int32_t priority); + +/* Set a bridge member STP-enabled flag. */ +int bridge_port_set_stp_enable(const char *bif_name, struct bridge_port *bp, + uint32_t enable); + +/* Set a bridge member STP path cost. */ +int bridge_port_set_path_cost(const char *bif_name, struct bridge_port *bp, + int32_t path_cost); + +/* Set admin point-to-point link. */ +int bridge_port_set_admin_ptp(const char *bif_name, struct bridge_port *bp, + uint32_t admin_ptp); + +/* Set admin edge. */ +int bridge_port_set_admin_edge(const char *bif_name, struct bridge_port *bp, + uint32_t enable); + +/* Set 'private' flag. */ +int bridge_port_set_private(const char *bif_name, struct bridge_port *bp, + uint32_t priv_set); + +/* Add a bridge member port. */ +int bridge_port_addm(struct bridge_port *bp, const char *b_name); + +/* Delete a bridge member port. */ +int bridge_port_delm(struct bridge_port *bp, const char *b_name); + +/* Get the current value from the module for bridge PF control. */ +int32_t bridge_get_pfval(uint8_t which); + +/* Get/Set a bridge PF control. */ +int32_t bridge_do_pfctl(int32_t bridge_ctl, enum snmp_op op, int32_t *val); + +#endif /* SNMP_BRIDGE_H */ diff --git a/src/include.new/bsnmp/snmp.h b/src/include.new/bsnmp/snmp.h new file mode 100644 index 0000000..631d2f2 --- /dev/null +++ b/src/include.new/bsnmp/snmp.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Shteryana Sotirova Shopova + * under sponsorship from the FreeBSD Foundation. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/lib/snmp.h,v 1.30 2004/08/06 08:46:54 brandt Exp $ + * + * Header file for SNMP functions. + */ +#ifndef snmp_h_ +#define snmp_h_ + +#include + +#define SNMP_COMMUNITY_MAXLEN 128 +#define SNMP_MAX_BINDINGS 100 +#define SNMP_CONTEXT_NAME_SIZ (32 + 1) +#define SNMP_ENGINE_ID_SIZ 32 +#define SNMP_TIME_WINDOW 150 + +enum snmp_syntax { + SNMP_SYNTAX_NULL = 0, + SNMP_SYNTAX_INTEGER, /* == INTEGER32 */ + SNMP_SYNTAX_OCTETSTRING, + SNMP_SYNTAX_OID, + SNMP_SYNTAX_IPADDRESS, + SNMP_SYNTAX_COUNTER, + SNMP_SYNTAX_GAUGE, /* == UNSIGNED32 */ + SNMP_SYNTAX_TIMETICKS, + + /* v2 additions */ + SNMP_SYNTAX_COUNTER64, + SNMP_SYNTAX_NOSUCHOBJECT, /* exception */ + SNMP_SYNTAX_NOSUCHINSTANCE, /* exception */ + SNMP_SYNTAX_ENDOFMIBVIEW, /* exception */ +}; + +struct snmp_value { + struct asn_oid var; + enum snmp_syntax syntax; + union snmp_values { + int32_t integer; /* also integer32 */ + struct { + u_int len; + u_char *octets; + } octetstring; + struct asn_oid oid; + u_char ipaddress[4]; + uint32_t uint32; /* also gauge32, counter32, + unsigned32, timeticks */ + uint64_t counter64; + } v; +}; + +enum snmp_version { + SNMP_Verr = 0, + SNMP_V1 = 1, + SNMP_V2c = 2, + SNMP_V3, +}; + +#define SNMP_MPM_SNMP_V1 0 +#define SNMP_MPM_SNMP_V2c 1 +#define SNMP_MPM_SNMP_V3 3 + +#define SNMP_ADM_STR32_SIZ (32 + 1) +#define SNMP_AUTH_KEY_SIZ 40 +#define SNMP_PRIV_KEY_SIZ 32 +#define SNMP_USM_AUTH_SIZE 12 +#define SNMP_USM_PRIV_SIZE 8 +#define SNMP_AUTH_HMACMD5_KEY_SIZ 16 +#define SNMP_AUTH_HMACSHA_KEY_SIZ 20 +#define SNMP_PRIV_AES_KEY_SIZ 16 +#define SNMP_PRIV_DES_KEY_SIZ 8 + + +enum snmp_secmodel { + SNMP_SECMODEL_ANY = 0, + SNMP_SECMODEL_SNMPv1 = 1, + SNMP_SECMODEL_SNMPv2c = 2, + SNMP_SECMODEL_USM = 3, + SNMP_SECMODEL_UNKNOWN +}; + +enum snmp_usm_level { + SNMP_noAuthNoPriv = 1, + SNMP_authNoPriv = 2, + SNMP_authPriv = 3 +}; + +enum snmp_authentication { + SNMP_AUTH_NOAUTH = 0, + SNMP_AUTH_HMAC_MD5, + SNMP_AUTH_HMAC_SHA +}; + +enum snmp_privacy { + SNMP_PRIV_NOPRIV = 0, + SNMP_PRIV_DES = 1, + SNMP_PRIV_AES +}; + +struct snmp_engine { + uint8_t engine_id[SNMP_ENGINE_ID_SIZ]; + uint32_t engine_len; + int32_t engine_boots; + int32_t engine_time; + int32_t max_msg_size; +}; + +struct snmp_user { + char sec_name[SNMP_ADM_STR32_SIZ]; + enum snmp_authentication auth_proto; + enum snmp_privacy priv_proto; + uint8_t auth_key[SNMP_AUTH_KEY_SIZ]; + uint8_t priv_key[SNMP_PRIV_KEY_SIZ]; +}; + +struct snmp_pdu { + char community[SNMP_COMMUNITY_MAXLEN + 1]; + enum snmp_version version; + u_int type; + + /* SNMPv3 PDU header fields */ + int32_t identifier; + uint8_t flags; + int32_t security_model; + struct snmp_engine engine; + + /* Associated USM user parameters */ + struct snmp_user user; + uint8_t msg_digest[SNMP_USM_AUTH_SIZE]; + uint8_t msg_salt[SNMP_USM_PRIV_SIZE]; + + /* View-based Access Model */ + /* XXX: put in separate structure - conflicts with struct snmp_context */ + uint32_t context_engine_len; + uint8_t context_engine[SNMP_ENGINE_ID_SIZ]; + char context_name[SNMP_CONTEXT_NAME_SIZ]; + + /* trap only */ + struct asn_oid enterprise; + u_char agent_addr[4]; + int32_t generic_trap; + int32_t specific_trap; + uint32_t time_stamp; + + /* others */ + int32_t request_id; + int32_t error_status; + int32_t error_index; + + /* fixes for encoding */ + size_t outer_len; + size_t scoped_len; + u_char *outer_ptr; + u_char *digest_ptr; + u_char *encrypted_ptr; + u_char *scoped_ptr; + u_char *pdu_ptr; + u_char *vars_ptr; + + + struct snmp_value bindings[SNMP_MAX_BINDINGS]; + u_int nbindings; +}; +#define snmp_v1_pdu snmp_pdu + +#define SNMP_PDU_GET 0 +#define SNMP_PDU_GETNEXT 1 +#define SNMP_PDU_RESPONSE 2 +#define SNMP_PDU_SET 3 +#define SNMP_PDU_TRAP 4 /* v1 */ +#define SNMP_PDU_GETBULK 5 /* v2 */ +#define SNMP_PDU_INFORM 6 /* v2 */ +#define SNMP_PDU_TRAP2 7 /* v2 */ +#define SNMP_PDU_REPORT 8 /* v2 */ + +#define SNMP_ERR_NOERROR 0 +#define SNMP_ERR_TOOBIG 1 +#define SNMP_ERR_NOSUCHNAME 2 /* v1 */ +#define SNMP_ERR_BADVALUE 3 /* v1 */ +#define SNMP_ERR_READONLY 4 /* v1 */ +#define SNMP_ERR_GENERR 5 +#define SNMP_ERR_NO_ACCESS 6 /* v2 */ +#define SNMP_ERR_WRONG_TYPE 7 /* v2 */ +#define SNMP_ERR_WRONG_LENGTH 8 /* v2 */ +#define SNMP_ERR_WRONG_ENCODING 9 /* v2 */ +#define SNMP_ERR_WRONG_VALUE 10 /* v2 */ +#define SNMP_ERR_NO_CREATION 11 /* v2 */ +#define SNMP_ERR_INCONS_VALUE 12 /* v2 */ +#define SNMP_ERR_RES_UNAVAIL 13 /* v2 */ +#define SNMP_ERR_COMMIT_FAILED 14 /* v2 */ +#define SNMP_ERR_UNDO_FAILED 15 /* v2 */ +#define SNMP_ERR_AUTH_ERR 16 /* v2 */ +#define SNMP_ERR_NOT_WRITEABLE 17 /* v2 */ +#define SNMP_ERR_INCONS_NAME 18 /* v2 */ + +#define SNMP_TRAP_COLDSTART 0 +#define SNMP_TRAP_WARMSTART 1 +#define SNMP_TRAP_LINKDOWN 2 +#define SNMP_TRAP_LINKUP 3 +#define SNMP_TRAP_AUTHENTICATION_FAILURE 4 +#define SNMP_TRAP_EGP_NEIGHBOR_LOSS 5 +#define SNMP_TRAP_ENTERPRISE 6 + +enum snmp_code { + SNMP_CODE_OK = 0, + SNMP_CODE_FAILED, + SNMP_CODE_BADVERS, + SNMP_CODE_BADLEN, + SNMP_CODE_BADENC, + SNMP_CODE_OORANGE, + SNMP_CODE_BADSECLEVEL, + SNMP_CODE_NOTINTIME, + SNMP_CODE_BADUSER, + SNMP_CODE_BADENGINE, + SNMP_CODE_BADDIGEST, + SNMP_CODE_EDECRYPT +}; + +#define SNMP_MSG_AUTH_FLAG 0x1 +#define SNMP_MSG_PRIV_FLAG 0x2 +#define SNMP_MSG_REPORT_FLAG 0x4 +#define SNMP_MSG_AUTODISCOVER 0x80 + +void snmp_value_free(struct snmp_value *); +int snmp_value_parse(const char *, enum snmp_syntax, union snmp_values *); +int snmp_value_copy(struct snmp_value *, const struct snmp_value *); + +void snmp_pdu_free(struct snmp_pdu *); +void snmp_pdu_init_secparams(struct snmp_pdu *); +enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *); +enum snmp_code snmp_pdu_decode_header(struct asn_buf *, struct snmp_pdu *); +enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *); +enum snmp_code snmp_pdu_encode(struct snmp_pdu *, struct asn_buf *); +enum snmp_code snmp_pdu_decode_secmode(struct asn_buf *, struct snmp_pdu *); + +int snmp_pdu_snoop(const struct asn_buf *); + +void snmp_pdu_dump(const struct snmp_pdu *pdu); + +enum snmp_code snmp_passwd_to_keys(struct snmp_user *, char *); +enum snmp_code snmp_get_local_keys(struct snmp_user *, uint8_t *, uint32_t); +enum snmp_code snmp_calc_keychange(struct snmp_user *, uint8_t *); + +extern void (*snmp_error)(const char *, ...); +extern void (*snmp_printf)(const char *, ...); + +#define TRUTH_MK(F) ((F) ? 1 : 2) +#define TRUTH_GET(T) (((T) == 1) ? 1 : 0) +#define TRUTH_OK(T) ((T) == 1 || (T) == 2) + +#endif diff --git a/src/include.new/bsnmp/snmp_atm.h b/src/include.new/bsnmp/snmp_atm.h new file mode 100644 index 0000000..50784cc --- /dev/null +++ b/src/include.new/bsnmp/snmp_atm.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2001-2002 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * Copyright (c) 2003-2004 + * Hartmut Brandt + * All rights reserved. + * + * Author: Hartmut Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: libunimsg/snmp_atm/snmp_atm.h,v 1.2 2004/08/06 17:30:40 brandt Exp $ + */ +#ifndef _BSNMP_SNMP_ATM_H +#define _BSNMP_SNMP_ATM_H + +enum atmif_notify { + ATMIF_NOTIFY_DESTROY, /* interface has been destroyed */ + ATMIF_NOTIFY_CARRIER, /* carriere change */ + ATMIF_NOTIFY_VCC /* VCC change */ +}; + +enum atmif_carrier_state { + ATMIF_CARRIER_ON = 1, + ATMIF_CARRIER_OFF = 2, + ATMIF_CARRIER_UNKNOWN = 3, + ATMIF_CARRIER_NONE = 4 +}; + +enum atmif_suni_mode { + ATMIF_SUNI_MODE_SONET = 1, + ATMIF_SUNI_MODE_SDH = 2, + ATMIF_SUNI_MODE_UNKNOWN = 3 +}; + +/* forward declaration */ +struct atmif; +typedef void (*atmif_event_f)(struct atmif *, enum atmif_notify, uintptr_t, + void *); + +struct atmif_mib { + u_int version; /* currently 0 */ + + u_int device; /* type of hardware (system specific) */ + u_int serial; /* card serial number (device specific) */ + u_int hw_version; /* card version (device specific) */ + u_int sw_version; /* firmware version (device specific) */ + u_int media; /* physical media (see MIB) */ + + u_char esi[6]; /* end system identifier (MAC) */ + u_int pcr; /* supported peak cell rate */ + u_int vpi_bits; /* number of used bits in VPI field */ + u_int vci_bits; /* number of used bits in VCI field */ + u_int max_vpcs; /* maximum number of VPCs */ + u_int max_vccs; /* maximum number of VCCs */ +}; + +struct atmif { + struct mibif *ifp; /* common interface data */ + struct atmif_mib *mib; /* ATM MIB */ + enum atmif_carrier_state carrier; + enum atmif_suni_mode mode; /* SUNI mode SDH or SONET */ +}; + +/* find an ATM interface by name */ +struct atmif *atm_find_if_name(const char *); + +/* get the interface from the interface index */ +struct atmif *atm_find_if(u_int); + +/* register for notifications */ +void *atm_notify_aif(struct atmif *, const struct lmodule *mod, + atmif_event_f, void *); +void atm_unnotify_aif(void *); + +/* return the If for a system-specific node number */ +struct atmif *atm_node2if(u_int); + +/* return the node id for the if */ +u_int atm_if2node(struct atmif *); + +#endif diff --git a/src/include.new/bsnmp/snmp_mibII.h b/src/include.new/bsnmp/snmp_mibII.h new file mode 100644 index 0000000..91e552e --- /dev/null +++ b/src/include.new/bsnmp/snmp_mibII.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/snmp_mibII/snmp_mibII.h,v 1.18 2006/02/14 09:04:19 brandt_h Exp $ + * + * Implementation of the interfaces and IP groups of MIB-II. + */ +#ifndef snmp_mibII_h_ +#define snmp_mibII_h_ + +/* forward declaration */ +struct mibif; + +enum mibif_notify { + MIBIF_NOTIFY_DESTROY +}; + +typedef void (*mibif_notify_f)(struct mibif *, enum mibif_notify, void *); + +/* + * Interfaces. This structure describes one interface as seen in the MIB. + * Interfaces are indexed by ifindex. This is not the same as the index + * used by the system because of the rules in RFC-2863 section 3.1.5. This + * RFC requires, that an ifindex is not to be re-used for ANOTHER dynamically + * interfaces once the interface was deleted. The system's ifindex is in + * sysindex. Mapping is via the mapping table below. + */ +struct mibif { + TAILQ_ENTRY(mibif) link; + u_int flags; + u_int index; /* the logical ifindex */ + u_int sysindex; + char name[IFNAMSIZ]; + char descr[256]; + struct ifmibdata mib; + uint64_t mibtick; + void *specmib; + size_t specmiblen; + u_char *physaddr; + u_int physaddrlen; + int has_connector; + int trap_enable; + uint64_t counter_disc; + + /* + * This is needed to handle interface type specific information + * in sub-modules. It contains a function pointer which handles + * notifications and a data pointer to arbitrary data. + * Should be set via the mibif_notify function. + */ + mibif_notify_f xnotify; + void *xnotify_data; + const struct lmodule *xnotify_mod; + + /* to be set by ifType specific modules. This is ifSpecific. */ + struct asn_oid spec_oid; + + /* private data - don't touch */ + void *private; +}; + +/* + * Interface IP-address table. + */ +struct mibifa { + TAILQ_ENTRY(mibifa) link; + struct in_addr inaddr; + struct in_addr inmask; + struct in_addr inbcast; + struct asn_oid index; /* index for table search */ + u_int ifindex; + u_int flags; +}; + +/* + * Interface receive addresses. Interface link-level multicast, broadcast + * and hardware addresses are handled automatically. + */ +struct mibrcvaddr { + TAILQ_ENTRY(mibrcvaddr) link; + struct asn_oid index; + u_int ifindex; + u_char addr[ASN_MAXOIDLEN]; + size_t addrlen; + u_int flags; +}; +enum { + MIBRCVADDR_VOLATILE = 0x00000001, + MIBRCVADDR_BCAST = 0x00000002, + MIBRCVADDR_HW = 0x00000004, +}; + +/* network socket */ +extern int mib_netsock; + +/* set an interface name to dynamic mode */ +void mib_if_set_dyn(const char *); + +/* re-read the systems interface list */ +void mib_refresh_iflist(void); + +/* find interface by index */ +struct mibif *mib_find_if(u_int); +struct mibif *mib_find_if_sys(u_int); +struct mibif *mib_find_if_name(const char *); + +/* iterate through all interfaces */ +struct mibif *mib_first_if(void); +struct mibif *mib_next_if(const struct mibif *); + +/* register for interface creations */ +int mib_register_newif(int (*)(struct mibif *), const struct lmodule *); +void mib_unregister_newif(const struct lmodule *); + +/* get fresh MIB data */ +int mib_fetch_ifmib(struct mibif *); + +/* change the ADMIN status of an interface and refresh the MIB */ +int mib_if_admin(struct mibif *, int up); + +/* find interface address by address */ +struct mibifa *mib_find_ifa(struct in_addr); + +/* find first/next address for a given interface */ +struct mibifa *mib_first_ififa(const struct mibif *); +struct mibifa *mib_next_ififa(struct mibifa *); + +/* create/delete stacking entries */ +int mib_ifstack_create(const struct mibif *lower, const struct mibif *upper); +void mib_ifstack_delete(const struct mibif *lower, const struct mibif *upper); + +/* find receive address */ +struct mibrcvaddr *mib_find_rcvaddr(u_int, const u_char *, size_t); + +/* create/delete receive addresses */ +struct mibrcvaddr *mib_rcvaddr_create(struct mibif *, const u_char *, size_t); +void mib_rcvaddr_delete(struct mibrcvaddr *); + +/* register for interface notification */ +void *mibif_notify(struct mibif *, const struct lmodule *, mibif_notify_f, + void *); +void mibif_unnotify(void *); + +#endif diff --git a/src/include.new/bsnmp/snmp_netgraph.h b/src/include.new/bsnmp/snmp_netgraph.h new file mode 100644 index 0000000..780c5b4 --- /dev/null +++ b/src/include.new/bsnmp/snmp_netgraph.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Redistribution of this software and documentation and use in source and + * binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * + * 1. Redistributions of source code or documentation must retain the above + * copyright notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS + * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/10.2/usr.sbin/bsnmpd/modules/snmp_netgraph/snmp_netgraph.h 122405 2003-11-10 09:17:34Z harti $ + * + * Netgraph interface for SNMPd. Exported stuff. + */ +#ifndef SNMP_NETGRAPH_H_ +#define SNMP_NETGRAPH_H_ + +#include + +extern ng_ID_t snmp_node; +extern u_char *snmp_nodename; + +typedef void ng_cookie_f(const struct ng_mesg *, const char *, ng_ID_t, void *); +typedef void ng_hook_f(const char *, const u_char *, size_t, void *); + +void *ng_register_cookie(const struct lmodule *, uint32_t cookie, + ng_ID_t, ng_cookie_f *, void *); +void ng_unregister_cookie(void *reg); + +void *ng_register_hook(const struct lmodule *, const char *, + ng_hook_f *, void *); +void ng_unregister_hook(void *reg); + +void ng_unregister_module(const struct lmodule *); + +int ng_output(const char *path, u_int cookie, u_int opcode, + const void *arg, size_t arglen); +int ng_output_node(const char *node, u_int cookie, u_int opcode, + const void *arg, size_t arglen); +int ng_output_id(ng_ID_t node, u_int cookie, u_int opcode, + const void *arg, size_t arglen); + +struct ng_mesg *ng_dialog(const char *path, u_int cookie, u_int opcode, + const void *arg, size_t arglen); +struct ng_mesg *ng_dialog_node(const char *node, u_int cookie, u_int opcode, + const void *arg, size_t arglen); +struct ng_mesg *ng_dialog_id(ng_ID_t id, u_int cookie, u_int opcode, + const void *arg, size_t arglen); + +int ng_send_data(const char *hook, const void *sndbuf, size_t sndlen); + +ng_ID_t ng_mkpeer_id(ng_ID_t, const char *name, const char *type, + const char *hook, const char *peerhook); +int ng_connect_node(const char *node, const char *ourhook, const char *peerhook); +int ng_connect_id(ng_ID_t id, const char *ourhook, const char *peerhook); +int ng_connect2_id(ng_ID_t id, ng_ID_t peer, const char *ourhook, + const char *peerhook); +int ng_connect2_tee_id(ng_ID_t id, ng_ID_t peer, const char *ourhook, + const char *peerhook); +int ng_rmhook(const char *ourhook); +int ng_rmhook_id(ng_ID_t, const char *); +int ng_rmhook_tee_id(ng_ID_t, const char *); +int ng_shutdown_id(ng_ID_t); + +ng_ID_t ng_next_node_id(ng_ID_t node, const char *type, const char *hook); +ng_ID_t ng_node_id(const char *path); +ng_ID_t ng_node_id_node(const char *node); +ng_ID_t ng_node_name(ng_ID_t, char *); +ng_ID_t ng_node_type(ng_ID_t, char *); +int ng_peer_hook_id(ng_ID_t, const char *, char *); + +#endif diff --git a/src/include.new/bsnmp/snmpagent.h b/src/include.new/bsnmp/snmpagent.h new file mode 100644 index 0000000..66019c9 --- /dev/null +++ b/src/include.new/bsnmp/snmpagent.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/lib/snmpagent.h,v 1.13 2004/08/06 08:46:56 brandt Exp $ + * + * Header file for SNMP functions. This requires snmp.h to be included. + */ +#ifndef snmp_agent_h_ +#define snmp_agent_h_ + +struct snmp_dependency; + +enum snmp_ret { + /* OK, generate a response */ + SNMP_RET_OK = 0, + /* Error, ignore packet (no response) */ + SNMP_RET_IGN = 1, + /* Error, generate response from original packet */ + SNMP_RET_ERR = 2 +}; + +/* Semi-Opaque object for SET operations */ +struct snmp_context { + u_int var_index; + struct snmp_scratch *scratch; + struct snmp_dependency *dep; + void *data; /* user data */ + enum snmp_ret code; /* return code */ +}; + +struct snmp_scratch { + void *ptr1; + void *ptr2; + uint32_t int1; + uint32_t int2; +}; + +enum snmp_depop { + SNMP_DEPOP_COMMIT, + SNMP_DEPOP_ROLLBACK, + SNMP_DEPOP_FINISH +}; + +typedef int (*snmp_depop_t)(struct snmp_context *, struct snmp_dependency *, + enum snmp_depop); + +struct snmp_dependency { + struct asn_oid obj; + struct asn_oid idx; +}; + +/* + * The TREE + */ +enum snmp_node_type { + SNMP_NODE_LEAF = 1, + SNMP_NODE_COLUMN +}; + +enum snmp_op { + SNMP_OP_GET = 1, + SNMP_OP_GETNEXT, + SNMP_OP_SET, + SNMP_OP_COMMIT, + SNMP_OP_ROLLBACK, +}; + +typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *, + u_int, u_int, enum snmp_op); + +struct snmp_node { + struct asn_oid oid; + const char *name; /* name of the leaf */ + enum snmp_node_type type; /* type of this node */ + enum snmp_syntax syntax; + snmp_op_t op; + u_int flags; + uint32_t index; /* index data */ + void *data; /* application data */ + void *tree_data; /* application data */ +}; +extern struct snmp_node *tree; +extern u_int tree_size; + +#define SNMP_NODE_CANSET 0x0001 /* SET allowed */ + +#define SNMP_INDEXES_MAX 7 +#define SNMP_INDEX_SHIFT 4 +#define SNMP_INDEX_MASK 0xf +#define SNMP_INDEX_COUNT(V) ((V) & SNMP_INDEX_MASK) +#define SNMP_INDEX(V,I) \ + (((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & SNMP_INDEX_MASK) + +enum { + SNMP_TRACE_GET = 0x00000001, + SNMP_TRACE_GETNEXT = 0x00000002, + SNMP_TRACE_SET = 0x00000004, + SNMP_TRACE_DEPEND = 0x00000008, + SNMP_TRACE_FIND = 0x00000010, +}; +/* trace flag for the following functions */ +extern u_int snmp_trace; + +/* called to write the trace */ +extern void (*snmp_debug)(const char *fmt, ...); + +enum snmp_ret snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b, + struct snmp_pdu *resp, void *); +enum snmp_ret snmp_getnext(struct snmp_pdu *pdu, struct asn_buf *resp_b, + struct snmp_pdu *resp, void *); +enum snmp_ret snmp_getbulk(struct snmp_pdu *pdu, struct asn_buf *resp_b, + struct snmp_pdu *resp, void *); +enum snmp_ret snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b, + struct snmp_pdu *resp, void *); + +enum snmp_ret snmp_make_errresp(const struct snmp_pdu *, struct asn_buf *, + struct asn_buf *); + +struct snmp_dependency *snmp_dep_lookup(struct snmp_context *, + const struct asn_oid *, const struct asn_oid *, size_t, snmp_depop_t); + +struct snmp_context *snmp_init_context(void); +int snmp_dep_commit(struct snmp_context *); +int snmp_dep_rollback(struct snmp_context *); +void snmp_dep_finish(struct snmp_context *); + +#endif diff --git a/src/include.new/bsnmp/snmpclient.h b/src/include.new/bsnmp/snmpclient.h new file mode 100644 index 0000000..619f726 --- /dev/null +++ b/src/include.new/bsnmp/snmpclient.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * Kendy Kutzner + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/lib/snmpclient.h,v 1.19 2005/05/23 11:10:14 brandt_h Exp $ + */ +#ifndef _BSNMP_SNMPCLIENT_H +#define _BSNMP_SNMPCLIENT_H + +#include +#include +#include +#include +#include + + +#define SNMP_STRERROR_LEN 200 + +#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX" + +/* + * transport methods + */ +#define SNMP_TRANS_UDP 0 +#define SNMP_TRANS_LOC_DGRAM 1 +#define SNMP_TRANS_LOC_STREAM 2 + +/* type of callback function for responses + * this callback function is responsible for free() any memory associated with + * any of the PDUs. Therefor it may call snmp_pdu_free() */ +typedef void (*snmp_send_cb_f)(struct snmp_pdu *, struct snmp_pdu *, void *); + +/* type of callback function for timeouts */ +typedef void (*snmp_timeout_cb_f)(void * ); + +/* timeout start function */ +typedef void *(*snmp_timeout_start_f)(struct timeval *timeout, + snmp_timeout_cb_f callback, void *); + +/* timeout stop function */ +typedef void (*snmp_timeout_stop_f)(void *timeout_id); + +/* + * Client context. + */ +struct snmp_client { + enum snmp_version version; + int trans; /* which transport to use */ + + /* these two are read-only for the application */ + char *cport; /* port number as string */ + char *chost; /* host name or IP address as string */ + + char read_community[SNMP_COMMUNITY_MAXLEN + 1]; + char write_community[SNMP_COMMUNITY_MAXLEN + 1]; + + /* SNMPv3 specific fields */ + int32_t identifier; + int32_t security_model; + struct snmp_engine engine; + struct snmp_user user; + + /* SNMPv3 Access control - VACM*/ + uint32_t clen; + uint8_t cengine[SNMP_ENGINE_ID_SIZ]; + char cname[SNMP_CONTEXT_NAME_SIZ]; + + struct timeval timeout; + u_int retries; + + int dump_pdus; + + size_t txbuflen; + size_t rxbuflen; + + int fd; + + int32_t next_reqid; + int32_t max_reqid; + int32_t min_reqid; + + char error[SNMP_STRERROR_LEN]; + + snmp_timeout_start_f timeout_start; + snmp_timeout_stop_f timeout_stop; + + char local_path[sizeof(SNMP_LOCAL_PATH)]; +}; + +/* the global context */ +extern struct snmp_client snmp_client; + +/* initizialies a snmp_client structure */ +void snmp_client_init(struct snmp_client *); + +/* initialize fields */ +int snmp_client_set_host(struct snmp_client *, const char *); +int snmp_client_set_port(struct snmp_client *, const char *); + +/* open connection to snmp server (hostname or portname can be NULL) */ +int snmp_open(const char *_hostname, const char *_portname, + const char *_read_community, const char *_write_community); + +/* close connection */ +void snmp_close(void); + +/* initialize a snmp_pdu structure */ +void snmp_pdu_create(struct snmp_pdu *, u_int _op); + +/* add pairs of (struct asn_oid *, enum snmp_syntax) to an existing pdu */ +int snmp_add_binding(struct snmp_pdu *, ...); + +/* check wheater the answer is valid or not */ +int snmp_pdu_check(const struct snmp_pdu *_req, const struct snmp_pdu *_resp); + +int32_t snmp_pdu_send(struct snmp_pdu *_pdu, snmp_send_cb_f _func, void *_arg); + +/* append an index to an oid */ +int snmp_oid_append(struct asn_oid *_oid, const char *_fmt, ...); + +/* receive a packet */ +int snmp_receive(int _blocking); + +/* + * This structure is used to describe an SNMP table that is to be fetched. + * The C-structure that is produced by the fetch function must start with + * a TAILQ_ENTRY and an u_int64_t. + */ +struct snmp_table { + /* base OID of the table */ + struct asn_oid table; + /* type OID of the LastChange variable for the table if any */ + struct asn_oid last_change; + /* maximum number of iterations if table has changed */ + u_int max_iter; + /* size of the C-structure */ + size_t entry_size; + /* number of index fields */ + u_int index_size; + /* bit mask of required fields */ + uint64_t req_mask; + + /* indexes and columns to fetch. Ended by a NULL syntax entry */ + struct snmp_table_entry { + /* the column sub-oid, ignored for index fields */ + asn_subid_t subid; + /* the syntax of the column or index */ + enum snmp_syntax syntax; + /* offset of the field into the C-structure. For octet strings + * this points to an u_char * followed by a size_t */ + off_t offset; +#if defined(__GNUC__) && __GNUC__ < 3 + } entries[0]; +#else + } entries[]; +#endif +}; + +/* callback type for table fetch */ +typedef void (*snmp_table_cb_f)(void *_list, void *_arg, int _res); + +/* fetch a table. The argument points to a TAILQ_HEAD */ +int snmp_table_fetch(const struct snmp_table *descr, void *); +int snmp_table_fetch_async(const struct snmp_table *, void *, + snmp_table_cb_f, void *); + +/* send a request and wait for the response */ +int snmp_dialog(struct snmp_pdu *_req, struct snmp_pdu *_resp); + +/* discover an authorative snmpEngineId */ +int snmp_discover_engine(char *); + +/* parse a server specification */ +int snmp_parse_server(struct snmp_client *, const char *); + +#endif /* _BSNMP_SNMPCLIENT_H */ diff --git a/src/include.new/bsnmp/snmpmod.h b/src/include.new/bsnmp/snmpmod.h new file mode 100644 index 0000000..4abc460 --- /dev/null +++ b/src/include.new/bsnmp/snmpmod.h @@ -0,0 +1,625 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Harti Brandt + * + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Shteryana Sotirova Shopova + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Begemot: bsnmp/snmpd/snmpmod.h,v 1.32 2006/02/14 09:04:20 brandt_h Exp $ + * + * SNMP daemon data and functions exported to modules. + */ +#ifndef snmpmod_h_ +#define snmpmod_h_ + +#include +#include +#include +#include +#include +#include "asn1.h" +#include "snmp.h" +#include "snmpagent.h" + +#define MAX_MOD_ARGS 16 + +/* + * These macros help to handle object lists for SNMP tables. They use + * tail queues to hold the objects in ascending order in the list. + * ordering can be done either on an integer/unsigned field, an asn_oid + * or an ordering function. + */ +#define INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \ + __typeof (PTR) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if (asn_compare_oid(&_lelem->INDEX, &(PTR)->INDEX) > 0) \ + break; \ + if (_lelem == NULL) \ + TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ + else \ + TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ + } while (0) + +#define INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \ + __typeof (PTR) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((asn_subid_t)_lelem->INDEX > (asn_subid_t)(PTR)->INDEX)\ + break; \ + if (_lelem == NULL) \ + TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ + else \ + TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ + } while (0) + +#define INSERT_OBJECT_FUNC_LINK(PTR, LIST, LINK, FUNC) do { \ + __typeof (PTR) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((FUNC)(_lelem, (PTR)) > 0) \ + break; \ + if (_lelem == NULL) \ + TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ + else \ + TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ + } while (0) + +#define INSERT_OBJECT_FUNC_LINK_REV(PTR, LIST, HEAD, LINK, FUNC) do { \ + __typeof (PTR) _lelem; \ + \ + TAILQ_FOREACH_REVERSE(_lelem, (LIST), HEAD, LINK) \ + if ((FUNC)(_lelem, (PTR)) < 0) \ + break; \ + if (_lelem == NULL) \ + TAILQ_INSERT_HEAD((LIST), (PTR), LINK); \ + else \ + TAILQ_INSERT_AFTER((LIST), _lelem, (PTR), LINK); \ + } while (0) + +#define FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if (index_compare(OID, SUB, &_lelem->INDEX) == 0) \ + break; \ + (_lelem); \ + }) + +#define NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if (index_compare(OID, SUB, &_lelem->INDEX) < 0) \ + break; \ + (_lelem); \ + }) + +#define FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + if ((OID)->len - SUB != 1) \ + _lelem = NULL; \ + else \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((OID)->subs[SUB] == (asn_subid_t)_lelem->INDEX)\ + break; \ + (_lelem); \ + }) + +#define NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + if ((OID)->len - SUB == 0) \ + _lelem = TAILQ_FIRST(LIST); \ + else \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((OID)->subs[SUB] < (asn_subid_t)_lelem->INDEX)\ + break; \ + (_lelem); \ + }) + +#define FIND_OBJECT_FUNC_LINK(LIST, OID, SUB, LINK, FUNC) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((FUNC)(OID, SUB, _lelem) == 0) \ + break; \ + (_lelem); \ + }) + +#define NEXT_OBJECT_FUNC_LINK(LIST, OID, SUB, LINK, FUNC) ({ \ + __typeof (TAILQ_FIRST(LIST)) _lelem; \ + \ + TAILQ_FOREACH(_lelem, (LIST), LINK) \ + if ((FUNC)(OID, SUB, _lelem) < 0) \ + break; \ + (_lelem); \ + }) + +/* + * Macros for the case where the index field is called 'index' + */ +#define INSERT_OBJECT_OID_LINK(PTR, LIST, LINK) \ + INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, index) + +#define INSERT_OBJECT_INT_LINK(PTR, LIST, LINK) do { \ + INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, index) + +#define FIND_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \ + FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index) + +#define NEXT_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \ + NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index) + +#define FIND_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \ + FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index) + +#define NEXT_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \ + NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index) + +/* + * Macros for the case where the index field is called 'index' and the + * link field 'link'. + */ +#define INSERT_OBJECT_OID(PTR, LIST) \ + INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, link, index) + +#define INSERT_OBJECT_INT(PTR, LIST) \ + INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, link, index) + +#define INSERT_OBJECT_FUNC_REV(PTR, LIST, HEAD, FUNC) \ + INSERT_OBJECT_FUNC_LINK_REV(PTR, LIST, HEAD, link, FUNC) + +#define FIND_OBJECT_OID(LIST, OID, SUB) \ + FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index) + +#define FIND_OBJECT_INT(LIST, OID, SUB) \ + FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index) + +#define FIND_OBJECT_FUNC(LIST, OID, SUB, FUNC) \ + FIND_OBJECT_FUNC_LINK(LIST, OID, SUB, link, FUNC) + +#define NEXT_OBJECT_OID(LIST, OID, SUB) \ + NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index) + +#define NEXT_OBJECT_INT(LIST, OID, SUB) \ + NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index) + +#define NEXT_OBJECT_FUNC(LIST, OID, SUB, FUNC) \ + NEXT_OBJECT_FUNC_LINK(LIST, OID, SUB, link, FUNC) + +struct lmodule; + +/* The tick when the program was started. This is the absolute time of + * the start in 100th of a second. */ +extern uint64_t start_tick; + +/* The tick when the current packet was received. This is the absolute + * time in 100th of second. */ +extern uint64_t this_tick; + +/* Get the current absolute time in 100th of a second. */ +uint64_t get_ticks(void); + +/* + * Return code for proxy function + */ +enum snmpd_proxy_err { + /* proxy code will process the PDU */ + SNMPD_PROXY_OK, + /* proxy code does not process PDU */ + SNMPD_PROXY_REJ, + /* drop this PDU */ + SNMPD_PROXY_DROP, + /* drop because of bad community */ + SNMPD_PROXY_BADCOMM, + /* drop because of bad community use */ + SNMPD_PROXY_BADCOMMUSE +}; + +/* + * Input handling + */ +enum snmpd_input_err { + /* proceed with packet */ + SNMPD_INPUT_OK, + /* fatal error in packet, ignore it */ + SNMPD_INPUT_FAILED, + /* value encoding has wrong length in a SET operation */ + SNMPD_INPUT_VALBADLEN, + /* value encoding is out of range */ + SNMPD_INPUT_VALRANGE, + /* value has bad encoding */ + SNMPD_INPUT_VALBADENC, + /* need more data (truncated packet) */ + SNMPD_INPUT_TRUNC, + /* unknown community */ + SNMPD_INPUT_BAD_COMM, +}; + +/* + * Every loadable module must have one of this structures with + * the external name 'config'. + */ +struct snmp_module { + /* a comment describing what this module implements */ + const char *comment; + + /* the initialization function */ + int (*init)(struct lmodule *, int argc, char *argv[]); + + /* the finalisation function */ + int (*fini)(void); + + /* the idle function */ + void (*idle)(void); + + /* the dump function */ + void (*dump)(void); + + /* re-configuration function */ + void (*config)(void); + + /* start operation */ + void (*start)(void); + + /* proxy a PDU */ + enum snmpd_proxy_err (*proxy)(struct snmp_pdu *, void *, + const struct asn_oid *, const struct sockaddr *, socklen_t, + enum snmpd_input_err, int32_t, int); + + /* the tree this module is going to server */ + const struct snmp_node *tree; + u_int tree_size; + + /* function called, when another module was unloaded/loaded */ + void (*loading)(const struct lmodule *, int); +}; + +/* + * Stuff exported to modules + */ + +/* + * The system group. + */ +struct systemg { + u_char *descr; + struct asn_oid object_id; + u_char *contact; + u_char *name; + u_char *location; + uint32_t services; + uint32_t or_last_change; +}; +extern struct systemg systemg; + +/* + * Community support. + * + * We have 2 fixed communities for SNMP read and write access. Modules + * can create their communities dynamically. They are deleted automatically + * if the module is unloaded. + */ +#define COMM_INITIALIZE 0 +#define COMM_READ 1 +#define COMM_WRITE 2 + +u_int comm_define(u_int, const char *descr, struct lmodule *, const char *str); +const char * comm_string(u_int); + +/* community for current packet */ +extern u_int community; + +/* + * SNMP User-based Security Model data. Modified via the snmp_usm(3) module. + */ +struct snmpd_usmstat { + uint32_t unsupported_seclevels; + uint32_t not_in_time_windows; + uint32_t unknown_users; + uint32_t unknown_engine_ids; + uint32_t wrong_digests; + uint32_t decrypt_errors; +}; + +extern struct snmpd_usmstat snmpd_usmstats; +struct snmpd_usmstat *bsnmpd_get_usm_stats(void); +void bsnmpd_reset_usm_stats(void); + +struct usm_user { + struct snmp_user suser; + uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ]; + uint32_t user_engine_len; + char user_public[SNMP_ADM_STR32_SIZ]; + uint32_t user_public_len; + int32_t status; + int32_t type; + SLIST_ENTRY(usm_user) up; +}; + +SLIST_HEAD(usm_userlist, usm_user); +struct usm_user *usm_first_user(void); +struct usm_user *usm_next_user(struct usm_user *); +struct usm_user *usm_find_user(uint8_t *, uint32_t, char *); +struct usm_user *usm_new_user(uint8_t *, uint32_t, char *); +void usm_delete_user(struct usm_user *); +void usm_flush_users(void); + +/* USM user for current packet */ +extern struct usm_user *usm_user; + +/* + * SNMP View-based Access Control Model data. Modified via the snmp_vacm(3) module. + */ +struct vacm_group; + +struct vacm_user { + /* Security user name from USM */ + char secname[SNMP_ADM_STR32_SIZ]; + int32_t sec_model; + /* Back pointer to user assigned group name */ + struct vacm_group *group; + int32_t type; + int32_t status; + SLIST_ENTRY(vacm_user) vvu; + SLIST_ENTRY(vacm_user) vvg; +}; + +SLIST_HEAD(vacm_userlist, vacm_user); + +struct vacm_group { + char groupname[SNMP_ADM_STR32_SIZ]; + struct vacm_userlist group_users; + SLIST_ENTRY(vacm_group) vge; +}; + +SLIST_HEAD(vacm_grouplist, vacm_group); + +struct vacm_access { + /* The group name is index, not a column in the table */ + struct vacm_group *group; + char ctx_prefix[SNMP_ADM_STR32_SIZ]; + int32_t sec_model; + int32_t sec_level; + int32_t ctx_match; + struct vacm_view *read_view; + struct vacm_view *write_view; + struct vacm_view *notify_view; + int32_t type; + int32_t status; + TAILQ_ENTRY(vacm_access) vva; +}; + +TAILQ_HEAD(vacm_accesslist, vacm_access); + +struct vacm_view { + char viewname[SNMP_ADM_STR32_SIZ]; /* key */ + struct asn_oid subtree; /* key */ + uint8_t mask[16]; + uint8_t exclude; + int32_t type; + int32_t status; + SLIST_ENTRY(vacm_view) vvl; +}; + +SLIST_HEAD(vacm_viewlist, vacm_view); + +struct vacm_context { + /* The ID of the module that registered this context */ + int32_t regid; + char ctxname[SNMP_ADM_STR32_SIZ]; + SLIST_ENTRY(vacm_context) vcl; +}; + +SLIST_HEAD(vacm_contextlist, vacm_context); + +void vacm_groups_init(void); +struct vacm_user *vacm_first_user(void); +struct vacm_user *vacm_next_user(struct vacm_user *); +struct vacm_user *vacm_new_user(int32_t, char *); +int vacm_delete_user(struct vacm_user *); +int vacm_user_set_group(struct vacm_user *, u_char *, u_int); +struct vacm_access *vacm_first_access_rule(void); +struct vacm_access *vacm_next_access_rule(struct vacm_access *); +struct vacm_access *vacm_new_access_rule(char *, char *, int32_t, int32_t); +int vacm_delete_access_rule(struct vacm_access *); +struct vacm_view *vacm_first_view(void); +struct vacm_view *vacm_next_view(struct vacm_view *); +struct vacm_view *vacm_new_view(char *, struct asn_oid *); +int vacm_delete_view(struct vacm_view *); +struct vacm_context *vacm_first_context(void); +struct vacm_context *vacm_next_context(struct vacm_context *); +struct vacm_context *vacm_add_context(char *, int32_t); +void vacm_flush_contexts(int32_t); + +/* + * RFC 3413 SNMP Management Target & Notification MIB + */ + +struct snmpd_target_stats { + uint32_t unavail_contexts; + uint32_t unknown_contexts; +}; + +#define SNMP_UDP_ADDR_SIZ 6 +#define SNMP_TAG_SIZ (255 + 1) + +struct target_address { + char name[SNMP_ADM_STR32_SIZ]; + uint8_t address[SNMP_UDP_ADDR_SIZ]; + int32_t timeout; + int32_t retry; + char taglist[SNMP_TAG_SIZ]; + char paramname[SNMP_ADM_STR32_SIZ]; + int32_t type; + int32_t socket; + int32_t status; + SLIST_ENTRY(target_address) ta; +}; + +SLIST_HEAD(target_addresslist, target_address); + +struct target_param { + char name[SNMP_ADM_STR32_SIZ]; + int32_t mpmodel; + int32_t sec_model; + char secname[SNMP_ADM_STR32_SIZ]; + enum snmp_usm_level sec_level; + int32_t type; + int32_t status; + SLIST_ENTRY(target_param) tp; +}; + +SLIST_HEAD(target_paramlist, target_param); + +struct target_notify { + char name[SNMP_ADM_STR32_SIZ]; + char taglist[SNMP_TAG_SIZ]; + int32_t notify_type; + int32_t type; + int32_t status; + SLIST_ENTRY(target_notify) tn; +}; + +SLIST_HEAD(target_notifylist, target_notify); + +extern struct snmpd_target_stats snmpd_target_stats; +struct snmpd_target_stats *bsnmpd_get_target_stats(void); +struct target_address *target_first_address(void); +struct target_address *target_next_address(struct target_address *); +struct target_address *target_new_address(char *); +int target_activate_address(struct target_address *); +int target_delete_address(struct target_address *); +struct target_param *target_first_param(void); +struct target_param *target_next_param(struct target_param *); +struct target_param *target_new_param(char *); +int target_delete_param(struct target_param *); +struct target_notify *target_first_notify(void); +struct target_notify *target_next_notify(struct target_notify *); +struct target_notify *target_new_notify(char *); +int target_delete_notify (struct target_notify *); +void target_flush_all(void); + +/* + * Well known OIDs + */ +extern const struct asn_oid oid_zeroDotZero; + +/* SNMPv3 Engine Discovery */ +extern const struct asn_oid oid_usmUnknownEngineIDs; +extern const struct asn_oid oid_usmNotInTimeWindows; + +/* + * Request ID ranges. + * + * A module can request a range of request ids and associate them with a + * type field. All ranges are deleted if a module is unloaded. + */ +u_int reqid_allocate(int size, struct lmodule *); +int32_t reqid_next(u_int type); +int32_t reqid_base(u_int type); +int reqid_istype(int32_t reqid, u_int type); +u_int reqid_type(int32_t reqid); + +/* + * Timers. + */ +void *timer_start(u_int, void (*)(void *), void *, struct lmodule *); +void *timer_start_repeat(u_int, u_int, void (*)(void *), void *, + struct lmodule *); +void timer_stop(void *); + +/* + * File descriptors + */ +void *fd_select(int, void (*)(int, void *), void *, struct lmodule *); +void fd_deselect(void *); +void fd_suspend(void *); +int fd_resume(void *); + +/* + * Object resources + */ +u_int or_register(const struct asn_oid *, const char *, struct lmodule *); +void or_unregister(u_int); + +/* + * Buffers + */ +void *buf_alloc(int tx); +size_t buf_size(int tx); + +/* decode PDU and find community */ +enum snmpd_input_err snmp_input_start(const u_char *, size_t, const char *, + struct snmp_pdu *, int32_t *, size_t *); + +/* process the pdu. returns either _OK or _FAILED */ +enum snmpd_input_err snmp_input_finish(struct snmp_pdu *, const u_char *, + size_t, u_char *, size_t *, const char *, enum snmpd_input_err, int32_t, + void *); + +void snmp_output(struct snmp_pdu *, u_char *, size_t *, const char *); +void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *, + const struct sockaddr *, socklen_t); +enum snmp_code snmp_pdu_auth_access(struct snmp_pdu *, int32_t *); + +/* sending traps */ +void snmp_send_trap(const struct asn_oid *, ...); + +/* + * Action support + */ +int string_save(struct snmp_value *, struct snmp_context *, ssize_t, u_char **); +void string_commit(struct snmp_context *); +void string_rollback(struct snmp_context *, u_char **); +int string_get(struct snmp_value *, const u_char *, ssize_t); +int string_get_max(struct snmp_value *, const u_char *, ssize_t, size_t); +void string_free(struct snmp_context *); + +int ip_save(struct snmp_value *, struct snmp_context *, u_char *); +void ip_rollback(struct snmp_context *, u_char *); +void ip_commit(struct snmp_context *); +int ip_get(struct snmp_value *, u_char *); + +int oid_save(struct snmp_value *, struct snmp_context *, struct asn_oid *); +void oid_rollback(struct snmp_context *, struct asn_oid *); +void oid_commit(struct snmp_context *); +int oid_get(struct snmp_value *, const struct asn_oid *); + +int index_decode(const struct asn_oid *oid, u_int sub, u_int code, ...); +int index_compare(const struct asn_oid *, u_int, const struct asn_oid *); +int index_compare_off(const struct asn_oid *, u_int, const struct asn_oid *, + u_int); +void index_append(struct asn_oid *, u_int, const struct asn_oid *); +void index_append_off(struct asn_oid *, u_int, const struct asn_oid *, u_int); + +#endif diff --git a/src/include.new/bzlib.h b/src/include.new/bzlib.h new file mode 100644 index 0000000..8277123 --- /dev/null +++ b/src/include.new/bzlib.h @@ -0,0 +1,282 @@ + +/*-------------------------------------------------------------*/ +/*--- Public header file for the library. ---*/ +/*--- bzlib.h ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.6 of 6 September 2010 + Copyright (C) 1996-2010 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#ifndef _BZLIB_H +#define _BZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BZ_RUN 0 +#define BZ_FLUSH 1 +#define BZ_FINISH 2 + +#define BZ_OK 0 +#define BZ_RUN_OK 1 +#define BZ_FLUSH_OK 2 +#define BZ_FINISH_OK 3 +#define BZ_STREAM_END 4 +#define BZ_SEQUENCE_ERROR (-1) +#define BZ_PARAM_ERROR (-2) +#define BZ_MEM_ERROR (-3) +#define BZ_DATA_ERROR (-4) +#define BZ_DATA_ERROR_MAGIC (-5) +#define BZ_IO_ERROR (-6) +#define BZ_UNEXPECTED_EOF (-7) +#define BZ_OUTBUFF_FULL (-8) +#define BZ_CONFIG_ERROR (-9) + +typedef + struct { + char *next_in; + unsigned int avail_in; + unsigned int total_in_lo32; + unsigned int total_in_hi32; + + char *next_out; + unsigned int avail_out; + unsigned int total_out_lo32; + unsigned int total_out_hi32; + + void *state; + + void *(*bzalloc)(void *,int,int); + void (*bzfree)(void *,void *); + void *opaque; + } + bz_stream; + + +#ifndef BZ_IMPORT +#define BZ_EXPORT +#endif + +#ifndef BZ_NO_STDIO +/* Need a definitition for FILE */ +#include +#endif + +#ifdef _WIN32 +# include +# ifdef small + /* windows.h define small to char */ +# undef small +# endif +# ifdef BZ_EXPORT +# define BZ_API(func) WINAPI func +# define BZ_EXTERN extern +# else + /* import windows dll dynamically */ +# define BZ_API(func) (WINAPI * func) +# define BZ_EXTERN +# endif +#else +# define BZ_API(func) func +# define BZ_EXTERN extern +#endif + + +/*-- Core (low-level) library functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( + bz_stream* strm, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompress) ( + bz_stream* strm, + int action + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( + bz_stream *strm, + int verbosity, + int small + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( + bz_stream *strm + ); + + + +/*-- High(er) level library functions --*/ + +#ifndef BZ_NO_STDIO +#define BZ_MAX_UNUSED 5000 + +typedef void BZFILE; + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( + int* bzerror, + FILE* f, + int verbosity, + int small, + void* unused, + int nUnused + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( + int* bzerror, + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( + int* bzerror, + BZFILE* b, + void** unused, + int* nUnused + ); + +BZ_EXTERN int BZ_API(BZ2_bzRead) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( + int* bzerror, + FILE* f, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN void BZ_API(BZ2_bzWrite) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in, + unsigned int* nbytes_out + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in_lo32, + unsigned int* nbytes_in_hi32, + unsigned int* nbytes_out_lo32, + unsigned int* nbytes_out_hi32 + ); +#endif + + +/*-- Utility functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int small, + int verbosity + ); + + +/*-- + Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) + to support better zlib compatibility. + This code is not _officially_ part of libbzip2 (yet); + I haven't tested it, documented it, or considered the + threading-safeness of it. + If this code breaks, please contact both Yoshioka and me. +--*/ + +BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( + void + ); + +#ifndef BZ_NO_STDIO +BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( + const char *path, + const char *mode + ); + +BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( + int fd, + const char *mode + ); + +BZ_EXTERN int BZ_API(BZ2_bzread) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzwrite) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzflush) ( + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzclose) ( + BZFILE* b + ); + +BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( + BZFILE *b, + int *errnum + ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/*-------------------------------------------------------------*/ +/*--- end bzlib.h ---*/ +/*-------------------------------------------------------------*/ diff --git a/src/include.new/c++/3.4/algorithm b/src/include.new/c++/3.4/algorithm new file mode 100644 index 0000000..40e6246 --- /dev/null +++ b/src/include.new/c++/3.4/algorithm @@ -0,0 +1,71 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file algorithm + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_ALGORITHM +#define _GLIBCXX_ALGORITHM 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +#endif /* _GLIBCXX_ALGORITHM */ diff --git a/src/include.new/c++/3.4/backward/algo.h b/src/include.new/c++/3.4/backward/algo.h new file mode 100644 index 0000000..6f24835 --- /dev/null +++ b/src/include.new/c++/3.4/backward/algo.h @@ -0,0 +1,149 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGO_H +#define _BACKWARD_ALGO_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "tempbuf.h" +#include "iterator.h" +#include +#include +#include +#include + +// Names from +using std::for_each; +using std::find; +using std::find_if; +using std::adjacent_find; +using std::count; +using std::count_if; +using std::search; +using std::search_n; +using std::swap_ranges; +using std::transform; +using std::replace; +using std::replace_if; +using std::replace_copy; +using std::replace_copy_if; +using std::generate; +using std::generate_n; +using std::remove; +using std::remove_if; +using std::remove_copy; +using std::remove_copy_if; +using std::unique; +using std::unique_copy; +using std::reverse; +using std::reverse_copy; +using std::rotate; +using std::rotate_copy; +using std::random_shuffle; +using std::partition; +using std::stable_partition; +using std::sort; +using std::stable_sort; +using std::partial_sort; +using std::partial_sort_copy; +using std::nth_element; +using std::lower_bound; +using std::upper_bound; +using std::equal_range; +using std::binary_search; +using std::merge; +using std::inplace_merge; +using std::includes; +using std::set_union; +using std::set_intersection; +using std::set_difference; +using std::set_symmetric_difference; +using std::min_element; +using std::max_element; +using std::next_permutation; +using std::prev_permutation; +using std::find_first_of; +using std::find_end; + +// Names from stl_heap.h +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +// Names from stl_numeric.h +using std::accumulate; +using std::inner_product; +using std::partial_sum; +using std::adjacent_difference; + +// Names from ext/algorithm +using __gnu_cxx::random_sample; +using __gnu_cxx::random_sample_n; +using __gnu_cxx::is_sorted; +using __gnu_cxx::is_heap; +using __gnu_cxx::count; // Extension returning void +using __gnu_cxx::count_if; // Extension returning void + +// Names from ext/numeric +using __gnu_cxx::power; +using __gnu_cxx::iota; + +#endif /* _BACKWARD_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/algobase.h b/src/include.new/c++/3.4/backward/algobase.h new file mode 100644 index 0000000..86028a0 --- /dev/null +++ b/src/include.new/c++/3.4/backward/algobase.h @@ -0,0 +1,95 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGOBASE_H +#define _BACKWARD_ALGOBASE_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include +#include +#include +#include + +// Names from stl_algobase.h +using std::iter_swap; +using std::swap; +using std::min; +using std::max; +using std::copy; +using std::copy_backward; +using std::fill; +using std::fill_n; +using std::mismatch; +using std::equal; +using std::lexicographical_compare; + +// Names from stl_uninitialized.h +using std::uninitialized_copy; +using std::uninitialized_fill; +using std::uninitialized_fill_n; + +// Names from ext/algorithm +using __gnu_cxx::copy_n; +using __gnu_cxx::lexicographical_compare_3way; + +// Names from ext/memory +using __gnu_cxx::uninitialized_copy_n; + +#endif /* _BACKWARD_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/alloc.h b/src/include.new/c++/3.4/backward/alloc.h new file mode 100644 index 0000000..d3c3c73 --- /dev/null +++ b/src/include.new/c++/3.4/backward/alloc.h @@ -0,0 +1,52 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALLOC_H +#define _BACKWARD_ALLOC_H 1 + +#include "backward_warning.h" +#include +#include + +using std::allocator; + +#endif diff --git a/src/include.new/c++/3.4/backward/backward_warning.h b/src/include.new/c++/3.4/backward/backward_warning.h new file mode 100644 index 0000000..9e13777 --- /dev/null +++ b/src/include.new/c++/3.4/backward/backward_warning.h @@ -0,0 +1,39 @@ +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_BACKWARD_WARNING_H +#define _BACKWARD_BACKWARD_WARNING_H 1 + +#ifdef __DEPRECATED +#warning This file includes at least one deprecated or antiquated header. \ +Please consider using one of the 32 headers found in section 17.4.1.2 of the \ +C++ standard. Examples include substituting the header for the \ +header for C++ includes, or instead of the deprecated header \ +. To disable this warning use -Wno-deprecated. +#endif + +#endif diff --git a/src/include.new/c++/3.4/backward/bvector.h b/src/include.new/c++/3.4/backward/bvector.h new file mode 100644 index 0000000..9245792 --- /dev/null +++ b/src/include.new/c++/3.4/backward/bvector.h @@ -0,0 +1,68 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_BVECTOR_H +#define _BACKWARD_BVECTOR_H 1 + +#include "backward_warning.h" +#include + +typedef std::vector > bit_vector; + +#endif /* _BACKWARD_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/complex.h b/src/include.new/c++/3.4/backward/complex.h new file mode 100644 index 0000000..dfc6714 --- /dev/null +++ b/src/include.new/c++/3.4/backward/complex.h @@ -0,0 +1,43 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_COMPLEX_H +#define _BACKWARD_COMPLEX_H 1 + +#include "backward_warning.h" +#include + +using std::complex; +typedef complex float_complex; +typedef complex double_complex; +typedef complex long_double_complex; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/defalloc.h b/src/include.new/c++/3.4/backward/defalloc.h new file mode 100644 index 0000000..76ea52a --- /dev/null +++ b/src/include.new/c++/3.4/backward/defalloc.h @@ -0,0 +1,117 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header . + +#ifndef _BACKWARD_DEFALLOC_H +#define _BACKWARD_DEFALLOC_H 1 + +#include "backward_warning.h" +#include "new.h" +#include +#include +#include +#include "iostream.h" +#include "algobase.h" + + +template +inline _Tp* allocate(ptrdiff_t __size, _Tp*) { + set_new_handler(0); + _Tp* __tmp = (_Tp*)(::operator new((size_t)(__size * sizeof(_Tp)))); + if (__tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return __tmp; +} + + +template +inline void deallocate(_Tp* __buffer) { + ::operator delete(__buffer); +} + +template +class allocator { +public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type __n) { + return ::allocate((difference_type)__n, (pointer)0); + } + void deallocate(pointer __p) { ::deallocate(__p); } + pointer address(reference __x) { return (pointer)&__x; } + const_pointer const_address(const_reference __x) { + return (const_pointer)&__x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(_Tp))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); + } +}; + +class allocator { +public: + typedef void* pointer; +}; + + + +#endif /* _BACKWARD_DEFALLOC_H */ diff --git a/src/include.new/c++/3.4/backward/deque.h b/src/include.new/c++/3.4/backward/deque.h new file mode 100644 index 0000000..36c7479 --- /dev/null +++ b/src/include.new/c++/3.4/backward/deque.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_DEQUE_H +#define _BACKWARD_DEQUE_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::deque; + +#endif /* _BACKWARD_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/fstream.h b/src/include.new/c++/3.4/backward/fstream.h new file mode 100644 index 0000000..6dfd514 --- /dev/null +++ b/src/include.new/c++/3.4/backward/fstream.h @@ -0,0 +1,52 @@ +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_FSTREAM_H +#define _BACKWARD_FSTREAM_H 1 + +#include "backward_warning.h" +#include + +using std::filebuf; +using std::ifstream; +using std::ofstream; +using std::fstream; +using std::streampos; + +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wfilebuf; +using std::wifstream; +using std::wofstream; +using std::wfstream; +using std::wstreampos; +#endif + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/function.h b/src/include.new/c++/3.4/backward/function.h new file mode 100644 index 0000000..9fc8719 --- /dev/null +++ b/src/include.new/c++/3.4/backward/function.h @@ -0,0 +1,130 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_FUNCTION_H +#define _BACKWARD_FUNCTION_H 1 + +#include "backward_warning.h" +#include +#include +#include +#include + +// Names from stl_function.h +using std::unary_function; +using std::binary_function; +using std::plus; +using std::minus; +using std::multiplies; +using std::divides; +using std::modulus; +using std::negate; +using std::equal_to; +using std::not_equal_to; +using std::greater; +using std::less; +using std::greater_equal; +using std::less_equal; +using std::logical_and; +using std::logical_or; +using std::logical_not; +using std::unary_negate; +using std::binary_negate; +using std::not1; +using std::not2; +using std::binder1st; +using std::binder2nd; +using std::bind1st; +using std::bind2nd; +using std::pointer_to_unary_function; +using std::pointer_to_binary_function; +using std::ptr_fun; +using std::mem_fun_t; +using std::const_mem_fun_t; +using std::mem_fun_ref_t; +using std::const_mem_fun_ref_t; +using std::mem_fun1_t; +using std::const_mem_fun1_t; +using std::mem_fun1_ref_t; +using std::const_mem_fun1_ref_t; +using std::mem_fun; +using std::mem_fun_ref; + +// Names from ext/functional +using __gnu_cxx::identity_element; +using __gnu_cxx::unary_compose; +using __gnu_cxx::binary_compose; +using __gnu_cxx::compose1; +using __gnu_cxx::compose2; +using __gnu_cxx::identity; +using __gnu_cxx::select1st; +using __gnu_cxx::select2nd; +using __gnu_cxx::project1st; +using __gnu_cxx::project2nd; +using __gnu_cxx::constant_void_fun; +using __gnu_cxx::constant_unary_fun; +using __gnu_cxx::constant_binary_fun; +using __gnu_cxx::constant0; +using __gnu_cxx::constant1; +using __gnu_cxx::constant2; +using __gnu_cxx::subtractive_rng; +using __gnu_cxx::mem_fun1; +using __gnu_cxx::mem_fun1_ref; + +#endif /* _BACKWARD_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/hash_map.h b/src/include.new/c++/3.4/backward/hash_map.h new file mode 100644 index 0000000..bc9c148 --- /dev/null +++ b/src/include.new/c++/3.4/backward/hash_map.h @@ -0,0 +1,72 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_MAP_H +#define _BACKWARD_HASH_MAP_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_map; +using __gnu_cxx::hash_multimap; + +#endif /* _BACKWARD_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/hash_set.h b/src/include.new/c++/3.4/backward/hash_set.h new file mode 100644 index 0000000..89307de --- /dev/null +++ b/src/include.new/c++/3.4/backward/hash_set.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_SET_H +#define _BACKWARD_HASH_SET_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_set; +using __gnu_cxx::hash_multiset; + +#endif /* _BACKWARD_HASH_SET_H */ + diff --git a/src/include.new/c++/3.4/backward/hashtable.h b/src/include.new/c++/3.4/backward/hashtable.h new file mode 100644 index 0000000..abedd55 --- /dev/null +++ b/src/include.new/c++/3.4/backward/hashtable.h @@ -0,0 +1,76 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef _BACKWARD_HASHTABLE_H +#define _BACKWARD_HASHTABLE_H 1 + +#include "backward_warning.h" +#include +#include "algo.h" +#include "alloc.h" +#include "vector.h" + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; + +#endif /* _BACKWARD_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/heap.h b/src/include.new/c++/3.4/backward/heap.h new file mode 100644 index 0000000..2f19545 --- /dev/null +++ b/src/include.new/c++/3.4/backward/heap.h @@ -0,0 +1,71 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_HEAP_H +#define _BACKWARD_HEAP_H 1 + +#include "backward_warning.h" +#include +#include + +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +#endif /* _BACKWARD_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/iomanip.h b/src/include.new/c++/3.4/backward/iomanip.h new file mode 100644 index 0000000..160dbeb --- /dev/null +++ b/src/include.new/c++/3.4/backward/iomanip.h @@ -0,0 +1,70 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_IOMANIP_H +#define _BACKWARD_IOMANIP_H 1 + +#include "backward_warning.h" +#include "iostream.h" +#include + +// These are from as per [27.4]. +using std::boolalpha; +using std::noboolalpha; +using std::showbase; +using std::noshowbase; +using std::showpoint; +using std::noshowpoint; +using std::showpos; +using std::noshowpos; +using std::skipws; +using std::noskipws; +using std::uppercase; +using std::nouppercase; +using std::internal; +using std::left; +using std::right; +using std::dec; +using std::hex; +using std::oct; +using std::fixed; +using std::scientific; + +// These are from as per [27.6]. Manipulators from +// and (e.g., endl) are made available via . +using std::resetiosflags; +using std::setiosflags; +using std::setbase; +using std::setfill; +using std::setprecision; +using std::setw; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/iostream.h b/src/include.new/c++/3.4/backward/iostream.h new file mode 100644 index 0000000..5a5ccea --- /dev/null +++ b/src/include.new/c++/3.4/backward/iostream.h @@ -0,0 +1,60 @@ +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_IOSTREAM_H +#define _BACKWARD_IOSTREAM_H 1 + +#include "backward_warning.h" +#include + +using std::iostream; +using std::ostream; +using std::istream; +using std::ios; +using std::streambuf; + +using std::cout; +using std::cin; +using std::cerr; +using std::clog; +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wcout; +using std::wcin; +using std::wcerr; +using std::wclog; +#endif + +using std::ws; +using std::endl; +using std::ends; +using std::flush; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/istream.h b/src/include.new/c++/3.4/backward/istream.h new file mode 100644 index 0000000..707b575 --- /dev/null +++ b/src/include.new/c++/3.4/backward/istream.h @@ -0,0 +1,43 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_ISTREAM_H +#define _BACKWARD_ISTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: + + + + + diff --git a/src/include.new/c++/3.4/backward/iterator.h b/src/include.new/c++/3.4/backward/iterator.h new file mode 100644 index 0000000..8316a83 --- /dev/null +++ b/src/include.new/c++/3.4/backward/iterator.h @@ -0,0 +1,191 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ITERATOR_H +#define _BACKWARD_ITERATOR_H 1 + +#include "backward_warning.h" +#include "function.h" +#include +#include "iostream.h" +#include + +#include +#include + +#include // For 3-parameter distance extension + +// Names from stl_iterator.h +using std::input_iterator_tag; +using std::output_iterator_tag; +using std::forward_iterator_tag; +using std::bidirectional_iterator_tag; +using std::random_access_iterator_tag; + +#if 0 +using std::iterator; +#endif + +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (They have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. +template + struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template + struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template + struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template + struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +using std::iterator_traits; + +template + inline typename iterator_traits<_Iter>::iterator_category + iterator_category(const _Iter& __i) + { return __iterator_category(__i); } + +template + inline typename iterator_traits<_Iter>::difference_type* + distance_type(const _Iter&) + { return static_cast::difference_type*>(0); } + +template + inline typename iterator_traits<_Iter>::value_type* + value_type(const _Iter& __i) + { return static_cast::value_type*>(0); } + +using std::distance; +using __gnu_cxx::distance; // 3-parameter extension +using std::advance; + +using std::insert_iterator; +using std::front_insert_iterator; +using std::back_insert_iterator; +using std::inserter; +using std::front_inserter; +using std::back_inserter; + +using std::reverse_iterator; + +using std::istream_iterator; +using std::ostream_iterator; + +// Names from stl_construct.h +template + inline void + construct(_T1* __p, const _T2& __value) + { std::_Construct(__p, __value); } + +template + inline void + construct(_T1* __p) + { std::_Construct(__p); } + +template + inline void + destroy(_Tp* __pointer) + { std::_Destroy(__pointer); } + +template + inline void + destroy(_ForwardIterator __first, _ForwardIterator __last) + { std::_Destroy(__first, __last); } + + +// Names from stl_raw_storage_iter.h +using std::raw_storage_iterator; + +#endif /* _BACKWARD_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/list.h b/src/include.new/c++/3.4/backward/list.h new file mode 100644 index 0000000..00c11a6 --- /dev/null +++ b/src/include.new/c++/3.4/backward/list.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_LIST_H +#define _BACKWARD_LIST_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::list; + +#endif /* _BACKWARD_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/map.h b/src/include.new/c++/3.4/backward/map.h new file mode 100644 index 0000000..56d5c69 --- /dev/null +++ b/src/include.new/c++/3.4/backward/map.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MAP_H +#define _BACKWARD_MAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::map; + +#endif /* _BACKWARD_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/multimap.h b/src/include.new/c++/3.4/backward/multimap.h new file mode 100644 index 0000000..aba42f7 --- /dev/null +++ b/src/include.new/c++/3.4/backward/multimap.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTIMAP_H +#define _BACKWARD_MULTIMAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::multimap; + +#endif /* _BACKWARD_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/multiset.h b/src/include.new/c++/3.4/backward/multiset.h new file mode 100644 index 0000000..7ec0c94 --- /dev/null +++ b/src/include.new/c++/3.4/backward/multiset.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTISET_H +#define _BACKWARD_MULTISET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::multiset; + +#endif /* _BACKWARD_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/new.h b/src/include.new/c++/3.4/backward/new.h new file mode 100644 index 0000000..00a4819 --- /dev/null +++ b/src/include.new/c++/3.4/backward/new.h @@ -0,0 +1,42 @@ +// -*- C++ -*- forwarding header. +// Copyright (C) 2000 Free Software Foundation + +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_NEW_H +#define _BACKWARD_NEW_H 1 + +#include "backward_warning.h" +#include + +using std::bad_alloc; +using std::nothrow_t; +using std::nothrow; +using std::new_handler; +using std::set_new_handler; + +#endif diff --git a/src/include.new/c++/3.4/backward/ostream.h b/src/include.new/c++/3.4/backward/ostream.h new file mode 100644 index 0000000..a72de09 --- /dev/null +++ b/src/include.new/c++/3.4/backward/ostream.h @@ -0,0 +1,38 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_OSTREAM_H +#define _BACKWARD_OSTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/pair.h b/src/include.new/c++/3.4/backward/pair.h new file mode 100644 index 0000000..cbb3bc7 --- /dev/null +++ b/src/include.new/c++/3.4/backward/pair.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_PAIR_H +#define _BACKWARD_PAIR_H 1 + +#include "backward_warning.h" +#include +#include + +using std::pair; +using std::make_pair; + +#endif /* _BACKWARD_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/queue.h b/src/include.new/c++/3.4/backward/queue.h new file mode 100644 index 0000000..a3e2ff3 --- /dev/null +++ b/src/include.new/c++/3.4/backward/queue.h @@ -0,0 +1,41 @@ +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_QUEUE_H +#define _BACKWARD_QUEUE_H 1 + +#include "backward_warning.h" +#include + +using std::queue; +using std::priority_queue; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/rope.h b/src/include.new/c++/3.4/backward/rope.h new file mode 100644 index 0000000..fc6715a --- /dev/null +++ b/src/include.new/c++/3.4/backward/rope.h @@ -0,0 +1,60 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ROPE_H +#define _BACKWARD_ROPE_H 1 + +#include "backward_warning.h" +#include "hashtable.h" +#include + +using __gnu_cxx::char_producer; +using __gnu_cxx::sequence_buffer; +using __gnu_cxx::rope; +using __gnu_cxx::crope; +using __gnu_cxx::wrope; + +#endif /* _BACKWARD_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/set.h b/src/include.new/c++/3.4/backward/set.h new file mode 100644 index 0000000..6a8320b --- /dev/null +++ b/src/include.new/c++/3.4/backward/set.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_SET_H +#define _BACKWARD_SET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::set; + +#endif /* _BACKWARD_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/slist.h b/src/include.new/c++/3.4/backward/slist.h new file mode 100644 index 0000000..63db065 --- /dev/null +++ b/src/include.new/c++/3.4/backward/slist.h @@ -0,0 +1,56 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_SLIST_H +#define _BACKWARD_SLIST_H 1 + +#include "backward_warning.h" +#include + +using __gnu_cxx::slist; + +#endif /* _BACKWARD_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/stack.h b/src/include.new/c++/3.4/backward/stack.h new file mode 100644 index 0000000..0ff53a4 --- /dev/null +++ b/src/include.new/c++/3.4/backward/stack.h @@ -0,0 +1,72 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_STACK_H +#define _BACKWARD_STACK_H 1 + +#include "backward_warning.h" +#include "vector.h" +#include "deque.h" +#include "heap.h" +#include "queue.h" +#include + +using std::stack; + +#endif /* _BACKWARD_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/stream.h b/src/include.new/c++/3.4/backward/stream.h new file mode 100644 index 0000000..5540c7e --- /dev/null +++ b/src/include.new/c++/3.4/backward/stream.h @@ -0,0 +1,38 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_STREAM_H +#define _BACKWARD_STREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/streambuf.h b/src/include.new/c++/3.4/backward/streambuf.h new file mode 100644 index 0000000..fc9825e --- /dev/null +++ b/src/include.new/c++/3.4/backward/streambuf.h @@ -0,0 +1,40 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_STREAMBUF_H +#define _BACKWARD_STREAMBUF_H 1 + +#include "backward_warning.h" +#include + +using std::streambuf; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/strstream b/src/include.new/c++/3.4/backward/strstream new file mode 100644 index 0000000..a5b95c5 --- /dev/null +++ b/src/include.new/c++/3.4/backward/strstream @@ -0,0 +1,179 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: The classes defined in this header are DEPRECATED. This +// header is defined in section D.7.1 of the C++ standard, and it +// MAY BE REMOVED in a future standard revision. You should use the +// header instead. + +#ifndef __SGI_STL_STRSTREAM +#define __SGI_STL_STRSTREAM + +#include "backward_warning.h" +#include +#include +#include +#include +#include + +namespace std +{ + // Class strstreambuf, a streambuf class that manages an array of char. + // Note that this class is not a template. + class strstreambuf : public basic_streambuf > + { + public: + // Types. + typedef char_traits _Traits; + typedef basic_streambuf _Base; + + public: + // Constructor, destructor + explicit strstreambuf(streamsize __initial_capacity = 0); + strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); + + strstreambuf(char* __get, streamsize __n, char* __put = 0); + strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0); + strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0); + + strstreambuf(const char* __get, streamsize __n); + strstreambuf(const signed char* __get, streamsize __n); + strstreambuf(const unsigned char* __get, streamsize __n); + + virtual ~strstreambuf(); + + public: + void freeze(bool = true); + char* str(); + int pcount() const; + + protected: + virtual int_type overflow(int_type __c = _Traits::eof()); + virtual int_type pbackfail(int_type __c = _Traits::eof()); + virtual int_type underflow(); + virtual _Base* setbuf(char* __buf, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, + ios_base::openmode __mode + = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode + = ios_base::in | ios_base::out); + + private: + strstreambuf& + operator=(const strstreambuf&); + + strstreambuf(const strstreambuf&); + + // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. + char* _M_alloc(size_t); + void _M_free(char*); + + // Helper function used in constructors. + void _M_setup(char* __get, char* __put, streamsize __n); + + private: + // Data members. + void* (*_M_alloc_fun)(size_t); + void (*_M_free_fun)(void*); + + bool _M_dynamic : 1; + bool _M_frozen : 1; + bool _M_constant : 1; + }; + + // Class istrstream, an istream that manages a strstreambuf. + class istrstream : public basic_istream + { + public: + explicit istrstream(char*); + explicit istrstream(const char*); + istrstream(char* , streamsize); + istrstream(const char*, streamsize); + virtual ~istrstream(); + + strstreambuf* rdbuf() const; + char* str(); + + private: + strstreambuf _M_buf; + }; + + // Class ostrstream + class ostrstream : public basic_ostream + { + public: + ostrstream(); + ostrstream(char*, int, ios_base::openmode = ios_base::out); + virtual ~ostrstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + char* str(); + int pcount() const; + + private: + strstreambuf _M_buf; + }; + + // Class strstream + class strstream : public basic_iostream + { + public: + typedef char char_type; + typedef char_traits::int_type int_type; + typedef char_traits::pos_type pos_type; + typedef char_traits::off_type off_type; + + strstream(); + strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); + virtual ~strstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + int pcount() const; + char* str(); + + private: + strstreambuf _M_buf; + }; +} // namespace std +#endif diff --git a/src/include.new/c++/3.4/backward/tempbuf.h b/src/include.new/c++/3.4/backward/tempbuf.h new file mode 100644 index 0000000..06de2bd --- /dev/null +++ b/src/include.new/c++/3.4/backward/tempbuf.h @@ -0,0 +1,78 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_TEMPBUF_H +#define _BACKWARD_TEMPBUF_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include +#include +#include +#include +#include +#include +#include + +using std::get_temporary_buffer; +using std::return_temporary_buffer; +using __gnu_cxx::temporary_buffer; + +#endif /* _BACKWARD_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/tree.h b/src/include.new/c++/3.4/backward/tree.h new file mode 100644 index 0000000..fcfcbf4 --- /dev/null +++ b/src/include.new/c++/3.4/backward/tree.h @@ -0,0 +1,55 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_TREE +#define _BACKWARD_TREE 1 + +#include "backward_warning.h" +#include + +using __gnu_cxx::rb_tree; + +#endif +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/backward/vector.h b/src/include.new/c++/3.4/backward/vector.h new file mode 100644 index 0000000..ba9b704 --- /dev/null +++ b/src/include.new/c++/3.4/backward/vector.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_VECTOR_H +#define _BACKWARD_VECTOR_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::vector; + +#endif /* _BACKWARD_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/allocator.h b/src/include.new/c++/3.4/bits/allocator.h new file mode 100644 index 0000000..c9200ec --- /dev/null +++ b/src/include.new/c++/3.4/bits/allocator.h @@ -0,0 +1,130 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file allocator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H 1 + +// Define the base class to std::allocator. +#include + +namespace std +{ + template + class allocator; + + template<> + class allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + }; + + /** + * @brief The "standard" allocator, as per [20.4]. + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class allocator: public ___glibcxx_base_allocator<_Tp> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + + allocator() throw() { } + + allocator(const allocator& a) throw() + : ___glibcxx_base_allocator<_Tp>(a) { } + + template + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + // Inherit everything else. + }; + + template + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class allocator; + extern template class allocator; +#endif + + // Undefine. +#undef ___glibcxx_base_allocator +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/atomic_word.h b/src/include.new/c++/3.4/bits/atomic_word.h new file mode 100644 index 0000000..b46adc2 --- /dev/null +++ b/src/include.new/c++/3.4/bits/atomic_word.h @@ -0,0 +1,35 @@ +// Low-level type for atomic operations -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMIC_WORD_H +#define _GLIBCXX_ATOMIC_WORD_H 1 + +typedef int _Atomic_word; + +#endif diff --git a/src/include.new/c++/3.4/bits/atomicity.h b/src/include.new/c++/3.4/bits/atomicity.h new file mode 100644 index 0000000..d2620b0 --- /dev/null +++ b/src/include.new/c++/3.4/bits/atomicity.h @@ -0,0 +1,46 @@ +// Low-level functions for atomic operations -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include + +namespace __gnu_cxx +{ + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add(volatile _Atomic_word* __mem, int __val); + + void + __attribute__ ((__unused__)) + __atomic_add(volatile _Atomic_word* __mem, int __val); +} // namespace __gnu_cxx + +#endif diff --git a/src/include.new/c++/3.4/bits/basic_file.h b/src/include.new/c++/3.4/bits/basic_file.h new file mode 100644 index 0000000..6aa031b --- /dev/null +++ b/src/include.new/c++/3.4/bits/basic_file.h @@ -0,0 +1,110 @@ +// Wrapper of C-language FILE struct -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +/** @file basic_file.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_FILE_STDIO_H +#define _BASIC_FILE_STDIO_H 1 + +#pragma GCC system_header + +#include +#include + +namespace std +{ + // Generic declaration. + template + class __basic_file; + + // Specialization. + template<> + class __basic_file + { + // Underlying data source/sink. + __c_file* _M_cfile; + + // True iff we opened _M_cfile, and thus must close it ourselves. + bool _M_cfile_created; + + public: + __basic_file(__c_lock* __lock = 0); + + __basic_file* + open(const char* __name, ios_base::openmode __mode, int __prot = 0664); + + __basic_file* + sys_open(__c_file* __file, ios_base::openmode); + + __basic_file* + sys_open(int __fd, ios_base::openmode __mode); + + __basic_file* + close(); + + bool + is_open() const; + + int + fd(); + + __c_file* + file(); + + ~__basic_file(); + + streamsize + xsputn(const char* __s, streamsize __n); + + streamsize + xsputn_2(const char* __s1, streamsize __n1, + const char* __s2, streamsize __n2); + + streamsize + xsgetn(char* __s, streamsize __n); + + streamoff + seekoff(streamoff __off, ios_base::seekdir __way); + + int + sync(); + + streamsize + showmanyc(); + }; +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/basic_ios.h b/src/include.new/c++/3.4/bits/basic_ios.h new file mode 100644 index 0000000..7ffe40e --- /dev/null +++ b/src/include.new/c++/3.4/bits/basic_ios.h @@ -0,0 +1,467 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file basic_ios.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_IOS_H +#define _BASIC_IOS_H 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +namespace std +{ + // 27.4.5 Template class basic_ios + /** + * @brief Virtual base class for all stream classes. + * + * Most of the member functions called dispatched on stream objects + * (e.g., @c std::cout.foo(bar);) are consolidated in this class. + */ + template + class basic_ios : public ios_base + { + public: + //@{ + /** + * These are standard types. They permit a standardized way of + * referring to names of (or names dependant on) the template + * parameters, which are specific to the implementation. + */ + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + //@} + + //@{ + /** + * @if maint + * These are non-standard types. + * @endif + */ + typedef ctype<_CharT> __ctype_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + //@} + + // Data members: + protected: + basic_ostream<_CharT, _Traits>* _M_tie; + mutable char_type _M_fill; + mutable bool _M_fill_init; + basic_streambuf<_CharT, _Traits>* _M_streambuf; + + // Cached use_facet, which is based on the current locale info. + const __ctype_type* _M_ctype; + // For ostream. + const __num_put_type* _M_num_put; + // For istream. + const __num_get_type* _M_num_get; + + public: + //@{ + /** + * @brief The quick-and-easy status check. + * + * This allows you to write constructs such as + * "if (!a_stream) ..." and "while (a_stream) ..." + */ + operator void*() const + { return this->fail() ? 0 : const_cast(this); } + + bool + operator!() const + { return this->fail(); } + //@} + + /** + * @brief Returns the error state of the stream buffer. + * @return A bit pattern (well, isn't everything?) + * + * See std::ios_base::iostate for the possible bit values. Most + * users will call one of the interpreting wrappers, e.g., good(). + */ + iostate + rdstate() const + { return _M_streambuf_state; } + + /** + * @brief [Re]sets the error state. + * @param state The new state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. Most + * users will not need to pass an argument. + */ + void + clear(iostate __state = goodbit); + + /** + * @brief Sets additional flags in the error state. + * @param state The additional state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. + */ + void + setstate(iostate __state) + { this->clear(this->rdstate() | __state); } + + // Flip the internal state on for the proper state bits, then re + // throws the propagated exception if bit also set in + // exceptions(). + void + _M_setstate(iostate __state) + { + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + _M_streambuf_state |= __state; + if (this->exceptions() & __state) + __throw_exception_again; + } + + /** + * @brief Fast error checking. + * @return True if no error flags are set. + * + * A wrapper around rdstate. + */ + bool + good() const + { return this->rdstate() == 0; } + + /** + * @brief Fast error checking. + * @return True if the eofbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + eof() const + { return (this->rdstate() & eofbit) != 0; } + + /** + * @brief Fast error checking. + * @return True if either the badbit or the failbit is set. + * + * Checking the badbit in fail() is historical practice. + * Note that other iostate flags may also be set. + */ + bool + fail() const + { return (this->rdstate() & (badbit | failbit)) != 0; } + + /** + * @brief Fast error checking. + * @return True if the badbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + bad() const + { return (this->rdstate() & badbit) != 0; } + + /** + * @brief Throwing exceptions on errors. + * @return The current exceptions mask. + * + * This changes nothing in the stream. See the one-argument version + * of exceptions(iostate) for the meaning of the return value. + */ + iostate + exceptions() const + { return _M_exception; } + + /** + * @brief Throwing exceptions on errors. + * @param except The new exceptions mask. + * + * By default, error flags are set silently. You can set an + * exceptions mask for each stream; if a bit in the mask becomes set + * in the error flags, then an exception of type + * std::ios_base::failure is thrown. + * + * If the error flage is already set when the exceptions mask is + * added, the exception is immediately thrown. Try running the + * following under GCC 3.1 or later: + * @code + * #include + * #include + * #include + * + * int main() + * { + * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); + * + * std::ifstream f ("/etc/motd"); + * + * std::cerr << "Setting badbit\n"; + * f.setstate (std::ios_base::badbit); + * + * std::cerr << "Setting exception mask\n"; + * f.exceptions (std::ios_base::badbit); + * } + * @endcode + */ + void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); + } + + // Constructor/destructor: + /** + * @brief Constructor performs initialization. + * + * The parameter is passed by derived streams. + */ + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) + : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), + _M_ctype(0), _M_num_put(0), _M_num_get(0) + { this->init(__sb); } + + /** + * @brief Empty. + * + * The destructor does nothing. More specifically, it does not + * destroy the streambuf held by rdbuf(). + */ + virtual + ~basic_ios() { } + + // Members: + /** + * @brief Fetches the current @e tied stream. + * @return A pointer to the tied stream, or NULL if the stream is + * not tied. + * + * A stream may be @e tied (or synchronized) to a second output + * stream. When this stream performs any I/O, the tied stream is + * first flushed. For example, @c std::cin is tied to @c std::cout. + */ + basic_ostream<_CharT, _Traits>* + tie() const + { return _M_tie; } + + /** + * @brief Ties this stream to an output stream. + * @param tiestr The output stream. + * @return The previously tied output stream, or NULL if the stream + * was not tied. + * + * This sets up a new tie; see tie() for more. + */ + basic_ostream<_CharT, _Traits>* + tie(basic_ostream<_CharT, _Traits>* __tiestr) + { + basic_ostream<_CharT, _Traits>* __old = _M_tie; + _M_tie = __tiestr; + return __old; + } + + /** + * @brief Accessing the underlying buffer. + * @return The current stream buffer. + * + * This does not change the state of the stream. + */ + basic_streambuf<_CharT, _Traits>* + rdbuf() const + { return _M_streambuf; } + + /** + * @brief Changing the underlying buffer. + * @param sb The new stream buffer. + * @return The previous stream buffer. + * + * Associates a new buffer with the current stream, and clears the + * error state. + * + * Due to historical accidents which the LWG refuses to correct, the + * I/O library suffers from a design error: this function is hidden + * in derived classes by overrides of the zero-argument @c rdbuf(), + * which is non-virtual for hysterical raisins. As a result, you + * must use explicit qualifications to access this function via any + * derived class. For example: + * + * @code + * std::fstream foo; // or some other derived type + * std::streambuf* p = .....; + * + * foo.ios::rdbuf(p); // ios == basic_ios + * @endcode + */ + basic_streambuf<_CharT, _Traits>* + rdbuf(basic_streambuf<_CharT, _Traits>* __sb); + + /** + * @brief Copies fields of __rhs into this. + * @param __rhs The source values for the copies. + * @return Reference to this object. + * + * All fields of __rhs are copied into this object except that rdbuf() + * and rdstate() remain unchanged. All values in the pword and iword + * arrays are copied. Before copying, each callback is invoked with + * erase_event. After copying, each (new) callback is invoked with + * copyfmt_event. The final step is to copy exceptions(). + */ + basic_ios& + copyfmt(const basic_ios& __rhs); + + /** + * @brief Retreives the "empty" character. + * @return The current fill character. + * + * It defaults to a space (' ') in the current locale. + */ + char_type + fill() const + { + if (!_M_fill_init) + { + _M_fill = this->widen(' '); + _M_fill_init = true; + } + return _M_fill; + } + + /** + * @brief Sets a new "empty" character. + * @param ch The new character. + * @return The previous fill character. + * + * The fill character is used to fill out space when P+ characters + * have been requested (e.g., via setw), Q characters are actually + * used, and Qfill(); + _M_fill = __ch; + return __old; + } + + // Locales: + /** + * @brief Moves to a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Calls @c ios_base::imbue(loc), and if a stream buffer is associated + * with this stream, calls that buffer's @c pubimbue(loc). + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + locale + imbue(const locale& __loc); + + /** + * @brief Squeezes characters. + * @param c The character to narrow. + * @param dfault The character to narrow. + * @return The narrowed character. + * + * Maps a character of @c char_type to a character of @c char, + * if possible. + * + * Returns the result of + * @code + * std::use_facet >(getloc()).narrow(c,dfault) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char + narrow(char_type __c, char __dfault) const; + + /** + * @brief Widens characters. + * @param c The character to widen. + * @return The widened character. + * + * Maps a character of @c char to a character of @c char_type. + * + * Returns the result of + * @code + * std::use_facet >(getloc()).widen(c) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char_type + widen(char __c) const; + + protected: + // 27.4.5.1 basic_ios constructors + /** + * @brief Empty. + * + * The default constructor does nothing and is not normally + * accessible to users. + */ + basic_ios() + : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), + _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) + { } + + /** + * @brief All setup is performed here. + * + * This is called from the public constructor. It is not virtual and + * cannot be redefined. + */ + void + init(basic_streambuf<_CharT, _Traits>* __sb); + + void + _M_cache_locale(const locale& __loc); + }; +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +#include +#endif + +#endif /* _BASIC_IOS_H */ diff --git a/src/include.new/c++/3.4/bits/basic_ios.tcc b/src/include.new/c++/3.4/bits/basic_ios.tcc new file mode 100644 index 0000000..fcb4b02 --- /dev/null +++ b/src/include.new/c++/3.4/bits/basic_ios.tcc @@ -0,0 +1,200 @@ +// basic_ios member functions -*- C++ -*- + +// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BASIC_IOS_TCC +#define _BASIC_IOS_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + void + basic_ios<_CharT, _Traits>::clear(iostate __state) + { + if (this->rdbuf()) + _M_streambuf_state = __state; + else + _M_streambuf_state = __state | badbit; + if (this->exceptions() & this->rdstate()) + __throw_ios_failure(__N("basic_ios::clear")); + } + + template + basic_streambuf<_CharT, _Traits>* + basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) + { + basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; + _M_streambuf = __sb; + this->clear(); + return __old; + } + + template + basic_ios<_CharT, _Traits>& + basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 292. effects of a.copyfmt (a) + if (this != &__rhs) + { + // Per 27.1.1, do not call imbue, yet must trash all caches + // associated with imbue() + + // Alloc any new word array first, so if it fails we have "rollback". + _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? + _M_local_word : new _Words[__rhs._M_word_size]; + + // Bump refs before doing callbacks, for safety. + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_dispose_callbacks(); + + // NB: Don't want any added during above. + _M_callbacks = __cb; + for (int __i = 0; __i < __rhs._M_word_size; ++__i) + __words[__i] = __rhs._M_word[__i]; + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_word = __words; + _M_word_size = __rhs._M_word_size; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + _M_ios_locale = __rhs.getloc(); + _M_cache_locale(_M_ios_locale); + + _M_call_callbacks(copyfmt_event); + + // The next is required to be the last assignment. + this->exceptions(__rhs.exceptions()); + } + return *this; + } + + template + char + basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const + { return __check_facet(_M_ctype).narrow(__c, __dfault); } + + template + _CharT + basic_ios<_CharT, _Traits>::widen(char __c) const + { return __check_facet(_M_ctype).widen(__c); } + + // Locales: + template + locale + basic_ios<_CharT, _Traits>::imbue(const locale& __loc) + { + locale __old(this->getloc()); + ios_base::imbue(__loc); + _M_cache_locale(__loc); + if (this->rdbuf() != 0) + this->rdbuf()->pubimbue(__loc); + return __old; + } + + template + void + basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) + { + // NB: This may be called more than once on the same object. + ios_base::_M_init(); + + // Cache locale data and specific facets used by iostreams. + _M_cache_locale(_M_ios_locale); + + // NB: The 27.4.4.1 Postconditions Table specifies requirements + // after basic_ios::init() has been called. As part of this, + // fill() must return widen(' ') any time after init() has been + // called, which needs an imbued ctype facet of char_type to + // return without throwing an exception. Unfortunately, + // ctype is not necessarily a required facet, so + // streams with char_type != [char, wchar_t] will not have it by + // default. Because of this, the correct value for _M_fill is + // constructed on the first call of fill(). That way, + // unformatted input and output with non-required basic_ios + // instantiations is possible even without imbuing the expected + // ctype facet. + _M_fill = _CharT(); + _M_fill_init = false; + + _M_tie = 0; + _M_exception = goodbit; + _M_streambuf = __sb; + _M_streambuf_state = __sb ? goodbit : badbit; + } + + template + void + basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) + { + if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) + _M_ctype = &use_facet<__ctype_type>(__loc); + else + _M_ctype = 0; + + if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) + _M_num_put = &use_facet<__num_put_type>(__loc); + else + _M_num_put = 0; + + if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) + _M_num_get = &use_facet<__num_get_type>(__loc); + else + _M_num_get = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ios; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ios; +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/basic_string.h b/src/include.new/c++/3.4/bits/basic_string.h new file mode 100644 index 0000000..04e1500 --- /dev/null +++ b/src/include.new/c++/3.4/bits/basic_string.h @@ -0,0 +1,2365 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file basic_string.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_STRING_H +#define _BASIC_STRING_H 1 + +#pragma GCC system_header + +#include +#include + +namespace std +{ + /** + * @class basic_string basic_string.h + * @brief Managing sequences of characters and character-like objects. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence. Of the + * optional sequence requirements, only + * @c push_back, @c at, and array access are supported. + * + * @doctodo + * + * + * @if maint + * Documentation? What's that? + * Nathan Myers . + * + * A string looks like this: + * + * @code + * [_Rep] + * _M_length + * [basic_string] _M_capacity + * _M_dataplus _M_refcount + * _M_p ----------------> unnamed array of char_type + * @endcode + * + * Where the _M_p points to the first character in the string, and + * you cast it to a pointer-to-_Rep and subtract 1 to get a + * pointer to the header. + * + * This approach has the enormous advantage that a string object + * requires only one allocation. All the ugliness is confined + * within a single pair of inline functions, which each compile to + * a single "add" instruction: _Rep::_M_data(), and + * string::_M_rep(); and the allocation function which gets a + * block of raw bytes and with room enough and constructs a _Rep + * object at the front. + * + * The reason you want _M_data pointing to the character array and + * not the _Rep is so that the debugger can see the string + * contents. (Probably we should add a non-inline member to get + * the _Rep for the debugger to use, so users can check the actual + * string length.) + * + * Note that the _Rep object is a POD so that you can have a + * static "empty string" _Rep object already "constructed" before + * static constructors have run. The reference-count encoding is + * chosen so that a 0 indicates one reference, so you never try to + * destroy the empty-string _Rep object. + * + * All but the last paragraph is considered pretty conventional + * for a C++ string implementation. + * @endif + */ + // 21.3 Template class basic_string + template + class basic_string + { + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. + // 2. _M_capacity >= _M_length + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields==0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + + struct _Rep_base + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + }; + + struct _Rep : _Rep_base + { + // Types: + typedef typename _Alloc::template rebind::other _Raw_bytes_alloc; + + // (Public) Data members: + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // Solving for m: + // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 + // In addition, this implementation quarters this amount. + static const size_type _S_max_size; + static const _CharT _S_terminal; + + // The following storage is init'd to 0 by the linker, resulting + // (carefully) in an empty string with one reference. + static size_type _S_empty_rep_storage[]; + + static _Rep& + _S_empty_rep() + { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } + + bool + _M_is_leaked() const + { return this->_M_refcount < 0; } + + bool + _M_is_shared() const + { return this->_M_refcount > 0; } + + void + _M_set_leaked() + { this->_M_refcount = -1; } + + void + _M_set_sharable() + { this->_M_refcount = 0; } + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) + { + return (!_M_is_leaked() && __alloc1 == __alloc2) + ? _M_refcopy() : _M_clone(__alloc1); + } + + // Create & Destroy + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_dispose(const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0) + _M_destroy(__a); + } // XXX MT + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_refcopy() throw() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + __gnu_cxx::__atomic_add(&this->_M_refcount, 1); + return _M_refdata(); + } // XXX MT + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : _Alloc + { + _Alloc_hider(_CharT* __dat, const _Alloc& __a) + : _Alloc(__a), _M_p(__dat) { } + + _CharT* _M_p; // The actual data. + }; + + public: + // Data Members (public): + // NB: This is an unsigned type, and thus represents the maximum + // size that the allocator can hold. + /// @var + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast(-1); + + private: + // Data Members (private): + mutable _Alloc_hider _M_dataplus; + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + _CharT* + _M_data(_CharT* __p) + { return (_M_dataplus._M_p = __p); } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const { return iterator(_M_data()); } + + iterator + _M_iend() const { return iterator(_M_data() + this->size()); } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_rep()->_M_is_leaked()) + _M_leak_hard(); + } + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range(__N(__s)); + return __pos; + } + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + void + _M_mutate(size_type __pos, size_type __len1, size_type __len2); + + void + _M_leak_hard(); + + static _Rep& + _S_empty_rep() + { return _Rep::_S_empty_rep(); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + inline + basic_string(); + + /** + * @brief Construct an empty string using allocator a. + */ + explicit + basic_string(const _Alloc& __a); + + // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ + basic_string(const basic_string& __str); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a); + + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: s must have at least n characters, '\0' has no special + * meaning. + */ + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); + + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ + template + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()); + + /** + * @brief Destroy the string instance. + */ + ~basic_string() + { _M_rep()->_M_dispose(this->get_allocator()); } + + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ + basic_string& + operator=(const basic_string& __str) + { + this->assign(__str); + return *this; + } + + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ + basic_string& + operator=(const _CharT* __s) + { + this->assign(__s); + return *this; + } + + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ + iterator + begin() + { + _M_leak(); + return iterator(_M_data()); + } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const + { return const_iterator(_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ + iterator + end() + { + _M_leak(); + return iterator(_M_data() + this->size()); + } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const + { return const_iterator(_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const { return _M_rep()->_M_length; } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const { return _M_rep()->_M_length; } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const { return _Rep::_S_max_size; } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) { this->resize(__n, _CharT()); } + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const { return _M_rep()->_M_capacity; } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param n Number of characters required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0); + + /** + * Erases the string, making it empty. + */ + void + clear() { _M_mutate(0, this->size(), 0); } + + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ + bool + empty() const { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ + reference + operator[](size_type __pos) + { + _GLIBCXX_DEBUG_ASSERT(__pos < size()); + _M_leak(); + return _M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("basic_string::at")); + return _M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range(__N("basic_string::at")); + _M_leak(); + return _M_data()[__n]; + } + + // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const basic_string& __str) { return this->append(__str); } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const _CharT* __s) { return this->append(__s); } + + /** + * @brief Append a character. + * @param s The character to append. + * @return Reference to this string. + */ + basic_string& + operator+=(_CharT __c) { return this->append(size_type(1), __c); } + + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + append(const basic_string& __str); + + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __n); + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->append(__s, traits_type::length(__s)); + } + + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ + basic_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + /** + * @brief Append a single character. + * @param c Character to append. + */ + void + push_back(_CharT __c) + { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); } + + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ + basic_string& + assign(const basic_string& __str); + + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return this->assign(__str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ + basic_string& + assign(const _CharT* __s, size_type __n); + + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ + basic_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->assign(__s, traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ + template + void insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->insert(__pos1, __str, size_type(0), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->insert(__pos1, __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n); + + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->insert(__pos, __s, traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ + iterator + insert(iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + _M_rep()->_M_set_leaked(); + return this->_M_ibegin() + __pos; + } + + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { return _M_replace_safe(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n), NULL, size_type(0)); } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + _M_replace_safe(__pos, size_type(1), NULL, size_type(0)); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __pos; + } + + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + _M_replace_safe(__pos, __last - __first, NULL, size_type(0)); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __pos; + } + + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a str are inserted, or all + * of @a str if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2); + + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a str are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + basic_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + private: + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, __true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::_M_replace_aux")); + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = __c; + else if (__n2) + traits_type::assign(_M_data() + __pos1, __n2, __c); + return *this; + } + + basic_string& + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) + { + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = *__s; + else if (__n2) + traits_type::copy(_M_data() + __pos1, __s, __n2); + return *this; + } + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIter is an integral type + template + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __true_type) + { return _S_construct(static_cast(__beg), + static_cast(__end), __a); } + + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename _Is_integer<_InIterator>::_Integral _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ + void + swap(basic_string& __s); + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const { return _M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const { return _M_dataplus; } + + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default 0). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. Determines the effective length rlen of the strings to + * compare as the smallest of size() and str.size(). The function + * then compares the two strings by calling traits::compare(data(), + * str.data(),rlen). If the result of the comparison is nonzero returns + * it, otherwise the shorter one is ordered first. + */ + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and @a str.size(). The function then compares the two + * strings by calling traits::compare(substring.data(),str.data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. Determines the effective length rlen of the strings + * to compare as the smallest of the lengths of the substrings. The + * function then compares the two strings by calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and the length of a string constructed from @a s. The + * function then compares the two string by calling + * traits::compare(substring.data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. Determines the effective + * length rlen of the strings to compare as the smallest of the length + * of the substring and @a n2. The function then compares the two + * strings by calling traits::compare(substring.data(),s,rlen). If the + * result of the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; + + template + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } +#else + : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } +#endif + + // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str(__lhs); + __str.append(__size_type(1), __rhs); + return __str; + } + + // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ + template + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Alloc>& __str); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ + template + basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ + template + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); +} // namespace std + +#endif /* _BASIC_STRING_H */ diff --git a/src/include.new/c++/3.4/bits/basic_string.tcc b/src/include.new/c++/3.4/bits/basic_string.tcc new file mode 100644 index 0000000..fc90111 --- /dev/null +++ b/src/include.new/c++/3.4/bits/basic_string.tcc @@ -0,0 +1,975 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +// This file is included by . It is not meant to be included +// separately. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. + +#ifndef _BASIC_STRING_TCC +#define _BASIC_STRING_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template + inline bool + __is_null_pointer(_Type) + { return false; } + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; + + template + const _CharT + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_terminal = _CharT(); + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) + // at static init time (before static ctors are run). + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ + (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / + sizeof(size_type)]; + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Avoid reallocation for common case. + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + traits_type::copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_capacity) + { + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + traits_type::copy(__another->_M_refdata(), + __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_length = __len; + __r->_M_refdata()[__len] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + forward_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // NB: Not required, but considered best practice. + if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0)) + __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); + + const size_type __dnew = static_cast(std::distance(__beg, + __end)); + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_length = __dnew; + __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + traits_type::assign(__r->_M_refdata(), __n, __c); + + __r->_M_length = __n; + __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr + return __r->_M_refdata(); + } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + __str.get_allocator()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _Alloc& __a) + : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, size_type __n) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()), _Alloc()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a), __a) + { } + + // TBD: DPG annotate + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) + { } + + // TBD: DPG annotate + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(_S_construct(__n, __c, __a), __a) + { } + + // TBD: DPG annotate + template + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) + : _M_dataplus(_S_construct(__beg, __end, __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + if (__n > this->max_size()) + __throw_length_error(__N("basic_string::assign")); + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else + { + // Work in-place + const size_type __pos = __s - _M_data(); + if (__pos >= __n) + traits_type::copy(_M_data(), __s, __n); + else if (__pos) + traits_type::move(_M_data(), __s, __n); + _M_rep()->_M_set_sharable(); + _M_rep()->_M_length = __n; + _M_data()[__n] = _Rep::_S_terminal; // grr. + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check(__pos, "basic_string::insert"); + if (this->max_size() - this->size() < __n) + __throw_length_error(__N("basic_string::insert")); + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, size_type(0), __s, __n); + else + { + // Work in-place. If _M_mutate reallocates the string, __s + // does not point anymore to valid data, therefore we save its + // offset, then we restore it. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, 0, __n); + __s = _M_data() + __off; + _CharT* __p = _M_data() + __pos; + if (__s + __n <= __p) + traits_type::copy(__p, __s, __n); + else if (__s >= __p) + traits_type::copy(__p, __s + __n, __n); + else + { + const size_type __nleft = __p - __s; + traits_type::copy(__p, __s, __nleft); + traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); + } + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::replace"); + __n1 = _M_limit(__pos, __n1); + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::replace")); + bool __left; + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, __n1, __s, __n2); + else if ((__left = __s + __n2 <= _M_data() + __pos) + || _M_data() + __pos + __n1 <= __s) + { + // Work in-place: non-overlapping case. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, __n1, __n2); + if (__left) + traits_type::copy(_M_data() + __pos, + _M_data() + __off, __n2); + else + traits_type::copy(_M_data() + __pos, + _M_data() + __off + __n2 - __n1, __n2); + return *this; + } + else + { + // Todo: overlapping case. + const basic_string __tmp(__s, __n2); + return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (this == &_S_empty_rep()) + return; +#endif + const size_type __size = sizeof(_Rep_base) + + (this->_M_capacity + 1) * sizeof(_CharT); + _Raw_bytes_alloc(__a).deallocate(reinterpret_cast(this), __size); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (_M_rep() == &_S_empty_rep()) + return; +#endif + if (_M_rep()->_M_is_shared()) + _M_mutate(0, 0, 0); + _M_rep()->_M_set_leaked(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, size_type __len2) + { + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + const size_type __how_much = __old_size - __pos - __len1; + + if (__new_size > capacity() || _M_rep()->_M_is_shared()) + { + // Must reallocate. + const allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, capacity(), __a); + + if (__pos) + traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + traits_type::copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_rep()->_M_dispose(__a); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __len1 != __len2) + { + // Work in-place + traits_type::move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + } + _M_rep()->_M_set_sharable(); + _M_rep()->_M_length = __new_size; + _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res) + { + if (__res != this->capacity() || _M_rep()->_M_is_shared()) + { + if (__res > this->max_size()) + __throw_length_error(__N("basic_string::reserve")); + // Make sure we don't shrink below the current size + if (__res < this->size()) + __res = this->size(); + const allocator_type __a = get_allocator(); + _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + } + + template + void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s) + { + if (_M_rep()->_M_is_leaked()) + _M_rep()->_M_set_sharable(); + if (__s._M_rep()->_M_is_leaked()) + __s._M_rep()->_M_set_sharable(); + if (this->get_allocator() == __s.get_allocator()) + { + _CharT* __tmp = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp); + } + // The code below can usually be optimized away. + else + { + const basic_string __tmp1(_M_ibegin(), _M_iend(), + __s.get_allocator()); + const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); + *this = __tmp2; + __s = __tmp1; + } + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::_Rep* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > _S_max_size) + __throw_length_error(__N("basic_string::_S_create")); + + // The standard places no restriction on allocating more memory + // than is strictly needed within this layer at the moment or as + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an + // application attempts to allocate memory in a stepwise fashion + // growing each allocation size by only 1 char. Additionally, + // it makes little sense to allocate less linear memory than the + // natural blocking size of the malloc implementation. + // Unfortunately, we would need a somewhat low-level calculation + // with tuned parameters to get this perfect for any particular + // malloc implementation. Fortunately, generalizations about + // common features seen among implementations seems to suffice. + + // __pagesize need not match the actual VM page size for good + // results in practice, thus we pick a common value on the low + // side. __malloc_header_size is an estimate of the amount of + // overhead per memory allocation (in practice seen N * sizeof + // (void*) where N is 0, 2 or 4). According to folklore, + // picking this value on the high side is better than + // low-balling it (especially when this algorithm is used with + // malloc implementations that allocate memory blocks rounded up + // to a size which is a power of 2). + const size_type __pagesize = 4096; // must be 2^i * __subpagesize + const size_type __subpagesize = 128; // should be >> __malloc_header_size + const size_type __malloc_header_size = 4 * sizeof (void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + // It's active for allocations requiring an amount of memory above + // system pagesize. This is consistent with the requirements of the + // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html + + // The biggest string which fits in a memory page + const size_type __page_capacity = ((__pagesize - __malloc_header_size + - sizeof(_Rep) - sizeof(_CharT)) + / sizeof(_CharT)); + + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity + && __capacity > __page_capacity) + __capacity = 2 * __old_capacity; + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure. + // Whew. Seemingly so needy, yet so elemental. + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + // Never allocate a string bigger than _S_max_size. + if (__capacity > _S_max_size) + __capacity = _S_max_size; + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + else if (__size > __subpagesize) + { + const size_type __extra = __subpagesize - __adj_size % __subpagesize; + __capacity += __extra / sizeof(_CharT); + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); + _Rep *__p = new (__place) _Rep; + __p->_M_capacity = __capacity; + __p->_M_set_sharable(); // One reference. + __p->_M_length = 0; + return __p; + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + // Requested capacity of the clone. + const size_type __requested_cap = this->_M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); + if (this->_M_length) + traits_type::copy(__r->_M_refdata(), _M_refdata(), + this->_M_length); + + __r->_M_length = this->_M_length; + __r->_M_refdata()[this->_M_length] = _Rep::_S_terminal; + return __r->_M_refdata(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) + { + if (__n > max_size()) + __throw_length_error(__N("basic_string::resize")); + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->erase(__n); + // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) + } + + template + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + if (this->max_size() - (this->size() - __n1) < __s.size()) + __throw_length_error(__N("basic_string::_M_replace_dispatch")); + return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // pointer __str._M_data() formed here. + const size_type __size = __str.size(); + const size_type __len = __size + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __str._M_data(), + __str.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // pointer __str._M_data() formed here. + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + const size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __str._M_data() + + __pos, __n); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + const size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __s, __n); + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + __glibcxx_requires_string(__lhs); + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str; + const __size_type __len = __rhs.size(); + __str.reserve(__len + 1); + __str.append(__size_type(1), __lhs); + __str.append(__rhs); + return __str; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + traits_type::copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + const _CharT* __data = _M_data(); + for (; __pos + __n <= __size; ++__pos) + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(_CharT __c, size_type __pos) const + { + const size_type __size = this->size(); + size_type __ret = npos; + if (__pos < __size) + { + const _CharT* __data = _M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = _M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, _M_data()[__pos])) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n, const basic_string& __str) const + { + _M_check(__pos, "basic_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); + if (!__r) + __r = __n - __osize; + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "basic_string::compare"); + __str._M_check(__pos2, "basic_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(const _CharT* __s) const + { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(_M_data(), __s, __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + __glibcxx_requires_string(__s); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __osize; + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, string&); + extern template + basic_ostream& + operator<<(basic_ostream&, const string&); + extern template + basic_istream& + getline(basic_istream&, string&, char); + extern template + basic_istream& + getline(basic_istream&, string&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, wstring&); + extern template + basic_ostream& + operator<<(basic_ostream&, const wstring&); + extern template + basic_istream& + getline(basic_istream&, wstring&, wchar_t); + extern template + basic_istream& + getline(basic_istream&, wstring&); +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/boost_concept_check.h b/src/include.new/c++/3.4/bits/boost_concept_check.h new file mode 100644 index 0000000..ff154f7 --- /dev/null +++ b/src/include.new/c++/3.4/bits/boost_concept_check.h @@ -0,0 +1,932 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// + +// GCC Note: based on version 1.12.0 of the Boost library. + +/** @file boost_concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BOOST_CONCEPT_CHECK_H +#define _BOOST_CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include // for ptrdiff_t, used next +#include // for traits and tags +#include // for pair<> + +namespace __gnu_cxx +{ + +#define _IsUnused __attribute__ ((__unused__)) + +// When the C-C code is in use, we would like this function to do as little +// as possible at runtime, use as few resources as possible, and hopefully +// be elided out of existence... hmmm. +template +inline void __function_requires() +{ + void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; +} + +// No definition: if this is referenced, there's a problem with +// the instantiating type not being one of the required integer types. +// Unfortunately, this results in a link-time error, not a compile-time error. +void __error_type_must_be_an_integer_type(); +void __error_type_must_be_an_unsigned_integer_type(); +void __error_type_must_be_a_signed_integer_type(); + +// ??? Should the "concept_checking*" structs begin with more than _ ? +#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ + typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ + template <_func##_type_var##_concept _Tp1> \ + struct _concept_checking##_type_var##_concept { }; \ + typedef _concept_checking##_type_var##_concept< \ + &_ns::_concept <_type_var>::__constraints> \ + _concept_checking_typedef##_type_var##_concept + +#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ + template <_func##_type_var1##_type_var2##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_concept< \ + &_ns::_concept <_type_var1,_type_var2>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_concept + +#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept + +#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept + + +template +struct _Aux_require_same { }; + +template +struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; + + template + struct _SameTypeConcept + { + void __constraints() { + typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; + } + }; + + template + struct _IntegerConcept { + void __constraints() { + __error_type_must_be_an_integer_type(); + } + }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints(){} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept + { void __constraints() {} }; + + template + struct _SignedIntegerConcept { + void __constraints() { + __error_type_must_be_a_signed_integer_type(); + } + }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints(){}}; + + template + struct _UnsignedIntegerConcept { + void __constraints() { + __error_type_must_be_an_unsigned_integer_type(); + } + }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + + //=========================================================================== + // Basic Concepts + + template + struct _DefaultConstructibleConcept + { + void __constraints() { + _Tp __a _IsUnused; // require default constructor + } + }; + + template + struct _AssignableConcept + { + void __constraints() { + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + __a = __b; // const required for argument to assignment + } + _Tp __a; + // possibly should be "Tp* a;" and then dereference "a" in constraint + // functions? present way would require a default ctor, i think... + }; + + template + struct _CopyConstructibleConcept + { + void __constraints() { + _Tp __a(__b); // require copy constructor + _Tp* __ptr _IsUnused = &__a; // require address of operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __a) { + _Tp __c _IsUnused(__a); // require const copy constructor + const _Tp* __ptr _IsUnused = &__a; // require const address of operator + } + _Tp __b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + template + struct _SGIAssignableConcept + { + void __constraints() { + _Tp __b _IsUnused(__a); + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + _Tp __c _IsUnused(__b); + __a = __b; // const required for argument to assignment + } + _Tp __a; + }; + + template + struct _ConvertibleConcept + { + void __constraints() { + _To __y _IsUnused = __x; + } + _From __x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template + void __aux_require_boolean_expr(const _Tp& __t) { + bool __x _IsUnused = __t; + } + +// FIXME + template + struct _EqualityComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a == __b); + } + _Tp __a, __b; + }; + + template + struct _LessThanComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + } + _Tp __a, __b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + template + struct _ComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + __aux_require_boolean_expr(__a > __b); + __aux_require_boolean_expr(__a <= __b); + __aux_require_boolean_expr(__a >= __b); + } + _Tp __a, __b; + }; + +#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ + template \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + bool __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + +#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ + template \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + _Ret __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); + + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); + +#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT +#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT + + //=========================================================================== + // Function Object Concepts + + template + struct _GeneratorConcept + { + void __constraints() { + const _Return& __r _IsUnused = __f();// require operator() member function + } + _Func __f; + }; + + + template + struct _GeneratorConcept<_Func,void> + { + void __constraints() { + __f(); // require operator() member function + } + _Func __f; + }; + + template + struct _UnaryFunctionConcept + { + void __constraints() { + __r = __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + _Return __r; + }; + + template + struct _UnaryFunctionConcept<_Func, void, _Arg> { + void __constraints() { + __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + }; + + template + struct _BinaryFunctionConcept + { + void __constraints() { + __r = __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + _Return __r; + }; + + template + struct _BinaryFunctionConcept<_Func, void, _First, _Second> + { + void __constraints() { + __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + }; + + template + struct _UnaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__arg)); // require op() returning bool + } + _Func __f; + _Arg __arg; + }; + + template + struct _BinaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool + } + _Func __f; + _First __a; + _Second __b; + }; + + // use this when functor is used inside a container class like std::set + template + struct _Const_BinaryPredicateConcept { + void __constraints() { + __const_constraints(__f); + } + void __const_constraints(const _Func& __fun) { + __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); + // operator() must be a const member function + __aux_require_boolean_expr(__fun(__a, __b)); + } + _Func __f; + _First __a; + _Second __b; + }; + + //=========================================================================== + // Iterator Concepts + + template + struct _TrivialIteratorConcept + { + void __constraints() { +// __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _AssignableConcept<_Tp> >(); + __function_requires< _EqualityComparableConcept<_Tp> >(); +// typedef typename std::iterator_traits<_Tp>::value_type _V; + (void)*__i; // require dereference operator + } + _Tp __i; + }; + + template + struct _Mutable_TrivialIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + *__i = *__j; // require dereference and assignment + } + _Tp __i, __j; + }; + + template + struct _InputIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + // require iterator_traits typedef's + typedef typename std::iterator_traits<_Tp>::difference_type _Diff; +// __function_requires< _SignedIntegerConcept<_Diff> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + typedef typename std::iterator_traits<_Tp>::pointer _Pt; + typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::input_iterator_tag> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + } + _Tp __i; + }; + + template + struct _OutputIteratorConcept + { + void __constraints() { + __function_requires< _AssignableConcept<_Tp> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + *__i++ = __t; // require postincrement and assignment + } + _Tp __i; + _ValueT __t; + }; + + template + struct _ForwardIteratorConcept + { + void __constraints() { + __function_requires< _InputIteratorConcept<_Tp> >(); + __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::forward_iterator_tag> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + _Ref __r _IsUnused = *__i; + } + _Tp __i; + }; + + template + struct _Mutable_ForwardIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + *__i++ = *__i; // require postincrement and assignment + } + _Tp __i; + }; + + template + struct _BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::bidirectional_iterator_tag> >(); + --__i; // require predecrement operator + __i--; // require postdecrement operator + } + _Tp __i; + }; + + template + struct _Mutable_BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); + *__i-- = *__i; // require postdecrement and assignment + } + _Tp __i; + }; + + + template + struct _RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _ComparableConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::random_access_iterator_tag> >(); + // ??? We don't use _Ref, are we just checking for "referenceability"? + typedef typename std::iterator_traits<_Tp>::reference _Ref; + + __i += __n; // require assignment addition operator + __i = __i + __n; __i = __n + __i; // require addition with difference type + __i -= __n; // require assignment subtraction op + __i = __i - __n; // require subtraction with + // difference type + __n = __i - __j; // require difference operator + (void)__i[__n]; // require element access operator + } + _Tp __a, __b; + _Tp __i, __j; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + template + struct _Mutable_RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _RandomAccessIteratorConcept<_Tp> >(); + __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); + __i[__n] = *__i; // require element access and assignment + } + _Tp __i; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + //=========================================================================== + // Container Concepts + + template + struct _ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::difference_type _Difference_type; + typedef typename _Container::size_type _Size_type; + typedef typename _Container::const_reference _Const_reference; + typedef typename _Container::const_pointer _Const_pointer; + typedef typename _Container::const_iterator _Const_iterator; + + void __constraints() { + __function_requires< _InputIteratorConcept<_Const_iterator> >(); + __function_requires< _AssignableConcept<_Container> >(); + const _Container __c; + __i = __c.begin(); + __i = __c.end(); + __n = __c.size(); + __n = __c.max_size(); + __b = __c.empty(); + } + bool __b; + _Const_iterator __i; + _Size_type __n; + }; + + template + struct _Mutable_ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::reference _Reference; + typedef typename _Container::iterator _Iterator; + typedef typename _Container::pointer _Pointer; + + void __constraints() { + __function_requires< _ContainerConcept<_Container> >(); + __function_requires< _AssignableConcept<_Value_type> >(); + __function_requires< _InputIteratorConcept<_Iterator> >(); + + __i = __c.begin(); + __i = __c.end(); + __c.swap(__c2); + } + _Iterator __i; + _Container __c, __c2; + }; + + template + struct _ForwardContainerConcept + { + void __constraints() { + __function_requires< _ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::const_iterator _Const_iterator; + __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); + } + }; + + template + struct _Mutable_ForwardContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); + __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::iterator _Iterator; + __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); + } + }; + + template + struct _ReversibleContainerConcept + { + typedef typename _ReversibleContainer::const_iterator _Const_iterator; + typedef typename _ReversibleContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); + __function_requires< + _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); + + const _ReversibleContainer __c; + _Const_reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + }; + + template + struct _Mutable_ReversibleContainerConcept + { + typedef typename _ReversibleContainer::iterator _Iterator; + typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); + __function_requires< + _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); + + _Reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + _ReversibleContainer __c; + }; + + template + struct _RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::const_reference _Const_reference; + typedef typename _RandomAccessContainer::const_iterator _Const_iterator; + typedef typename _RandomAccessContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< + _ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); + __function_requires< + _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); + + const _RandomAccessContainer __c; + _Const_reference __r _IsUnused = __c[__n]; + } + _Size_type __n; + }; + + template + struct _Mutable_RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::reference _Reference; + typedef typename _RandomAccessContainer::iterator _Iterator; + typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires< + _RandomAccessContainerConcept<_RandomAccessContainer> >(); + __function_requires< + _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); + + _Reference __r _IsUnused = __c[__i]; + } + _Size_type __i; + _RandomAccessContainer __c; + }; + + // A Sequence is inherently mutable + template + struct _SequenceConcept + { + typedef typename _Sequence::reference _Reference; + typedef typename _Sequence::const_reference _Const_reference; + + void __constraints() { + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container + // function_requires< DefaultConstructible >(); + __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); + __function_requires< _DefaultConstructibleConcept<_Sequence> >(); + + _Sequence + __c _IsUnused(__n, __t), + __c2 _IsUnused(__first, __last); + + __c.insert(__p, __t); + __c.insert(__p, __n, __t); + __c.insert(__p, __first, __last); + + __c.erase(__p); + __c.erase(__p, __q); + + _Reference __r _IsUnused = __c.front(); + + __const_constraints(__c); + } + void __const_constraints(const _Sequence& __c) { + _Const_reference __r _IsUnused = __c.front(); + } + typename _Sequence::value_type __t; + typename _Sequence::size_type __n; + typename _Sequence::value_type *__first, *__last; + typename _Sequence::iterator __p, __q; + }; + + template + struct _FrontInsertionSequenceConcept + { + void __constraints() { + __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); + + __c.push_front(__t); + __c.pop_front(); + } + _FrontInsertionSequence __c; + typename _FrontInsertionSequence::value_type __t; + }; + + template + struct _BackInsertionSequenceConcept + { + typedef typename _BackInsertionSequence::reference _Reference; + typedef typename _BackInsertionSequence::const_reference _Const_reference; + + void __constraints() { + __function_requires< _SequenceConcept<_BackInsertionSequence> >(); + + __c.push_back(__t); + __c.pop_back(); + _Reference __r _IsUnused = __c.back(); + } + void __const_constraints(const _BackInsertionSequence& __c) { + _Const_reference __r _IsUnused = __c.back(); + }; + _BackInsertionSequence __c; + typename _BackInsertionSequence::value_type __t; + }; + + template + struct _AssociativeContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_AssociativeContainer> >(); + __function_requires< + _DefaultConstructibleConcept<_AssociativeContainer> >(); + + __i = __c.find(__k); + __r = __c.equal_range(__k); + __c.erase(__k); + __c.erase(__i); + __c.erase(__r.first, __r.second); + __const_constraints(__c); + } + void __const_constraints(const _AssociativeContainer& __c) { + __ci = __c.find(__k); + __n = __c.count(__k); + __cr = __c.equal_range(__k); + } + typedef typename _AssociativeContainer::iterator _Iterator; + typedef typename _AssociativeContainer::const_iterator _Const_iterator; + + _AssociativeContainer __c; + _Iterator __i; + std::pair<_Iterator,_Iterator> __r; + _Const_iterator __ci; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _AssociativeContainer::key_type __k; + typename _AssociativeContainer::size_type __n; + }; + + template + struct _UniqueAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_UniqueAssociativeContainer> >(); + + _UniqueAssociativeContainer __c(__first, __last); + + __pos_flag = __c.insert(__t); + __c.insert(__first, __last); + } + std::pair __pos_flag; + typename _UniqueAssociativeContainer::value_type __t; + typename _UniqueAssociativeContainer::value_type *__first, *__last; + }; + + template + struct _MultipleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_MultipleAssociativeContainer> >(); + + _MultipleAssociativeContainer __c(__first, __last); + + __pos = __c.insert(__t); + __c.insert(__first, __last); + + } + typename _MultipleAssociativeContainer::iterator __pos; + typename _MultipleAssociativeContainer::value_type __t; + typename _MultipleAssociativeContainer::value_type *__first, *__last; + }; + + template + struct _SimpleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type + _Required; + } + }; + + template + struct _PairAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type; + typedef std::pair _Required_value_type; + typedef typename _Aux_require_same<_Value_type, + _Required_value_type>::_Type _Required; + } + }; + + template + struct _SortedAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SortedAssociativeContainer> >(); + __function_requires< + _ReversibleContainerConcept<_SortedAssociativeContainer> >(); + + _SortedAssociativeContainer + __c _IsUnused(__kc), + __c2 _IsUnused(__first, __last), + __c3 _IsUnused(__first, __last, __kc); + + __p = __c.upper_bound(__k); + __p = __c.lower_bound(__k); + __r = __c.equal_range(__k); + + __c.insert(__p, __t); + } + void __const_constraints(const _SortedAssociativeContainer& __c) { + __kc = __c.key_comp(); + __vc = __c.value_comp(); + + __cp = __c.upper_bound(__k); + __cp = __c.lower_bound(__k); + __cr = __c.equal_range(__k); + } + typename _SortedAssociativeContainer::key_compare __kc; + typename _SortedAssociativeContainer::value_compare __vc; + typename _SortedAssociativeContainer::value_type __t; + typename _SortedAssociativeContainer::key_type __k; + typedef typename _SortedAssociativeContainer::iterator _Iterator; + typedef typename _SortedAssociativeContainer::const_iterator + _Const_iterator; + + _Iterator __p; + _Const_iterator __cp; + std::pair<_Iterator,_Iterator> __r; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _SortedAssociativeContainer::value_type *__first, *__last; + }; + + // HashedAssociativeContainer + +} // namespace __gnu_cxx + +#undef _IsUnused + +#endif // _GLIBCXX_BOOST_CONCEPT_CHECK + + diff --git a/src/include.new/c++/3.4/bits/c++allocator.h b/src/include.new/c++/3.4/bits/c++allocator.h new file mode 100644 index 0000000..442f89c --- /dev/null +++ b/src/include.new/c++/3.4/bits/c++allocator.h @@ -0,0 +1,37 @@ +// Base to std::allocator -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CXX_ALLOCATOR_H +#define _CXX_ALLOCATOR_H 1 + +// Define new_allocator as the base class to std::allocator. +#include +#define ___glibcxx_base_allocator __gnu_cxx::new_allocator + +#endif diff --git a/src/include.new/c++/3.4/bits/c++config.h b/src/include.new/c++/3.4/bits/c++config.h new file mode 100644 index 0000000..3d7d115 --- /dev/null +++ b/src/include.new/c++/3.4/bits/c++config.h @@ -0,0 +1,1293 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CXXCONFIG +#define _CXXCONFIG 1 + +// Pick up any OS-specific definitions. +#include + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCXX__ 20060311 + +// Allow use of "export template." This is currently not a feature +// that g++ supports. +// #define _GLIBCXX_EXPORT_TEMPLATE 1 + +// Allow use of the GNU syntax extension, "extern template." This +// extension is fully documented in the g++ manual, but in a nutshell, +// it inhibits all implicit instantiations and is used throughout the +// library to avoid multiple weak definitions for required types that +// are already explicitly instantiated in the library binary. This +// substantially reduces the binary size of resulting executables. +#ifndef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE 1 +#endif + +// Debug mode support. Debug mode basic_string is not allowed to be +// associated with std, because of locale and exception link +// dependence. +namespace __gnu_debug_def { } + +namespace __gnu_debug +{ + using namespace __gnu_debug_def; +} + +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_STD __gnu_norm +namespace __gnu_norm +{ + using namespace std; +} +namespace std +{ + using namespace __gnu_debug_def __attribute__ ((strong)); +} +#else +# define _GLIBCXX_STD std +#endif + + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + +// Create a boolean flag to be used to determine if --fast-math is set. +#ifdef __FAST_MATH__ +# define _GLIBCXX_FAST_MATH 1 +#else +# define _GLIBCXX_FAST_MATH 0 +#endif + +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) + +// End of prewritten config; the discovered settings follow. +/* $FreeBSD: src/gnu/lib/libstdc++/config.h,v 1.11 2005/03/26 08:27:53 das Exp $ */ + +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ +// acconfig.h symbols and macros for libstdc++ v3 -*- C++ -*- + +// Defines libstdc++ version. +/* #undef _GLIBCXX_PACKAGE */ +/* #undef _GLIBCXX_VERSION */ + +// Needed for gettext. +/* #undef ENABLE_NLS */ +/* #undef _GLIBCXX_HAVE_CATGETS */ +/* #undef _GLIBCXX_HAVE_GETTEXT */ +/* #undef _GLIBCXX_HAVE_STPCPY */ + +// Include I/O support for 'long long' and 'unsigned long long'. +#define _GLIBCXX_USE_LONG_LONG 1 + +// Include support for 'long double'. +/* #undef _GLIBCXX_USE_LONG_DOUBLE */ + +// Define if C99 math functions (like fpclassify) should be exposed. +#define _GLIBCXX_USE_C99_MATH 1 + +// Define if C99 features such as lldiv_t, llabs, lldiv should be exposed. +#define _GLIBCXX_USE_C99 1 + +// Define if code specialized for wchar_t should be used. +#define _GLIBCXX_USE_WCHAR_T 1 + +// Define if using setrlimit to limit memory usage during 'make check'. +#define _GLIBCXX_MEM_LIMITS 1 + +// Define to use concept checking code from the boost libraries. +/* #undef _GLIBCXX_CONCEPT_CHECKS */ + +// Define to use symbol versioning in the shared library. +/* #undef _GLIBCXX_SYMVER */ + +// Define symbol versioning in assember directives. If symbol +// versioning is beigng used, and the assembler supports this kind of +// thing, then use it. +// NB: _GLIBCXX_AT_AT is a hack to work around quoting issues in m4. +#if _GLIBCXX_SYMVER + #define _GLIBCXX_ASM_SYMVER(cur, old, version) \ + asm (".symver " #cur "," #old _GLIBCXX_AT_AT #version); +#else + #define _GLIBCXX_ASM_SYMVER(cur, old, version) +#endif + +// Define if LFS support is available. +/* #undef _GLIBCXX_USE_LFS */ + +// Define if NLS translations are to be used. +/* #undef _GLIBCXX_USE_NLS */ + +// Define if gthr-default.h exists (meaning that threading support is enabled). +#define _GLIBCXX_HAVE_GTHR_DEFAULT 1 + +// Define if the atan2f function exists. +#define _GLIBCXX_HAVE_ATAN2F 1 + +// Define if the atan2l function exists. +/* #undef _GLIBCXX_HAVE_ATAN2L */ + +// Define if the tanl function exists. +/* #undef _GLIBCXX_HAVE_TANL */ + +// Define if the copysignf function exists. +#define _GLIBCXX_HAVE_COPYSIGNF 1 + +// Define if getpagesize exists. +#define _GLIBCXX_HAVE_GETPAGESIZE 1 + +// Define if setenv exists. +#define _GLIBCXX_HAVE_SETENV 1 + +// Define if sigsetjmp exists. +#define _GLIBCXX_HAVE_SIGSETJMP 1 + +// Define if mbstate_t exists in wchar.h. +#define _GLIBCXX_HAVE_MBSTATE_T 1 + +// Define if you have the modff function. +#define _GLIBCXX_HAVE_MODFF 1 + +// Define if you have the modfl function. +/* #undef _GLIBCXX_HAVE_MODFL */ + +// Define if you have the expf function. +#define _GLIBCXX_HAVE_EXPF 1 + +// Define if you have the expl function. +/* #undef _GLIBCXX_HAVE_EXPL */ + +// Define if you have the hypot function. +#define _GLIBCXX_HAVE_HYPOT 1 + +// Define if you have the hypotf function. +#define _GLIBCXX_HAVE_HYPOTF 1 + +// Define if you have the hypotl function. +/* #undef _GLIBCXX_HAVE_HYPOTL */ + +// Define if the compiler/host combination has __builtin_abs +#define _GLIBCXX_HAVE___BUILTIN_ABS 1 + +// Define if the compiler/host combination has __builtin_labs +#define _GLIBCXX_HAVE___BUILTIN_LABS 1 + +// Define if the compiler/host combination has __builtin_cos +#define _GLIBCXX_HAVE___BUILTIN_COS 1 + +// Define if the compiler/host combination has __builtin_cosf +#define _GLIBCXX_HAVE___BUILTIN_COSF 1 + +// Define if the compiler/host combination has __builtin_cosl +#define _GLIBCXX_HAVE___BUILTIN_COSL 1 + +// Define if the compiler/host combination has __builtin_fabs +#define _GLIBCXX_HAVE___BUILTIN_FABS 1 + +// Define if the compiler/host combination has __builtin_fabsf +#define _GLIBCXX_HAVE___BUILTIN_FABSF 1 + +// Define if the compiler/host combination has __builtin_fabsl +#define _GLIBCXX_HAVE___BUILTIN_FABSL 1 + +// Define if the compiler/host combination has __builtin_sin +#define _GLIBCXX_HAVE___BUILTIN_SIN 1 + +// Define if the compiler/host combination has __builtin_sinf +#define _GLIBCXX_HAVE___BUILTIN_SINF 1 + +// Define if the compiler/host combination has __builtin_sinl +#define _GLIBCXX_HAVE___BUILTIN_SINL 1 + +// Define if the compiler/host combination has __builtin_sqrt +#define _GLIBCXX_HAVE___BUILTIN_SQRT 1 + +// Define if the compiler/host combination has __builtin_sqrtf +#define _GLIBCXX_HAVE___BUILTIN_SQRTF 1 + +// Define if the compiler/host combination has __builtin_sqrtl +#define _GLIBCXX_HAVE___BUILTIN_SQRTL 1 + +// Define if poll is available in . +#define _GLIBCXX_HAVE_POLL 1 + +// Define if S_ISREG (Posix) is available in . +#define _GLIBCXX_HAVE_S_ISREG 1 + +// Define if S_IFREG is available in . +/* #undef _GLIBCXX_HAVE_S_IFREG */ + +// Define if writev is available in . +#define _GLIBCXX_HAVE_WRITEV 1 + +// Define if int64_t is available in . +#define _GLIBCXX_HAVE_INT64_T 1 + +// Define if LC_MESSAGES is available in . +#define _GLIBCXX_HAVE_LC_MESSAGES 1 + +// Define if exists. +#define _GLIBCXX_HAVE_FLOAT_H 1 + +// Define if modf is present in +/* #undef _GLIBCXX_HAVE_MODF */ + + +/* Define to 1 if you have the `acosf' function. */ +#define _GLIBCXX_HAVE_ACOSF 1 + +/* Define to 1 if you have the `acosl' function. */ +/* #undef _GLIBCXX_HAVE_ACOSL */ + +/* Define to 1 if you have the `asinf' function. */ +#define _GLIBCXX_HAVE_ASINF 1 + +/* Define to 1 if you have the `asinl' function. */ +/* #undef _GLIBCXX_HAVE_ASINL */ + +/* Define to 1 if you have the `atan2f' function. */ +#define _GLIBCXX_HAVE_ATAN2F 1 + +/* Define to 1 if you have the `atan2l' function. */ +/* #undef _GLIBCXX_HAVE_ATAN2L */ + +/* Define to 1 if you have the `atanf' function. */ +#define _GLIBCXX_HAVE_ATANF 1 + +/* Define to 1 if you have the `atanl' function. */ +/* #undef _GLIBCXX_HAVE_ATANL */ + +/* Define to 1 if you have the `btowc' function. */ +#define _GLIBCXX_HAVE_BTOWC 1 + +/* Define to 1 if you have the `ceilf' function. */ +#define _GLIBCXX_HAVE_CEILF 1 + +/* Define to 1 if you have the `ceill' function. */ +#define _GLIBCXX_HAVE_CEILL 1 + +/* Define to 1 if you have the `copysign' function. */ +#define _GLIBCXX_HAVE_COPYSIGN 1 + +/* Define to 1 if you have the `copysignf' function. */ +#define _GLIBCXX_HAVE_COPYSIGNF 1 + +/* Define to 1 if you have the `copysignl' function. */ +#define _GLIBCXX_HAVE_COPYSIGNL 1 + +/* Define to 1 if you have the `cosf' function. */ +#define _GLIBCXX_HAVE_COSF 1 + +/* Define to 1 if you have the `coshf' function. */ +#define _GLIBCXX_HAVE_COSHF 1 + +/* Define to 1 if you have the `coshl' function. */ +/* #undef _GLIBCXX_HAVE_COSHL */ + +/* Define to 1 if you have the `cosl' function. */ +/* #undef _GLIBCXX_HAVE_COSL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_ENDIAN_H */ + +/* Define to 1 if you have the `expf' function. */ +#define _GLIBCXX_HAVE_EXPF 1 + +/* Define to 1 if you have the `expl' function. */ +/* #undef _GLIBCXX_HAVE_EXPL */ + +/* Define to 1 if you have the `fabsf' function. */ +#define _GLIBCXX_HAVE_FABSF 1 + +/* Define to 1 if you have the `fabsl' function. */ +#define _GLIBCXX_HAVE_FABSL 1 + +/* Define to 1 if you have the `fgetwc' function. */ +#define _GLIBCXX_HAVE_FGETWC 1 + +/* Define to 1 if you have the `fgetws' function. */ +#define _GLIBCXX_HAVE_FGETWS 1 + +/* Define to 1 if you have the `finite' function. */ +#define _GLIBCXX_HAVE_FINITE 1 + +/* Define to 1 if you have the `finitef' function. */ +#define _GLIBCXX_HAVE_FINITEF 1 + +/* Define to 1 if you have the `finitel' function. */ +/* #undef _GLIBCXX_HAVE_FINITEL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floorf' function. */ +#define _GLIBCXX_HAVE_FLOORF 1 + +/* Define to 1 if you have the `floorl' function. */ +#define _GLIBCXX_HAVE_FLOORL 1 + +/* Define to 1 if you have the `fmodf' function. */ +#define _GLIBCXX_HAVE_FMODF 1 + +/* Define to 1 if you have the `fmodl' function. */ +/* #undef _GLIBCXX_HAVE_FMODL */ + +/* Define to 1 if you have the `fpclass' function. */ +/* #undef _GLIBCXX_HAVE_FPCLASS */ + +/* Define to 1 if you have the `fputwc' function. */ +#define _GLIBCXX_HAVE_FPUTWC 1 + +/* Define to 1 if you have the `fputws' function. */ +#define _GLIBCXX_HAVE_FPUTWS 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_FP_H */ + +/* Define to 1 if you have the `frexpf' function. */ +#define _GLIBCXX_HAVE_FREXPF 1 + +/* Define to 1 if you have the `frexpl' function. */ +#define _GLIBCXX_HAVE_FREXPL 1 + +/* Define to 1 if you have the `fwide' function. */ +#define _GLIBCXX_HAVE_FWIDE 1 + +/* Define to 1 if you have the `fwprintf' function. */ +#define _GLIBCXX_HAVE_FWPRINTF 1 + +/* Define to 1 if you have the `fwscanf' function. */ +#define _GLIBCXX_HAVE_FWSCANF 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_GCONV_H */ + +/* Define to 1 if you have the `getpagesize' function. */ +#define _GLIBCXX_HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getwc' function. */ +#define _GLIBCXX_HAVE_GETWC 1 + +/* Define to 1 if you have the `getwchar' function. */ +#define _GLIBCXX_HAVE_GETWCHAR 1 + +/* Define to 1 if you have the `hypot' function. */ +#define _GLIBCXX_HAVE_HYPOT 1 + +/* Define to 1 if you have the `hypotf' function. */ +#define _GLIBCXX_HAVE_HYPOTF 1 + +/* Define to 1 if you have the `hypotl' function. */ +/* #undef _GLIBCXX_HAVE_HYPOTL */ + +/* Define to 1 if you have the `iconv' function. */ +#define _GLIBCXX_HAVE_ICONV 1 + +/* Define to 1 if you have the `iconv_close' function. */ +#define _GLIBCXX_HAVE_ICONV_CLOSE 1 + +/* Define to 1 if you have the `iconv_open' function. */ +#define _GLIBCXX_HAVE_ICONV_OPEN 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_IEEEFP_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isinf' function. */ +#define _GLIBCXX_HAVE_ISINF 1 + +/* Define to 1 if you have the `isinff' function. */ +/* #undef _GLIBCXX_HAVE_ISINFF */ + +/* Define to 1 if you have the `isinfl' function. */ +/* #undef _GLIBCXX_HAVE_ISINFL */ + +/* Define to 1 if you have the `isnan' function. */ +#define _GLIBCXX_HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +#define _GLIBCXX_HAVE_ISNANF 1 + +/* Define to 1 if you have the `isnanl' function. */ +/* #undef _GLIBCXX_HAVE_ISNANL */ + +/* Define to 1 if you have the `iswblank' function. */ +#define _GLIBCXX_HAVE_ISWBLANK 1 + +/* Define to 1 if you have the `ldexpf' function. */ +#define _GLIBCXX_HAVE_LDEXPF 1 + +/* Define to 1 if you have the `ldexpl' function. */ +#define _GLIBCXX_HAVE_LDEXPL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_LIBINTL_H */ + +/* Define to 1 if you have the `m' library (-lm). */ +#define _GLIBCXX_HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `log10f' function. */ +#define _GLIBCXX_HAVE_LOG10F 1 + +/* Define to 1 if you have the `log10l' function. */ +/* #undef _GLIBCXX_HAVE_LOG10L */ + +/* Define to 1 if you have the `logf' function. */ +#define _GLIBCXX_HAVE_LOGF 1 + +/* Define to 1 if you have the `logl' function. */ +/* #undef _GLIBCXX_HAVE_LOGL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MACHINE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MACHINE_PARAM_H 1 + +/* Define to 1 if you have the `mbrlen' function. */ +#define _GLIBCXX_HAVE_MBRLEN 1 + +/* Define to 1 if you have the `mbrtowc' function. */ +#define _GLIBCXX_HAVE_MBRTOWC 1 + +/* Define to 1 if you have the `mbsinit' function. */ +#define _GLIBCXX_HAVE_MBSINIT 1 + +/* Define to 1 if you have the `mbsrtowcs' function. */ +#define _GLIBCXX_HAVE_MBSRTOWCS 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_MEMLIMIT_AS 0 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_MEMLIMIT_DATA 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_MEMLIMIT_RSS 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_MEMLIMIT_VMEM 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MEMORY_H 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define _GLIBCXX_HAVE_MMAP 1 + +/* Define to 1 if you have the `modff' function. */ +#define _GLIBCXX_HAVE_MODFF 1 + +/* Define to 1 if you have the `modfl' function. */ +/* #undef _GLIBCXX_HAVE_MODFL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_NAN_H */ + +/* Define to 1 if you have the `nl_langinfo' function. */ +#define _GLIBCXX_HAVE_NL_LANGINFO 1 + +/* Define to 1 if you have the `powf' function. */ +#define _GLIBCXX_HAVE_POWF 1 + +/* Define to 1 if you have the `powl' function. */ +/* #undef _GLIBCXX_HAVE_POWL */ + +/* Define to 1 if you have the `putwc' function. */ +#define _GLIBCXX_HAVE_PUTWC 1 + +/* Define to 1 if you have the `putwchar' function. */ +#define _GLIBCXX_HAVE_PUTWCHAR 1 + +/* Define to 1 if you have the `qfpclass' function. */ +/* #undef _GLIBCXX_HAVE_QFPCLASS */ + +/* Define to 1 if you have the `setenv' function. */ +#define _GLIBCXX_HAVE_SETENV 1 + +/* Define if sigsetjmp is available. */ +#define _GLIBCXX_HAVE_SIGSETJMP 1 + +/* Define to 1 if you have the `sincos' function. */ +/* #undef _GLIBCXX_HAVE_SINCOS */ + +/* Define to 1 if you have the `sincosf' function. */ +/* #undef _GLIBCXX_HAVE_SINCOSF */ + +/* Define to 1 if you have the `sincosl' function. */ +/* #undef _GLIBCXX_HAVE_SINCOSL */ + +/* Define to 1 if you have the `sinf' function. */ +#define _GLIBCXX_HAVE_SINF 1 + +/* Define to 1 if you have the `sinhf' function. */ +#define _GLIBCXX_HAVE_SINHF 1 + +/* Define to 1 if you have the `sinhl' function. */ +/* #undef _GLIBCXX_HAVE_SINHL */ + +/* Define to 1 if you have the `sinl' function. */ +/* #undef _GLIBCXX_HAVE_SINL */ + +/* Define to 1 if you have the `sqrtf' function. */ +#define _GLIBCXX_HAVE_SQRTF 1 + +/* Define to 1 if you have the `sqrtl' function. */ +/* #undef _GLIBCXX_HAVE_SQRTL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtof' function. */ +#define _GLIBCXX_HAVE_STRTOF 1 + +/* Define to 1 if you have the `strtold' function. */ +#define _GLIBCXX_HAVE_STRTOLD 1 + +/* Define to 1 if you have the `swprintf' function. */ +#define _GLIBCXX_HAVE_SWPRINTF 1 + +/* Define to 1 if you have the `swscanf' function. */ +#define _GLIBCXX_HAVE_SWSCANF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_PARAM_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the `tanf' function. */ +#define _GLIBCXX_HAVE_TANF 1 + +/* Define to 1 if you have the `tanhf' function. */ +#define _GLIBCXX_HAVE_TANHF 1 + +/* Define to 1 if you have the `tanhl' function. */ +/* #undef _GLIBCXX_HAVE_TANHL */ + +/* Define to 1 if you have the `tanl' function. */ +/* #undef _GLIBCXX_HAVE_TANL */ + +/* Define to 1 if you have the `ungetwc' function. */ +#define _GLIBCXX_HAVE_UNGETWC 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vfwprintf' function. */ +#define _GLIBCXX_HAVE_VFWPRINTF 1 + +/* Define to 1 if you have the `vfwscanf' function. */ +#define _GLIBCXX_HAVE_VFWSCANF 1 + +/* Define to 1 if you have the `vswprintf' function. */ +#define _GLIBCXX_HAVE_VSWPRINTF 1 + +/* Define to 1 if you have the `vswscanf' function. */ +#define _GLIBCXX_HAVE_VSWSCANF 1 + +/* Define to 1 if you have the `vwprintf' function. */ +#define _GLIBCXX_HAVE_VWPRINTF 1 + +/* Define to 1 if you have the `vwscanf' function. */ +#define _GLIBCXX_HAVE_VWSCANF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCHAR_H 1 + +/* Define to 1 if you have the `wcrtomb' function. */ +#define _GLIBCXX_HAVE_WCRTOMB 1 + +/* Define to 1 if you have the `wcscat' function. */ +#define _GLIBCXX_HAVE_WCSCAT 1 + +/* Define to 1 if you have the `wcschr' function. */ +#define _GLIBCXX_HAVE_WCSCHR 1 + +/* Define to 1 if you have the `wcscmp' function. */ +#define _GLIBCXX_HAVE_WCSCMP 1 + +/* Define to 1 if you have the `wcscoll' function. */ +#define _GLIBCXX_HAVE_WCSCOLL 1 + +/* Define to 1 if you have the `wcscpy' function. */ +#define _GLIBCXX_HAVE_WCSCPY 1 + +/* Define to 1 if you have the `wcscspn' function. */ +#define _GLIBCXX_HAVE_WCSCSPN 1 + +/* Define to 1 if you have the `wcsftime' function. */ +#define _GLIBCXX_HAVE_WCSFTIME 1 + +/* Define to 1 if you have the `wcslen' function. */ +#define _GLIBCXX_HAVE_WCSLEN 1 + +/* Define to 1 if you have the `wcsncat' function. */ +#define _GLIBCXX_HAVE_WCSNCAT 1 + +/* Define to 1 if you have the `wcsncmp' function. */ +#define _GLIBCXX_HAVE_WCSNCMP 1 + +/* Define to 1 if you have the `wcsncpy' function. */ +#define _GLIBCXX_HAVE_WCSNCPY 1 + +/* Define to 1 if you have the `wcspbrk' function. */ +#define _GLIBCXX_HAVE_WCSPBRK 1 + +/* Define to 1 if you have the `wcsrchr' function. */ +#define _GLIBCXX_HAVE_WCSRCHR 1 + +/* Define to 1 if you have the `wcsrtombs' function. */ +#define _GLIBCXX_HAVE_WCSRTOMBS 1 + +/* Define to 1 if you have the `wcsspn' function. */ +#define _GLIBCXX_HAVE_WCSSPN 1 + +/* Define to 1 if you have the `wcsstr' function. */ +#define _GLIBCXX_HAVE_WCSSTR 1 + +/* Define to 1 if you have the `wcstod' function. */ +#define _GLIBCXX_HAVE_WCSTOD 1 + +/* Define to 1 if you have the `wcstof' function. */ +#define _GLIBCXX_HAVE_WCSTOF 1 + +/* Define to 1 if you have the `wcstok' function. */ +#define _GLIBCXX_HAVE_WCSTOK 1 + +/* Define to 1 if you have the `wcstol' function. */ +#define _GLIBCXX_HAVE_WCSTOL 1 + +/* Define to 1 if you have the `wcstoul' function. */ +#define _GLIBCXX_HAVE_WCSTOUL 1 + +/* Define to 1 if you have the `wcsxfrm' function. */ +#define _GLIBCXX_HAVE_WCSXFRM 1 + +/* Define to 1 if you have the `wctob' function. */ +#define _GLIBCXX_HAVE_WCTOB 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCTYPE_H 1 + +/* Define to 1 if you have the `wmemchr' function. */ +#define _GLIBCXX_HAVE_WMEMCHR 1 + +/* Define to 1 if you have the `wmemcmp' function. */ +#define _GLIBCXX_HAVE_WMEMCMP 1 + +/* Define to 1 if you have the `wmemcpy' function. */ +#define _GLIBCXX_HAVE_WMEMCPY 1 + +/* Define to 1 if you have the `wmemmove' function. */ +#define _GLIBCXX_HAVE_WMEMMOVE 1 + +/* Define to 1 if you have the `wmemset' function. */ +#define _GLIBCXX_HAVE_WMEMSET 1 + +/* Define to 1 if you have the `wprintf' function. */ +#define _GLIBCXX_HAVE_WPRINTF 1 + +/* Define to 1 if you have the `wscanf' function. */ +#define _GLIBCXX_HAVE_WSCANF 1 + +/* Define to 1 if you have the `_acosf' function. */ +/* #undef _GLIBCXX_HAVE__ACOSF */ + +/* Define to 1 if you have the `_acosl' function. */ +/* #undef _GLIBCXX_HAVE__ACOSL */ + +/* Define to 1 if you have the `_asinf' function. */ +/* #undef _GLIBCXX_HAVE__ASINF */ + +/* Define to 1 if you have the `_asinl' function. */ +/* #undef _GLIBCXX_HAVE__ASINL */ + +/* Define to 1 if you have the `_atan2f' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2F */ + +/* Define to 1 if you have the `_atan2l' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2L */ + +/* Define to 1 if you have the `_atanf' function. */ +/* #undef _GLIBCXX_HAVE__ATANF */ + +/* Define to 1 if you have the `_atanl' function. */ +/* #undef _GLIBCXX_HAVE__ATANL */ + +/* Define to 1 if you have the `_ceilf' function. */ +/* #undef _GLIBCXX_HAVE__CEILF */ + +/* Define to 1 if you have the `_ceill' function. */ +/* #undef _GLIBCXX_HAVE__CEILL */ + +/* Define to 1 if you have the `_copysign' function. */ +/* #undef _GLIBCXX_HAVE__COPYSIGN */ + +/* Define to 1 if you have the `_copysignl' function. */ +/* #undef _GLIBCXX_HAVE__COPYSIGNL */ + +/* Define to 1 if you have the `_cosf' function. */ +/* #undef _GLIBCXX_HAVE__COSF */ + +/* Define to 1 if you have the `_coshf' function. */ +/* #undef _GLIBCXX_HAVE__COSHF */ + +/* Define to 1 if you have the `_coshl' function. */ +/* #undef _GLIBCXX_HAVE__COSHL */ + +/* Define to 1 if you have the `_cosl' function. */ +/* #undef _GLIBCXX_HAVE__COSL */ + +/* Define to 1 if you have the `_expf' function. */ +/* #undef _GLIBCXX_HAVE__EXPF */ + +/* Define to 1 if you have the `_expl' function. */ +/* #undef _GLIBCXX_HAVE__EXPL */ + +/* Define to 1 if you have the `_fabsf' function. */ +/* #undef _GLIBCXX_HAVE__FABSF */ + +/* Define to 1 if you have the `_fabsl' function. */ +/* #undef _GLIBCXX_HAVE__FABSL */ + +/* Define to 1 if you have the `_finite' function. */ +/* #undef _GLIBCXX_HAVE__FINITE */ + +/* Define to 1 if you have the `_finitef' function. */ +/* #undef _GLIBCXX_HAVE__FINITEF */ + +/* Define to 1 if you have the `_finitel' function. */ +/* #undef _GLIBCXX_HAVE__FINITEL */ + +/* Define to 1 if you have the `_floorf' function. */ +/* #undef _GLIBCXX_HAVE__FLOORF */ + +/* Define to 1 if you have the `_floorl' function. */ +/* #undef _GLIBCXX_HAVE__FLOORL */ + +/* Define to 1 if you have the `_fmodf' function. */ +/* #undef _GLIBCXX_HAVE__FMODF */ + +/* Define to 1 if you have the `_fmodl' function. */ +/* #undef _GLIBCXX_HAVE__FMODL */ + +/* Define to 1 if you have the `_fpclass' function. */ +/* #undef _GLIBCXX_HAVE__FPCLASS */ + +/* Define to 1 if you have the `_frexpf' function. */ +/* #undef _GLIBCXX_HAVE__FREXPF */ + +/* Define to 1 if you have the `_frexpl' function. */ +/* #undef _GLIBCXX_HAVE__FREXPL */ + +/* Define to 1 if you have the `_hypot' function. */ +/* #undef _GLIBCXX_HAVE__HYPOT */ + +/* Define to 1 if you have the `_hypotf' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTF */ + +/* Define to 1 if you have the `_hypotl' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTL */ + +/* Define to 1 if you have the `_isinf' function. */ +/* #undef _GLIBCXX_HAVE__ISINF */ + +/* Define to 1 if you have the `_isinff' function. */ +/* #undef _GLIBCXX_HAVE__ISINFF */ + +/* Define to 1 if you have the `_isinfl' function. */ +/* #undef _GLIBCXX_HAVE__ISINFL */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef _GLIBCXX_HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef _GLIBCXX_HAVE__ISNANF */ + +/* Define to 1 if you have the `_isnanl' function. */ +/* #undef _GLIBCXX_HAVE__ISNANL */ + +/* Define to 1 if you have the `_ldexpf' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPF */ + +/* Define to 1 if you have the `_ldexpl' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPL */ + +/* Define to 1 if you have the `_log10f' function. */ +/* #undef _GLIBCXX_HAVE__LOG10F */ + +/* Define to 1 if you have the `_log10l' function. */ +/* #undef _GLIBCXX_HAVE__LOG10L */ + +/* Define to 1 if you have the `_logf' function. */ +/* #undef _GLIBCXX_HAVE__LOGF */ + +/* Define to 1 if you have the `_logl' function. */ +/* #undef _GLIBCXX_HAVE__LOGL */ + +/* Define to 1 if you have the `_modff' function. */ +/* #undef _GLIBCXX_HAVE__MODFF */ + +/* Define to 1 if you have the `_modfl' function. */ +/* #undef _GLIBCXX_HAVE__MODFL */ + +/* Define to 1 if you have the `_powf' function. */ +/* #undef _GLIBCXX_HAVE__POWF */ + +/* Define to 1 if you have the `_powl' function. */ +/* #undef _GLIBCXX_HAVE__POWL */ + +/* Define to 1 if you have the `_qfpclass' function. */ +/* #undef _GLIBCXX_HAVE__QFPCLASS */ + +/* Define to 1 if you have the `_sincos' function. */ +/* #undef _GLIBCXX_HAVE__SINCOS */ + +/* Define to 1 if you have the `_sincosf' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSF */ + +/* Define to 1 if you have the `_sincosl' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSL */ + +/* Define to 1 if you have the `_sinf' function. */ +/* #undef _GLIBCXX_HAVE__SINF */ + +/* Define to 1 if you have the `_sinhf' function. */ +/* #undef _GLIBCXX_HAVE__SINHF */ + +/* Define to 1 if you have the `_sinhl' function. */ +/* #undef _GLIBCXX_HAVE__SINHL */ + +/* Define to 1 if you have the `_sinl' function. */ +/* #undef _GLIBCXX_HAVE__SINL */ + +/* Define to 1 if you have the `_sqrtf' function. */ +/* #undef _GLIBCXX_HAVE__SQRTF */ + +/* Define to 1 if you have the `_sqrtl' function. */ +/* #undef _GLIBCXX_HAVE__SQRTL */ + +/* Define to 1 if you have the `_tanf' function. */ +/* #undef _GLIBCXX_HAVE__TANF */ + +/* Define to 1 if you have the `_tanhf' function. */ +/* #undef _GLIBCXX_HAVE__TANHF */ + +/* Define to 1 if you have the `_tanhl' function. */ +/* #undef _GLIBCXX_HAVE__TANHL */ + +/* Define to 1 if you have the `_tanl' function. */ +/* #undef _GLIBCXX_HAVE__TANL */ + +/* Define to 1 if you have the `__signbit' function. */ +#define _GLIBCXX_HAVE___SIGNBIT 1 + +/* Define to 1 if you have the `__signbitf' function. */ +#define _GLIBCXX_HAVE___SIGNBITF 1 + +/* Define to 1 if you have the `__signbitl' function. */ +#define _GLIBCXX_HAVE___SIGNBITL 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define _GLIBCXX_PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define _GLIBCXX_PACKAGE_NAME "package-unused" + +/* Define to the full name and version of this package. */ +#define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" + +/* Define to the one symbol short name of this package. */ +#define _GLIBCXX_PACKAGE_TARNAME "libstdc++" + +/* Define to the version of this package. */ +#define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if a full hosted library is built, or 0 if freestanding. */ +#define _GLIBCXX_HOSTED 1 + +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +/* #undef _GLIBCXX_SJLJ_EXCEPTIONS */ +// +// Systems that have certain non-standard functions prefixed with an +// underscore, we'll handle those here. Must come after config.h.in. +// +#if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) +# define _GLIBCXX_HAVE_ISNAN 1 +# define isnan _isnan +#endif + +#if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) +# define _GLIBCXX_HAVE_ISNANF 1 +# define isnanf _isnanf +#endif + +#if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) +# define _GLIBCXX_HAVE_ISNANL 1 +# define isnanl _isnanl +#endif + +#if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) +# define _GLIBCXX_HAVE_ISINF 1 +# define isinf _isinf +#endif + +#if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) +# define _GLIBCXX_HAVE_ISINFF 1 +# define isinff _isinff +#endif + +#if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) +# define _GLIBCXX_HAVE_ISINFL 1 +# define isinfl _isinfl +#endif + +#if defined (_GLIBCXX_HAVE__COPYSIGN) && ! defined (_GLIBCXX_HAVE_COPYSIGN) +# define _GLIBCXX_HAVE_COPYSIGN 1 +# define copysign _copysign +#endif + +#if defined (_GLIBCXX_HAVE__COPYSIGNL) && ! defined (_GLIBCXX_HAVE_COPYSIGNL) +# define _GLIBCXX_HAVE_COPYSIGNL 1 +# define copysignl _copysignl +#endif + +#if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) +# define _GLIBCXX_HAVE_COSF 1 +# define cosf _cosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) +# define _GLIBCXX_HAVE_ACOSF 1 +# define acosf _acosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) +# define _GLIBCXX_HAVE_ACOSL 1 +# define acosl _acosl +#endif + +#if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) +# define _GLIBCXX_HAVE_ASINF 1 +# define asinf _asinf +#endif + +#if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) +# define _GLIBCXX_HAVE_ASINL 1 +# define asinl _asinl +#endif + +#if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) +# define _GLIBCXX_HAVE_ATANF 1 +# define atanf _atanf +#endif + +#if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) +# define _GLIBCXX_HAVE_ATANL 1 +# define atanl _atanl +#endif + +#if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) +# define _GLIBCXX_HAVE_CEILF 1 +# define aceil _ceilf +#endif + +#if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) +# define _GLIBCXX_HAVE_CEILL 1 +# define aceil _ceill +#endif + +#if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) +# define _GLIBCXX_HAVE_COSHF 1 +# define coshf _coshf +#endif + +#if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) +# define _GLIBCXX_HAVE_COSL 1 +# define cosl _cosl +#endif + +#if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) +# define _GLIBCXX_HAVE_LOGF 1 +# define logf _logf +#endif + +#if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) +# define _GLIBCXX_HAVE_COSHL 1 +# define coshl _coshl +#endif + +#if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) +# define _GLIBCXX_HAVE_EXPF 1 +# define expf _expf +#endif + +#if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) +# define _GLIBCXX_HAVE_EXPL 1 +# define expl _expl +#endif + +#if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) +# define _GLIBCXX_HAVE_FABSF 1 +# define fabsf _fabsf +#endif + +#if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) +# define _GLIBCXX_HAVE_FABSL 1 +# define fabsl _fabsl +#endif + +#if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) +# define _GLIBCXX_HAVE_FLOORF 1 +# define floorf _floorf +#endif + +#if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) +# define _GLIBCXX_HAVE_FLOORL 1 +# define floorl _floorl +#endif + +#if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) +# define _GLIBCXX_HAVE_FMODF 1 +# define fmodf _fmodf +#endif + +#if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) +# define _GLIBCXX_HAVE_FMODL 1 +# define fmodl _fmodl +#endif + +#if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) +# define _GLIBCXX_HAVE_FREXPF 1 +# define frexpf _frexpf +#endif + +#if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) +# define _GLIBCXX_HAVE_FREXPL 1 +# define frexpl _frexpl +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) +# define _GLIBCXX_HAVE_LDEXPF 1 +# define ldexpf _ldexpf +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) +# define _GLIBCXX_HAVE_LDEXPL 1 +# define ldexpl _ldexpl +#endif + +#if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) +# define _GLIBCXX_HAVE_LOG10F 1 +# define log10f _log10f +#endif + +#if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) +# define _GLIBCXX_HAVE_LOGL 1 +# define logl _logl +#endif + +#if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) +# define _GLIBCXX_HAVE_POWF 1 +# define powf _powf +#endif + +#if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) +# define _GLIBCXX_HAVE_LOG10L 1 +# define log10l _log10l +#endif + +#if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) +# define _GLIBCXX_HAVE_MODF 1 +# define modf _modf +#endif + +#if defined (_GLIBCXX_HAVE__MODL) && ! defined (_GLIBCXX_HAVE_MODL) +# define _GLIBCXX_HAVE_MODL 1 +# define modl _modl +#endif + +#if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) +# define _GLIBCXX_HAVE_SINF 1 +# define sinf _sinf +#endif + +#if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) +# define _GLIBCXX_HAVE_POWL 1 +# define powl _powl +#endif + +#if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) +# define _GLIBCXX_HAVE_SINHF 1 +# define sinhf _sinhf +#endif + +#if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) +# define _GLIBCXX_HAVE_SINL 1 +# define sinl _sinl +#endif + +#if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) +# define _GLIBCXX_HAVE_SQRTF 1 +# define sqrtf _sqrtf +#endif + +#if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) +# define _GLIBCXX_HAVE_SINHL 1 +# define sinhl _sinhl +#endif + +#if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) +# define _GLIBCXX_HAVE_SQRTL 1 +# define sqrtl _sqrtl +#endif + +#if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) +# define _GLIBCXX_HAVE_TANHF 1 +# define tanhf _tanhf +#endif + +#if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) +# define _GLIBCXX_HAVE_STRTOF 1 +# define strtof _strtof +#endif + +#if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) +# define _GLIBCXX_HAVE_TANHL 1 +# define tanhl _tanhl +#endif + +#if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) +# define _GLIBCXX_HAVE_STRTOLD 1 +# define strtold _strtold +#endif + +#if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) +# define _GLIBCXX_HAVE_SINCOS 1 +# define sincos _sincos +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) +# define _GLIBCXX_HAVE_SINCOSF 1 +# define sincosf _sincosf +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) +# define _GLIBCXX_HAVE_SINCOSL 1 +# define sincosl _sincosl +#endif + +#if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) +# define _GLIBCXX_HAVE_FINITE 1 +# define finite _finite +#endif + +#if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) +# define _GLIBCXX_HAVE_FINITEF 1 +# define finitef _finitef +#endif + +#if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) +# define _GLIBCXX_HAVE_FINITEL 1 +# define finitel _finitel +#endif + +#if defined (_GLIBCXX_HAVE__QFINITE) && ! defined (_GLIBCXX_HAVE_QFINITE) +# define _GLIBCXX_HAVE_QFINITE 1 +# define qfinite _qfinite +#endif + +#if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) +# define _GLIBCXX_HAVE_FPCLASS 1 +# define fpclass _fpclass +#endif + +#if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) +# define _GLIBCXX_HAVE_QFPCLASS 1 +# define qfpclass _qfpclass +#endif + +#endif // _CXXCONFIG_ diff --git a/src/include.new/c++/3.4/bits/c++io.h b/src/include.new/c++/3.4/bits/c++io.h new file mode 100644 index 0000000..5659c13 --- /dev/null +++ b/src/include.new/c++/3.4/bits/c++io.h @@ -0,0 +1,86 @@ +// underlying io library -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// c_io_stdio.h - Defines for using "C" stdio.h + +#ifndef _C_IO_STDIO_H +#define _C_IO_STDIO_H 1 + +#include +#include +#include + +namespace std +{ + typedef __gthread_mutex_t __c_lock; + + // for basic_file.h + typedef FILE __c_file; + + // XXX GLIBCXX_ABI Deprecated + // for ios_base.h + struct __ios_flags + { + typedef short __int_type; + + static const __int_type _S_boolalpha = 0x0001; + static const __int_type _S_dec = 0x0002; + static const __int_type _S_fixed = 0x0004; + static const __int_type _S_hex = 0x0008; + static const __int_type _S_internal = 0x0010; + static const __int_type _S_left = 0x0020; + static const __int_type _S_oct = 0x0040; + static const __int_type _S_right = 0x0080; + static const __int_type _S_scientific = 0x0100; + static const __int_type _S_showbase = 0x0200; + static const __int_type _S_showpoint = 0x0400; + static const __int_type _S_showpos = 0x0800; + static const __int_type _S_skipws = 0x1000; + static const __int_type _S_unitbuf = 0x2000; + static const __int_type _S_uppercase = 0x4000; + static const __int_type _S_adjustfield = 0x0020 | 0x0080 | 0x0010; + static const __int_type _S_basefield = 0x0002 | 0x0040 | 0x0008; + static const __int_type _S_floatfield = 0x0100 | 0x0004; + + // 27.4.2.1.3 Type ios_base::iostate + static const __int_type _S_badbit = 0x01; + static const __int_type _S_eofbit = 0x02; + static const __int_type _S_failbit = 0x04; + + // 27.4.2.1.4 Type openmode + static const __int_type _S_app = 0x01; + static const __int_type _S_ate = 0x02; + static const __int_type _S_bin = 0x04; + static const __int_type _S_in = 0x08; + static const __int_type _S_out = 0x10; + static const __int_type _S_trunc = 0x20; + }; +} + +#endif diff --git a/src/include.new/c++/3.4/bits/c++locale.h b/src/include.new/c++/3.4/bits/c++locale.h new file mode 100644 index 0000000..7b2282b --- /dev/null +++ b/src/include.new/c++/3.4/bits/c++locale.h @@ -0,0 +1,86 @@ +// Wrapper for underlying C-language localization -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.8 Standard locale categories. +// + +// Written by Benjamin Kosnik + +#ifndef _C_LOCALE_H +#define _C_LOCALE_H 1 + +#pragma GCC system_header + +#include +#include // get std::strlen +#include // get std::snprintf or std::sprintf + +#define _GLIBCXX_NUM_CATEGORIES 0 + +namespace std +{ + typedef int* __c_locale; + + // Convert numeric value of type _Tv to string and return length of + // string. If snprintf is available use it, otherwise fall back to + // the unsafe sprintf which, in general, can be dangerous and should + // be avoided. + template + int + __convert_from_v(char* __out, + const int __size __attribute__((__unused__)), + const char* __fmt, + _Tv __v, const __c_locale&, int __prec) + { + char* __old = std::setlocale(LC_NUMERIC, NULL); + char* __sav = NULL; + if (std::strcmp(__old, "C")) + { + __sav = new char[std::strlen(__old) + 1]; + std::strcpy(__sav, __old); + std::setlocale(LC_NUMERIC, "C"); + } + +#ifdef _GLIBCXX_USE_C99 + const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v); +#else + const int __ret = std::sprintf(__out, __fmt, __prec, __v); +#endif + + if (__sav) + { + std::setlocale(LC_NUMERIC, __sav); + delete [] __sav; + } + return __ret; + } +} + +#endif diff --git a/src/include.new/c++/3.4/bits/c++locale_internal.h b/src/include.new/c++/3.4/bits/c++locale_internal.h new file mode 100644 index 0000000..fb26352 --- /dev/null +++ b/src/include.new/c++/3.4/bits/c++locale_internal.h @@ -0,0 +1,30 @@ +// Locale internal implementation header -*- C++ -*- + +// Copyright (C) 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// The generic locale code doesn't need to do anything here (yet) diff --git a/src/include.new/c++/3.4/bits/char_traits.h b/src/include.new/c++/3.4/bits/char_traits.h new file mode 100644 index 0000000..323fdfb --- /dev/null +++ b/src/include.new/c++/3.4/bits/char_traits.h @@ -0,0 +1,376 @@ +// Character Traits for use by standard string and iostream -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file char_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CHAR_TRAITS_H +#define _CHAR_TRAITS_H 1 + +#pragma GCC system_header + +#include // For memmove, memset, memchr +#include // For copy, lexicographical_compare, fill_n +#include // For streampos + +namespace __gnu_cxx +{ + /** + * @brief Mapping from character type to associated types. + * + * + * @note This is an implementation class for the generic version + * of char_traits. It defines int_type, off_type, pos_type, and + * state_type. By default these are unsigned long, streamoff, + * streampos, and mbstate_t. Users who need a different set of + * types, but who don't need to change the definitions of any function + * defined in char_traits, can specialize __gnu_cxx::_Char_types + * while leaving __gnu_cxx::char_traits alone. */ + template + struct _Char_types + { + typedef unsigned long int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + typedef std::mbstate_t state_type; + }; + + + /** + * @brief Base class used to implement std::char_traits. + * + * @note For any given actual character type, this definition is + * probably wrong. (Most of the member functions are likely to be + * right, but the int_type and state_type typedefs, and the eof() + * member function, are likely to be wrong.) The reason this class + * exists is so users can specialize it. Classes in namespace std + * may not be specialized for fundamentl types, but classes in + * namespace __gnu_cxx may be. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. */ + template + struct char_traits + { + typedef _CharT char_type; + typedef typename _Char_types<_CharT>::int_type int_type; + typedef typename _Char_types<_CharT>::pos_type pos_type; + typedef typename _Char_types<_CharT>::off_type off_type; + typedef typename _Char_types<_CharT>::state_type state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, std::size_t __n); + + static std::size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, std::size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + assign(char_type* __s, std::size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + static int_type + to_int_type(const char_type& __c) + { return static_cast(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast(EOF); } + + static int_type + not_eof(const int_type& __c) + { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } + }; + + template + int + char_traits<_CharT>:: + compare(const char_type* __s1, const char_type* __s2, std::size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } + + template + std::size_t + char_traits<_CharT>:: + length(const char_type* __p) + { + std::size_t __i = 0; + while (!eq(__p[__i], char_type())) + ++__i; + return __i; + } + + template + const typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + find(const char_type* __s, std::size_t __n, const char_type& __a) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (eq(__s[__i], __a)) + return __s + __i; + return 0; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + move(char_type* __s1, const char_type* __s2, std::size_t __n) + { + return static_cast<_CharT*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + copy(char_type* __s1, const char_type* __s2, std::size_t __n) + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + assign(char_type* __s, std::size_t __n, char_type __a) + { + std::fill_n(__s, __n, __a); + return __s; + } +} + +namespace std +{ + // 21.1 + /** + * @brief Basis for explicit traits specializations. + * + * @note For any given actual character type, this definition is + * probably wrong. Since this is just a thin wrapper around + * __gnu_cxx::char_traits, it is possible to achieve a more + * appropriate definition by specializing __gnu_cxx::char_traits. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. + */ + template + struct char_traits + : public __gnu_cxx::char_traits<_CharT> + { }; + + + /// 21.1.3.1 char_traits specializations + template<> + struct char_traits + { + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return strlen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return static_cast(memchr(__s, __a, __n)); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memmove(__s1, __s2, __n)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return static_cast(memset(__s, __a, __n)); } + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + // To keep both the byte 0xff and the eof symbol 0xffffffff + // from ending up as 0xffffffff. + static int_type + to_int_type(const char_type& __c) + { return static_cast(static_cast(__c)); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(EOF); } + + static int_type + not_eof(const int_type& __c) + { return (__c == eof()) ? 0 : __c; } + }; + + +#ifdef _GLIBCXX_USE_WCHAR_T + /// 21.1.3.2 char_traits specializations + template<> + struct char_traits + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return wcslen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return wmemchr(__s, __a, __n); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemmove(__s1, __s2, __n); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcpy(__s1, __s2, __n); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return wmemset(__s, __a, __n); } + + static char_type + to_char_type(const int_type& __c) { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(WEOF); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? 0 : __c; } + }; +#endif //_GLIBCXX_USE_WCHAR_T + + template + struct _Char_traits_match + { + _CharT _M_c; + _Char_traits_match(_CharT const& __c) : _M_c(__c) { } + + bool + operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); } + }; +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/cmath.tcc b/src/include.new/c++/3.4/bits/cmath.tcc new file mode 100644 index 0000000..d771467 --- /dev/null +++ b/src/include.new/c++/3.4/bits/cmath.tcc @@ -0,0 +1,54 @@ +// -*- C++ -*- C math library. + +// Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file was written by Gabriel Dos Reis + +#ifndef _GLIBCXX_CMATH_TCC +#define _GLIBCXX_CMATH_TCC 1 + +namespace std +{ + template + inline _Tp + __cmath_power(_Tp __x, unsigned int __n) + { + _Tp __y = __n % 2 ? __x : 1; + + while (__n >>= 1) + { + __x = __x * __x; + if (__n % 2) + __y = __y * __x; + } + + return __y; + } +} + +#endif diff --git a/src/include.new/c++/3.4/bits/codecvt.h b/src/include.new/c++/3.4/bits/codecvt.h new file mode 100644 index 0000000..d31ebf2 --- /dev/null +++ b/src/include.new/c++/3.4/bits/codecvt.h @@ -0,0 +1,478 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Written by Benjamin Kosnik + +/** @file codecvt.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CODECVT_H +#define _CODECVT_H 1 + +#pragma GCC system_header + + // 22.2.1.5 Template class codecvt + /// Base class for codecvt facet providing conversion result enum. + class codecvt_base + { + public: + enum result + { + ok, + partial, + error, + noconv + }; + }; + + // Template class __codecvt_abstract_base + // NB: An abstract base class that fills in the public inlines, so + // that the specializations don't have to re-copy the public + // interface. + /** + * @brief Common base for codecvt facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abstract stubs for the protected virtual + * functions. + */ + template + class __codecvt_abstract_base + : public locale::facet, public codecvt_base + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + // 22.2.1.5.1 codecvt members + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This is analogous to wcsrtombs. It does this by + * calling codecvt::do_out. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + return this->do_out(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + /** + * @brief Reset conversion state. + * + * Writes characters to output that would restore @a state to initial + * conditions. The idea is that if a partial conversion occurs, then + * the converting the characters written by this function would leave + * the state in initial conditions, rather than partial conversion + * state. It does this by calling codecvt::do_unshift(). + * + * For example, if 4 external characters always converted to 1 internal + * character, and input to in() had 6 external characters with state + * saved, this function would write two characters to the output and + * set the state to initialized conditions. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The result returned is a member of codecvt_base::result. If the + * state could be reset and data written, returns codecvt_base::ok. If + * no conversion is necessary, returns codecvt_base::noconv. If the + * output has insufficient space, returns codecvt_base::partial. + * Otherwise the reset failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + unshift(state_type& __state, extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { return this->do_unshift(__state, __to,__to_end,__to_next); } + + /** + * @brief Convert from external to internal character set. + * + * Converts input string of extern_type to output string of + * intern_type. This is analogous to mbsrtowcs. It does this by + * calling codecvt::do_in. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + return this->do_in(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + int + encoding() const throw() + { return this->do_encoding(); } + + bool + always_noconv() const throw() + { return this->do_always_noconv(); } + + int + length(state_type& __state, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return this->do_length(__state, __from, __end, __max); } + + int + max_length() const throw() + { return this->do_max_length(); } + + protected: + explicit + __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~__codecvt_abstract_base() { } + + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This function is a hook for derived classes to change + * the value returned. @see out for more information. + */ + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const = 0; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const = 0; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const = 0; + + virtual int + do_encoding() const throw() = 0; + + virtual bool + do_always_noconv() const throw() = 0; + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const = 0; + + virtual int + do_max_length() const throw() = 0; + }; + + // 22.2.1.5 Template class codecvt + // NB: Generic, mostly useless implementation. + template + class codecvt + : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template + locale::id codecvt<_InternT, _ExternT, _StateT>::id; + + // codecvt required specialization + template<> + class codecvt + : public __codecvt_abstract_base + { + public: + // Types: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + // codecvt required specialization + template<> + class codecvt + : public __codecvt_abstract_base + { + public: + // Types: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, + const extern_type* __from, const extern_type* __from_end, + const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual + int do_encoding() const throw(); + + virtual + bool do_always_noconv() const throw(); + + virtual + int do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; +#endif //_GLIBCXX_USE_WCHAR_T + + // 22.2.1.6 Template class codecvt_byname + template + class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> + { + public: + explicit + codecvt_byname(const char* __s, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_codecvt); + this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); + } + } + + protected: + virtual + ~codecvt_byname() { } + }; + + // Include host and configuration specific partial specializations + // with additional functionality, if possible. +#ifdef _GLIBCXX_USE_WCHAR_T + #include +#endif + +#endif // _CODECVT_H diff --git a/src/include.new/c++/3.4/bits/codecvt_specializations.h b/src/include.new/c++/3.4/bits/codecvt_specializations.h new file mode 100644 index 0000000..24db4c8 --- /dev/null +++ b/src/include.new/c++/3.4/bits/codecvt_specializations.h @@ -0,0 +1,38 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Warning: this file is not meant for user inclusion. Use . + +// Written by Benjamin Kosnik + +// XXX dummy file diff --git a/src/include.new/c++/3.4/bits/concept_check.h b/src/include.new/c++/3.4/bits/concept_check.h new file mode 100644 index 0000000..80c1439 --- /dev/null +++ b/src/include.new/c++/3.4/bits/concept_check.h @@ -0,0 +1,85 @@ +// Concept-checking control -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CONCEPT_CHECK_H +#define _CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include + +// All places in libstdc++-v3 where these are used, or /might/ be used, or +// don't need to be used, or perhaps /should/ be used, are commented with +// "concept requirements" (and maybe some more text). So grep like crazy +// if you're looking for additional places to use these. + +// Concept-checking code is off by default unless users turn it on via +// configure options or editing c++config.h. + +#ifndef _GLIBCXX_CONCEPT_CHECKS + +#define __glibcxx_function_requires(...) +#define __glibcxx_class_requires(_a,_b) +#define __glibcxx_class_requires2(_a,_b,_c) +#define __glibcxx_class_requires3(_a,_b,_c,_d) +#define __glibcxx_class_requires4(_a,_b,_c,_d,_e) + +#else // the checks are on + +#include + +// Note that the obvious and elegant approach of +// +//#define glibcxx_function_requires(C) boost::function_requires< boost::C >() +// +// won't work due to concept templates with more than one parameter, e.g., +// BinaryPredicateConcept. The preprocessor tries to split things up on +// the commas in the template argument list. We can't use an inner pair of +// parenthesis to hide the commas, because "boost::(Temp)" isn't +// a valid instantiation pattern. Thus, we steal a feature from C99. + +#define __glibcxx_function_requires(...) \ + __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >(); +#define __glibcxx_class_requires(_a,_C) \ + _GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C); +#define __glibcxx_class_requires2(_a,_b,_C) \ + _GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); +#define __glibcxx_class_requires3(_a,_b,_c,_C) \ + _GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); +#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \ + _GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); + +#endif // enable/disable + +#endif // _GLIBCXX_CONCEPT_CHECK diff --git a/src/include.new/c++/3.4/bits/concurrence.h b/src/include.new/c++/3.4/bits/concurrence.h new file mode 100644 index 0000000..c436a1b --- /dev/null +++ b/src/include.new/c++/3.4/bits/concurrence.h @@ -0,0 +1,95 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CONCURRENCE_H +#define _CONCURRENCE_H 1 + +// GCC's thread abstraction layer +#include "bits/gthr.h" + +#if __GTHREADS + +# ifdef __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) \ +__gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# else +// Implies __GTHREAD_MUTEX_INIT_FUNCTION +struct __glibcxx_mutex : public __gthread_mutex_t +{ + __glibcxx_mutex() { __GTHREAD_MUTEX_INIT_FUNCTION(this); } +}; + +# define __glibcxx_mutex_type __glibcxx_mutex +# define __glibcxx_mutex_define_initialized(NAME) \ +__glibcxx_mutex NAME +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# endif + +# define __glibcxx_mutex_unlock(NAME) __gthread_mutex_unlock(&NAME) + +#else + +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) __gthread_mutex_t NAME +# define __glibcxx_mutex_lock(NAME) +# define __glibcxx_mutex_unlock(NAME) + +#endif + +namespace __gnu_cxx +{ + typedef __glibcxx_mutex_type mutex_type; + + // Scoped lock idiom. + // Acquire the mutex here with a constructor call, then release with + // the destructor call in accordance with RAII style. + class lock + { + // Externally defined and initialized. + mutex_type& device; + + public: + explicit lock(mutex_type& name) : device(name) + { __glibcxx_mutex_lock(device); } + + ~lock() throw() + { __glibcxx_mutex_unlock(device); } + + private: + lock(const lock&); + lock& operator=(const lock&); + }; +} + +#endif diff --git a/src/include.new/c++/3.4/bits/cpp_type_traits.h b/src/include.new/c++/3.4/bits/cpp_type_traits.h new file mode 100644 index 0000000..d4e4ea0 --- /dev/null +++ b/src/include.new/c++/3.4/bits/cpp_type_traits.h @@ -0,0 +1,345 @@ +// The -*- C++ -*- type traits classes for internal use in libstdc++ + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file cpp_type_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CPP_TYPE_TRAITS_H +#define _CPP_TYPE_TRAITS_H 1 + +#pragma GCC system_header + +// +// This file provides some compile-time information about various types. +// These representations were designed, on purpose, to be constant-expressions +// and not types as found in . In particular, they +// can be used in control structures and the optimizer hopefully will do +// the obvious thing. +// +// Why integral expressions, and not functions nor types? +// Firstly, these compile-time entities are used as template-arguments +// so function return values won't work: We need compile-time entities. +// We're left with types and constant integral expressions. +// Secondly, from the point of view of ease of use, type-based compile-time +// information is -not- *that* convenient. On has to write lots of +// overloaded functions and to hope that the compiler will select the right +// one. As a net effect, the overall structure isn't very clear at first +// glance. +// Thirdly, partial ordering and overload resolution (of function templates) +// is highly costly in terms of compiler-resource. It is a Good Thing to +// keep these resource consumption as least as possible. +// +// See valarray_array.h for a case use. +// +// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. +// + +// NB: g++ can not compile these if declared within the class +// __is_pod itself. +namespace __gnu_internal +{ + typedef char __one; + typedef char __two[2]; + + template + __one __test_type (int _Tp::*); + template + __two& __test_type (...); +} // namespace __gnu_internal + +namespace std +{ + // Compare for equality of types. + template + struct __are_same + { + enum + { + _M_type = 0 + }; + }; + + template + struct __are_same<_Tp, _Tp> + { + enum + { + _M_type = 1 + }; + }; + + // Define a nested type if some predicate holds. + template + struct __enable_if + { + }; + + template + struct __enable_if<_Tp, true> + { + typedef _Tp _M_type; + }; + + // Holds if the template-argument is a void type. + template + struct __is_void + { + enum + { + _M_type = 0 + }; + }; + + template<> + struct __is_void + { + enum + { + _M_type = 1 + }; + }; + + // + // Integer types + // + template + struct __is_integer + { + enum + { + _M_type = 0 + }; + }; + + // Thirteen specializations (yes there are eleven standard integer + // types; 'long long' and 'unsigned long long' are supported as + // extensions) + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + +# ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; +# endif + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + // + // Floating point types + // + template + struct __is_floating + { + enum + { + _M_type = 0 + }; + }; + + // three specializations (float, double and 'long double') + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + // + // An arithmetic type is an integer type or a floating point type + // + template + struct __is_arithmetic + { + enum + { + _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type + }; + }; + + // + // A fundamental type is `void' or and arithmetic type + // + template + struct __is_fundamental + { + enum + { + _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type + }; + }; + + // + // For the immediate use, the following is a good approximation + // + template + struct __is_pod + { + enum + { + _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0)) + != sizeof(__gnu_internal::__one)) + }; + }; + +} // namespace std + +#endif //_CPP_TYPE_TRAITS_H diff --git a/src/include.new/c++/3.4/bits/ctype_base.h b/src/include.new/c++/3.4/bits/ctype_base.h new file mode 100644 index 0000000..f44a7c7 --- /dev/null +++ b/src/include.new/c++/3.4/bits/ctype_base.h @@ -0,0 +1,76 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2000, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Information as gleaned from /usr/include/ctype.h on FreeBSD 3.4, +// 4.0 and all versions of the CVS managed file at: +// :pserver:anoncvs@anoncvs.freebsd.org:/home/ncvs/src/include/ctype.h + + struct ctype_base + { + // Non-standard typedefs. + typedef const int* __to_type; + + // NB: Offsets into ctype::_M_table force a particular size + // on the mask type. Because of this, we don't use an enum. + typedef unsigned long mask; +#ifdef _CTYPE_S + // FreeBSD 4.0 uses this style of define. + static const mask upper = _CTYPE_U; + static const mask lower = _CTYPE_L; + static const mask alpha = _CTYPE_A; + static const mask digit = _CTYPE_D; + static const mask xdigit = _CTYPE_X; + static const mask space = _CTYPE_S; + static const mask print = _CTYPE_R; + static const mask graph = _CTYPE_A | _CTYPE_D | _CTYPE_P; + static const mask cntrl = _CTYPE_C; + static const mask punct = _CTYPE_P; + static const mask alnum = _CTYPE_A | _CTYPE_D; +#else + // Older versions, including Free BSD 3.4, use this style of define. + static const mask upper = _U; + static const mask lower = _L; + static const mask alpha = _A; + static const mask digit = _D; + static const mask xdigit = _X; + static const mask space = _S; + static const mask print = _R; + static const mask graph = _A | _D | _P; + static const mask cntrl = _C; + static const mask punct = _P; + static const mask alnum = _A | _D; +#endif + }; + + + diff --git a/src/include.new/c++/3.4/bits/ctype_inline.h b/src/include.new/c++/3.4/bits/ctype_inline.h new file mode 100644 index 0000000..d69324a --- /dev/null +++ b/src/include.new/c++/3.4/bits/ctype_inline.h @@ -0,0 +1,106 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2000, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) +// functions go in ctype.cc + + bool + ctype:: + is(mask __m, char __c) const + { + if (_M_table) + return _M_table[static_cast(__c)] & __m; + else + return __istype(__c, __m); + } + + const char* + ctype:: + is(const char* __low, const char* __high, mask* __vec) const + { + if (_M_table) + while (__low < __high) + *__vec++ = _M_table[static_cast(*__low++)]; + else + for (;__low < __high; ++__vec, ++__low) + { +#if defined (_CTYPE_S) || defined (__istype) + *__vec = __maskrune (*__low, upper | lower | alpha | digit | xdigit + | space | print | graph | cntrl | punct | alnum); +#else + mask __m = 0; + if (this->is(upper, *__low)) __m |= upper; + if (this->is(lower, *__low)) __m |= lower; + if (this->is(alpha, *__low)) __m |= alpha; + if (this->is(digit, *__low)) __m |= digit; + if (this->is(xdigit, *__low)) __m |= xdigit; + if (this->is(space, *__low)) __m |= space; + if (this->is(print, *__low)) __m |= print; + if (this->is(graph, *__low)) __m |= graph; + if (this->is(cntrl, *__low)) __m |= cntrl; + if (this->is(punct, *__low)) __m |= punct; + // Do not include explicit line for alnum mask since it is a + // pure composite of masks on FreeBSD. + *__vec = __m; +#endif + } + return __high; + } + + const char* + ctype:: + scan_is(mask __m, const char* __low, const char* __high) const + { + if (_M_table) + while (__low < __high + && !(_M_table[static_cast(*__low)] & __m)) + ++__low; + else + while (__low < __high && !this->is(__m, *__low)) + ++__low; + return __low; + } + + const char* + ctype:: + scan_not(mask __m, const char* __low, const char* __high) const + { + if (_M_table) + while (__low < __high + && (_M_table[static_cast(*__low)] & __m) != 0) + ++__low; + else + while (__low < __high && this->is(__m, *__low) != 0) + ++__low; + return __low; + } diff --git a/src/include.new/c++/3.4/bits/ctype_noninline.h b/src/include.new/c++/3.4/bits/ctype_noninline.h new file mode 100644 index 0000000..ec5b575 --- /dev/null +++ b/src/include.new/c++/3.4/bits/ctype_noninline.h @@ -0,0 +1,91 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Information as gleaned from /usr/include/ctype.h + + const ctype_base::mask* + ctype::classic_table() throw() + { return 0; } + + ctype::ctype(__c_locale, const mask* __table, bool __del, + size_t __refs) + : facet(__refs), _M_del(__table != 0 && __del), + _M_toupper(NULL), _M_tolower(NULL), + _M_table(__table ? __table : classic_table()) + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } + + ctype::ctype(const mask* __table, bool __del, size_t __refs) + : facet(__refs), _M_del(__table != 0 && __del), + _M_toupper(NULL), _M_tolower(NULL), + _M_table(__table ? __table : classic_table()) + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } + + char + ctype::do_toupper(char __c) const + { return ::toupper((int) __c); } + + const char* + ctype::do_toupper(char* __low, const char* __high) const + { + while (__low < __high) + { + *__low = ::toupper((int) *__low); + ++__low; + } + return __high; + } + + char + ctype::do_tolower(char __c) const + { return ::tolower((int) __c); } + + const char* + ctype::do_tolower(char* __low, const char* __high) const + { + while (__low < __high) + { + *__low = ::tolower((int) *__low); + ++__low; + } + return __high; + } diff --git a/src/include.new/c++/3.4/bits/deque.tcc b/src/include.new/c++/3.4/bits/deque.tcc new file mode 100644 index 0000000..e8e0438 --- /dev/null +++ b/src/include.new/c++/3.4/bits/deque.tcc @@ -0,0 +1,719 @@ +// Deque implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file deque.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_TCC +#define _DEQUE_TCC 1 + +namespace _GLIBCXX_STD +{ + template + deque<_Tp,_Alloc>& + deque<_Tp,_Alloc>:: + operator=(const deque& __x) + { + const size_type __len = size(); + if (&__x != this) + { + if (__len >= __x.size()) + erase(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start), + this->_M_impl._M_finish); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); + } + } + return *this; + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + insert(iterator position, const value_type& __x) + { + if (position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(__x); + return this->_M_impl._M_start; + } + else if (position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(__x); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(position, __x); + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + erase(iterator __position) + { + iterator __next = __position; + ++__next; + size_type __index = __position - this->_M_impl._M_start; + if (__index < (size() >> 1)) + { + std::copy_backward(this->_M_impl._M_start, __position, __next); + pop_front(); + } + else + { + std::copy(__next, this->_M_impl._M_finish, __position); + pop_back(); + } + return this->_M_impl._M_start + __index; + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == this->_M_impl._M_start && __last == this->_M_impl._M_finish) + { + clear(); + return this->_M_impl._M_finish; + } + else + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - this->_M_impl._M_start; + if (static_cast(__elems_before) < (size() - __n) / 2) + { + std::copy_backward(this->_M_impl._M_start, __first, __last); + iterator __new_start = this->_M_impl._M_start + __n; + std::_Destroy(this->_M_impl._M_start, __new_start); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node); + this->_M_impl._M_start = __new_start; + } + else + { + std::copy(__last, this->_M_impl._M_finish, __first); + iterator __new_finish = this->_M_impl._M_finish - __n; + std::_Destroy(__new_finish, this->_M_impl._M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __new_finish; + } + return this->_M_impl._M_start + __elems_before; + } + } + + template + void + deque<_Tp,_Alloc>:: + clear() + { + for (_Map_pointer __node = this->_M_impl._M_start._M_node + 1; + __node < this->_M_impl._M_finish._M_node; + ++__node) + { + std::_Destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } + + if (this->_M_impl._M_start._M_node != this->_M_impl._M_finish._M_node) + { + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_start._M_last); + std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur); + _M_deallocate_node(this->_M_impl._M_finish._M_first); + } + else + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_finish._M_cur); + + this->_M_impl._M_finish = this->_M_impl._M_start; + } + + template + template + void + deque<_Tp,_Alloc> + ::_M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void + deque<_Tp,_Alloc>:: + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_fill(__new_start, this->_M_impl._M_start, __x); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __n, __x); + } + + template + void + deque<_Tp,_Alloc>:: + _M_fill_initialize(const value_type& __value) + { + _Map_pointer __cur; + try + { + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + std::uninitialized_fill(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + __value); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur)); + __throw_exception_again; + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + this->_M_initialize_map(0); + try + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + catch(...) + { + clear(); + __throw_exception_again; + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_initialize_map(__n); + + _Map_pointer __cur_node; + try + { + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; + ++__cur_node) + { + _ForwardIterator __mid = __first; + std::advance(__mid, _S_buffer_size()); + std::uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish._M_first); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. + template + void + deque<_Tp,_Alloc>:: + _M_push_back_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. + template + void + deque<_Tp,_Alloc>:: + _M_push_front_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + std::_Construct(this->_M_impl._M_start._M_cur, __t_copy); + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. + template + void deque<_Tp,_Alloc>:: + _M_pop_back_aux() + { + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + std::_Destroy(this->_M_impl._M_finish._M_cur); + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. Note that + // if the deque has at least one element (a precondition for this member + // function), and if _M_impl._M_start._M_cur == _M_impl._M_start._M_last, then the deque + // must have at least two nodes. + template + void deque<_Tp,_Alloc>:: + _M_pop_front_aux() + { + std::_Destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_insert_aux(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) + { std::copy(__first, __last, std::inserter(*this, __pos)); } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + size_type __n = std::distance(__first, __last); + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_copy(__first, __last, __new_start); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __first, __last, __n); + } + + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, const value_type& __x) + { + difference_type __index = __pos - this->_M_impl._M_start; + value_type __x_copy = __x; // XXX copy + if (static_cast(__index) < size() / 2) + { + push_front(front()); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::copy(__front2, __pos1, __front1); + } + else + { + push_back(back()); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; + } + + template + void + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) + { + const difference_type __elems_before = __pos - this->_M_impl._M_start; + size_type __length = this->size(); + value_type __x_copy = __x; + if (__elems_before < difference_type(__length / 2)) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos, + __new_start, + this->_M_impl._M_start, __x_copy); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_copy(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n) + { + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; + size_type __length = size(); + if (static_cast(__elemsbefore) < __length / 2) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_copy_copy(this->_M_impl._M_start, __pos, + __first, __mid, __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = this->_M_impl._M_finish - __elemsafter; + try + { + if (__elemsafter > difference_type(__n)) + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_copy(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_new_elements_at_front(size_type __new_elems) + { + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); + __throw_exception_again; + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_new_elements_at_back(size_type __new_elems) + { + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); + __throw_exception_again; + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) + { + size_type __old_num_nodes + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) + { + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + else + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else + { + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, + __nodes_to_add) + 2; + + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; + } + + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + } +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/fstream.tcc b/src/include.new/c++/3.4/bits/fstream.tcc new file mode 100644 index 0000000..3b433ea --- /dev/null +++ b/src/include.new/c++/3.4/bits/fstream.tcc @@ -0,0 +1,892 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _FSTREAM_TCC +#define _FSTREAM_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + void + basic_filebuf<_CharT, _Traits>:: + _M_allocate_internal_buffer() + { + // Allocate internal buffer only if one doesn't already exist + // (either allocated or provided by the user via setbuf). + if (!_M_buf_allocated && !this->_M_buf) + { + this->_M_buf = new char_type[this->_M_buf_size]; + _M_buf_allocated = true; + } + } + + template + void + basic_filebuf<_CharT, _Traits>:: + _M_destroy_internal_buffer() throw() + { + if (_M_buf_allocated) + { + delete [] this->_M_buf; + this->_M_buf = NULL; + _M_buf_allocated = false; + } + delete [] _M_ext_buf; + _M_ext_buf = NULL; + _M_ext_buf_size = 0; + _M_ext_next = NULL; + _M_ext_end = NULL; + } + + template + basic_filebuf<_CharT, _Traits>:: + basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), + _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), + _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ), + _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), + _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), + _M_ext_end(0) + { + if (has_facet<__codecvt_type>(this->_M_buf_locale)) + _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); + } + + template + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + open(const char* __s, ios_base::openmode __mode) + { + __filebuf_type *__ret = NULL; + if (!this->is_open()) + { + _M_file.open(__s, __mode); + if (this->is_open()) + { + _M_allocate_internal_buffer(); + this->_M_mode = __mode; + + // Setup initial buffer to 'uncommitted' mode. + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + + // Reset to initial state. + _M_state_last = _M_state_cur = _M_state_beg; + + // 27.8.1.3,4 + if ((__mode & ios_base::ate) + && this->seekoff(0, ios_base::end, __mode) + == pos_type(off_type(-1))) + this->close(); + else + __ret = this; + } + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + close() throw() + { + __filebuf_type* __ret = NULL; + if (this->is_open()) + { + bool __testfail = false; + try + { + if (!_M_terminate_output()) + __testfail = true; + } + catch(...) + { __testfail = true; } + + // NB: Do this here so that re-opened filebufs will be cool... + this->_M_mode = ios_base::openmode(0); + this->_M_pback_init = false; + _M_destroy_internal_buffer(); + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + + if (!_M_file.close()) + __testfail = true; + + if (!__testfail) + __ret = this; + } + return __ret; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + showmanyc() + { + streamsize __ret = -1; + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && this->is_open()) + { + // For a stateful encoding (-1) the pending sequence might be just + // shift and unshift prefixes with no actual character. + __ret = this->egptr() - this->gptr(); + if (__check_facet(_M_codecvt).encoding() >= 0) + __ret += _M_file.showmanyc() / _M_codecvt->max_length(); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Check for pback madness, and if so swich back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = this->_M_buf_size > 1 + ? this->_M_buf_size - 1 : 1; + + // Will be set to true if ::read() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) + { + __ilen = _M_file.xsgetn(reinterpret_cast(this->eback()), + __buflen); + if (__ilen == 0) + __got_eof = true; + } + else + { + // Worst-case number of external bytes. + // XXX Not done encoding() == -1. + const int __enc = _M_codecvt->encoding(); + streamsize __blen; // Minimum buffer size. + streamsize __rlen; // Number of chars to read. + if (__enc > 0) + __blen = __rlen = __buflen * __enc; + else + { + __blen = __buflen + _M_codecvt->max_length() - 1; + __rlen = __buflen; + } + const streamsize __remainder = _M_ext_end - _M_ext_next; + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; + + // An imbue in 'read' mode implies first converting the external + // chars already present. + if (_M_reading && this->egptr() == this->eback() && __remainder) + __rlen = 0; + + // Allocate buffer if necessary and move unconverted + // bytes to front. + if (_M_ext_buf_size < __blen) + { + char* __buf = new char[__blen]; + if (__remainder) + std::memcpy(__buf, _M_ext_next, __remainder); + + delete [] _M_ext_buf; + _M_ext_buf = __buf; + _M_ext_buf_size = __blen; + } + else if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_state_last = _M_state_cur; + + do + { + if (__rlen > 0) + { + // Sanity check! + // This may fail if the return value of + // codecvt::max_length() is bogus. + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) + { + __throw_ios_failure(__N("basic_filebuf::underflow " + "codecvt::max_length() " + "is not valid")); + } + streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); + if (__elen == 0) + __got_eof = true; + else if (__elen == -1) + break; + _M_ext_end += __elen; + } + + char_type* __iend; + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, + _M_ext_end, _M_ext_next, this->eback(), + this->eback() + __buflen, __iend); + if (__r == codecvt_base::noconv) + { + size_t __avail = _M_ext_end - _M_ext_buf; + __ilen = std::min(__avail, __buflen); + traits_type::copy(this->eback(), + reinterpret_cast(_M_ext_buf), __ilen); + _M_ext_next = _M_ext_buf + __ilen; + } + else + __ilen = __iend - this->eback(); + + // _M_codecvt->in may return error while __ilen > 0: this is + // ok, and actually occurs in case of mixed encodings (e.g., + // XML files). + if (__r == codecvt_base::error) + break; + + __rlen = 1; + } + while (__ilen == 0 && !__got_eof); + } + + if (__ilen > 0) + { + _M_set_buffer(__ilen); + _M_reading = true; + __ret = traits_type::to_int_type(*this->gptr()); + } + else if (__got_eof) + { + // If the actual end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without an + // intervening seek. + _M_set_buffer(-1); + _M_reading = false; + // However, reaching it while looping on partial means that + // the file has got an incomplete character. + if (__r == codecvt_base::partial) + __throw_ios_failure(__N("basic_filebuf::underflow " + "incomplete character in file")); + } + else if (__r == codecvt_base::error) + __throw_ios_failure(__N("basic_filebuf::underflow " + "invalid byte sequence in file")); + else + __throw_ios_failure(__N("basic_filebuf::underflow " + "error reading the file")); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + pbackfail(int_type __i) + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Remember whether the pback buffer is active, otherwise below + // we may try to store in it a second char (libstdc++/9761). + const bool __testpb = this->_M_pback_init; + const bool __testeof = traits_type::eq_int_type(__i, __ret); + int_type __tmp; + if (this->eback() < this->gptr()) + { + this->gbump(-1); + __tmp = traits_type::to_int_type(*this->gptr()); + } + else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) + { + __tmp = this->underflow(); + if (traits_type::eq_int_type(__tmp, __ret)) + return __ret; + } + else + { + // At the beginning of the buffer, need to make a + // putback position available. But the seek may fail + // (f.i., at the beginning of a file, see + // libstdc++/9439) and in that case we return + // traits_type::eof(). + return __ret; + } + + // Try to put back __i into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) + __ret = __i; + else if (__testeof) + __ret = traits_type::not_eof(__i); + else if (!__testpb) + { + _M_create_pback(); + _M_reading = true; + *this->gptr() = traits_type::to_char_type(__i); + __ret = __i; + } + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = this->_M_mode & ios_base::out; + if (__testout && !_M_reading) + { + if (this->pbase() < this->pptr()) + { + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_M_convert_to_external(this->pbase(), + this->pptr() - this->pbase())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (this->_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + __ret = traits_type::not_eof(__c); + } + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _M_convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } + } + return __ret; + } + + template + bool + basic_filebuf<_CharT, _Traits>:: + _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) + { + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) + { + __elen = _M_file.xsputn(reinterpret_cast(__ibuf), __ilen); + __plen = __ilen; + } + else + { + // Worst-case number of external bytes needed. + // XXX Not done encoding() == -1. + streamsize __blen = __ilen * _M_codecvt->max_length(); + char* __buf = static_cast(__builtin_alloca(__blen)); + + char* __bend; + const char_type* __iend; + codecvt_base::result __r; + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, + __iend, __buf, __buf + __blen, __bend); + + if (__r == codecvt_base::ok || __r == codecvt_base::partial) + __blen = __bend - __buf; + else if (__r == codecvt_base::noconv) + { + // Same as the always_noconv case above. + __buf = reinterpret_cast(__ibuf); + __blen = __ilen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + + __elen = _M_file.xsputn(__buf, __blen); + __plen = __blen; + + // Try once more for partial conversions. + if (__r == codecvt_base::partial && __elen == __plen) + { + const char_type* __iresume = __iend; + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); + if (__r != codecvt_base::error) + { + __rlen = __bend - __buf; + __elen = _M_file.xsputn(__buf, __rlen); + __plen = __rlen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + } + } + return __elen == __plen; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsgetn(_CharT* __s, streamsize __n) + { + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (this->_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = this->_M_mode & ios_base::in; + const streamsize __buflen = this->_M_buf_size > 1 ? this->_M_buf_size - 1 + : 1; + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin && !_M_writing) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + // Need to loop in case of short reads (relatively common + // with pipes). + streamsize __len; + for (;;) + { + __len = _M_file.xsgetn(reinterpret_cast(__s), + __n); + if (__len == -1) + __throw_ios_failure(__N("basic_filebuf::xsgetn " + "error reading the file")); + if (__len == 0) + break; + + __n -= __len; + __ret += __len; + if (__n == 0) + break; + + __s += __len; + } + + if (__n == 0) + { + _M_set_buffer(0); + _M_reading = true; + } + else if (__len == 0) + { + // If end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without + // an intervening seek. + _M_set_buffer(-1); + _M_reading = false; + } + } + else + __ret += __streambuf_type::xsgetn(__s, __n); + + return __ret; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsputn(const _CharT* __s, streamsize __n) + { + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = this->_M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) + { + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); + + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && this->_M_buf_size > 1) + __bufavail = this->_M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast(this->pbase()); + __ret = _M_file.xsputn_2(__buf, __buffill, + reinterpret_cast(__s), + __n); + if (__ret == __buffill + __n) + { + _M_set_buffer(0); + _M_writing = true; + } + if (__ret > __buffill) + __ret -= __buffill; + else + __ret = 0; + } + else + __ret = __streambuf_type::xsputn(__s, __n); + } + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::__streambuf_type* + basic_filebuf<_CharT, _Traits>:: + setbuf(char_type* __s, streamsize __n) + { + if (!this->is_open()) + if (__s == 0 && __n == 0) + this->_M_buf_size = 1; + else if (__s && __n > 0) + { + // This is implementation-defined behavior, and assumes that + // an external char_type array of length __n exists and has + // been pre-allocated. If this is not the case, things will + // quickly blow up. When __n > 1, __n - 1 positions will be + // used for the get area, __n - 1 for the put area and 1 + // position to host the overflow char of a full put area. + // When __n == 1, 1 position will be used for the get area + // and 0 for the put area, as in the unbuffered case above. + this->_M_buf = __s; + this->_M_buf_size = __n; + } + return this; + } + + + // According to 27.8.1.4 p11 - 13, seekoff should ignore the last + // argument (of type openmode). + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) + { + int __width = 0; + if (_M_codecvt) + __width = _M_codecvt->encoding(); + if (__width < 0) + __width = 0; + + pos_type __ret = pos_type(off_type(-1)); + const bool __testfail = __off != 0 && __width <= 0; + if (this->is_open() && !__testfail) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + + // Correct state at destination. Note that this is the correct + // state for the current position during output, because + // codecvt::unshift() returns the state to the initial state. + // This is also the correct state at the end of the file because + // an unshift sequence should have been written at the end. + __state_type __state = _M_state_beg; + off_type __computed_off = __off * __width; + if (_M_reading && __way == ios_base::cur) + { + if (_M_codecvt->always_noconv()) + __computed_off += this->gptr() - this->egptr(); + else + { + // Calculate offset from _M_ext_buf that corresponds + // to gptr(). Note: uses _M_state_last, which + // corresponds to eback(). + const int __gptr_off = + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + __computed_off += _M_ext_buf + __gptr_off - _M_ext_end; + + // _M_state_last is modified by codecvt::length() so + // it now corresponds to gptr(). + __state = _M_state_last; + } + } + __ret = _M_seek(__computed_off, __way, __state); + } + return __ret; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 171. Strange seekpos() semantics due to joint position + // According to the resolution of DR 171, seekpos should ignore the last + // argument (of type openmode). + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekpos(pos_type __pos, ios_base::openmode) + { + pos_type __ret = pos_type(off_type(-1)); + if (this->is_open()) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) + { + pos_type __ret = pos_type(off_type(-1)); + if (_M_terminate_output()) + { + // Returns pos_type(off_type(-1)) in case of failure. + __ret = pos_type(_M_file.seekoff(__off, __way)); + _M_reading = false; + _M_writing = false; + _M_ext_next = _M_ext_end = _M_ext_buf; + _M_set_buffer(-1); + _M_state_cur = __state; + __ret.state(_M_state_cur); + } + return __ret; + } + + template + bool + basic_filebuf<_CharT, _Traits>:: + _M_terminate_output() + { + // Part one: update the output sequence. + bool __testvalid = true; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + + // Part two: output unshift sequence. + if (_M_writing && !__check_facet(_M_codecvt).always_noconv() + && __testvalid) + { + // Note: this value is arbitrary, since there is no way to + // get the length of the unshift sequence from codecvt, + // without calling unshift. + const size_t __blen = 128; + char __buf[__blen]; + codecvt_base::result __r; + streamsize __ilen = 0; + + do + { + char* __next; + __r = _M_codecvt->unshift(_M_state_cur, __buf, + __buf + __blen, __next); + if (__r == codecvt_base::error) + __testvalid = false; + else if (__r == codecvt_base::ok || + __r == codecvt_base::partial) + { + __ilen = __next - __buf; + if (__ilen > 0) + { + const streamsize __elen = _M_file.xsputn(__buf, __ilen); + if (__elen != __ilen) + __testvalid = false; + } + } + } + while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); + + if (__testvalid) + { + // This second call to overflow() is required by the standard, + // but it's not clear why it's needed, since the output buffer + // should be empty by this point (it should have been emptied + // in the first call to overflow()). + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + } + return __testvalid; + } + + template + int + basic_filebuf<_CharT, _Traits>:: + sync() + { + // Make sure that the internal buffer resyncs its idea of + // the file position with the external file. + int __ret = 0; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __ret = -1; + } + return __ret; + } + + template + void + basic_filebuf<_CharT, _Traits>:: + imbue(const locale& __loc) + { + bool __testvalid = true; + + const __codecvt_type* _M_codecvt_tmp = 0; + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) + _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); + + if (this->is_open()) + { + // encoding() == -1 is ok only at the beginning. + if ((_M_reading || _M_writing) + && __check_facet(_M_codecvt).encoding() == -1) + __testvalid = false; + else + { + if (_M_reading) + { + if (__check_facet(_M_codecvt).always_noconv()) + { + if (_M_codecvt_tmp + && !__check_facet(_M_codecvt_tmp).always_noconv()) + __testvalid = this->seekoff(0, ios_base::cur, this->_M_mode) + != pos_type(off_type(-1)); + } + else + { + // External position corresponding to gptr(). + _M_ext_next = _M_ext_buf + + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + const streamsize __remainder = _M_ext_end - _M_ext_next; + if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + } + } + else if (_M_writing && (__testvalid = _M_terminate_output())) + _M_set_buffer(-1); + } + } + + if (__testvalid) + _M_codecvt = _M_codecvt_tmp; + else + _M_codecvt = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_filebuf; + extern template class basic_ifstream; + extern template class basic_ofstream; + extern template class basic_fstream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_filebuf; + extern template class basic_ifstream; + extern template class basic_ofstream; + extern template class basic_fstream; +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/functexcept.h b/src/include.new/c++/3.4/bits/functexcept.h new file mode 100644 index 0000000..8b1d16c --- /dev/null +++ b/src/include.new/c++/3.4/bits/functexcept.h @@ -0,0 +1,85 @@ +// Function-Based Exception Support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#include + +namespace std +{ + // Helper for exception objects in + void + __throw_bad_exception(void); + + // Helper for exception objects in + void + __throw_bad_alloc(void); + + // Helper for exception objects in + void + __throw_bad_cast(void); + + void + __throw_bad_typeid(void); + + // Helpers for exception objects in + void + __throw_logic_error(const char* __s); + + void + __throw_domain_error(const char* __s); + + void + __throw_invalid_argument(const char* __s); + + void + __throw_length_error(const char* __s); + + void + __throw_out_of_range(const char* __s); + + void + __throw_runtime_error(const char* __s); + + void + __throw_range_error(const char* __s); + + void + __throw_overflow_error(const char* __s); + + void + __throw_underflow_error(const char* __s); + + // Helpers for exception objects in basic_ios + void + __throw_ios_failure(const char* __s); +} // namespace std + diff --git a/src/include.new/c++/3.4/bits/gslice.h b/src/include.new/c++/3.4/bits/gslice.h new file mode 100644 index 0000000..78f8a67 --- /dev/null +++ b/src/include.new/c++/3.4/bits/gslice.h @@ -0,0 +1,165 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file gslice.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GSLICE_H +#define _GSLICE_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Class defining multi-dimensional subset of an array. + * + * The slice class represents a multi-dimensional subset of an array, + * specified by three parameter sets: start offset, size array, and stride + * array. The start offset is the index of the first element of the array + * that is part of the subset. The size and stride array describe each + * dimension of the slice. Size is the number of elements in that + * dimension, and stride is the distance in the array between successive + * elements in that dimension. Each dimension's size and stride is taken + * to begin at an array element described by the previous dimension. The + * size array and stride array must be the same size. + * + * For example, if you have offset==3, stride[0]==11, size[1]==3, + * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], + * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], + * slice[1,2]==array[20]. + */ + class gslice + { + public: + /// Construct an empty slice. + gslice (); + + /** + * @brief Construct a slice. + * + * Constructs a slice with as many dimensions as the length of the @a l + * and @a s arrays. + * + * @param o Offset in array of first element. + * @param l Array of dimension lengths. + * @param s Array of dimension strides between array elements. + */ + gslice(size_t, const valarray&, const valarray&); + + // XXX: the IS says the copy-ctor and copy-assignment operators are + // synthetized by the compiler but they are just unsuitable + // for a ref-counted semantic + /// Copy constructor. + gslice(const gslice&); + + /// Destructor. + ~gslice(); + + // XXX: See the note above. + /// Assignment operator. + gslice& operator=(const gslice&); + + /// Return array offset of first slice element. + size_t start() const; + + /// Return array of sizes of slice dimensions. + valarray size() const; + + /// Return array of array strides for each dimension. + valarray stride() const; + + private: + struct _Indexer { + size_t _M_count; + size_t _M_start; + valarray _M_size; + valarray _M_stride; + valarray _M_index; // Linear array of referenced indices + _Indexer(size_t, const valarray&, + const valarray&); + void _M_increment_use() { ++_M_count; } + size_t _M_decrement_use() { return --_M_count; } + }; + + _Indexer* _M_index; + + template friend class valarray; + }; + + inline size_t + gslice::start () const + { return _M_index ? _M_index->_M_start : 0; } + + inline valarray + gslice::size () const + { return _M_index ? _M_index->_M_size : valarray(); } + + inline valarray + gslice::stride () const + { return _M_index ? _M_index->_M_stride : valarray(); } + + inline gslice::gslice () : _M_index(0) {} + + inline + gslice::gslice(size_t __o, const valarray& __l, + const valarray& __s) + : _M_index(new gslice::_Indexer(__o, __l, __s)) {} + + inline + gslice::gslice(const gslice& __g) : _M_index(__g._M_index) + { if (_M_index) _M_index->_M_increment_use(); } + + inline + gslice::~gslice() + { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } + + inline gslice& + gslice::operator= (const gslice& __g) + { + if (__g._M_index) __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; + _M_index = __g._M_index; + return *this; + } + + +} // std:: + + +#endif /* _GSLICE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/gslice_array.h b/src/include.new/c++/3.4/bits/gslice_array.h new file mode 100644 index 0000000..7e2e684 --- /dev/null +++ b/src/include.new/c++/3.4/bits/gslice_array.h @@ -0,0 +1,220 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file gslice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GSLICE_ARRAY_H +#define _GSLICE_ARRAY_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Reference to multi-dimensional subset of an array. + * + * A gslice_array is a reference to the actual elements of an array + * specified by a gslice. The way to get a gslice_array is to call + * operator[](gslice) on a valarray. The returned gslice_array then + * permits carrying operations out on the referenced subset of elements in + * the original valarray. For example, operator+=(valarray) will add + * values to the subset of elements in the underlying valarray this + * gslice_array refers to. + * + * @param Tp Element type. + */ + template + class gslice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + gslice_array(const gslice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + gslice_array& operator=(const gslice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + _Array<_Tp> _M_array; + const valarray& _M_index; + + friend class valarray<_Tp>; + + gslice_array(_Array<_Tp>, const valarray&); + + // not implemented + gslice_array(); + }; + + template + inline + gslice_array<_Tp>::gslice_array(_Array<_Tp> __a, + const valarray& __i) + : _M_array(__a), _M_index(__i) {} + + + template + inline + gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a) + : _M_array(__a._M_array), _M_index(__a._M_index) {} + + + template + inline gslice_array<_Tp>& + gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a) + { + std::__valarray_copy(_Array<_Tp>(__a._M_array), + _Array(__a._M_index), _M_index.size(), + _M_array, _Array(_M_index)); + return *this; + } + + template + inline void + gslice_array<_Tp>::operator=(const _Tp& __t) const + { + std::__valarray_fill(_M_array, _Array(_M_index), + _M_index.size(), __t); + } + + template + inline void + gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { + std::__valarray_copy(_Array<_Tp>(__v), __v.size(), + _M_array, _Array(_M_index)); + } + + template + template + inline void + gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const + { + std::__valarray_copy (__e, _M_index.size(), _M_array, + _Array(_M_index)); + } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _Array(_M_index), \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template \ + template \ + inline void \ + gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _Array(_M_index), __e,\ + _M_index.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _GSLICE_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/gthr-default.h b/src/include.new/c++/3.4/bits/gthr-default.h new file mode 100644 index 0000000..1898d24 --- /dev/null +++ b/src/include.new/c++/3.4/bits/gthr-default.h @@ -0,0 +1,517 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_POSIX_H +#define _GLIBCXX_GCC_GTHR_POSIX_H + +/* POSIX threads specific definitions. + Easy, since the interface is just one-to-one mapping. */ + +#define __GTHREADS 1 + +/* Some implementations of require this to be defined. */ +#ifndef _REENTRANT +#define _REENTRANT 1 +#endif + +#include +#include + +typedef pthread_key_t __gthread_key_t; +typedef pthread_once_t __gthread_once_t; +typedef pthread_mutex_t __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT + +#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_create + +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_trylock +#pragma weak pthread_mutex_unlock + +#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) +/* Objective-C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but + we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak sched_get_priority_max +#pragma weak sched_get_priority_min +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#pragma weak sched_yield +#pragma weak pthread_attr_destroy +#pragma weak pthread_attr_init +#pragma weak pthread_attr_setdetachstate +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak pthread_getschedparam +#pragma weak pthread_setschedparam +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#endif /* _LIBOBJC || _LIBOBJC_WEAK */ + +static inline int +__gthread_active_p (void) +{ + static void *const __gthread_active_ptr = (void *) &pthread_create; + return __gthread_active_ptr != 0; +} + +#else /* not __GXX_WEAK__ */ + +static inline int +__gthread_active_p (void) +{ + return 1; +} + +#endif /* __GXX_WEAK__ */ + +#ifdef _LIBOBJC + +/* This is the config.h file in libobjc/ */ +#include + +#ifdef HAVE_SCHED_H +# include +#endif + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; +static pthread_attr_t _objc_thread_attribs; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + if (__gthread_active_p ()) + { + /* Initialize the thread storage key */ + if (pthread_key_create (&_objc_thread_storage, NULL) == 0) + { + /* The normal default detach state for threads is + * PTHREAD_CREATE_JOINABLE which causes threads to not die + * when you think they should. */ + if (pthread_attr_init (&_objc_thread_attribs) == 0 + && pthread_attr_setdetachstate (&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } + } + + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + if (__gthread_active_p () + && pthread_key_delete (_objc_thread_storage) == 0 + && pthread_attr_destroy (&_objc_thread_attribs) == 0) + return 0; + + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg))) + thread_id = (objc_thread_t) new_thread_handle; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int priority) +{ + if (!__gthread_active_p ()) + return -1; + else + { +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + pthread_t thread_id = pthread_self (); + int policy; + struct sched_param params; + int priority_min, priority_max; + + if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0) + { + if ((priority_max = sched_get_priority_max (policy)) == -1) + return -1; + + if ((priority_min = sched_get_priority_min (policy)) == -1) + return -1; + + if (priority > priority_max) + priority = priority_max; + else if (priority < priority_min) + priority = priority_min; + params.sched_priority = priority; + + /* + * The solaris 7 and several other man pages incorrectly state that + * this should be a pointer to policy but pthread.h is universally + * at odds with this. + */ + if (pthread_setschedparam (thread_id, policy, ¶ms) == 0) + return 0; + } +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return -1; + } +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + if (__gthread_active_p ()) + { + int policy; + struct sched_param params; + + if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0) + return params.sched_priority; + else + return -1; + } + else +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + if (__gthread_active_p ()) + sched_yield (); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit (&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + if (__gthread_active_p ()) + return (objc_thread_t) pthread_self (); + else + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific (_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + if (__gthread_active_p ()) + return pthread_getspecific (_objc_thread_storage); + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); + + if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL)) + { + objc_free (mutex->backend); + mutex->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + int count; + + /* + * Posix Threads specifically require that the thread be unlocked + * for pthread_mutex_destroy to work. + */ + + do + { + count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); + if (count < 0) + return -1; + } + while (count); + + if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) + return -1; + + objc_free (mutex->backend); + mutex->backend = NULL; + } + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + condition->backend = objc_malloc (sizeof (pthread_cond_t)); + + if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL)) + { + objc_free (condition->backend); + condition->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + if (pthread_cond_destroy ((pthread_cond_t *) condition->backend)) + return -1; + + objc_free (condition->backend); + condition->backend = NULL; + } + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_cond_wait ((pthread_cond_t *) condition->backend, + (pthread_mutex_t *) mutex->backend); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_broadcast ((pthread_cond_t *) condition->backend); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_signal ((pthread_cond_t *) condition->backend); + else + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_once (__gthread_once_t *once, void (*func) (void)) +{ + if (__gthread_active_p ()) + return pthread_once (once, func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + return pthread_key_create (key, dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t key) +{ + return pthread_key_delete (key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t key) +{ + return pthread_getspecific (key); +} + +static inline int +__gthread_setspecific (__gthread_key_t key, const void *ptr) +{ + return pthread_setspecific (key, ptr); +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_trylock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock (mutex); + else + return 0; +} + +#endif /* _LIBOBJC */ + +#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ diff --git a/src/include.new/c++/3.4/bits/gthr-posix.h b/src/include.new/c++/3.4/bits/gthr-posix.h new file mode 100644 index 0000000..1898d24 --- /dev/null +++ b/src/include.new/c++/3.4/bits/gthr-posix.h @@ -0,0 +1,517 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_POSIX_H +#define _GLIBCXX_GCC_GTHR_POSIX_H + +/* POSIX threads specific definitions. + Easy, since the interface is just one-to-one mapping. */ + +#define __GTHREADS 1 + +/* Some implementations of require this to be defined. */ +#ifndef _REENTRANT +#define _REENTRANT 1 +#endif + +#include +#include + +typedef pthread_key_t __gthread_key_t; +typedef pthread_once_t __gthread_once_t; +typedef pthread_mutex_t __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT + +#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_create + +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_trylock +#pragma weak pthread_mutex_unlock + +#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) +/* Objective-C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but + we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak sched_get_priority_max +#pragma weak sched_get_priority_min +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#pragma weak sched_yield +#pragma weak pthread_attr_destroy +#pragma weak pthread_attr_init +#pragma weak pthread_attr_setdetachstate +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak pthread_getschedparam +#pragma weak pthread_setschedparam +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#endif /* _LIBOBJC || _LIBOBJC_WEAK */ + +static inline int +__gthread_active_p (void) +{ + static void *const __gthread_active_ptr = (void *) &pthread_create; + return __gthread_active_ptr != 0; +} + +#else /* not __GXX_WEAK__ */ + +static inline int +__gthread_active_p (void) +{ + return 1; +} + +#endif /* __GXX_WEAK__ */ + +#ifdef _LIBOBJC + +/* This is the config.h file in libobjc/ */ +#include + +#ifdef HAVE_SCHED_H +# include +#endif + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; +static pthread_attr_t _objc_thread_attribs; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + if (__gthread_active_p ()) + { + /* Initialize the thread storage key */ + if (pthread_key_create (&_objc_thread_storage, NULL) == 0) + { + /* The normal default detach state for threads is + * PTHREAD_CREATE_JOINABLE which causes threads to not die + * when you think they should. */ + if (pthread_attr_init (&_objc_thread_attribs) == 0 + && pthread_attr_setdetachstate (&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } + } + + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + if (__gthread_active_p () + && pthread_key_delete (_objc_thread_storage) == 0 + && pthread_attr_destroy (&_objc_thread_attribs) == 0) + return 0; + + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg))) + thread_id = (objc_thread_t) new_thread_handle; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int priority) +{ + if (!__gthread_active_p ()) + return -1; + else + { +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + pthread_t thread_id = pthread_self (); + int policy; + struct sched_param params; + int priority_min, priority_max; + + if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0) + { + if ((priority_max = sched_get_priority_max (policy)) == -1) + return -1; + + if ((priority_min = sched_get_priority_min (policy)) == -1) + return -1; + + if (priority > priority_max) + priority = priority_max; + else if (priority < priority_min) + priority = priority_min; + params.sched_priority = priority; + + /* + * The solaris 7 and several other man pages incorrectly state that + * this should be a pointer to policy but pthread.h is universally + * at odds with this. + */ + if (pthread_setschedparam (thread_id, policy, ¶ms) == 0) + return 0; + } +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return -1; + } +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + if (__gthread_active_p ()) + { + int policy; + struct sched_param params; + + if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0) + return params.sched_priority; + else + return -1; + } + else +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + if (__gthread_active_p ()) + sched_yield (); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit (&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + if (__gthread_active_p ()) + return (objc_thread_t) pthread_self (); + else + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific (_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + if (__gthread_active_p ()) + return pthread_getspecific (_objc_thread_storage); + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); + + if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL)) + { + objc_free (mutex->backend); + mutex->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + int count; + + /* + * Posix Threads specifically require that the thread be unlocked + * for pthread_mutex_destroy to work. + */ + + do + { + count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); + if (count < 0) + return -1; + } + while (count); + + if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) + return -1; + + objc_free (mutex->backend); + mutex->backend = NULL; + } + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + condition->backend = objc_malloc (sizeof (pthread_cond_t)); + + if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL)) + { + objc_free (condition->backend); + condition->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + if (pthread_cond_destroy ((pthread_cond_t *) condition->backend)) + return -1; + + objc_free (condition->backend); + condition->backend = NULL; + } + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_cond_wait ((pthread_cond_t *) condition->backend, + (pthread_mutex_t *) mutex->backend); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_broadcast ((pthread_cond_t *) condition->backend); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_signal ((pthread_cond_t *) condition->backend); + else + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_once (__gthread_once_t *once, void (*func) (void)) +{ + if (__gthread_active_p ()) + return pthread_once (once, func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + return pthread_key_create (key, dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t key) +{ + return pthread_key_delete (key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t key) +{ + return pthread_getspecific (key); +} + +static inline int +__gthread_setspecific (__gthread_key_t key, const void *ptr) +{ + return pthread_setspecific (key, ptr); +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_trylock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock (mutex); + else + return 0; +} + +#endif /* _LIBOBJC */ + +#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ diff --git a/src/include.new/c++/3.4/bits/gthr-single.h b/src/include.new/c++/3.4/bits/gthr-single.h new file mode 100644 index 0000000..68e425b --- /dev/null +++ b/src/include.new/c++/3.4/bits/gthr-single.h @@ -0,0 +1,239 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_SINGLE_H +#define _GLIBCXX_GCC_GTHR_SINGLE_H + +/* Just provide compatibility for mutex handling. */ + +typedef int __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT 0 + +#ifdef __cplusplus +#define _GLIBCXX_UNUSED(x) +#else +#define _GLIBCXX_UNUSED(x) x __attribute__((unused)) +#endif + +#ifdef _LIBOBJC + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + /* No thread support available */ + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + /* No thread support available */ + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (* func)(void *), void * _GLIBCXX_UNUSED(arg)) +{ + /* No thread support available */ + return NULL; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int _GLIBCXX_UNUSED(priority)) +{ + /* No thread support available */ + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + return; +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + /* No thread support available */ + /* Should we really exit the program */ + /* exit (&__objc_thread_exit_status); */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + /* No thread support, use 1. */ + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + thread_local_storage = value; + return 0; +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t _GLIBCXX_UNUSED(condition), + objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_active_p (void) +{ + return 0; +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +#endif /* _LIBOBJC */ + +#undef _GLIBCXX_UNUSED + +#endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */ diff --git a/src/include.new/c++/3.4/bits/gthr.h b/src/include.new/c++/3.4/bits/gthr.h new file mode 100644 index 0000000..fe5740c --- /dev/null +++ b/src/include.new/c++/3.4/bits/gthr.h @@ -0,0 +1,103 @@ +/* Threads compatibility routines for libgcc2. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_H +#define _GLIBCXX_GCC_GTHR_H + +/* If this file is compiled with threads support, it must + #define __GTHREADS 1 + to indicate that threads support is present. Also it has define + function + int __gthread_active_p () + that returns 1 if thread system is active, 0 if not. + + The threads interface must define the following types: + __gthread_key_t + __gthread_once_t + __gthread_mutex_t + + The threads interface must define the following macros: + + __GTHREAD_ONCE_INIT + to initialize __gthread_once_t + __GTHREAD_MUTEX_INIT + to initialize __gthread_mutex_t to get a fast + non-recursive mutex. + __GTHREAD_MUTEX_INIT_FUNCTION + some systems can't initialize a mutex without a + function call. On such systems, define this to a + function which looks like this: + void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) + Don't define __GTHREAD_MUTEX_INIT in this case + + The threads interface must define the following static functions: + + int __gthread_once (__gthread_once_t *once, void (*func) ()) + + int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *)) + int __gthread_key_delete (__gthread_key_t key) + + void *__gthread_getspecific (__gthread_key_t key) + int __gthread_setspecific (__gthread_key_t key, const void *ptr) + + int __gthread_mutex_lock (__gthread_mutex_t *mutex); + int __gthread_mutex_trylock (__gthread_mutex_t *mutex); + int __gthread_mutex_unlock (__gthread_mutex_t *mutex); + + All functions returning int should return zero on success or the error + number. If the operation is not supported, -1 is returned. + + Currently supported threads packages are + POSIX threads with -D_PTHREADS + DCE threads with -D_DCE_THREADS + Solaris/UI threads with -D_SOLARIS_THREADS +*/ + +/* Check first for thread specific defines. */ +#if _GLIBCXX__PTHREADS +#include +#elif _GLIBCXX__DCE_THREADS +#include +#elif _GLIBCXX__SOLARIS_THREADS +#include + +/* Include GTHREAD_FILE if one is defined. */ +#elif defined(_GLIBCXX_HAVE_GTHR_DEFAULT) +#if __GXX_WEAK__ +#ifndef _GLIBCXX_GTHREAD_USE_WEAK +#define _GLIBCXX_GTHREAD_USE_WEAK 1 +#endif +#endif +#include + +/* Fallback to single thread definitions. */ +#else +#include +#endif + +#endif /* ! _GLIBCXX_GCC_GTHR_H */ diff --git a/src/include.new/c++/3.4/bits/indirect_array.h b/src/include.new/c++/3.4/bits/indirect_array.h new file mode 100644 index 0000000..912f522 --- /dev/null +++ b/src/include.new/c++/3.4/bits/indirect_array.h @@ -0,0 +1,212 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file indirect_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _INDIRECT_ARRAY_H +#define _INDIRECT_ARRAY_H 1 + +#pragma GCC system_header + +namespace std +{ + /** + * @brief Reference to arbitrary subset of an array. + * + * An indirect_array is a reference to the actual elements of an array + * specified by an ordered array of indices. The way to get an indirect_array is to + * call operator[](valarray) on a valarray. The returned + * indirect_array then permits carrying operations out on the referenced + * subset of elements in the original valarray. + * + * For example, if an indirect_array is obtained using the array (4,2,0) as + * an argument, and then assigned to an array containing (1,2,3), then the + * underlying array will have array[0]==3, array[2]==2, and array[4]==1. + * + * @param Tp Element type. + */ + template + class indirect_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(const indirect_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + indirect_array& operator=(const indirect_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator= (const _Tp&) const; + // ~indirect_array(); + + template + void operator=(const _Expr<_Dom, _Tp>&) const; + template + void operator*=(const _Expr<_Dom, _Tp>&) const; + template + void operator/=(const _Expr<_Dom, _Tp>&) const; + template + void operator%=(const _Expr<_Dom, _Tp>&) const; + template + void operator+=(const _Expr<_Dom, _Tp>&) const; + template + void operator-=(const _Expr<_Dom, _Tp>&) const; + template + void operator^=(const _Expr<_Dom, _Tp>&) const; + template + void operator&=(const _Expr<_Dom, _Tp>&) const; + template + void operator|=(const _Expr<_Dom, _Tp>&) const; + template + void operator<<=(const _Expr<_Dom, _Tp>&) const; + template + void operator>>=(const _Expr<_Dom, _Tp>&) const; + + private: + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(_Array<_Tp>, size_t, _Array); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array(); + }; + + template + inline + indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {} + + template + inline + indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s, + _Array __i) + : _M_sz(__s), _M_index(__i), _M_array(__a) {} + + template + inline indirect_array<_Tp>& + indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index); + return *this; + } + + + template + inline void + indirect_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_index, _M_sz, __t); } + + template + inline void + indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); } + + template + template + inline void + indirect_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \ + } \ + \ + template \ + template \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _INDIRECT_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/ios_base.h b/src/include.new/c++/3.4/bits/ios_base.h new file mode 100644 index 0000000..08c952d --- /dev/null +++ b/src/include.new/c++/3.4/bits/ios_base.h @@ -0,0 +1,969 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +/** @file ios_base.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _IOS_BASE_H +#define _IOS_BASE_H 1 + +#pragma GCC system_header + +#include +#include +#include + +namespace std +{ + // The following definitions of bitmask types are enums, not ints, + // as permitted (but not required) in the standard, in order to provide + // better type safety in iostream calls. A side effect is that + // expressions involving them are no longer compile-time constants. + enum _Ios_Fmtflags + { + _S_boolalpha = 1L << 0, + _S_dec = 1L << 1, + _S_fixed = 1L << 2, + _S_hex = 1L << 3, + _S_internal = 1L << 4, + _S_left = 1L << 5, + _S_oct = 1L << 6, + _S_right = 1L << 7, + _S_scientific = 1L << 8, + _S_showbase = 1L << 9, + _S_showpoint = 1L << 10, + _S_showpos = 1L << 11, + _S_skipws = 1L << 12, + _S_unitbuf = 1L << 13, + _S_uppercase = 1L << 14, + _S_adjustfield = _S_left | _S_right | _S_internal, + _S_basefield = _S_dec | _S_oct | _S_hex, + _S_floatfield = _S_scientific | _S_fixed, + _S_ios_fmtflags_end = 1L << 16 + }; + + inline _Ios_Fmtflags + operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Fmtflags + operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Fmtflags + operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Fmtflags& + operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a | __b; } + + inline _Ios_Fmtflags& + operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a & __b; } + + inline _Ios_Fmtflags& + operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a ^ __b; } + + inline _Ios_Fmtflags + operator~(_Ios_Fmtflags __a) + { return _Ios_Fmtflags(~static_cast(__a)); } + + + enum _Ios_Openmode + { + _S_app = 1L << 0, + _S_ate = 1L << 1, + _S_bin = 1L << 2, + _S_in = 1L << 3, + _S_out = 1L << 4, + _S_trunc = 1L << 5, + _S_ios_openmode_end = 1L << 16 + }; + + inline _Ios_Openmode + operator&(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Openmode + operator|(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Openmode + operator^(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Openmode& + operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a | __b; } + + inline _Ios_Openmode& + operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a & __b; } + + inline _Ios_Openmode& + operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a ^ __b; } + + inline _Ios_Openmode + operator~(_Ios_Openmode __a) + { return _Ios_Openmode(~static_cast(__a)); } + + + enum _Ios_Iostate + { + _S_goodbit = 0, + _S_badbit = 1L << 0, + _S_eofbit = 1L << 1, + _S_failbit = 1L << 2, + _S_ios_iostate_end = 1L << 16 + }; + + inline _Ios_Iostate + operator&(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Iostate + operator|(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Iostate + operator^(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Iostate& + operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a | __b; } + + inline _Ios_Iostate& + operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a & __b; } + + inline _Ios_Iostate& + operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a ^ __b; } + + inline _Ios_Iostate + operator~(_Ios_Iostate __a) + { return _Ios_Iostate(~static_cast(__a)); } + + enum _Ios_Seekdir + { + _S_beg = 0, + _S_cur = SEEK_CUR, + _S_end = SEEK_END, + _S_ios_seekdir_end = 1L << 16 + }; + + // 27.4.2 Class ios_base + /** + * @brief The very top of the I/O class hierarchy. + * + * This class defines everything that can be defined about I/O that does + * not depend on the type of characters being input or output. Most + * people will only see @c ios_base when they need to specify the full + * name of the various I/O flags (e.g., the openmodes). + */ + class ios_base + { + public: + + // 27.4.2.1.1 Class ios_base::failure + /// These are thrown to indicate problems. Doc me. + class failure : public exception + { + public: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 48. Use of non-existent exception constructor + explicit + failure(const string& __str) throw(); + + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual + ~failure() throw(); + + virtual const char* + what() const throw(); + + private: + string _M_msg; + }; + + // 27.4.2.1.2 Type ios_base::fmtflags + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Fmtflags" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type fmtflags are: + * - boolalpha + * - dec + * - fixed + * - hex + * - internal + * - left + * - oct + * - right + * - scientific + * - showbase + * - showpoint + * - showpos + * - skipws + * - unitbuf + * - uppercase + * - adjustfield + * - basefield + * - floatfield + */ + typedef _Ios_Fmtflags fmtflags; + + /// Insert/extract @c bool in alphabetic rather than numeric format. + static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha); + + /// Converts integer input or generates integer output in decimal base. + static const fmtflags dec = fmtflags(__ios_flags::_S_dec); + + /// Generate floating-point output in fixed-point notation. + static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed); + + /// Converts integer input or generates integer output in hexadecimal base. + static const fmtflags hex = fmtflags(__ios_flags::_S_hex); + + /// Adds fill characters at a designated internal point in certain + /// generated output, or identical to @c right if no such point is + /// designated. + static const fmtflags internal = fmtflags(__ios_flags::_S_internal); + + /// Adds fill characters on the right (final positions) of certain + /// generated output. (I.e., the thing you print is flush left.) + static const fmtflags left = fmtflags(__ios_flags::_S_left); + + /// Converts integer input or generates integer output in octal base. + static const fmtflags oct = fmtflags(__ios_flags::_S_oct); + + /// Adds fill characters on the left (initial positions) of certain + /// generated output. (I.e., the thing you print is flush right.) + static const fmtflags right = fmtflags(__ios_flags::_S_right); + + /// Generates floating-point output in scientific notation. + static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific); + + /// Generates a prefix indicating the numeric base of generated integer + /// output. + static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase); + + /// Generates a decimal-point character unconditionally in generated + /// floating-point output. + static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint); + + /// Generates a + sign in non-negative generated numeric output. + static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos); + + /// Skips leading white space before certain input operations. + static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws); + + /// Flushes output after each output operation. + static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf); + + /// Replaces certain lowercase letters with their uppercase equivalents + /// in generated output. + static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase); + + /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. + static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield); + + /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. + static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield); + + /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. + static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield); + + // 27.4.2.1.3 Type ios_base::iostate + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Iostate" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type iostate are: + * - badbit + * - eofbit + * - failbit + * - goodbit + */ + typedef _Ios_Iostate iostate; + + /// Indicates a loss of integrity in an input or output sequence (such + /// as an irrecoverable read error from a file). + static const iostate badbit = iostate(__ios_flags::_S_badbit); + + /// Indicates that an input operation reached the end of an input sequence. + static const iostate eofbit = iostate(__ios_flags::_S_eofbit); + + /// Indicates that an input operation failed to read the expected + /// characters, or that an output operation failed to generate the + /// desired characters. + static const iostate failbit = iostate(__ios_flags::_S_failbit); + + /// Indicates all is well. + static const iostate goodbit = iostate(0); + + // 27.4.2.1.4 Type ios_base::openmode + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Openmode" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type openmode are: + * - app + * - ate + * - binary + * - in + * - out + * - trunc + */ + typedef _Ios_Openmode openmode; + + /// Seek to end before each write. + static const openmode app = openmode(__ios_flags::_S_app); + + /// Open and seek to end immediately after opening. + static const openmode ate = openmode(__ios_flags::_S_ate); + + /// Perform input and output in binary mode (as opposed to text mode). + /// This is probably not what you think it is; see + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more. + static const openmode binary = openmode(__ios_flags::_S_bin); + + /// Open for input. Default for @c ifstream and fstream. + static const openmode in = openmode(__ios_flags::_S_in); + + /// Open for output. Default for @c ofstream and fstream. + static const openmode out = openmode(__ios_flags::_S_out); + + /// Open for input. Default for @c ofstream. + static const openmode trunc = openmode(__ios_flags::_S_trunc); + + // 27.4.2.1.5 Type ios_base::seekdir + /** + * @brief This is an enumerated type. + * + * @c "_Ios_Seekdir" is implementation-defined. Defined values + * of type seekdir are: + * - beg + * - cur, equivalent to @c SEEK_CUR in the C standard library. + * - end, equivalent to @c SEEK_END in the C standard library. + */ + typedef _Ios_Seekdir seekdir; + + /// Request a seek relative to the beginning of the stream. + static const seekdir beg = seekdir(0); + + /// Request a seek relative to the current position within the sequence. + static const seekdir cur = seekdir(SEEK_CUR); + + /// Request a seek relative to the current end of the sequence. + static const seekdir end = seekdir(SEEK_END); + +#ifdef _GLIBCXX_DEPRECATED + // Annex D.6 + typedef int io_state; + typedef int open_mode; + typedef int seek_dir; + + typedef std::streampos streampos; + typedef std::streamoff streamoff; +#endif + + // Callbacks; + /** + * @brief The set of events that may be passed to an event callback. + * + * erase_event is used during ~ios() and copyfmt(). imbue_event is used + * during imbue(). copyfmt_event is used during copyfmt(). + */ + enum event + { + erase_event, + imbue_event, + copyfmt_event + }; + + /** + * @brief The type of an event callback function. + * @param event One of the members of the event enum. + * @param ios_base Reference to the ios_base object. + * @param int The integer provided when the callback was registered. + * + * Event callbacks are user defined functions that get called during + * several ios_base and basic_ios functions, specifically imbue(), + * copyfmt(), and ~ios(). + */ + typedef void (*event_callback) (event, ios_base&, int); + + /** + * @brief Add the callback __fn with parameter __index. + * @param __fn The function to add. + * @param __index The integer to pass to the function when invoked. + * + * Registers a function as an event callback with an integer parameter to + * be passed to the function when invoked. Multiple copies of the + * function are allowed. If there are multiple callbacks, they are + * invoked in the order they were registered. + */ + void + register_callback(event_callback __fn, int __index); + + protected: + //@{ + /** + * @if maint + * ios_base data members (doc me) + * @endif + */ + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + iostate _M_exception; + iostate _M_streambuf_state; + //@} + + // 27.4.2.6 Members for callbacks + // 27.4.2.6 ios_base callbacks + struct _Callback_list + { + // Data Members + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; + _Atomic_word _M_refcount; // 0 means one reference. + + _Callback_list(ios_base::event_callback __fn, int __index, + _Callback_list* __cb) + : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } + + void + _M_add_reference() { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + // 0 => OK to delete. + int + _M_remove_reference() + { return __gnu_cxx::__exchange_and_add(&_M_refcount, -1); } + }; + + _Callback_list* _M_callbacks; + + void + _M_call_callbacks(event __ev) throw(); + + void + _M_dispose_callbacks(void); + + // 27.4.2.5 Members for iword/pword storage + struct _Words + { + void* _M_pword; + long _M_iword; + _Words() : _M_pword(0), _M_iword(0) { } + }; + + // Only for failed iword/pword calls. + _Words _M_word_zero; + + // Guaranteed storage. + // The first 5 iword and pword slots are reserved for internal use. + static const int _S_local_word_size = 8; + _Words _M_local_word[_S_local_word_size]; + + // Allocated storage. + int _M_word_size; + _Words* _M_word; + + _Words& + _M_grow_words(int __index, bool __iword); + + // Members for locale and locale caching. + locale _M_ios_locale; + + void + _M_init(); + + public: + + // 27.4.2.1.6 Class ios_base::Init + // Used to initialize standard streams. In theory, g++ could use + // -finit-priority to order this stuff correctly without going + // through these machinations. + class Init + { + friend class ios_base; + public: + Init(); + ~Init(); + + private: + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; + }; + + // [27.4.2.2] fmtflags state functions + /** + * @brief Access to format flags. + * @return The format control flags for both input and output. + */ + inline fmtflags + flags() const { return _M_flags; } + + /** + * @brief Setting new format flags all at once. + * @param fmtfl The new flags to set. + * @return The previous format control flags. + * + * This function overwrites all the format flags with @a fmtfl. + */ + inline fmtflags + flags(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @return The previous format control flags. + * + * This function sets additional flags in format control. Flags that + * were previously set remain set. + */ + inline fmtflags + setf(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @param mask The flags mask for @a fmtfl. + * @return The previous format control flags. + * + * This function clears @a mask in the format flags, then sets + * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. + */ + inline fmtflags + setf(fmtflags __fmtfl, fmtflags __mask) + { + fmtflags __old = _M_flags; + _M_flags &= ~__mask; + _M_flags |= (__fmtfl & __mask); + return __old; + } + + /** + * @brief Clearing format flags. + * @param mask The flags to unset. + * + * This function clears @a mask in the format flags. + */ + inline void + unsetf(fmtflags __mask) { _M_flags &= ~__mask; } + + /** + * @brief Flags access. + * @return The precision to generate on certain output operations. + * + * @if maint + * Be careful if you try to give a definition of "precision" here; see + * DR 189. + * @endif + */ + inline streamsize + precision() const { return _M_precision; } + + /** + * @brief Changing flags. + * @param prec The new precision value. + * @return The previous value of precision(). + */ + inline streamsize + precision(streamsize __prec) + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; + } + + /** + * @brief Flags access. + * @return The minimum field width to generate on output operations. + * + * "Minimum field width" refers to the number of characters. + */ + inline streamsize + width() const { return _M_width; } + + /** + * @brief Changing flags. + * @param wide The new width value. + * @return The previous value of width(). + */ + inline streamsize + width(streamsize __wide) + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; + } + + // [27.4.2.4] ios_base static members + /** + * @brief Interaction with the standard C I/O objects. + * @param sync Whether to synchronize or not. + * @return True if the standard streams were previously synchronized. + * + * The synchronization referred to is @e only that between the standard + * C facilities (e.g., stdout) and the standard C++ objects (e.g., + * cout). User-declared streams are unaffected. See + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#8 for more. + */ + static bool + sync_with_stdio(bool __sync = true); + + // [27.4.2.3] ios_base locale functions + /** + * @brief Setting a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Sets the new locale for this stream, and then invokes each callback + * with imbue_event. + */ + locale + imbue(const locale& __loc); + + /** + * @brief Locale access + * @return A copy of the current locale. + * + * If @c imbue(loc) has previously been called, then this function + * returns @c loc. Otherwise, it returns a copy of @c std::locale(), + * the global C++ locale. + */ + inline locale + getloc() const { return _M_ios_locale; } + + /** + * @brief Locale access + * @return A reference to the current locale. + * + * Like getloc above, but returns a reference instead of + * generating a copy. + */ + inline const locale& + _M_getloc() const { return _M_ios_locale; } + + // [27.4.2.5] ios_base storage functions + /** + * @brief Access to unique indices. + * @return An integer different from all previous calls. + * + * This function returns a unique integer every time it is called. It + * can be used for any purpose, but is primarily intended to be a unique + * index for the iword and pword functions. The expectation is that an + * application calls xalloc in order to obtain an index in the iword and + * pword arrays that can be used without fear of conflict. + * + * The implementation maintains a static variable that is incremented and + * returned on each invocation. xalloc is guaranteed to return an index + * that is safe to use in the iword and pword arrays. + */ + static int + xalloc() throw(); + + /** + * @brief Access to integer array. + * @param __ix Index into the array. + * @return A reference to an integer associated with the index. + * + * The iword function provides access to an array of integers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All integers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline long& + iword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, true); + return __word._M_iword; + } + + /** + * @brief Access to void pointer array. + * @param __ix Index into the array. + * @return A reference to a void* associated with the index. + * + * The pword function provides access to an array of pointers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All pointers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline void*& + pword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, false); + return __word._M_pword; + } + + // Destructor + /** + * Invokes each callback with erase_event. Destroys local storage. + * + * Note that the ios_base object for the standard streams never gets + * destroyed. As a result, any callbacks registered with the standard + * streams will not get invoked with erase_event (unless copyfmt is + * used). + */ + virtual ~ios_base(); + + protected: + ios_base(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 50. Copy constructor and assignment operator of ios_base + private: + ios_base(const ios_base&); + + ios_base& + operator=(const ios_base&); + }; + + // [27.4.5.1] fmtflags manipulators + /// Calls base.setf(ios_base::boolalpha). + inline ios_base& + boolalpha(ios_base& __base) + { + __base.setf(ios_base::boolalpha); + return __base; + } + + /// Calls base.unsetf(ios_base::boolalpha). + inline ios_base& + noboolalpha(ios_base& __base) + { + __base.unsetf(ios_base::boolalpha); + return __base; + } + + /// Calls base.setf(ios_base::showbase). + inline ios_base& + showbase(ios_base& __base) + { + __base.setf(ios_base::showbase); + return __base; + } + + /// Calls base.unsetf(ios_base::showbase). + inline ios_base& + noshowbase(ios_base& __base) + { + __base.unsetf(ios_base::showbase); + return __base; + } + + /// Calls base.setf(ios_base::showpoint). + inline ios_base& + showpoint(ios_base& __base) + { + __base.setf(ios_base::showpoint); + return __base; + } + + /// Calls base.unsetf(ios_base::showpoint). + inline ios_base& + noshowpoint(ios_base& __base) + { + __base.unsetf(ios_base::showpoint); + return __base; + } + + /// Calls base.setf(ios_base::showpos). + inline ios_base& + showpos(ios_base& __base) + { + __base.setf(ios_base::showpos); + return __base; + } + + /// Calls base.unsetf(ios_base::showpos). + inline ios_base& + noshowpos(ios_base& __base) + { + __base.unsetf(ios_base::showpos); + return __base; + } + + /// Calls base.setf(ios_base::skipws). + inline ios_base& + skipws(ios_base& __base) + { + __base.setf(ios_base::skipws); + return __base; + } + + /// Calls base.unsetf(ios_base::skipws). + inline ios_base& + noskipws(ios_base& __base) + { + __base.unsetf(ios_base::skipws); + return __base; + } + + /// Calls base.setf(ios_base::uppercase). + inline ios_base& + uppercase(ios_base& __base) + { + __base.setf(ios_base::uppercase); + return __base; + } + + /// Calls base.unsetf(ios_base::uppercase). + inline ios_base& + nouppercase(ios_base& __base) + { + __base.unsetf(ios_base::uppercase); + return __base; + } + + /// Calls base.setf(ios_base::unitbuf). + inline ios_base& + unitbuf(ios_base& __base) + { + __base.setf(ios_base::unitbuf); + return __base; + } + + /// Calls base.unsetf(ios_base::unitbuf). + inline ios_base& + nounitbuf(ios_base& __base) + { + __base.unsetf(ios_base::unitbuf); + return __base; + } + + // [27.4.5.2] adjustfield anipulators + /// Calls base.setf(ios_base::internal, ios_base::adjustfield). + inline ios_base& + internal(ios_base& __base) + { + __base.setf(ios_base::internal, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::left, ios_base::adjustfield). + inline ios_base& + left(ios_base& __base) + { + __base.setf(ios_base::left, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::right, ios_base::adjustfield). + inline ios_base& + right(ios_base& __base) + { + __base.setf(ios_base::right, ios_base::adjustfield); + return __base; + } + + // [27.4.5.3] basefield anipulators + /// Calls base.setf(ios_base::dec, ios_base::basefield). + inline ios_base& + dec(ios_base& __base) + { + __base.setf(ios_base::dec, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::hex, ios_base::basefield). + inline ios_base& + hex(ios_base& __base) + { + __base.setf(ios_base::hex, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::oct, ios_base::basefield). + inline ios_base& + oct(ios_base& __base) + { + __base.setf(ios_base::oct, ios_base::basefield); + return __base; + } + + // [27.4.5.4] floatfield anipulators + /// Calls base.setf(ios_base::fixed, ios_base::floatfield). + inline ios_base& + fixed(ios_base& __base) + { + __base.setf(ios_base::fixed, ios_base::floatfield); + return __base; + } + + /// Calls base.setf(ios_base::scientific, ios_base::floatfield). + inline ios_base& + scientific(ios_base& __base) + { + __base.setf(ios_base::scientific, ios_base::floatfield); + return __base; + } +} // namespace std + +#endif /* _IOS_BASE_H */ + diff --git a/src/include.new/c++/3.4/bits/istream.tcc b/src/include.new/c++/3.4/bits/istream.tcc new file mode 100644 index 0000000..9decce3 --- /dev/null +++ b/src/include.new/c++/3.4/bits/istream.tcc @@ -0,0 +1,1192 @@ +// istream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _ISTREAM_TCC +#define _ISTREAM_TCC 1 + +#pragma GCC system_header + +#include +#include // For flush() + +namespace std +{ + template + basic_istream<_CharT, _Traits>::sentry:: + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + if (__in.good()) + { + if (__in.tie()) + __in.tie()->flush(); + if (!__noskip && (__in.flags() & ios_base::skipws)) + { + const __int_type __eof = traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + const __ctype_type& __ct = __check_facet(__in._M_ctype); + while (!traits_type::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, + traits_type::to_char_type(__c))) + __c = __sb->snextc(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 195. Should basic_istream::sentry's constructor ever + // set eofbit? + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + } + + if (__in.good() && __err == ios_base::goodbit) + _M_ok = true; + else + { + __err |= ios_base::failbit; + __in.setstate(__err); + } + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__istream_type& (*__pf)(__istream_type&)) + { return __pf(*this); } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__ios_type& (*__pf)(__ios_type&)) + { + __pf(*this); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(ios_base& (*__pf)(ios_base&)) + { + __pf(*this); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(bool& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + if (!(__err & ios_base::failbit) + && (numeric_limits::min() <= __l + && __l <= numeric_limits::max())) + __n = __l; + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + if (!(__err & ios_base::failbit) + && (numeric_limits::min() <= __l + && __l <= numeric_limits::max())) + __n = __l; + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } +#endif + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(float& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(void*& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__streambuf_type* __sbout) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, false); + if (__cerb && __sbout) + { + try + { + if (!__copy_streambufs(this->rdbuf(), __sbout)) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbout) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + get(void) + { + const int_type __eof = traits_type::eof(); + int_type __c = __eof; + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + __c = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__c, __eof)) + _M_gcount = 1; + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type& __c) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __cb = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__cb, traits_type::eof())) + { + _M_gcount = 1; + __c = traits_type::to_char_type(__cb); + } + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(__streambuf_type& __sb, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __this_sb = this->rdbuf(); + int_type __c = __this_sb->sgetc(); + char_type __c2 = traits_type::to_char_type(__c); + + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) + && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) + { + ++_M_gcount; + __c = __this_sb->snextc(); + __c2 = traits_type::to_char_type(__c); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + __n - _M_gcount - 1); + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + } + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __idelim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n, int_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c; + + if (__n != numeric_limits::max()) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) + { + ++_M_gcount; + if (traits_type::eq_int_type(__c, __delim)) + break; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + peek(void) + { + int_type __c = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __c = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + read(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + _M_gcount = this->rdbuf()->sgetn(__s, __n); + if (_M_gcount != __n) + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + streamsize + basic_istream<_CharT, _Traits>:: + readsome(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // Cannot compare int_type with streamsize generically. + const streamsize __num = this->rdbuf()->in_avail(); + if (__num > 0) + _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); + else if (__num == -1) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return _M_gcount; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + putback(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + unget(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sungetc(), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + int + basic_istream<_CharT, _Traits>:: + sync(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + int __ret = -1; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __streambuf_type* __sb = this->rdbuf(); + if (__sb) + { + if (__sb->pubsync() == -1) + __err |= ios_base::badbit; + else + __ret = 0; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __ret; + } + + template + typename basic_istream<_CharT, _Traits>::pos_type + basic_istream<_CharT, _Traits>:: + tellg(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(pos_type __pos) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(off_type __off, ios_base::seekdir __dir) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + // 27.6.1.2.3 Character extraction templates + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __int_type __cb = __in.rdbuf()->sbumpc(); + if (!_Traits::eq_int_type(__cb, _Traits::eof())) + __c = _Traits::to_char_type(__cb); + else + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + if (__err) + __in.setstate(__err); + } + return __in; + } + + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Figure out how many characters to extract. + streamsize __num = __in.width(); + if (__num <= 0) + __num = numeric_limits::max(); + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + + const int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + int_type __c = __sb->sgetc(); + + while (__extracted < __num - 1 + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + _Traits::to_char_type(__c))) + { + *__s++ = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 68. Extractors for char* should store null at end + *__s = char_type(); + __in.width(0); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + // 27.6.1.4 Standard basic_istream manipulators + template + basic_istream<_CharT,_Traits>& + ws(basic_istream<_CharT,_Traits>& __in) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename __istream_type::int_type __int_type; + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (!_Traits::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) + __c = __sb->snextc(); + + if (_Traits::eq_int_type(__c, __eof)) + __in.setstate(ios_base::eofbit); + return __in; + } + + // 21.3.7.9 basic_string::getline and operators + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + // 211. operator>>(istream&, string&) doesn't set failbit + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT,_Traits,_Alloc>& __str) + { return getline(__in, __str, __in.widen('\n')); } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_istream; + extern template istream& ws(istream&); + extern template istream& operator>>(istream&, char&); + extern template istream& operator>>(istream&, char*); + extern template istream& operator>>(istream&, unsigned char&); + extern template istream& operator>>(istream&, signed char&); + extern template istream& operator>>(istream&, unsigned char*); + extern template istream& operator>>(istream&, signed char*); + + extern template class basic_iostream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_istream; + extern template wistream& ws(wistream&); + extern template wistream& operator>>(wistream&, wchar_t&); + extern template wistream& operator>>(wistream&, wchar_t*); + + extern template class basic_iostream; +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/list.tcc b/src/include.new/c++/3.4/bits/list.tcc new file mode 100644 index 0000000..aaaa8c3 --- /dev/null +++ b/src/include.new/c++/3.4/bits/list.tcc @@ -0,0 +1,377 @@ +// List implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file list.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_TCC +#define _LIST_TCC 1 + +namespace _GLIBCXX_STD +{ + template + void + _List_base<_Tp,_Alloc>:: + _M_clear() + { + typedef _List_node<_Tp> _Node; + _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); + while (__cur != &this->_M_impl._M_node) + { + _Node* __tmp = __cur; + __cur = static_cast<_Node*>(__cur->_M_next); + std::_Destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + } + + template + typename list<_Tp,_Alloc>::iterator + list<_Tp,_Alloc>:: + insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + return __tmp; + } + + template + typename list<_Tp,_Alloc>::iterator + list<_Tp,_Alloc>:: + erase(iterator __position) + { + iterator __ret = __position._M_node->_M_next; + _M_erase(__position); + return __ret; + } + + template + void + list<_Tp,_Alloc>:: + resize(size_type __new_size, const value_type& __x) + { + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); + } + + template + list<_Tp,_Alloc>& + list<_Tp,_Alloc>:: + operator=(const list& __x) + { + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; + } + + template + void + list<_Tp,_Alloc>:: + _M_fill_assign(size_type __n, const value_type& __val) + { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); + } + + template + template + void + list<_Tp,_Alloc>:: + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) + { + iterator __first1 = begin(); + iterator __last1 = end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + + template + void + list<_Tp,_Alloc>:: + remove(const value_type& __value) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (*__first == __value) + _M_erase(__first); + __first = __next; + } + } + + template + void + list<_Tp,_Alloc>:: + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + list<_Tp,_Alloc>:: + merge(list& __x) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + void + list<_Tp,_Alloc>:: + sort() + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1) ); + swap( *(__fill-1) ); + } + } + + template + template + void + list<_Tp,_Alloc>:: + remove_if(_Predicate __pred) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (__pred(*__first)) + _M_erase(__first); + __first = __next; + } + } + + template + template + void + list<_Tp,_Alloc>:: + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + template + void + list<_Tp,_Alloc>:: + merge(list& __x, _StrictWeakOrdering __comp) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + template + void + list<_Tp,_Alloc>:: + sort(_StrictWeakOrdering __comp) + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1), __comp ); + swap( *(__fill-1) ); + } + } +} // namespace std + +#endif /* _LIST_TCC */ + diff --git a/src/include.new/c++/3.4/bits/locale_classes.h b/src/include.new/c++/3.4/bits/locale_classes.h new file mode 100644 index 0000000..95d9c03 --- /dev/null +++ b/src/include.new/c++/3.4/bits/locale_classes.h @@ -0,0 +1,599 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file localefwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_CLASSES_H +#define _LOCALE_CLASSES_H 1 + +#pragma GCC system_header + +#include +#include // For strcmp. +#include +#include +#include + +namespace std +{ + // 22.1.1 Class locale + /** + * @brief Container class for localization functionality. + * + * The locale class is first a class wrapper for C library locales. It is + * also an extensible container for user-defined localization. A locale is + * a collection of facets that implement various localization features such + * as money, time, and number printing. + * + * Constructing C++ locales does not change the C library locale. + * + * This library supports efficient construction and copying of locales + * through a reference counting implementation of the locale class. + */ + class locale + { + public: + // Types: + /// Definition of locale::category. + typedef int category; + + // Forward decls and friends: + class facet; + class id; + class _Impl; + + friend class facet; + friend class _Impl; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; + + //@{ + /** + * @brief Category values. + * + * The standard category values are none, ctype, numeric, collate, time, + * monetary, and messages. They form a bitmask that supports union and + * intersection. The category all is the union of these values. + * + * @if maint + * NB: Order must match _S_facet_categories definition in locale.cc + * @endif + */ + static const category none = 0; + static const category ctype = 1L << 0; + static const category numeric = 1L << 1; + static const category collate = 1L << 2; + static const category time = 1L << 3; + static const category monetary = 1L << 4; + static const category messages = 1L << 5; + static const category all = (ctype | numeric | collate | + time | monetary | messages); + //@} + + // Construct/copy/destroy: + + /** + * @brief Default constructor. + * + * Constructs a copy of the global locale. If no locale has been + * explicitly set, this is the "C" locale. + */ + locale() throw(); + + /** + * @brief Copy constructor. + * + * Constructs a copy of @a other. + * + * @param other The locale to copy. + */ + locale(const locale& __other) throw(); + + /** + * @brief Named locale constructor. + * + * Constructs a copy of the named C library locale. + * + * @param s Name of the locale to construct. + * @throw std::runtime_error if s is null or an undefined locale. + */ + explicit + locale(const char* __s); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale named by @a s. If base is + * named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param s Name of the locale to use facets from. + * @param cat Set of categories defining the facets to use from s. + * @throw std::runtime_error if s is null or an undefined locale. + */ + locale(const locale& __base, const char* __s, category __cat); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale @a add. If @a base and @a + * add are named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param add The locale to use facets from. + * @param cat Set of categories defining the facets to use from add. + */ + locale(const locale& __base, const locale& __add, category __cat); + + /** + * @brief Construct locale with another facet. + * + * Constructs a copy of the locale @a other. The facet @f is added to + * @other, replacing an existing facet of type Facet if there is one. If + * @f is null, this locale is a copy of @a other. + * + * @param other The locale to copy. + * @param f The facet to add in. + */ + template + locale(const locale& __other, _Facet* __f); + + /// Locale destructor. + ~locale() throw(); + + /** + * @brief Assignment operator. + * + * Set this locale to be a copy of @a other. + * + * @param other The locale to copy. + * @return A reference to this locale. + */ + const locale& + operator=(const locale& __other) throw(); + + /** + * @brief Construct locale with another facet. + * + * Constructs and returns a new copy of this locale. Adds or replaces an + * existing facet of type Facet from the locale @a other into the new + * locale. + * + * @param Facet The facet type to copy from other + * @param other The locale to copy from. + * @return Newly constructed locale. + * @throw std::runtime_error if other has no facet of type Facet. + */ + template + locale + combine(const locale& __other) const; + + // Locale operations: + /** + * @brief Return locale name. + * @return Locale name or "*" if unnamed. + */ + string + name() const; + + /** + * @brief Locale equality. + * + * @param other The locale to compare against. + * @return True if other and this refer to the same locale instance, are + * copies, or have the same name. False otherwise. + */ + bool + operator==(const locale& __other) const throw (); + + /** + * @brief Locale inequality. + * + * @param other The locale to compare against. + * @return ! (*this == other) + */ + inline bool + operator!=(const locale& __other) const throw () + { return !(this->operator==(__other)); } + + /** + * @brief Compare two strings according to collate. + * + * Template operator to compare two strings using the compare function of + * the collate facet in this locale. One use is to provide the locale to + * the sort function. For example, a vector v of strings could be sorted + * according to locale loc by doing: + * @code + * std::sort(v.begin(), v.end(), loc); + * @endcode + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return True if collate facet compares s1 < s2, else false. + */ + template + bool + operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, + const basic_string<_Char, _Traits, _Alloc>& __s2) const; + + // Global locale objects: + /** + * @brief Set global locale + * + * This function sets the global locale to the argument and returns a + * copy of the previous global locale. If the argument has a name, it + * will also call std::setlocale(LC_ALL, loc.name()). + * + * @param locale The new locale to make global. + * @return Copy of the old global locale. + */ + static locale + global(const locale&); + + /** + * @brief Return reference to the "C" locale. + */ + static const locale& + classic(); + + private: + // The (shared) implementation + _Impl* _M_impl; + + // The "C" reference locale + static _Impl* _S_classic; + + // Current global locale + static _Impl* _S_global; + + // Names of underlying locale categories. + // NB: locale::global() has to know how to modify all the + // underlying categories, not just the ones required by the C++ + // standard. + static const char* const* const _S_categories; + + // Number of standard categories. For C++, these categories are + // collate, ctype, monetary, numeric, time, and messages. These + // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, + // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE + // 1003.1-2001) specifies LC_MESSAGES. + // In addition to the standard categories, the underlying + // operating system is allowed to define extra LC_* + // macros. For GNU systems, the following are also valid: + // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, + // and LC_IDENTIFICATION. + static const size_t _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + explicit + locale(_Impl*) throw(); + + static void + _S_initialize(); + + static void + _S_initialize_once(); + + static category + _S_normalize_category(category); + + void + _M_coalesce(const locale& __base, const locale& __add, category __cat); + }; + + + // 22.1.1.1.2 Class locale::facet + /** + * @brief Localization functionality base class. + * + * The facet class is the base class for a localization feature, such as + * money, time, and number printing. It provides common support for facets + * and reference management. + * + * Facets may not be copied or assigned. + */ + class locale::facet + { + private: + friend class locale; + friend class locale::_Impl; + + mutable _Atomic_word _M_refcount; + + // Contains data from the underlying "C" library for the classic locale. + static __c_locale _S_c_locale; + + // String literal for the name of the classic locale. + static const char _S_c_name[2]; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + static void + _S_initialize_once(); + + protected: + /** + * @brief Facet constructor. + * + * This is the constructor provided by the standard. If refs is 0, the + * facet is destroyed when the last referencing locale is destroyed. + * Otherwise the facet will never be destroyed. + * + * @param refs The initial value for reference count. + */ + explicit + facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) + { } + + /// Facet destructor. + virtual + ~facet(); + + static void + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); + + static __c_locale + _S_clone_c_locale(__c_locale& __cloc); + + static void + _S_destroy_c_locale(__c_locale& __cloc); + + // Returns data from the underlying "C" library data for the + // classic locale. + static __c_locale + _S_get_c_locale(); + + static const char* + _S_get_c_name(); + + private: + inline void + _M_add_reference() const throw() + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + inline void + _M_remove_reference() const throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch (...) + { } + } + } + + facet(const facet&); // Not defined. + + facet& + operator=(const facet&); // Not defined. + }; + + + // 22.1.1.1.3 Class locale::id + /** + * @brief Facet ID class. + * + * The ID class provides facets with an index used to identify them. + * Every facet class must define a public static member locale::id, or be + * derived from a facet that provides this member, otherwise the facet + * cannot be used in a locale. The locale::id ensures that each class + * type gets a unique identifier. + */ + class locale::id + { + private: + friend class locale; + friend class locale::_Impl; + + template + friend const _Facet& + use_facet(const locale&); + + template + friend bool + has_facet(const locale&) throw (); + + // NB: There is no accessor for _M_index because it may be used + // before the constructor is run; the effect of calling a member + // function (even an inline) would be undefined. + mutable size_t _M_index; + + // Last id number assigned. + static _Atomic_word _S_refcount; + + void + operator=(const id&); // Not defined. + + id(const id&); // Not defined. + + public: + // NB: This class is always a static data member, and thus can be + // counted on to be zero-initialized. + /// Constructor. + id() { } + + size_t + _M_id() const; + }; + + + // Implementation object for locale. + class locale::_Impl + { + public: + // Friends. + friend class locale; + friend class locale::facet; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; + + private: + // Data Members. + _Atomic_word _M_refcount; + const facet** _M_facets; + size_t _M_facets_size; + const facet** _M_caches; + char** _M_names; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_messages[]; + static const locale::id* const* const _S_facet_categories[]; + + inline void + _M_add_reference() throw() + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + inline void + _M_remove_reference() throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch(...) + { } + } + } + + _Impl(const _Impl&, size_t); + _Impl(const char*, size_t); + _Impl(size_t) throw(); + + ~_Impl() throw(); + + _Impl(const _Impl&); // Not defined. + + void + operator=(const _Impl&); // Not defined. + + inline bool + _M_check_same_name() + { + bool __ret = true; + for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) + __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0; + return __ret; + } + + void + _M_replace_categories(const _Impl*, category); + + void + _M_replace_category(const _Impl*, const locale::id* const*); + + void + _M_replace_facet(const _Impl*, const locale::id*); + + void + _M_install_facet(const locale::id*, const facet*); + + template + inline void + _M_init_facet(_Facet* __facet) + { _M_install_facet(&_Facet::id, __facet); } + + void + _M_install_cache(const facet* __cache, size_t __index) throw() + { + __cache->_M_add_reference(); + _M_caches[__index] = __cache; + } + }; + + template + locale::locale(const locale& __other, _Facet* __f) + { + _M_impl = new _Impl(*__other._M_impl, 1); + + char* _M_tmp_names[_S_categories_size]; + size_t __i = 0; + try + { + for (; __i < _S_categories_size; ++__i) + { + _M_tmp_names[__i] = new char[2]; + std::strcpy(_M_tmp_names[__i], "*"); + } + _M_impl->_M_install_facet(&_Facet::id, __f); + } + catch(...) + { + _M_impl->_M_remove_reference(); + for (size_t __j = 0; __j < __i; ++__j) + delete [] _M_tmp_names[__j]; + __throw_exception_again; + } + + for (size_t __k = 0; __k < _S_categories_size; ++__k) + { + delete [] _M_impl->_M_names[__k]; + _M_impl->_M_names[__k] = _M_tmp_names[__k]; + } + } +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/locale_facets.h b/src/include.new/c++/3.4/bits/locale_facets.h new file mode 100644 index 0000000..db0e951 --- /dev/null +++ b/src/include.new/c++/3.4/bits/locale_facets.h @@ -0,0 +1,4558 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file locale_facets.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FACETS_H +#define _LOCALE_FACETS_H 1 + +#pragma GCC system_header + +#include // For struct tm +#include // For wctype_t +#include +#include // For ios_base, ios_base::iostate +#include + +namespace std +{ + // NB: Don't instantiate required wchar_t facets if no wchar_t support. +#ifdef _GLIBCXX_USE_WCHAR_T +# define _GLIBCXX_NUM_FACETS 28 +#else +# define _GLIBCXX_NUM_FACETS 14 +#endif + + // Convert string to numeric value of type _Tv and store results. + // NB: This is specialized for all required types, there is no + // generic definition. + template + void + __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, + const __c_locale& __cloc); + + // Explicit specializations for required types. + template<> + void + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&); + + // NB: __pad is a struct, rather than a function, so it can be + // partially-specialized. + template + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, + const streamsize __oldlen, const bool __num); + }; + + // Used by both numeric and monetary facets. + // Inserts "group separator" characters into an array of characters. + // It's recursive, one iteration per group. It moves the characters + // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this + // only with __glen != 0. + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last); + + // This template permits specializing facet output code for + // ostreambuf_iterator. For ostreambuf_iterator, sputn is + // significantly more efficient than incrementing iterators. + template + inline + ostreambuf_iterator<_CharT> + __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) + { + __s._M_put(__ws, __len); + return __s; + } + + // This is the unspecialized form of the template. + template + inline + _OutIter + __write(_OutIter __s, const _CharT* __ws, int __len) + { + for (int __j = 0; __j < __len; __j++, ++__s) + *__s = __ws[__j]; + return __s; + } + + + // 22.2.1.1 Template class ctype + // Include host and configuration specific ctype enums for ctype_base. + #include + + // Common base for ctype<_CharT>. + /** + * @brief Common base for ctype facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abtract stubs for the protected virtual + * functions. + */ + template + class __ctype_abstract_base : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter + typedef _CharT char_type; + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * It does so by returning the value of ctype::do_is(). + * + * @param c The char_type to compare the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + bool + is(mask __m, char_type __c) const + { return this->do_is(__m, __c); } + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the char array. It does so by returning the value of + * ctype::do_is(). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + const char_type* + is(const char_type *__lo, const char_type *__hi, mask *__vec) const + { return this->do_is(__lo, __hi, __vec); } + + /** + * @brief Find char_type matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. It does so by returning + * ctype::do_scan_is(). + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to matching char_type if found, else @a hi. + */ + const char_type* + scan_is(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_is(__m, __lo, __hi); } + + /** + * @brief Find char_type not matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is false. It does so by returning + * ctype::do_scan_not(). + * + * @param m The mask to compare against. + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return Pointer to non-matching char if found, else @a hi. + */ + const char_type* + scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_not(__m, __lo, __hi); } + + /** + * @brief Convert to uppercase. + * + * This function converts the argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. It does + * so by returning ctype::do_toupper(). + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char_type in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. It does so + * by returning ctype:: do_toupper(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the argument to lowercase if possible. If + * not possible (for example, '2'), returns the argument. It does so + * by returning ctype::do_tolower(c). + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char_type in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. It does so + * by returning ctype:: do_tolower(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char to char_type + * + * This function converts the char argument to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type. + */ + char_type + widen(char __c) const + { return this->do_widen(__c); } + + /** + * @brief Widen array to char_type + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { return this->do_widen(__lo, __hi, __to); } + + /** + * @brief Narrow char_type to char + * + * This function converts the char_type to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. It does so by returning + * ctype::do_narrow(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + char + narrow(char_type __c, char __dfault) const + { return this->do_narrow(__c, __dfault); } + + /** + * @brief Narrow array to char array + * + * This function converts each char_type in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char_type in the input that cannot be + * converted, @a dfault is used instead. It does so by returning + * ctype::do_narrow(lo, hi, dfault, to). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { return this->do_narrow(__lo, __hi, __dfault, __to); } + + protected: + explicit + __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } + + virtual + ~__ctype_abstract_base() { } + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The char_type to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const = 0; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const = 0; + + /** + * @brief Find char_type matching mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Find char_type not matching mask + * + * This function searches for and returns a pointer to the first + * char_type c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char_type argument to uppercase + * if possible. If not possible (for example, '2'), returns the + * argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const = 0; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const = 0; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Widen char + * + * This virtual function converts the char to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type + */ + virtual char_type + do_widen(char) const = 0; + + /** + * @brief Widen char array + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, + char_type* __dest) const = 0; + + /** + * @brief Narrow char_type to char + * + * This virtual function converts the argument to char using the + * simplest reasonable transformation. If the conversion fails, dfault + * is returned instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const = 0; + + /** + * @brief Narrow char_type array to char + * + * This virtual function converts each char_type in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any element in the input that + * cannot be converted, @a dfault is used instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const = 0; + }; + + // NB: Generic, mostly useless implementation. + /** + * @brief Template ctype facet + * + * This template class defines classification and conversion functions for + * character sets. It wraps functionality. Ctype gets used by + * streams for many I/O operations. + * + * This template provides the protected virtual functions the developer + * will have to replace in a derived class or specialization to make a + * working facet. The public functions that access them are defined in + * __ctype_abstract_base, to allow for implementation flexibility. See + * ctype for an example. The functions are documented in + * __ctype_abstract_base. + * + * Note: implementations are provided for all the protected virtual + * functions, but will likely not be useful. + */ + template + class ctype : public __ctype_abstract_base<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef typename __ctype_abstract_base<_CharT>::mask mask; + + /// The facet id for ctype + static locale::id id; + + explicit + ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } + + protected: + virtual + ~ctype(); + + virtual bool + do_is(mask __m, char_type __c) const; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual char_type + do_toupper(char_type __c) const; + + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_tolower(char_type __c) const; + + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_widen(char __c) const; + + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + }; + + template + locale::id ctype<_CharT>::id; + + // 22.2.1.3 ctype specialization. + /** + * @brief The ctype specialization. + * + * This class defines classification and conversion functions for + * the char type. It gets used by char streams for many I/O + * operations. The char specialization provides a number of + * optimizations as well. + */ + template<> + class ctype : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter char. + typedef char char_type; + + protected: + // Data Members: + __c_locale _M_c_locale_ctype; + bool _M_del; + __to_type _M_toupper; + __to_type _M_tolower; + const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast(-1)]; + mutable char _M_narrow[1 + static_cast(-1)]; + mutable char _M_narrow_ok; // 0 uninitialized, 1 init, + // 2 memcpy can't be used + + public: + /// The facet id for ctype + static locale::id id; + /// The size of the mask table. It is SCHAR_MAX + 1. + static const size_t table_size = 1 + static_cast(-1); + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param table If non-zero, table is used as the per-char mask. + * Else classic_table() is used. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param table If non-zero, table is used as the per-char mask. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, + size_t __refs = 0); + + /** + * @brief Test char classification. + * + * This function compares the mask table[c] to @a m. + * + * @param c The char to compare the mask of. + * @param m The mask to compare against. + * @return True if m & table[c] is true, false otherwise. + */ + inline bool + is(mask __m, char __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char in the range [lo, hi) and + * successively writes it to vec. vec must have as many elements as + * the char array. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + inline const char* + is(const char* __lo, const char* __hi, mask* __vec) const; + + /** + * @brief Find char matching a mask + * + * This function searches for and returns the first char in [lo,hi) for + * which is(m,char) is true. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char if found, else @a hi. + */ + inline const char* + scan_is(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Find char not matching a mask + * + * This function searches for and returns a pointer to the first char + * in [lo,hi) for which is(m,char) is false. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char if found, else @a hi. + */ + inline const char* + scan_not(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This function converts the char argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * toupper() acts as if it returns ctype::do_toupper(c). + * do_toupper() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char in the range [lo,hi) to uppercase + * if possible. Other chars remain untouched. + * + * toupper() acts as if it returns ctype:: do_toupper(lo, hi). + * do_toupper() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the char argument to lowercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * tolower() acts as if it returns ctype::do_tolower(c). + * do_tolower() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char in the range [lo,hi) to lowercase + * if possible. Other chars remain untouched. + * + * tolower() acts as if it returns ctype:: do_tolower(lo, hi). + * do_tolower() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char + * + * This function converts the char to char_type using the simplest + * reasonable transformation. For an underived ctype facet, the + * argument will be returned unchanged. + * + * This function works as if it returns ctype::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + char_type + widen(char __c) const + { + if (_M_widen_ok) + return _M_widen[static_cast(__c)]; + this->_M_widen_init(); + return this->do_widen(__c); + } + + /** + * @brief Widen char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { + if (_M_widen_ok == 1) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_widen_ok) + _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } + + /** + * @brief Narrow char + * + * This function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype facet, @a c + * will be returned unchanged. + * + * This function works as if it returns ctype::do_narrow(c). + * do_narrow() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted character. + */ + char + narrow(char_type __c, char __dfault) const + { + if (_M_narrow[static_cast(__c)]) + return _M_narrow[static_cast(__c)]; + const char __t = do_narrow(__c, __dfault); + if (__t != __dfault) + _M_narrow[static_cast(__c)] = __t; + return __t; + } + + /** + * @brief Narrow char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char in the input that cannot be + * converted, @a dfault is used instead. For an underived ctype + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype::do_narrow(lo, hi, + * dfault, to). do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { + if (__builtin_expect(_M_narrow_ok == 1, true)) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_narrow_ok) + _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } + + protected: + /// Returns a pointer to the mask table provided to the constructor, or + /// the default from classic_table() if none was provided. + const mask* + table() const throw() + { return _M_table; } + + /// Returns a pointer to the C locale mask table. + static const mask* + classic_table() throw(); + + /** + * @brief Destructor. + * + * This function deletes table() if @a del was true in the + * constructor. + */ + virtual + ~ctype(); + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char in the range [lo,hi) to + * uppercase if possible. Other chars remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the char argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char in the range [lo,hi) to + * lowercase if possible. Other chars remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. For an underived ctype facet, the + * argument will be returned unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + virtual char_type + do_widen(char __c) const + { return __c; } + + /** + * @brief Widen char array + * + * This function converts each char in the range [lo,hi) to char using + * the simplest reasonable transformation. For an underived + * ctype facet, the argument will be copied unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + /** + * @brief Narrow char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype facet, @a c will be + * returned unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type __c, char) const + { return __c; } + + /** + * @brief Narrow char array to char array + * + * This virtual function converts each char in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any char in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype facet, the argument will be copied unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char, char* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + private: + + void _M_widen_init() const + { + char __tmp[sizeof(_M_widen)]; + for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) + __tmp[__i] = __i; + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); + + _M_widen_ok = 1; + // Set _M_widen_ok to 2 if memcpy can't be used. + if (memcmp(__tmp, _M_widen, sizeof(_M_widen))) + _M_widen_ok = 2; + } + + // Fill in the narrowing cache and flag whether all values are + // valid or not. _M_narrow_ok is set to 2 if memcpy can't + // be used. + void _M_narrow_init() const + { + char __tmp[sizeof(_M_narrow)]; + for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) + __tmp[__i] = __i; + do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); + + _M_narrow_ok = 1; + if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) + _M_narrow_ok = 2; + else + { + // Deal with the special case of zero: renarrow with a + // different default and compare. + char __c; + do_narrow(__tmp, __tmp + 1, 1, &__c); + if (__c == 1) + _M_narrow_ok = 2; + } + } + }; + + template<> + const ctype& + use_facet >(const locale& __loc); + +#ifdef _GLIBCXX_USE_WCHAR_T + // 22.2.1.3 ctype specialization + /** + * @brief The ctype specialization. + * + * This class defines classification and conversion functions for the + * wchar_t type. It gets used by wchar_t streams for many I/O operations. + * The wchar_t specialization provides a number of optimizations as well. + * + * ctype inherits its public methods from + * __ctype_abstract_base. + */ + template<> + class ctype : public __ctype_abstract_base + { + public: + // Types: + /// Typedef for the template parameter wchar_t. + typedef wchar_t char_type; + typedef wctype_t __wmask_type; + + protected: + __c_locale _M_c_locale_ctype; + + // Pre-computed narrowed and widened chars. + bool _M_narrow_ok; + char _M_narrow[128]; + wint_t _M_widen[1 + static_cast(-1)]; + + // Pre-computed elements for do_is. + mask _M_bit[16]; + __wmask_type _M_wmask[16]; + + public: + // Data Members: + /// The facet id for ctype + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + ctype(size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, size_t __refs = 0); + + protected: + __wmask_type + _M_convert_to_wmask(const mask __m) const; + + /// Destructor + virtual + ~ctype(); + + /** + * @brief Test wchar_t classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The wchar_t to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each wchar_t in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + /** + * @brief Find wchar_t matching mask + * + * This function searches for and returns the first wchar_t c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + /** + * @brief Find wchar_t not matching mask + * + * This function searches for and returns a pointer to the first + * wchar_t c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the wchar_t argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The uppercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The lowercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char to wchar_t + * + * This virtual function converts the char to wchar_t using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be cast to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted wchar_t. + */ + virtual char_type + do_widen(char) const; + + /** + * @brief Widen char array to wchar_t array + * + * This function converts each char in the input to wchar_t using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be copied, casting each element to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + /** + * @brief Narrow wchar_t to char + * + * This virtual function converts the argument to char using + * the simplest reasonable transformation. If the conversion + * fails, dfault is returned instead. For an underived + * ctype facet, @a c will be cast to char and + * returned. + * + * do_narrow() is a hook for a derived facet to change the + * behavior of narrowing. do_narrow() must always return the + * same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The wchar_t to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const; + + /** + * @brief Narrow wchar_t array to char array + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any wchar_t in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype facet, the argument will be copied, casting each + * element to char. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + + // For use at construction time only. + void + _M_initialize_ctype(); + }; + + template<> + const ctype& + use_facet >(const locale& __loc); +#endif //_GLIBCXX_USE_WCHAR_T + + // Include host and configuration specific ctype inlines. + #include + + // 22.2.1.2 Template class ctype_byname + template + class ctype_byname : public ctype<_CharT> + { + public: + typedef _CharT char_type; + + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname() { }; + }; + + // 22.2.1.4 Class ctype_byname specializations. + template<> + ctype_byname::ctype_byname(const char*, size_t refs); + + template<> + ctype_byname::ctype_byname(const char*, size_t refs); + + // 22.2.1.5 Template class codecvt + #include + + // 22.2.2 The numeric category. + class __num_base + { + public: + // NB: Code depends on the order of _S_atoms_out elements. + // Below are the indices into _S_atoms_out. + enum + { + _S_ominus, + _S_oplus, + _S_ox, + _S_oX, + _S_odigits, + _S_odigits_end = _S_odigits + 16, + _S_oudigits = _S_odigits_end, + _S_oudigits_end = _S_oudigits + 16, + _S_oe = _S_odigits + 14, // For scientific notation, 'e' + _S_oE = _S_oudigits + 14, // For scientific notation, 'E' + _S_oend = _S_oudigits_end + }; + + // A list of valid numeric literals for output. This array + // contains chars that will be passed through the current locale's + // ctype<_CharT>.widen() and then used to render numbers. + // For the standard "C" locale, this is + // "-+xX0123456789abcdef0123456789ABCDEF". + static const char* _S_atoms_out; + + // String literal of acceptable (narrow) input, for num_get. + // "-+xX0123456789abcdefABCDEF" + static const char* _S_atoms_in; + + enum + { + _S_iminus, + _S_iplus, + _S_ix, + _S_iX, + _S_izero, + _S_ie = _S_izero + 14, + _S_iE = _S_izero + 20, + _S_iend = 26 + }; + + // num_put + // Construct and return valid scanf format for floating point types. + static void + _S_format_float(const ios_base& __io, char* __fptr, char __mod); + }; + + template + struct __numpunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + const _CharT* _M_truename; + size_t _M_truename_size; + const _CharT* _M_falsename; + size_t _M_falsename_size; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + + // A list of valid numeric literals for output: in the standard + // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_out[__num_base::_S_oend]; + + // A list of valid numeric literals for input: in the standard + // "C" locale, this is "-+xX0123456789abcdefABCDEF" + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_in[__num_base::_S_iend]; + + bool _M_allocated; + + __numpunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), + _M_falsename_size(0), _M_decimal_point(_CharT()), + _M_thousands_sep(_CharT()), _M_allocated(false) + { } + + ~__numpunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __numpunct_cache& + operator=(const __numpunct_cache&); + + explicit + __numpunct_cache(const __numpunct_cache&); + }; + + template + __numpunct_cache<_CharT>::~__numpunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_truename; + delete [] _M_falsename; + } + } + + /** + * @brief Numpunct facet. + * + * This facet stores several pieces of information related to printing and + * scanning numbers, such as the decimal point character. It takes a + * template parameter specifying the char type. The numpunct facet is + * used by streams for many I/O operations involving numbers. + * + * The numpunct template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from a numpunct facet. + */ + template + class numpunct : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __numpunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Numpunct constructor. + * + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up the + * predefined locale facets. + * + * @param cache __numpunct_cache object. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(__cloc); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * numpunct::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * numpunct::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of a number. Groupings indicate where thousands + * separators should be inserted in the integer part of a number. + * + * Each char in the return string is interpret as an integer + * rather than a character. These numbers represent the number + * of digits in a group. The first char in the string + * represents the number of digits in the least significant + * group. If a char is negative, it indicates an unlimited + * number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is + * applied to the number 123456789, this corresponds to + * 12,34,56,789. Note that if the string was "32", this would + * put more than 50 digits into the least significant group if + * the character set is ASCII. + * + * The string is returned by calling + * numpunct::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return string representation of bool true. + * + * This function returns a string_type containing the text + * representation for true bool variables. It does so by calling + * numpunct::do_truename(). + * + * @return string_type representing printed form of true. + */ + string_type + truename() const + { return this->do_truename(); } + + /** + * @brief Return string representation of bool false. + * + * This function returns a string_type containing the text + * representation for false bool variables. It does so by calling + * numpunct::do_falsename(). + * + * @return string_type representing printed form of false. + */ + string_type + falsename() const + { return this->do_falsename(); } + + protected: + /// Destructor. + virtual + ~numpunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return string representation of bool true. + * + * Returns a string_type containing the text representation for true + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of true. + */ + virtual string_type + do_truename() const + { return _M_data->_M_truename; } + + /** + * @brief Return string representation of bool false. + * + * Returns a string_type containing the text representation for false + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of false. + */ + virtual string_type + do_falsename() const + { return _M_data->_M_falsename; } + + // For use at construction time only. + void + _M_initialize_numpunct(__c_locale __cloc = NULL); + }; + + template + locale::id numpunct<_CharT>::id; + + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); +#endif + + template + class numpunct_byname : public numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + numpunct_byname(const char* __s, size_t __refs = 0) + : numpunct<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_numpunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~numpunct_byname() { } + }; + + /** + * @brief Facet for parsing number strings. + * + * This facet encapsulates the code to parse and return a number + * from a string. It is used by the istream numeric extraction + * operators. + * + * The num_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_get facet. + */ + template + class num_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the bool @a v. It does so by calling + * num_put::do_put(). + * + * If ios_base::boolalpha is set, attempts to read + * ctype::truename() or ctype::falsename(). Sets + * @a v to true or false if successful. Sets err to + * ios_base::failbit if reading the string fails. Sets err to + * ios_base::eofbit if the stream is emptied. + * + * If ios_base::boolalpha is not set, proceeds as with reading a long, + * except if the value is 1, sets @a v to true, if the value is 0, sets + * @a v to false, and otherwise set err to ios_base::failbit. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * Parsing is affected by the flag settings in @a io. + * + * The basic parse is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, parses like the + * scanf %o specifier. Else if equal to ios_base::hex, parses like %X + * specifier. Else if basefield equal to 0, parses like the %i + * specifier. Otherwise, parses like %d for signed and %u for unsigned + * types. The matching type length modifier is also used. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %g specifier. The + * matching type length modifier is also used. + * + * The decimal point character used is numpunct::decimal_point(). + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + //@} + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the pointer variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %p specifier. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * Note that the digit grouping effect for pointers is a bit ambiguous + * in the standard and shouldn't be relied on. See DR 344. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + protected: + /// Destructor. + virtual ~num_get() { } + + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + string& __xtrc) const; + + template + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + _ValueT& __v) const; + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the variable @a v. This function is a + * hook for derived classes to change the value returned. @see get() + * for more details. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned short&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned int&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long&) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long long&) const; +#endif + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + float&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + void*&) const; + //@} + }; + + template + locale::id num_get<_CharT, _InIter>::id; + + + /** + * @brief Facet for converting numbers to strings. + * + * This facet encapsulates the code to convert a number to a string. It is + * used by the ostream numeric insertion operators. + * + * The num_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_put facet. + */ + template + class num_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric formatting. + * + * Formats the boolean @a v and inserts it into a stream. It does so + * by calling num_put::do_put(). + * + * If ios_base::boolalpha is set, writes ctype::truename() or + * ctype::falsename(). Otherwise formats @a v as an int. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const + { return this->do_put(__s, __f, __fill, __v); } + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the integral value @a v and inserts it into a + * stream. It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, formats like the + * printf %o specifier. Else if equal to ios_base::hex, formats like + * %x or %X with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu + * for unsigned values. Note that if both oct and hex are set, neither + * will take effect. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showbase is set, '0' precedes octal values (except 0) + * and '0[xX]' precedes hex values. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long __v) const + { return this->do_put(__s, __f, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long long __v) const + { return this->do_put(__s, __f, __fill, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the floating point value @a v and inserts it into a stream. + * It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::floatfield. If equal to ios_base::fixed, formats like the + * printf %f specifier. Else if equal to ios_base::scientific, formats + * like %e or %E with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %g or %G depending on uppercase. Note that + * if both fixed and scientific are set, the effect will also be like + * %g or %G. + * + * The output precision is given by io.precision(). This precision is + * capped at numeric_limits::digits10 + 2 (different for double and + * long double). The default precision is 6. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showpoint is set, a decimal point will always be + * output. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, double __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + long double __v) const + { return this->do_put(__s, __f, __fill, __v); } + //@} + + /** + * @brief Numeric formatting. + * + * Formats the pointer value @a v and inserts it into a stream. It + * does so by calling num_put::do_put(). + * + * This function formats @a v as an unsigned long with ios_base::hex + * and ios_base::showbase set. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + const void* __v) const + { return this->do_put(__s, __f, __fill, __v); } + + protected: + template + iter_type + _M_insert_float(iter_type, ios_base& __io, char_type __fill, + char __mod, _ValueT __v) const; + + void + _M_group_float(const char* __grouping, size_t __grouping_size, + char_type __sep, const char_type* __p, char_type* __new, + char_type* __cs, int& __len) const; + + template + iter_type + _M_insert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; + + void + _M_group_int(const char* __grouping, size_t __grouping_size, + char_type __sep, ios_base& __io, char_type* __new, + char_type* __cs, int& __len) const; + + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; + + /// Destructor. + virtual + ~num_put() { }; + + //@{ + /** + * @brief Numeric formatting. + * + * These functions do the work of formatting numeric values and + * inserting them into a stream. This function is a hook for derived + * classes to change the value returned. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, bool __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; + //@} + }; + + template + locale::id num_put<_CharT, _OutIter>::id; + + + /** + * @brief Facet for localized string comparison. + * + * This facet encapsulates the code to compare strings in a localized + * manner. + * + * The collate template uses protected virtual functions to provide + * the actual results. The public accessors forward the call to + * the virtual functions. These virtual functions are hooks for + * developers to implement the behavior they require from the + * collate facet. + */ + template + class collate : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by collate_byname as well. + __c_locale _M_c_locale_collate; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + collate(size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) + { } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Passed to the base facet class. + */ + explicit + collate(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) + { } + + /** + * @brief Compare two strings. + * + * This function compares two strings and returns the result by calling + * collate::do_compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + int + compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } + + /** + * @brief Transform string to comparable form. + * + * This function is a wrapper for strxfrm functionality. It takes the + * input string and returns a modified string that can be directly + * compared to other transformed strings. In the "C" locale, this + * function just returns a copy of the input string. In some other + * locales, it may replace two chars with one, change a char for + * another, etc. It does so by returning collate::do_transform(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Transformed string_type. + */ + string_type + transform(const _CharT* __lo, const _CharT* __hi) const + { return this->do_transform(__lo, __hi); } + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. It + * does so by returning collate::do_hash(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + long + hash(const _CharT* __lo, const _CharT* __hi) const + { return this->do_hash(__lo, __hi); } + + // Used to abstract out _CharT bits in virtual member functions, below. + int + _M_compare(const _CharT*, const _CharT*) const; + + size_t + _M_transform(_CharT*, const _CharT*, size_t) const; + + protected: + /// Destructor. + virtual + ~collate() + { _S_destroy_c_locale(_M_c_locale_collate); } + + /** + * @brief Compare two strings. + * + * This function is a hook for derived classes to change the value + * returned. @see compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual int + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const; + + /** + * @brief Transform string to comparable form. + * + * This function is a hook for derived classes to change the value + * returned. + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual string_type + do_transform(const _CharT* __lo, const _CharT* __hi) const; + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. This + * function is a hook for derived classes to change the value returned. + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + virtual long + do_hash(const _CharT* __lo, const _CharT* __hi) const; + }; + + template + locale::id collate<_CharT>::id; + + // Specializations. + template<> + int + collate::_M_compare(const char*, const char*) const; + + template<> + size_t + collate::_M_transform(char*, const char*, size_t) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + int + collate::_M_compare(const wchar_t*, const wchar_t*) const; + + template<> + size_t + collate::_M_transform(wchar_t*, const wchar_t*, size_t) const; +#endif + + template + class collate_byname : public collate<_CharT> + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + explicit + collate_byname(const char* __s, size_t __refs = 0) + : collate<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_collate); + this->_S_create_c_locale(this->_M_c_locale_collate, __s); + } + } + + protected: + virtual + ~collate_byname() { } + }; + + + /** + * @brief Time format ordering data. + * + * This class provides an enum representing different orderings of day, + * month, and year. + */ + class time_base + { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template + struct __timepunct_cache : public locale::facet + { + // List of all known timezones, with GMT first. + static const _CharT* _S_timezones[14]; + + const _CharT* _M_date_format; + const _CharT* _M_date_era_format; + const _CharT* _M_time_format; + const _CharT* _M_time_era_format; + const _CharT* _M_date_time_format; + const _CharT* _M_date_time_era_format; + const _CharT* _M_am; + const _CharT* _M_pm; + const _CharT* _M_am_pm_format; + + // Day names, starting with "C"'s Sunday. + const _CharT* _M_day1; + const _CharT* _M_day2; + const _CharT* _M_day3; + const _CharT* _M_day4; + const _CharT* _M_day5; + const _CharT* _M_day6; + const _CharT* _M_day7; + + // Abbreviated day names, starting with "C"'s Sun. + const _CharT* _M_aday1; + const _CharT* _M_aday2; + const _CharT* _M_aday3; + const _CharT* _M_aday4; + const _CharT* _M_aday5; + const _CharT* _M_aday6; + const _CharT* _M_aday7; + + // Month names, starting with "C"'s January. + const _CharT* _M_month01; + const _CharT* _M_month02; + const _CharT* _M_month03; + const _CharT* _M_month04; + const _CharT* _M_month05; + const _CharT* _M_month06; + const _CharT* _M_month07; + const _CharT* _M_month08; + const _CharT* _M_month09; + const _CharT* _M_month10; + const _CharT* _M_month11; + const _CharT* _M_month12; + + // Abbreviated month names, starting with "C"'s Jan. + const _CharT* _M_amonth01; + const _CharT* _M_amonth02; + const _CharT* _M_amonth03; + const _CharT* _M_amonth04; + const _CharT* _M_amonth05; + const _CharT* _M_amonth06; + const _CharT* _M_amonth07; + const _CharT* _M_amonth08; + const _CharT* _M_amonth09; + const _CharT* _M_amonth10; + const _CharT* _M_amonth11; + const _CharT* _M_amonth12; + + bool _M_allocated; + + __timepunct_cache(size_t __refs = 0) : facet(__refs), + _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), + _M_time_era_format(NULL), _M_date_time_format(NULL), + _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), + _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), + _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), + _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), + _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), + _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), + _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), + _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), + _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), + _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), + _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), + _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) + { } + + ~__timepunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __timepunct_cache& + operator=(const __timepunct_cache&); + + explicit + __timepunct_cache(const __timepunct_cache&); + }; + + template + __timepunct_cache<_CharT>::~__timepunct_cache() + { + if (_M_allocated) + { + // Unused. + } + } + + // Specializations. + template<> + const char* + __timepunct_cache::_S_timezones[14]; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache::_S_timezones[14]; +#endif + + // Generic. + template + const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; + + template + class __timepunct : public locale::facet + { + public: + // Types: + typedef _CharT __char_type; + typedef basic_string<_CharT> __string_type; + typedef __timepunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + __c_locale _M_c_locale_timepunct; + const char* _M_name_timepunct; + + public: + /// Numpunct facet id. + static locale::id id; + + explicit + __timepunct(size_t __refs = 0); + + explicit + __timepunct(__cache_type* __cache, size_t __refs = 0); + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); + + void + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + const tm* __tm) const; + + void + _M_date_formats(const _CharT** __date) const + { + // Always have default first. + __date[0] = _M_data->_M_date_format; + __date[1] = _M_data->_M_date_era_format; + } + + void + _M_time_formats(const _CharT** __time) const + { + // Always have default first. + __time[0] = _M_data->_M_time_format; + __time[1] = _M_data->_M_time_era_format; + } + + void + _M_date_time_formats(const _CharT** __dt) const + { + // Always have default first. + __dt[0] = _M_data->_M_date_time_format; + __dt[1] = _M_data->_M_date_time_era_format; + } + + void + _M_am_pm_format(const _CharT* __ampm) const + { __ampm = _M_data->_M_am_pm_format; } + + void + _M_am_pm(const _CharT** __ampm) const + { + __ampm[0] = _M_data->_M_am; + __ampm[1] = _M_data->_M_pm; + } + + void + _M_days(const _CharT** __days) const + { + __days[0] = _M_data->_M_day1; + __days[1] = _M_data->_M_day2; + __days[2] = _M_data->_M_day3; + __days[3] = _M_data->_M_day4; + __days[4] = _M_data->_M_day5; + __days[5] = _M_data->_M_day6; + __days[6] = _M_data->_M_day7; + } + + void + _M_days_abbreviated(const _CharT** __days) const + { + __days[0] = _M_data->_M_aday1; + __days[1] = _M_data->_M_aday2; + __days[2] = _M_data->_M_aday3; + __days[3] = _M_data->_M_aday4; + __days[4] = _M_data->_M_aday5; + __days[5] = _M_data->_M_aday6; + __days[6] = _M_data->_M_aday7; + } + + void + _M_months(const _CharT** __months) const + { + __months[0] = _M_data->_M_month01; + __months[1] = _M_data->_M_month02; + __months[2] = _M_data->_M_month03; + __months[3] = _M_data->_M_month04; + __months[4] = _M_data->_M_month05; + __months[5] = _M_data->_M_month06; + __months[6] = _M_data->_M_month07; + __months[7] = _M_data->_M_month08; + __months[8] = _M_data->_M_month09; + __months[9] = _M_data->_M_month10; + __months[10] = _M_data->_M_month11; + __months[11] = _M_data->_M_month12; + } + + void + _M_months_abbreviated(const _CharT** __months) const + { + __months[0] = _M_data->_M_amonth01; + __months[1] = _M_data->_M_amonth02; + __months[2] = _M_data->_M_amonth03; + __months[3] = _M_data->_M_amonth04; + __months[4] = _M_data->_M_amonth05; + __months[5] = _M_data->_M_amonth06; + __months[6] = _M_data->_M_amonth07; + __months[7] = _M_data->_M_amonth08; + __months[8] = _M_data->_M_amonth09; + __months[9] = _M_data->_M_amonth10; + __months[10] = _M_data->_M_amonth11; + __months[11] = _M_data->_M_amonth12; + } + + protected: + virtual + ~__timepunct(); + + // For use at construction time only. + void + _M_initialize_timepunct(__c_locale __cloc = NULL); + }; + + template + locale::id __timepunct<_CharT>::id; + + // Specializations. + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(char*, size_t, const char*, const tm*) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(wchar_t*, size_t, const wchar_t*, + const tm*) const; +#endif + + // Include host and configuration specific timepunct functions. + #include + + /** + * @brief Facet for parsing dates and times. + * + * This facet encapsulates the code to parse and return a date or + * time from a string. It is used by the istream numeric + * extraction operators. + * + * The time_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_get facet. + */ + template + class time_get : public locale::facet, public time_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + typedef basic_string<_CharT> __string_type; + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_get(size_t __refs = 0) + : facet (__refs) { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. If the format "x" for the associated + * locale uses other fields, this function returns + * timebase::dateorder::noorder. + * + * NOTE: The library always returns noorder at the moment. + * + * @return A member of timebase::dateorder. + */ + dateorder + date_order() const + { return this->do_date_order(); } + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_time(). + * + * If there is a valid time string according to format "x", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the time string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + iter_type + get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_time(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_date(). + * + * If there is a valid date string according to format "X", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the date string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + iter_type + get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_date(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_weekday(). + * + * Parsing starts by parsing an abbreviated weekday name. If a valid + * abbreviation is followed by a character that would lead to the full + * weekday name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + iter_type + get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_monthname(). + * + * Parsing starts by parsing an abbreviated month name. If a valid + * abbreviation is followed by a character that would lead to the full + * month name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= + * ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + iter_type + get_monthname(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. The result is + * returned by calling time_get::do_get_year(). + * + * 4 consecutive digits are interpreted as a full year. If there are + * exactly 2 consecutive digits, the library interprets this as the + * number of years since 1900. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + iter_type + get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_year(__beg, __end, __io, __err, __tm); } + + protected: + /// Destructor. + virtual + ~time_get() { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. This function is a hook for derived + * classes to change the value returned. + * + * @return A member of timebase::dateorder. + */ + virtual dateorder + do_date_order() const; + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_time() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + virtual iter_type + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_date() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + virtual iter_type + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_weekday() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + virtual iter_type + do_get_weekday(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_monthname() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + virtual iter_type + do_get_monthname(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. This function is a + * hook for derived classes to change the value returned. @see + * get_year() for details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + virtual iter_type + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + // Extract numeric component of length __len. + iter_type + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract day or month name, or any unique array of string + // literals in a const _CharT* array. + iter_type + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract on a component-by-component basis, via __format argument. + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const; + }; + + template + locale::id time_get<_CharT, _InIter>::id; + + template + class time_get_byname : public time_get<_CharT, _InIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + explicit + time_get_byname(const char*, size_t __refs = 0) + : time_get<_CharT, _InIter>(__refs) { } + + protected: + virtual + ~time_get_byname() { } + }; + + /** + * @brief Facet for outputting dates and times. + * + * This facet encapsulates the code to format and output dates and times + * according to formats used by strftime(). + * + * The time_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_put facet. + */ + template + class time_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_put(size_t __refs = 0) + : facet(__refs) { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format string. The format string is interpreted as by + * strftime(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param beg Start of format string. + * @param end End of format string. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const; + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. The format and modifier + * are interpreted as by strftime(). It does so by returning + * time_put::do_put(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + const tm* __tm, char __format, char __mod = 0) const + { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } + + protected: + /// Destructor. + virtual + ~time_put() + { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. This function is a hook + * for derived classes to change the value returned. @see put() for + * more details. + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + char __format, char __mod) const; + }; + + template + locale::id time_put<_CharT, _OutIter>::id; + + template + class time_put_byname : public time_put<_CharT, _OutIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _OutIter iter_type; + + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter>(__refs) + { }; + + protected: + virtual + ~time_put_byname() { } + }; + + + /** + * @brief Money format ordering data. + * + * This class contains an ordered array of 4 fields to represent the + * pattern for formatting a money amount. Each field may contain one entry + * from the part enum. symbol, sign, and value must be present and the + * remaining field must contain either none or space. @see + * moneypunct::pos_format() and moneypunct::neg_format() for details of how + * these fields are interpreted. + */ + class money_base + { + public: + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + + static const pattern _S_default_pattern; + + enum + { + _S_minus, + _S_zero, + _S_end = 11 + }; + + // String literal of acceptable (narrow) input/output, for + // money_get/money_put. "-0123456789" + static const char* _S_atoms; + + // Construct and return valid pattern consisting of some combination of: + // space none symbol sign value + static pattern + _S_construct_pattern(char __precedes, char __space, char __posn); + }; + + template + struct __moneypunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + const _CharT* _M_curr_symbol; + size_t _M_curr_symbol_size; + const _CharT* _M_positive_sign; + size_t _M_positive_sign_size; + const _CharT* _M_negative_sign; + size_t _M_negative_sign_size; + int _M_frac_digits; + money_base::pattern _M_pos_format; + money_base::pattern _M_neg_format; + + // A list of valid numeric literals for input and output: in the standard + // "C" locale, this is "-0123456789". This array contains the chars after + // having been passed through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms[money_base::_S_end]; + + bool _M_allocated; + + __moneypunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), + _M_curr_symbol(NULL), _M_curr_symbol_size(0), + _M_positive_sign(NULL), _M_positive_sign_size(0), + _M_negative_sign(NULL), _M_negative_sign_size(0), + _M_frac_digits(0), + _M_pos_format(money_base::pattern()), + _M_neg_format(money_base::pattern()), _M_allocated(false) + { } + + ~__moneypunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __moneypunct_cache& + operator=(const __moneypunct_cache&); + + explicit + __moneypunct_cache(const __moneypunct_cache&); + }; + + template + __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_curr_symbol; + delete [] _M_positive_sign; + delete [] _M_negative_sign; + } + } + + /** + * @brief Facet for formatting data for money amounts. + * + * This facet encapsulates the punctuation, grouping and other formatting + * features of money amount string representations. + */ + template + class moneypunct : public locale::facet, public money_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + private: + __cache_type* _M_data; + + public: + /// This value is provided by the standard, but no reason for its + /// existence. + static const bool intl = _Intl; + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(); } + + /** + * @brief Constructor performs initialization. + * + * This is an internal constructor. + * + * @param cache Cache for optimization. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_moneypunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(__cloc, __s); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * moneypunct::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * moneypunct::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of an amount. Groupings indicate where thousands + * separators should be inserted. + * + * Each char in the return string is interpret as an integer rather + * than a character. These numbers represent the number of digits in a + * group. The first char in the string represents the number of digits + * in the least significant group. If a char is negative, it indicates + * an unlimited number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is applied to + * the number 123456789, this corresponds to 12,34,56,789. Note that + * if the string was "32", this would put more than 50 digits into the + * least significant group if the character set is ASCII. + * + * The string is returned by calling + * moneypunct::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. It + * does so by returning returning + * moneypunct::do_curr_symbol(). + * + * @return @a string_type representing a currency symbol. + */ + string_type + curr_symbol() const + { return this->do_curr_symbol(); } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. It does so by returning returning + * moneypunct::do_positive_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by pos_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a positive sign. + */ + string_type + positive_sign() const + { return this->do_positive_sign(); } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. It does so by returning returning + * moneypunct::do_negative_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by neg_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a negative sign. + */ + string_type + negative_sign() const + { return this->do_negative_sign(); } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. It does so by returning + * returning moneypunct::do_frac_digits(). + * + * The fractional part of a money amount is optional. But if it is + * present, there must be frac_digits() digits. + * + * @return Number of digits in amount fraction. + */ + int + frac_digits() const + { return this->do_frac_digits(); } + + //@{ + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive or negative valued money amount. It does so by returning + * returning moneypunct::do_pos_format() or + * moneypunct::do_neg_format(). + * + * The pattern has 4 fields describing the ordering of symbol, sign, + * value, and none or space. There must be one of each in the pattern. + * The none and space enums may not appear in the first field and space + * may not appear in the final field. + * + * The parts of a money string must appear in the order indicated by + * the fields of the pattern. The symbol field indicates that the + * value of curr_symbol() may be present. The sign field indicates + * that the value of positive_sign() or negative_sign() must be + * present. The value field indicates that the absolute value of the + * money amount is present. none indicates 0 or more whitespace + * characters, except at the end, where it permits no whitespace. + * space indicates that 1 or more whitespace characters must be + * present. + * + * For example, for the US locale and pos_format() pattern + * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == + * '+', and value 10.01, and options set to force the symbol, the + * corresponding string is "$+10.01". + * + * @return Pattern for money values. + */ + pattern + pos_format() const + { return this->do_pos_format(); } + + pattern + neg_format() const + { return this->do_neg_format(); } + //@} + + protected: + /// Destructor. + virtual + ~moneypunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. + * This function is a hook for derived classes to change the value + * returned. @see curr_symbol() for details. + * + * @return @a string_type representing a currency symbol. + */ + virtual string_type + do_curr_symbol() const + { return _M_data->_M_curr_symbol; } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. This function is a hook for derived classes to change the + * value returned. @see positive_sign() for details. + * + * @return @a string_type representing a positive sign. + */ + virtual string_type + do_positive_sign() const + { return _M_data->_M_positive_sign; } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. This function is a hook for derived classes to change the + * value returned. @see negative_sign() for details. + * + * @return @a string_type representing a negative sign. + */ + virtual string_type + do_negative_sign() const + { return _M_data->_M_negative_sign; } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. This function is a hook for + * derived classes to change the value returned. @see frac_digits() + * for details. + * + * @return Number of digits in amount fraction. + */ + virtual int + do_frac_digits() const + { return _M_data->_M_frac_digits; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive valued money amount. This function is a hook for derived + * classes to change the value returned. @see pos_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_pos_format() const + { return _M_data->_M_pos_format; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * negative valued money amount. This function is a hook for derived + * classes to change the value returned. @see neg_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_neg_format() const + { return _M_data->_M_neg_format; } + + // For use at construction time only. + void + _M_initialize_moneypunct(__c_locale __cloc = NULL, + const char* __name = NULL); + }; + + template + locale::id moneypunct<_CharT, _Intl>::id; + + template + const bool moneypunct<_CharT, _Intl>::intl; + + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); +#endif + + template + class moneypunct_byname : public moneypunct<_CharT, _Intl> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static const bool intl = _Intl; + + explicit + moneypunct_byname(const char* __s, size_t __refs = 0) + : moneypunct<_CharT, _Intl>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_moneypunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~moneypunct_byname() { } + }; + + template + const bool moneypunct_byname<_CharT, _Intl>::intl; + + /** + * @brief Facet for parsing monetary amounts. + * + * This facet encapsulates the code to parse and return a monetary + * amount from a string. + * + * The money_get template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_get facet. + */ + template + class money_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a units as an integral + * value moneypunct::frac_digits() * the actual amount. For example, + * the string $10.01 in a US locale would store 1001 in @a units. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). @a units is + * unchanged if parsing fails. + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param units Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { return this->do_get(__s, __end, __intl, __io, __err, __units); } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a digits. For example, + * the string $10.01 in a US locale would store "1001" in @a digits. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param digits Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { return this->do_get(__s, __end, __intl, __io, __err, __digits); } + + protected: + /// Destructor. + virtual + ~money_get() { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const; + + template + iter_type + _M_extract(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __digits) const; + }; + + template + locale::id money_get<_CharT, _InIter>::id; + + /** + * @brief Facet for outputting monetary amounts. + * + * This facet encapsulates the code to format and output a monetary + * amount. + * + * The money_put template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_put facet. + */ + template + class money_put : public locale::facet + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, long double __units) const + { return this->do_put(__s, __intl, __io, __fill, __units); } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, const string_type& __digits) const + { return this->do_put(__s, __intl, __io, __fill, __digits); } + + protected: + /// Destructor. + virtual + ~money_put() { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const; + + template + iter_type + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const; + }; + + template + locale::id money_put<_CharT, _OutIter>::id; + + /** + * @brief Messages facet base class providing catalog typedef. + */ + struct messages_base + { + typedef int catalog; + }; + + /** + * @brief Facet for handling message catalogs + * + * This facet encapsulates the code to retrieve messages from + * message catalogs. The only thing defined by the standard for this facet + * is the interface. All underlying functionality is + * implementation-defined. + * + * This library currently implements 3 versions of the message facet. The + * first version (gnu) is a wrapper around gettext, provided by libintl. + * The second version (ieee) is a wrapper around catgets. The final + * version (default) does no actual translation. These implementations are + * only provided for char and wchar_t instantiations. + * + * The messages template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the messages facet. + */ + template + class messages : public locale::facet, public messages_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by messages_byname as well. + __c_locale _M_c_locale_messages; + const char* _M_name_messages; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + messages(size_t __refs = 0); + + // Non-standard. + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Refcount to pass to the base class. + */ + explicit + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog by + * returning do_open(s, loc). + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string& __s, const locale& __loc) const + { return this->do_open(__s, __loc); } + + // Non-standard and unorthodox, yet effective. + /* + * @brief Open a message catalog. + * + * This non-standard function opens and returns a handle to a message + * catalog by returning do_open(s, loc). The third argument provides a + * message catalog root directory for gnu gettext and is ignored + * otherwise. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @param dir Message catalog root directory. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string&, const locale&, const char*) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog by + * returning do_get(c, set, msgid, s). + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + string_type + get(catalog __c, int __set, int __msgid, const string_type& __s) const + { return this->do_get(__c, __set, __msgid, __s); } + + /* + * @brief Close a message catalog. + * + * Closes catalog @a c by calling do_close(c). + * + * @param c The catalog to close. + */ + void + close(catalog __c) const + { return this->do_close(__c); } + + protected: + /// Destructor. + virtual + ~messages(); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the opened catalog, value < 0 if open failed. + */ + virtual catalog + do_open(const basic_string&, const locale&) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + virtual string_type + do_get(catalog, int, int, const string_type& __dfault) const; + + /* + * @brief Close a message catalog. + * + * @param c The catalog to close. + */ + virtual void + do_close(catalog) const; + + // Returns a locale and codeset-converted string, given a char* message. + char* + _M_convert_to_char(const string_type& __msg) const + { + // XXX + return reinterpret_cast(const_cast<_CharT*>(__msg.c_str())); + } + + // Returns a locale and codeset-converted string, given a char* message. + string_type + _M_convert_from_char(char*) const + { +#if 0 + // Length of message string without terminating null. + size_t __len = char_traits::length(__msg) - 1; + + // "everybody can easily convert the string using + // mbsrtowcs/wcsrtombs or with iconv()" + + // Convert char* to _CharT in locale used to open catalog. + // XXX need additional template parameter on messages class for this.. + // typedef typename codecvt __codecvt_type; + typedef typename codecvt __codecvt_type; + + __codecvt_type::state_type __state; + // XXX may need to initialize state. + //initialize_state(__state._M_init()); + + char* __from_next; + // XXX what size for this string? + _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); + __cvt.out(__state, __msg, __msg + __len, __from_next, + __to, __to + __len + 1, __to_next); + return string_type(__to); +#endif +#if 0 + typedef ctype<_CharT> __ctype_type; + // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); + const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); + // XXX Again, proper length of converted string an issue here. + // For now, assume the converted length is not larger. + _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + __cvt.widen(__msg, __msg + __len, __dest); + return basic_string<_CharT>(__dest); +#endif + return string_type(); + } + }; + + template + locale::id messages<_CharT>::id; + + // Specializations for required instantiations. + template<> + string + messages::do_get(catalog, int, int, const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + wstring + messages::do_get(catalog, int, int, const wstring&) const; +#endif + + template + class messages_byname : public messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + messages_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~messages_byname() + { } + }; + + // Include host and configuration specific messages functions. + #include + + + // Subclause convenience interfaces, inlines. + // NB: These are inline because, when used in a loop, some compilers + // can hoist the body out of the loop; then it's just as fast as the + // C is*() function. + //@{ + /// Convenience interface to ctype.is(). + template + inline bool + isspace(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::space, __c); } + + template + inline bool + isprint(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::print, __c); } + + template + inline bool + iscntrl(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::cntrl, __c); } + + template + inline bool + isupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::upper, __c); } + + template + inline bool islower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::lower, __c); } + + template + inline bool + isalpha(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alpha, __c); } + + template + inline bool + isdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::digit, __c); } + + template + inline bool + ispunct(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::punct, __c); } + + template + inline bool + isxdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::xdigit, __c); } + + template + inline bool + isalnum(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alnum, __c); } + + template + inline bool + isgraph(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::graph, __c); } + + template + inline _CharT + toupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).toupper(__c); } + + template + inline _CharT + tolower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).tolower(__c); } + //@} +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/locale_facets.tcc b/src/include.new/c++/3.4/bits/locale_facets.tcc new file mode 100644 index 0000000..4f65844 --- /dev/null +++ b/src/include.new/c++/3.4/bits/locale_facets.tcc @@ -0,0 +1,2744 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Warning: this file is not meant for user inclusion. Use . + +#ifndef _LOCALE_FACETS_TCC +#define _LOCALE_FACETS_TCC 1 + +#pragma GCC system_header + +#include // For numeric_limits +#include // For bad_cast. +#include + +namespace std +{ + template + locale + locale::combine(const locale& __other) const + { + _Impl* __tmp = new _Impl(*_M_impl, 1); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + __throw_exception_again; + } + return locale(__tmp); + } + + template + bool + locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, + const basic_string<_CharT, _Traits, _Alloc>& __s2) const + { + typedef std::collate<_CharT> __collate_type; + const __collate_type& __collate = use_facet<__collate_type>(*this); + return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), + __s2.data(), __s2.data() + __s2.length()) < 0); + } + + /** + * @brief Test for the presence of a facet. + * + * has_facet tests the locale argument for the presence of the facet type + * provided as the template parameter. Facets derived from the facet + * parameter will also return true. + * + * @param Facet The facet type to test the presence of. + * @param locale The locale to test. + * @return true if locale contains a facet of type Facet, else false. + */ + template + inline bool + has_facet(const locale& __loc) throw() + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); + } + + /** + * @brief Return a facet. + * + * use_facet looks for and returns a reference to a facet of type Facet + * where Facet is the template parameter. If has_facet(locale) is true, + * there is a suitable facet to return. It throws std::bad_cast if the + * locale doesn't contain a facet of type Facet. + * + * @param Facet The facet type to access. + * @param locale The locale to use. + * @return Reference to facet of type Facet. + * @throw std::bad_cast if locale doesn't contain a facet of type Facet. + */ + template + inline const _Facet& + use_facet(const locale& __loc) + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) + __throw_bad_cast(); + return static_cast(*__facets[__i]); + } + + // Routine to access a cache for the facet. If the cache didn't + // exist before, it gets constructed on the fly. + template + struct __use_cache + { + const _Facet* + operator() (const locale& __loc) const; + }; + + // Specializations. + template + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = NULL; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast*>(__caches[__i]); + } + }; + + template + struct __use_cache<__moneypunct_cache<_CharT, _Intl> > + { + const __moneypunct_cache<_CharT, _Intl>* + operator() (const locale& __loc) const + { + const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; + try + { + __tmp = new __moneypunct_cache<_CharT, _Intl>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast< + const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); + } + }; + + template + void + __numpunct_cache<_CharT>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const numpunct<_CharT>& __np = use_facet >(__loc); + + _M_grouping_size = __np.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __np.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0; + + _M_truename_size = __np.truename().size(); + _CharT* __truename = new _CharT[_M_truename_size]; + __np.truename().copy(__truename, _M_truename_size); + _M_truename = __truename; + + _M_falsename_size = __np.falsename().size(); + _CharT* __falsename = new _CharT[_M_falsename_size]; + __np.falsename().copy(__falsename, _M_falsename_size); + _M_falsename = __falsename; + + _M_decimal_point = __np.decimal_point(); + _M_thousands_sep = __np.thousands_sep(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(__num_base::_S_atoms_out, + __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); + __ct.widen(__num_base::_S_atoms_in, + __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); + } + + template + void + __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const moneypunct<_CharT, _Intl>& __mp = + use_facet >(__loc); + + _M_grouping_size = __mp.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __mp.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0; + + _M_decimal_point = __mp.decimal_point(); + _M_thousands_sep = __mp.thousands_sep(); + _M_frac_digits = __mp.frac_digits(); + + _M_curr_symbol_size = __mp.curr_symbol().size(); + _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; + __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); + _M_curr_symbol = __curr_symbol; + + _M_positive_sign_size = __mp.positive_sign().size(); + _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; + __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); + _M_positive_sign = __positive_sign; + + _M_negative_sign_size = __mp.negative_sign().size(); + _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; + __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); + _M_negative_sign = __negative_sign; + + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); + } + + + // Used by both numeric and monetary facets. + // Check to make sure that the __grouping_tmp string constructed in + // money_get or num_get matches the canonical grouping for a given + // locale. + // __grouping_tmp is parsed L to R + // 1,222,444 == __grouping_tmp of "\1\3\3" + // __grouping is parsed R to L + // 1,222,444 == __grouping of "\3" == "\3\3\3" + static bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp); + + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, string& __xtrc) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // True if a mantissa is found. + bool __found_mantissa = false; + + // First check for sign. + if (__beg != __end) + { + const char_type __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } + } + + // Next, look for leading zeros. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero]) + { + if (!__found_mantissa) + { + __xtrc += '0'; + __found_mantissa = true; + } + ++__beg; + } + else + break; + } + + // Only need acceptable digits for floating point numbers. + bool __found_dec = false; + bool __found_sci = false; + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + int __sep_pos = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; + while (__beg != __end) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (!__found_dec && !__found_sci) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + ++__beg; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else + break; + } + else if (__c == __lc->_M_decimal_point) + { + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast(__sep_pos); + __xtrc += '.'; + __found_dec = true; + ++__beg; + } + else + break; + } + else if (__q = __traits_type::find(__lit_zero, 10, __c)) + { + __xtrc += __num_base::_S_atoms_in[__q - __lit]; + __found_mantissa = true; + ++__sep_pos; + ++__beg; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && __found_mantissa && !__found_sci) + { + // Scientific notation. + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast(__sep_pos); + __xtrc += 'e'; + __found_sci = true; + + // Remove optional plus or minus sign, if they exist. + if (++__beg != __end) + { + const bool __plus = *__beg == __lit[__num_base::_S_iplus]; + if ((__plus || *__beg == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep) + && !(*__beg == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } + } + } + else + // Not a valid input item. + break; + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping if a decimal or 'e'/'E' wasn't found. + if (!__found_dec && !__found_sci) + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + // Finish up. + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // NB: Iff __basefield == 0, __base can change based on contents. + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + // True if numeric digits are found. + bool __found_num = false; + + // First check for sign. + bool __negative = false; + if (__beg != __end) + { + const char_type __c = *__beg; + if (numeric_limits<_ValueT>::is_signed) + __negative = __c == __lit[__num_base::_S_iminus]; + if ((__negative || __c == __lit[__num_base::_S_iplus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + ++__beg; + } + + // Next, look for leading zeros and check required digits + // for base formats. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero] + && (!__found_num || __base == 10)) + { + __found_num = true; + ++__beg; + } + else if (__found_num) + { + if (__c == __lit[__num_base::_S_ix] + || __c == __lit[__num_base::_S_iX]) + { + if (__basefield == 0) + __base = 16; + if (__base == 16) + { + __found_num = false; + ++__beg; + } + } + else if (__basefield == 0) + __base = 8; + break; + } + else + break; + } + + // At this point, base is determined. If not hex, only allow + // base digits as valid input. + const size_t __len = __base == 16 ? (__num_base::_S_iend + - __num_base::_S_izero) + : __base; + + // Extract. + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + int __sep_pos = 0; + bool __overflow = false; + _ValueT __result = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; + if (__negative) + { + const _ValueT __min = numeric_limits<_ValueT>::min() / __base; + for (; __beg != __end; ++__beg) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result < __min) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + - __digit; + __overflow |= __new_result > __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + // Not a valid input item. + break; + } + } + else + { + const _ValueT __max = numeric_limits<_ValueT>::max() / __base; + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __max) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + + __digit; + __overflow |= __new_result < __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + break; + } + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping. + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + if (!(__err & ios_base::failbit) && !__overflow + && __found_num) + __v = __result; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 17. Bad bool parsing + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { + if (!(__io.flags() & ios_base::boolalpha)) + { + // Parse bool values as long. + // NB: We can't just call do_get(long) here, as it might + // refer to a derived class. + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = __l; + else + __err |= ios_base::failbit; + } + else + { + // Parse bool values as alphanumeric. + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + size_t __n; + for (__n = 0; __beg != __end; ++__n, ++__beg) + { + if (__testf) + if (__n < __lc->_M_falsename_size) + __testf = *__beg == __lc->_M_falsename[__n]; + else + break; + + if (__testt) + if (__n < __lc->_M_truename_size) + __testt = *__beg == __lc->_M_truename[__n]; + else + break; + + if (!__testf && !__testt) + break; + } + if (__testf && __n == __lc->_M_falsename_size) + __v = 0; + else if (__testt && __n == __lc->_M_truename_size) + __v = 1; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + } + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } +#endif + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { + // Prepare for hex formatted input. + typedef ios_base::fmtflags fmtflags; + const fmtflags __fmt = __io.flags(); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); + + unsigned long __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); + + // Reset from hex formatted input. + __io.flags(__fmt); + + if (!(__err & ios_base::failbit)) + __v = reinterpret_cast(__ul); + else + __err |= ios_base::failbit; + return __beg; + } + + // For use by integer and floating-point types after they have been + // converted into a char_type string. + template + void + num_put<_CharT, _OutIter>:: + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _CharT* __new, const _CharT* __cs, int& __len) const + { + // [22.2.2.2.2] Stage 3. + // If necessary, pad. + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, + __w, __len, true); + __len = static_cast(__w); + } + + // Forwarding functions to peel signed from unsigned integer types. + template + inline int + __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + unsigned long __ul = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ul = -__ul; + __neg = true; + } + return __int_to_char(__bufend, __ul, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + // About showpos, see Table 60 and C99 7.19.6.1, p6 (+). + return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + inline int + __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + unsigned long long __ull = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ull = -__ull; + __neg = true; + } + return __int_to_char(__bufend, __ull, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __bufend, unsigned long long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); } +#endif + + template + int + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __neg) + { + // Don't write base if already 0. + const bool __showbase = (__flags & ios_base::showbase) && __v; + const ios_base::fmtflags __basefield = __flags & ios_base::basefield; + _CharT* __buf = __bufend - 1; + + if (__builtin_expect(__basefield != ios_base::oct && + __basefield != ios_base::hex, true)) + { + // Decimal. + do + { + *__buf-- = __lit[(__v % 10) + __num_base::_S_odigits]; + __v /= 10; + } + while (__v != 0); + if (__neg) + *__buf-- = __lit[__num_base::_S_ominus]; + else if (__flags & ios_base::showpos) + *__buf-- = __lit[__num_base::_S_oplus]; + } + else if (__basefield == ios_base::oct) + { + // Octal. + do + { + *__buf-- = __lit[(__v & 0x7) + __num_base::_S_odigits]; + __v >>= 3; + } + while (__v != 0); + if (__showbase) + *__buf-- = __lit[__num_base::_S_odigits]; + } + else + { + // Hex. + const bool __uppercase = __flags & ios_base::uppercase; + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; + do + { + *__buf-- = __lit[(__v & 0xf) + __case_offset]; + __v >>= 4; + } + while (__v != 0); + if (__showbase) + { + // 'x' or 'X' + *__buf-- = __lit[__num_base::_S_ox + __uppercase]; + // '0' + *__buf-- = __lit[__num_base::_S_odigits]; + } + } + return __bufend - __buf - 1; + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, + ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const + { + // By itself __add_grouping cannot deal correctly with __cs when + // ios::showbase is set and ios_base::oct || ios_base::hex. + // Therefore we take care "by hand" of the initial 0, 0x or 0X. + // However, remember that the latter do not occur if the number + // printed is '0' (__len == 1). + streamsize __off = 0; + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + if ((__io.flags() & ios_base::showbase) && __len > 1) + if (__basefield == ios_base::oct) + { + __off = 1; + __new[0] = __cs[0]; + } + else if (__basefield == ios_base::hex) + { + __off = 2; + __new[0] = __cs[0]; + __new[1] = __cs[1]; + } + _CharT* __p; + __p = std::__add_grouping(__new + __off, __sep, __grouping, + __grouping_size, __cs + __off, + __cs + __len); + __len = __p - __new; + } + + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; + + // Long enough to hold hex, dec, and octal representations. + const int __ilen = 4 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __ilen)); + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + // Result is returned right-justified in the buffer. + int __len; + __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags()); + __cs += __ilen - __len; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __io, __cs2, __cs, __len); + __cs = __cs2; + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __cs, __len); + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_float(const char* __grouping, size_t __grouping_size, + _CharT __sep, const _CharT* __p, _CharT* __new, + _CharT* __cs, int& __len) const + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 282. What types does numpunct grouping refer to? + // Add grouping, if necessary. + _CharT* __p2; + const int __declen = __p ? __p - __cs : __len; + __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_size, + __cs, __cs + __declen); + + // Tack on decimal part. + int __newlen = __p2 - __new; + if (__p) + { + char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __newlen += __len - __declen; + } + __len = __newlen; + } + + // The following code uses snprintf (or sprintf(), when + // _GLIBCXX_USE_C99 is not defined) to convert floating point values + // for insertion into a stream. An optimization would be to replace + // them with code that works directly on a wide buffer and then use + // __pad to do the padding. It would be good to replace them anyway + // to gain back the efficiency that C++ provides by knowing up front + // the type of the values to insert. Also, sprintf is dangerous + // since may lead to accidental buffer overruns. This + // implementation follows the C++ standard fairly directly as + // outlined in 22.2.2.2 [lib.locale.num.put] + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _ValueT __v) const + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + // Use default precision if out of range. + streamsize __prec = __io.precision(); + if (__prec < static_cast(0)) + __prec = static_cast(6); + + const int __max_digits = numeric_limits<_ValueT>::digits10; + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + int __len; + // Long enough for the max format spec. + char __fbuf[16]; + +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough (most probably sufficient + // for non-ios_base::fixed outputs) + int __cs_size = __max_digits * 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); + + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); + } +#else + // Consider the possibility of long ios_base::fixed outputs + const bool __fixed = __io.flags() & ios_base::fixed; + const int __max_exp = numeric_limits<_ValueT>::max_exponent10; + + // The size of the output string is computed as follows. + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, 0, __fbuf, __v, + _S_get_c_locale(), __prec); +#endif + + // [22.2.2.2.2] Stage 2, convert to char_type, using correct + // numpunct.decimal_point() values for '.' and adding grouping. + const ctype<_CharT>& __ctype = use_facet >(__loc); + + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__cs, __cs + __len, __ws); + + // Replace decimal point. + const _CharT __cdec = __ctype.widen('.'); + const _CharT __dec = __lc->_M_decimal_point; + const _CharT* __p; + if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) + __ws[__p - __ws] = __dec; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __p, __ws2, __ws, __len); + __ws = __ws2; + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __ws3, __ws, __len); + __ws = __ws3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __ws, __len); + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + if ((__flags & ios_base::boolalpha) == 0) + { + const long __l = __v; + __s = _M_insert_int(__s, __io, __fill, __l); + } + else + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_size + : __lc->_M_falsename_size; + + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __cs + = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs, __name, __len); + __name = __cs; + } + __io.width(0); + __s = std::__write(__s, __name, __len); + } + return __s; + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const + { return _M_insert_int(__s, __b, __fill, __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } +#endif + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return _M_insert_float(__s, __io, __fill, char(), __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { return _M_insert_float(__s, __io, __fill, 'L', __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::basefield + | ios_base::uppercase + | ios_base::internal); + __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); + + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast(__v)); + __io.flags(__flags); + return __s; + } + + template + template + _InIter + money_get<_CharT, _InIter>:: + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __units) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Deduced sign. + bool __negative = false; + // Sign size. + size_type __sign_size = 0; + // True if sign is mandatory. + const bool __mandatory_sign = (__lc->_M_positive_sign_size + && __lc->_M_negative_sign_size); + // String of grouping info from thousands_sep plucked from __units. + string __grouping_tmp; + if (__lc->_M_use_grouping) + __grouping_tmp.reserve(32); + // Last position before the decimal point. + int __last_pos = 0; + // Separator positions, then, possibly, fractional digits. + int __n = 0; + // If input iterator is in a valid state. + bool __testvalid = true; + // Flag marking when a decimal point is found. + bool __testdecfound = false; + + // The tentative returned string is stored here. + string __res; + __res.reserve(32); + + const char_type* __lit_zero = __lit + money_base::_S_zero; + const char_type* __q; + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + // According to 22.2.6.1.2, p2, symbol is required + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. + if (__io.flags() & ios_base::showbase || __sign_size > 1 + || __i == 0 + || (__i == 1 && (__mandatory_sign + || (static_cast(__p.field[0]) + == money_base::sign) + || (static_cast(__p.field[2]) + == money_base::space))) + || (__i == 2 && ((static_cast(__p.field[3]) + == money_base::value) + || __mandatory_sign + && (static_cast(__p.field[3]) + == money_base::sign)))) + { + const size_type __len = __lc->_M_curr_symbol_size; + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __lc->_M_curr_symbol[__j]; + ++__beg, ++__j); + if (__j != __len + && (__j || __io.flags() & ios_base::showbase)) + __testvalid = false; + } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__lc->_M_positive_sign_size && __beg != __end + && *__beg == __lc->_M_positive_sign[0]) + { + __sign_size = __lc->_M_positive_sign_size; + ++__beg; + } + else if (__lc->_M_negative_sign_size && __beg != __end + && *__beg == __lc->_M_negative_sign[0]) + { + __negative = true; + __sign_size = __lc->_M_negative_sign_size; + ++__beg; + } + else if (__lc->_M_positive_sign_size + && !__lc->_M_negative_sign_size) + // "... if no sign is detected, the result is given the sign + // that corresponds to the source of the empty string" + __negative = true; + else if (__mandatory_sign) + __testvalid = false; + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + if (__q = __traits_type::find(__lit_zero, 10, *__beg)) + { + __res += money_base::_S_atoms[__q - __lit]; + ++__n; + } + else if (*__beg == __lc->_M_decimal_point && !__testdecfound) + { + __last_pos = __n; + __n = 0; + __testdecfound = true; + } + else if (__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep + && !__testdecfound) + { + if (__n) + { + // Mark position for later analysis. + __grouping_tmp += static_cast(__n); + __n = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + if (__res.empty()) + __testvalid = false; + break; + case money_base::space: + // At least one space is required. + if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) + ++__beg; + else + __testvalid = false; + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } + } + + // Need to get the rest of the sign characters, if they exist. + if (__sign_size > 1 && __testvalid) + { + const char_type* __sign = __negative ? __lc->_M_negative_sign + : __lc->_M_positive_sign; + size_type __i = 1; + for (; __beg != __end && __i < __sign_size + && *__beg == __sign[__i]; ++__beg, ++__i); + + if (__i != __sign_size) + __testvalid = false; + } + + if (__testvalid) + { + // Strip leading zeros. + if (__res.size() > 1) + { + const size_type __first = __res.find_first_not_of('0'); + const bool __only_zeros = __first == string::npos; + if (__first) + __res.erase(0, __only_zeros ? __res.size() - 1 : __first); + } + + // 22.2.6.1.2, p4 + if (__negative && __res[0] != '0') + __res.insert(__res.begin(), '-'); + + // Test for grouping fidelity. + if (__grouping_tmp.size()) + { + // Add the ending grouping. + __grouping_tmp += static_cast(__testdecfound ? __last_pos + : __n); + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __grouping_tmp)) + __testvalid = false; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound && __lc->_M_frac_digits > 0 + && __n != __lc->_M_frac_digits) + __testvalid = false; + } + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; + + // Iff valid sequence is not recognized. + if (!__testvalid) + __err |= ios_base::failbit; + else + __units.swap(__res); + + return __beg; + } + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { + string __str; + if (__intl) + __beg = _M_extract(__beg, __end, __io, __err, __str); + else + __beg = _M_extract(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __units) const + { + typedef typename string::size_type size_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + string __str; + const iter_type __ret = __intl ? _M_extract(__beg, __end, __io, + __err, __str) + : _M_extract(__beg, __end, __io, + __err, __str); + const size_type __len = __str.size(); + if (__len) + { + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__str.data(), __str.data() + __len, __ws); + __units.assign(__ws, __len); + } + + return __ret; + } + + template + template + _OutIter + money_put<_CharT, _OutIter>:: + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const + { + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Determine if negative or positive formats are to be used, and + // discard leading negative_sign if it is present. + const char_type* __beg = __digits.data(); + + money_base::pattern __p; + const char_type* __sign; + size_type __sign_size; + if (*__beg != __lit[money_base::_S_minus]) + { + __p = __lc->_M_pos_format; + __sign = __lc->_M_positive_sign; + __sign_size = __lc->_M_positive_sign_size; + } + else + { + __p = __lc->_M_neg_format; + __sign = __lc->_M_negative_sign; + __sign_size = __lc->_M_negative_sign_size; + if (__digits.size()) + ++__beg; + } + + // Look for valid numbers in the ctype facet within input digits. + size_type __len = __ctype.scan_not(ctype_base::digit, __beg, + __beg + __digits.size()) - __beg; + if (__len) + { + // Assume valid input, and attempt to format. + // Break down input numbers into base components, as follows: + // final_value = grouped units + (decimal point) + (digits) + string_type __value; + __value.reserve(2 * __len); + + // Add thousands separators to non-decimal digits, per + // grouping rules. + int __paddec = __len - __lc->_M_frac_digits; + if (__paddec > 0) + { + if (__lc->_M_frac_digits < 0) + __paddec = __len; + if (__lc->_M_grouping_size) + { + _CharT* __ws = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * 2 * __len)); + _CharT* __ws_end = + std::__add_grouping(__ws, __lc->_M_thousands_sep, + __lc->_M_grouping, + __lc->_M_grouping_size, + __beg, __beg + __paddec); + __value.assign(__ws, __ws_end - __ws); + } + else + __value.assign(__beg, __paddec); + } + + // Deal with decimal point, decimal digits. + if (__lc->_M_frac_digits > 0) + { + __value += __lc->_M_decimal_point; + if (__paddec >= 0) + __value.append(__beg + __paddec, __lc->_M_frac_digits); + else + { + // Have to pad zeros in the decimal position. + __value.append(-__paddec, __lit[money_base::_S_zero]); + __value.append(__beg, __len); + } + } + + // Calculate length of resulting string. + const ios_base::fmtflags __f = __io.flags() + & ios_base::adjustfield; + __len = __value.size() + __sign_size; + __len += ((__io.flags() & ios_base::showbase) + ? __lc->_M_curr_symbol_size : 0); + + string_type __res; + __res.reserve(2 * __len); + + const size_type __width = static_cast(__io.width()); + const bool __testipad = (__f == ios_base::internal + && __len < __width); + // Fit formatted digits into the required pattern. + for (int __i = 0; __i < 4; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase) + __res.append(__lc->_M_curr_symbol, + __lc->_M_curr_symbol_size); + break; + case money_base::sign: + // Sign might not exist, or be more than one + // charater long. In that case, add in the rest + // below. + if (__sign_size) + __res += __sign[0]; + break; + case money_base::value: + __res += __value; + break; + case money_base::space: + // At least one space is required, but if internal + // formatting is required, an arbitrary number of + // fill spaces will be necessary. + if (__testipad) + __res.append(__width - __len, __fill); + else + __res += __fill; + break; + case money_base::none: + if (__testipad) + __res.append(__width - __len, __fill); + break; + } + } + + // Special case of multi-part sign parts. + if (__sign_size > 1) + __res.append(__sign + 1, __sign_size - 1); + + // Pad, if still necessary. + __len = __res.size(); + if (__width > __len) + { + if (__f == ios_base::left) + // After. + __res.append(__width - __len, __fill); + else + // Before. + __res.insert(0, __width - __len, __fill); + __len = __width; + } + + // Write resulting, fully-formatted string to output iterator. + __s = std::__write(__s, __res.data(), __len); + } + __io.width(0); + return __s; + } + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const + { + const locale __loc = __io.getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough. + int __cs_size = 64; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, + _S_get_c_locale(), 0); + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, + _S_get_c_locale(), 0); + } +#else + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = numeric_limits::max_exponent10 + 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units, + _S_get_c_locale(), 0); +#endif + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __cs_size)); + __ctype.widen(__cs, __cs + __len, __ws); + const string_type __digits(__ws, __len); + return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); + } + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const + { return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); } + + + // NB: Not especially useful. Without an ios_base object or some + // kind of locale reference, we are left clawing at the air where + // the side of the mountain used to be... + template + time_base::dateorder + time_get<_CharT, _InIter>::do_date_order() const + { return time_base::no_order; } + + // Expand a strftime format string and parse it. E.g., do_get_date() may + // pass %m/%d/%Y => extracted characters. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const size_t __len = char_traits<_CharT>::length(__format); + + for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) + { + if (__ctype.narrow(__format[__i], 0) == '%') + { + // Verify valid formatting code, attempt to extract. + char __c = __ctype.narrow(__format[++__i], 0); + int __mem = 0; + if (__c == 'E' || __c == 'O') + __c = __ctype.narrow(__format[++__i], 0); + switch (__c) + { + const char* __cs; + _CharT __wcs[10]; + case 'a': + // Abbreviated weekday name [tm_wday] + const char_type* __days1[7]; + __tp._M_days_abbreviated(__days1); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, + 7, __io, __err); + break; + case 'A': + // Weekday name [tm_wday]. + const char_type* __days2[7]; + __tp._M_days(__days2); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, + 7, __io, __err); + break; + case 'h': + case 'b': + // Abbreviated month name [tm_mon] + const char_type* __months1[12]; + __tp._M_months_abbreviated(__months1); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months1, 12, __io, __err); + break; + case 'B': + // Month name [tm_mon]. + const char_type* __months2[12]; + __tp._M_months(__months2); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months2, 12, __io, __err); + break; + case 'c': + // Default time and date representation. + const char_type* __dt[2]; + __tp._M_date_time_formats(__dt); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dt[0]); + break; + case 'd': + // Day [01, 31]. [tm_mday] + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __io, __err); + break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, + 1, __io, __err); + else + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, + 2, __io, __err); + break; + case 'D': + // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] + __cs = "%m/%d/%y"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'H': + // Hour [00, 23]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __io, __err); + break; + case 'I': + // Hour [01, 12]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __io, __err); + break; + case 'm': + // Month [01, 12]. [tm_mon] + __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __io, __err); + if (!__err) + __tm->tm_mon = __mem - 1; + break; + case 'M': + // Minute [00, 59]. [tm_min] + __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __io, __err); + break; + case 'n': + if (__ctype.narrow(*__beg, 0) == '\n') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'R': + // Equivalent to (%H:%M). + __cs = "%H:%M"; + __ctype.widen(__cs, __cs + 6, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'S': + // Seconds. [tm_sec] + // [00, 60] in C99 (one leap-second), [00, 61] in C89. +#ifdef _GLIBCXX_USE_C99 + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, +#else + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, +#endif + __io, __err); + break; + case 't': + if (__ctype.narrow(*__beg, 0) == '\t') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'T': + // Equivalent to (%H:%M:%S). + __cs = "%H:%M:%S"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'x': + // Locale's date. + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + break; + case 'X': + // Locale's time. + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + break; + case 'y': + case 'C': // C99 + // Two digit year. [tm_year] + __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __io, __err); + break; + case 'Y': + // Year [1900). [tm_year] + __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, + __io, __err); + if (!__err) + __tm->tm_year = __mem - 1900; + break; + case 'Z': + // Timezone info. + if (__ctype.is(ctype_base::upper, *__beg)) + { + int __tmp; + __beg = _M_extract_name(__beg, __end, __tmp, + __timepunct_cache<_CharT>::_S_timezones, + 14, __io, __err); + + // GMT requires special effort. + if (__beg != __end && !__err && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) + { + __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __io, __err); + __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __io, __err); + } + } + else + __err |= ios_base::failbit; + break; + default: + // Not recognized. + __err |= ios_base::failbit; + } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __err |= ios_base::failbit; + } + } + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } + else + break; + } + if (__i == __len) + __member = __value; + else + __err |= ios_base::failbit; + return __beg; + } + + // Assumptions: + // All elements in __names are unique. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + int* __matches = static_cast(__builtin_alloca(sizeof(int) + * __indexlen)); + size_t __nmatches = 0; + size_t __pos = 0; + bool __testvalid = true; + const char_type* __name; + + // Look for initial matches. + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } + + while (__nmatches > 1) + { + // Find smallest matching string. + size_t __minlen = __traits_type::length(__names[__matches[0]]); + for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__beg, ++__pos; + if (__pos < __minlen && __beg != __end) + for (size_t __i3 = 0; __i3 < __nmatches;) + { + __name = __names[__matches[__i3]]; + if (__name[__pos] != *__beg) + __matches[__i3] = __matches[--__nmatches]; + else + ++__i3; + } + else + break; + } + + if (__nmatches == 1) + { + // Make sure found name is completely extracted. + ++__beg, ++__pos; + __name = __names[__matches[0]]; + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) + ++__beg, ++__pos; + + if (__len == __pos) + __member = __matches[0]; + else + __testvalid = false; + } + else + __testvalid = false; + if (!__testvalid) + __err |= ios_base::failbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __days[7]; + __tp._M_days_abbreviated(__days); + int __tmpwday; + __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_days and _M_days_abbreviated organized in + // exact same order, first to last, such that the resulting + // __days array with the same index points to a day, and that + // day's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__err && __beg != __end) + { + size_t __pos = __traits_type::length(__days[__tmpwday]); + __tp._M_days(__days); + const char_type* __name = __days[__tmpwday]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __err |= ios_base::failbit; + } + } + if (!__err) + __tm->tm_wday = __tmpwday; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_monthname(iter_type __beg, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __months[12]; + __tp._M_months_abbreviated(__months); + int __tmpmon; + __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, + __io, __err); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_months and _M_months_abbreviated organized in + // exact same order, first to last, such that the resulting + // __months array with the same index points to a month, and that + // month's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__err && __beg != __end) + { + size_t __pos = __traits_type::length(__months[__tmpmon]); + __tp._M_months(__months); + const char_type* __name = __months[__tmpmon]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __err |= ios_base::failbit; + } + } + if (!__err) + __tm->tm_mon = __tmpmon; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; + } + if (__i == 2 || __i == 4) + __tm->tm_year = __i == 2 ? __value : __value - 1900; + else + __err |= ios_base::failbit; + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); + } + else + break; + return __s; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + char __format, char __mod) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + + // NB: This size is arbitrary. Should this be a data member, + // initialized at construction? + const size_t __maxlen = 128; + char_type* __res = + static_cast(__builtin_alloca(sizeof(char_type) * __maxlen)); + + // NB: In IEE 1003.1-200x, and perhaps other locale models, it + // is possible that the format character will be longer than one + // character. Possibilities include 'E' or 'O' followed by a + // format character: if __mod is not the default argument, assume + // it's a valid modifier. + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); + if (!__mod) + { + __fmt[1] = __format; + __fmt[2] = char_type(); + } + else + { + __fmt[1] = __mod; + __fmt[2] = __format; + __fmt[3] = char_type(); + } + + __tp._M_put(__res, __maxlen, __fmt, __tm); + + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __res, char_traits::length(__res)); + } + + + // Generic version does nothing. + template + int + collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const + { return 0; } + + // Generic version does nothing. + template + size_t + collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const + { return 0; } + + template + int + collate<_CharT>:: + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { + // strcoll assumes zero-terminated strings so we make a copy + // and then put a zero at the end. + const string_type __one(__lo1, __hi1); + const string_type __two(__lo2, __hi2); + + const _CharT* __p = __one.c_str(); + const _CharT* __pend = __one.data() + __one.length(); + const _CharT* __q = __two.c_str(); + const _CharT* __qend = __two.data() + __two.length(); + + // strcoll stops when it sees a nul character so we break + // the strings into zero-terminated substrings and pass those + // to strcoll. + for (;;) + { + const int __res = _M_compare(__p, __q); + if (__res) + return __res; + + __p += char_traits<_CharT>::length(__p); + __q += char_traits<_CharT>::length(__q); + if (__p == __pend && __q == __qend) + return 0; + else if (__p == __pend) + return -1; + else if (__q == __qend) + return 1; + + __p++; + __q++; + } + } + + template + typename collate<_CharT>::string_type + collate<_CharT>:: + do_transform(const _CharT* __lo, const _CharT* __hi) const + { + // strxfrm assumes zero-terminated strings so we make a copy + string_type __str(__lo, __hi); + + const _CharT* __p = __str.c_str(); + const _CharT* __pend = __str.data() + __str.length(); + + size_t __len = (__hi - __lo) * 2; + + string_type __ret; + + // strxfrm stops when it sees a nul character so we break + // the string into zero-terminated substrings and pass those + // to strxfrm. + for (;;) + { + // First try a buffer perhaps big enough. + _CharT* __c = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); + size_t __res = _M_transform(__c, __p, __len); + // If the buffer was not large enough, try again with the + // correct size. + if (__res >= __len) + { + __len = __res + 1; + __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __res = _M_transform(__c, __p, __res + 1); + } + + __ret.append(__c, __res); + __p += char_traits<_CharT>::length(__p); + if (__p == __pend) + return __ret; + + __p++; + __ret.push_back(_CharT()); + } + } + + template + long + collate<_CharT>:: + do_hash(const _CharT* __lo, const _CharT* __hi) const + { + unsigned long __val = 0; + for (; __lo < __hi; ++__lo) + __val = *__lo + ((__val << 7) | + (__val >> (numeric_limits::digits - 7))); + return static_cast(__val); + } + + // Construct correctly padded string, as per 22.2.2.2.2 + // Assumes + // __newlen > __oldlen + // __news is allocated for __newlen size + // Used by both num_put and ostream inserters: if __num, + // internal-adjusted objects are padded according to the rules below + // concerning 0[xX] and +-, otherwise, exactly as right-adjusted + // ones are. + + // NB: Of the two parameters, _CharT can be deduced from the + // function arguments. The other (_Traits) has to be explicitly specified. + template + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, + const streamsize __oldlen, const bool __num) + { + const size_t __plen = static_cast(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + + // Padding last. + if (__adjust == ios_base::left) + { + _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; + } + + size_t __mod = 0; + if (__adjust == ios_base::internal && __num) + { + // Pad after the sign, if there is one. + // Pad after 0[xX], if there is one. + // Who came up with these rules, anyway? Jeeze. + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + const bool __testsign = (__ctype.widen('-') == __olds[0] + || __ctype.widen('+') == __olds[0]); + const bool __testhex = (__ctype.widen('0') == __olds[0] + && __oldlen > 1 + && (__ctype.widen('x') == __olds[1] + || __ctype.widen('X') == __olds[1])); + if (__testhex) + { + __news[0] = __olds[0]; + __news[1] = __olds[1]; + __mod = 2; + __news += 2; + } + else if (__testsign) + { + __news[0] = __olds[0]; + __mod = 1; + ++__news; + } + // else Padding first. + } + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), + __oldlen - __mod); + } + + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, __grouping_size - 1); + size_t __i = __n; + bool __test = true; + + // Parsed number groupings have to match the + // numpunct::grouping string exactly, starting at the + // right-most point of the parsed sequence of elements ... + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; + // ... but the last parsed grouping can be <= numpunct + // grouping. + __test &= __grouping_tmp[0] <= __grouping[__min]; + return __test; + } + + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last) + { + if (__last - __first > *__gbeg) + { + const bool __bump = __gsize != 1; + __s = std::__add_grouping(__s, __sep, __gbeg + __bump, + __gsize - __bump, __first, + __last - *__gbeg); + __first = __last - *__gbeg; + *__s++ = __sep; + } + do + *__s++ = *__first++; + while (__first != __last); + return __s; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class money_get; + extern template class money_put; + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + extern template class ctype_byname; + extern template class codecvt_byname; + extern template class collate; + extern template class collate_byname; + + extern template + const codecvt& + use_facet >(const locale&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class money_get; + extern template class money_put; + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + extern template class ctype_byname; + extern template class codecvt_byname; + extern template class collate; + extern template class collate_byname; + + extern template + const codecvt& + use_facet >(locale const&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/localefwd.h b/src/include.new/c++/3.4/bits/localefwd.h new file mode 100644 index 0000000..247158d --- /dev/null +++ b/src/include.new/c++/3.4/bits/localefwd.h @@ -0,0 +1,192 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file localefwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FWD_H +#define _LOCALE_FWD_H 1 + +#pragma GCC system_header + +#include +#include // Defines __c_locale, config-specific includes +#include // For ostreambuf_iterator, istreambuf_iterator +#include + +namespace std +{ + // 22.1.1 Locale + class locale; + + // 22.1.3 Convenience interfaces + template + inline bool + isspace(_CharT, const locale&); + + template + inline bool + isprint(_CharT, const locale&); + + template + inline bool + iscntrl(_CharT, const locale&); + + template + inline bool + isupper(_CharT, const locale&); + + template + inline bool + islower(_CharT, const locale&); + + template + inline bool + isalpha(_CharT, const locale&); + + template + inline bool + isdigit(_CharT, const locale&); + + template + inline bool + ispunct(_CharT, const locale&); + + template + inline bool + isxdigit(_CharT, const locale&); + + template + inline bool + isalnum(_CharT, const locale&); + + template + inline bool + isgraph(_CharT, const locale&); + + template + inline _CharT + toupper(_CharT, const locale&); + + template + inline _CharT + tolower(_CharT, const locale&); + + // 22.2.1 and 22.2.1.3 ctype + class ctype_base; + template + class ctype; + template<> class ctype; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class ctype; +#endif + template + class ctype_byname; + // NB: Specialized for char and wchar_t in locale_facets.h. + + class codecvt_base; + class __enc_traits; + template + class codecvt; + template<> class codecvt; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class codecvt; +#endif + template + class codecvt_byname; + + // 22.2.2 and 22.2.3 numeric + template > + class num_get; + template > + class num_put; + template class numpunct; + template class numpunct_byname; + + // 22.2.4 collation + template + class collate; + template class + collate_byname; + + // 22.2.5 date and time + class time_base; + template > + class time_get; + template > + class time_get_byname; + template > + class time_put; + template > + class time_put_byname; + + // 22.2.6 money + class money_base; + template > + class money_get; + template > + class money_put; + template + class moneypunct; + template + class moneypunct_byname; + + // 22.2.7 message retrieval + class messages_base; + template + class messages; + template + class messages_byname; + + template + bool + has_facet(const locale& __loc) throw(); + + template + const _Facet& + use_facet(const locale& __loc); + + template + inline const _Facet& + __check_facet(const _Facet* __f) + { + if (!__f) + __throw_bad_cast(); + return *__f; + } +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/mask_array.h b/src/include.new/c++/3.4/bits/mask_array.h new file mode 100644 index 0000000..1a694f3 --- /dev/null +++ b/src/include.new/c++/3.4/bits/mask_array.h @@ -0,0 +1,209 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file mask_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MASK_ARRAY_H +#define _MASK_ARRAY_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Reference to selected subset of an array. + * + * A mask_array is a reference to the actual elements of an array specified + * by a bitmask in the form of an array of bool. The way to get a + * mask_array is to call operator[](valarray) on a valarray. The + * returned mask_array then permits carrying operations out on the + * referenced subset of elements in the original valarray. + * + * For example, if a mask_array is obtained using the array (false, true, + * false, true) as an argument, the mask array has two elements referring + * to array[1] and array[3] in the underlying array. + * + * @param Tp Element type. + */ + template + class mask_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + mask_array (const mask_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + mask_array& operator=(const mask_array&); + + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + // ~mask_array (); + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + mask_array(_Array<_Tp>, size_t, _Array); + friend class valarray<_Tp>; + + const size_t _M_sz; + const _Array _M_mask; + const _Array<_Tp> _M_array; + + // not implemented + mask_array(); + }; + + + template + inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a) + : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {} + + template + inline + mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array __m) + : _M_sz(__s), _M_mask(__m), _M_array(__a) {} + + template + inline mask_array<_Tp>& + mask_array<_Tp>::operator=(const mask_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_mask, + _M_sz, _M_array, _M_mask); + return *this; + } + + template + inline void + mask_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); } + + template + inline void + mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } + + template + template + inline void + mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const + { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template \ + template \ + inline void \ + mask_array<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, __e, __e.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _MASK_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/messages_members.h b/src/include.new/c++/3.4/bits/messages_members.h new file mode 100644 index 0000000..4a2ff4a --- /dev/null +++ b/src/include.new/c++/3.4/bits/messages_members.h @@ -0,0 +1,84 @@ +// std::messages implementation details, generic version -*- C++ -*- + +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.7.1.2 messages virtual functions +// + +// Written by Benjamin Kosnik + + // Non-virtual member functions. + template + messages<_CharT>::messages(size_t __refs) + : facet(__refs) + { _M_c_locale_messages = _S_get_c_locale(); } + + template + messages<_CharT>::messages(__c_locale, const char*, size_t __refs) + : facet(__refs) + { _M_c_locale_messages = _S_get_c_locale(); } + + template + typename messages<_CharT>::catalog + messages<_CharT>::open(const basic_string& __s, const locale& __loc, + const char*) const + { return this->do_open(__s, __loc); } + + // Virtual member functions. + template + messages<_CharT>::~messages() + { _S_destroy_c_locale(_M_c_locale_messages); } + + template + typename messages<_CharT>::catalog + messages<_CharT>::do_open(const basic_string&, const locale&) const + { return 0; } + + template + typename messages<_CharT>::string_type + messages<_CharT>::do_get(catalog, int, int, + const string_type& __dfault) const + { return __dfault; } + + template + void + messages<_CharT>::do_close(catalog) const + { } + + // messages_byname + template + messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs) + : messages<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_messages); + this->_S_create_c_locale(this->_M_c_locale_messages, __s); + } + } diff --git a/src/include.new/c++/3.4/bits/os_defines.h b/src/include.new/c++/3.4/bits/os_defines.h new file mode 100644 index 0000000..1e46712 --- /dev/null +++ b/src/include.new/c++/3.4/bits/os_defines.h @@ -0,0 +1,44 @@ +// Specific definitions for BSD -*- C++ -*- + +// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#ifndef _GLIBCXX_OS_DEFINES +#define _GLIBCXX_OS_DEFINES 1 + +// System-specific #define, typedefs, corrections, etc, go here. This +// file will come before all others. + +#define _GLIBCXX_USE_C99_CHECK 1 +#define _GLIBCXX_USE_C99_DYNAMIC (!(__ISO_C_VISIBLE >= 1999)) +#define _GLIBCXX_USE_C99_LONG_LONG_CHECK 1 +#define _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC (_GLIBCXX_USE_C99_DYNAMIC || !defined __LONG_LONG_SUPPORTED) +#define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1 +#define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE + +#endif diff --git a/src/include.new/c++/3.4/bits/ostream.tcc b/src/include.new/c++/3.4/bits/ostream.tcc new file mode 100644 index 0000000..2d1b5b4 --- /dev/null +++ b/src/include.new/c++/3.4/bits/ostream.tcc @@ -0,0 +1,699 @@ +// ostream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#ifndef _OSTREAM_TCC +#define _OSTREAM_TCC 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + basic_ostream<_CharT, _Traits>::sentry:: + sentry(basic_ostream<_CharT, _Traits>& __os) + : _M_ok(false), _M_os(__os) + { + // XXX MT + if (__os.tie() && __os.good()) + __os.tie()->flush(); + + if (__os.good()) + _M_ok = true; + else + __os.setstate(ios_base::failbit); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ostream_type& (*__pf)(__ostream_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + return __pf(*this); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ios_type& (*__pf)(__ios_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(ios_base& (*__pf)(ios_base&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(bool __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long __l = static_cast(__n); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long long __l = (static_cast< + unsigned long long>(__n)); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } +#endif + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(double __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long double __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(const void* __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__streambuf_type* __sbin) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this); + if (__cerb && __sbin) + { + try + { + if (!__copy_streambufs(__sbin, this->rdbuf())) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbin) + __err |= ios_base::badbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + put(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __put = this->rdbuf()->sputc(__c); + if (traits_type::eq_int_type(__put, traits_type::eof())) + __err |= ios_base::badbit; + } + catch (...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + write(const _CharT* __s, streamsize __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an + // unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + try + { _M_write(__s, __n); } + catch (...) + { this->_M_setstate(ios_base::badbit); } + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + flush() + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::flush() is *not* an unformatted output function. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (this->rdbuf() && this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_ostream<_CharT, _Traits>::pos_type + basic_ostream<_CharT, _Traits>:: + tellp() + { + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(pos_type __pos) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(off_type __off, ios_base::seekdir __dir) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + // 27.6.2.5.4 Character inserters. + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = 1; + _CharT* __cs = &__c; + if (__w > __len) + { + __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + &__c, __w, __len, false); + __len = __w; + } + __out._M_write(__cs, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + return __out; + } + + // Specializations. + template + basic_ostream& + operator<<(basic_ostream& __out, char __c) + { + typedef basic_ostream __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = 1; + char* __cs = &__c; + if (__w > __len) + { + __cs = static_cast(__builtin_alloca(__w)); + __pad::_S_pad(__out, __out.fill(), __cs, + &__c, __w, __len, false); + __len = __w; + } + __out._M_write(__cs, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + return __out; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(_Traits::length(__s)); + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + __s, __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 167. Improper use of traits_type::length() + // Note that this is only in 'Review' status. + typedef char_traits __traits_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + size_t __clen = __traits_type::length(__s); + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __clen)); + for (size_t __i = 0; __i < __clen; ++__i) + __ws[__i] = __out.widen(__s[__i]); + _CharT* __str = __ws; + + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(__clen); + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + __ws, __w, __len, false); + __str = __cs; + __len = __w; + } + __out._M_write(__str, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + // Partial specializations. + template + basic_ostream& + operator<<(basic_ostream& __out, const char* __s) + { + typedef basic_ostream __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(_Traits::length(__s)); + if (__w > __len) + { + char* __cs = static_cast(__builtin_alloca(__w)); + __pad::_S_pad(__out, __out.fill(), __cs, + __s, __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + // 21.3.7.9 basic_string::operator<< + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, + const basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(__str.size()); + const _CharT* __s = __str.data(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 25. String operator<< uses width() value wrong + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s, + __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + return __out; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ostream; + extern template ostream& endl(ostream&); + extern template ostream& ends(ostream&); + extern template ostream& flush(ostream&); + extern template ostream& operator<<(ostream&, char); + extern template ostream& operator<<(ostream&, unsigned char); + extern template ostream& operator<<(ostream&, signed char); + extern template ostream& operator<<(ostream&, const char*); + extern template ostream& operator<<(ostream&, const unsigned char*); + extern template ostream& operator<<(ostream&, const signed char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ostream; + extern template wostream& endl(wostream&); + extern template wostream& ends(wostream&); + extern template wostream& flush(wostream&); + extern template wostream& operator<<(wostream&, wchar_t); + extern template wostream& operator<<(wostream&, char); + extern template wostream& operator<<(wostream&, const wchar_t*); + extern template wostream& operator<<(wostream&, const char*); +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/postypes.h b/src/include.new/c++/3.4/bits/postypes.h new file mode 100644 index 0000000..0cfb61b --- /dev/null +++ b/src/include.new/c++/3.4/bits/postypes.h @@ -0,0 +1,215 @@ +// Position types -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4.1 - Types +// ISO C++ 14882: 27.4.3 - Template class fpos +// + +/** @file postypes.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_POSTYPES_H +#define _GLIBCXX_POSTYPES_H 1 + +#pragma GCC system_header + +#include // For mbstate_t + +#ifdef _GLIBCXX_HAVE_STDINT_H +#include // For int64_t +#endif + +namespace std +{ + // The types streamoff, streampos and wstreampos and the class + // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, + // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbage, the + // behaviour of these types is mostly implementation defined or + // unspecified. The behaviour in this implementation is as noted + // below. + + /** + * @brief Type used by fpos, char_traits, and char_traits. + * + * @if maint + * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an + * implementation defined type. + * Note: In versions of GCC up to and including GCC 3.3, streamoff + * was typedef long. + * @endif + */ +#ifdef _GLIBCXX_HAVE_INT64_T + typedef int64_t streamoff; +#else + typedef long long streamoff; +#endif + + /// Integral type for I/O operation counts and buffer sizes. + typedef ptrdiff_t streamsize; // Signed integral type + + template + class fpos; + + /** + * @brief Class representing stream positions. + * + * The standard places no requirements upon the template parameter StateT. + * In this implementation StateT must be DefaultConstructible, + * CopyConstructible and Assignable. The standard only requires that fpos + * should contain a member of type StateT. In this implementation it also + * contains an offset stored as a signed integer. + * + * @param StateT Type passed to and returned from state(). + */ + template + class fpos + { + private: + streamoff _M_off; + _StateT _M_state; + + public: + // The standard doesn't require that fpos objects can be default + // constructed. This implementation provides a default + // constructor that initializes the offset to 0 and default + // constructs the state. + fpos() + : _M_off(0), _M_state() { } + + // The standard requires that fpos objects can be constructed + // from streamoff objects using the constructor syntax, and + // fails to give any meaningful semantics. In this + // implementation implicit conversion is also allowed, and this + // constructor stores the streamoff as the offset and default + // constructs the state. + /// Construct position from offset. + fpos(streamoff __off) + : _M_off(__off), _M_state() { } + + /// Convert to streamoff. + operator streamoff() const { return _M_off; } + + /// Remember the value of @a st. + void + state(_StateT __st) + { _M_state = __st; } + + /// Return the last set value of @a st. + _StateT + state() const + { return _M_state; } + + // The standard only requires that operator== must be an + // equivalence relation. In this implementation two fpos + // objects belong to the same equivalence class if the contained + // offsets compare equal. + /// Test if equivalent to another position. + bool + operator==(const fpos& __other) const + { return _M_off == __other._M_off; } + + /// Test if not equivalent to another position. + bool + operator!=(const fpos& __other) const + { return _M_off != __other._M_off; } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just adds it's + // argument to the stored offset and returns *this. + /// Add offset to this position. + fpos& + operator+=(streamoff __off) + { + _M_off += __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just subtracts + // it's argument from the stored offset and returns *this. + /// Subtract offset from this position. + fpos& + operator-=(streamoff __off) + { + _M_off -= __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator-. In this + // implementation it constructs a copy of *this, adds the + // argument to that copy using operator+= and then returns the + // copy. + /// Add position and offset. + fpos + operator+(streamoff __off) const + { + fpos __pos(*this); + __pos += __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it constructs a copy of *this, subtracts the + // argument from that copy using operator-= and then returns the + // copy. + /// Subtract offset from position. + fpos + operator-(streamoff __off) const + { + fpos __pos(*this); + __pos -= __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it returns the difference between the offset + // stored in *this and in the argument. + /// Subtract position to return offset. + streamoff + operator-(const fpos& __other) const + { return _M_off - __other._M_off; } + }; + + // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos + // as implementation defined types, but clause 27.2 requires that + // they must both be typedefs for fpos + /// File position for char streams. + typedef fpos streampos; + /// File position for wchar_t streams. + typedef fpos wstreampos; +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/slice_array.h b/src/include.new/c++/3.4/bits/slice_array.h new file mode 100644 index 0000000..31c89bc --- /dev/null +++ b/src/include.new/c++/3.4/bits/slice_array.h @@ -0,0 +1,273 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file slice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SLICE_ARRAY_H +#define _SLICE_ARRAY_H 1 + +#pragma GCC system_header + +namespace std +{ + /** + * @brief Class defining one-dimensional subset of an array. + * + * The slice class represents a one-dimensional subset of an array, + * specified by three parameters: start offset, size, and stride. The + * start offset is the index of the first element of the array that is part + * of the subset. The size is the total number of elements in the subset. + * Stride is the distance between each successive array element to include + * in the subset. + * + * For example, with an array of size 10, and a slice with offset 1, size 3 + * and stride 2, the subset consists of array elements 1, 3, and 5. + */ + class slice + { + public: + /// Construct an empty slice. + slice(); + + /** + * @brief Construct a slice. + * + * @param o Offset in array of first element. + * @param d Number of elements in slice. + * @param s Stride between array elements. + */ + slice(size_t, size_t, size_t); + + /// Return array offset of first slice element. + size_t start() const; + /// Return size of slice. + size_t size() const; + /// Return array stride of slice. + size_t stride() const; + + private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit + }; + + // The default constructor constructor is not required to initialize + // data members with any meaningful values, so we choose to do nothing. + inline + slice::slice() {} + + inline + slice::slice(size_t __o, size_t __d, size_t __s) + : _M_off(__o), _M_sz(__d), _M_st(__s) {} + + inline size_t + slice::start() const + { return _M_off; } + + inline size_t + slice::size() const + { return _M_sz; } + + inline size_t + slice::stride() const + { return _M_st; } + + /** + * @brief Reference to one-dimensional subset of an array. + * + * A slice_array is a reference to the actual elements of an array + * specified by a slice. The way to get a slice_array is to call + * operator[](slice) on a valarray. The returned slice_array then permits + * carrying operations out on the referenced subset of elements in the + * original valarray. For example, operator+=(valarray) will add values + * to the subset of elements in the underlying valarray this slice_array + * refers to. + * + * @param Tp Element type. + */ + template + class slice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + slice_array(const slice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + slice_array& operator=(const slice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp &) const; + // ~slice_array (); + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + friend class valarray<_Tp>; + slice_array(_Array<_Tp>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_Tp> _M_array; + + // not implemented + slice_array(); + }; + + template + inline + slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) + : _M_sz(__s.size()), _M_stride(__s.stride()), + _M_array(__a.begin() + __s.start()) {} + + template + inline + slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + + // template + // inline slice_array<_Tp>::~slice_array () {} + + template + inline slice_array<_Tp>& + slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, + _M_array, _M_stride); + return *this; + } + + template + inline void + slice_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } + + template + inline void + slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } + + template + template + inline void + slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ + template \ + inline void \ + slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\ + } \ + \ + template \ + template \ + inline void \ + slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \ + } + + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _SLICE_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/sstream.tcc b/src/include.new/c++/3.4/bits/sstream.tcc new file mode 100644 index 0000000..03f49fb --- /dev/null +++ b/src/include.new/c++/3.4/bits/sstream.tcc @@ -0,0 +1,227 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _SSTREAM_TCC +#define _SSTREAM_TCC 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + pbackfail(int_type __c) + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + + if (this->eback() < this->gptr()) + { + const bool __testeq = traits_type::eq(traits_type::to_char_type(__c), + this->gptr()[-1]); + this->gbump(-1); + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && __testeq) + __ret = __c; + else if (__testeof) + __ret = traits_type::not_eof(__c); + else + { + *this->gptr() = traits_type::to_char_type(__c); + __ret = __c; + } + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + overflow(int_type __c) + { + const bool __testout = this->_M_mode & ios_base::out; + if (__builtin_expect(!__testout, false)) + return traits_type::eof(); + + const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + if (__builtin_expect(__testeof, false)) + return traits_type::not_eof(__c); + + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); + const bool __testput = this->pptr() < this->epptr(); + if (__builtin_expect(!__testput && __capacity == __max_size, false)) + return traits_type::eof(); + + // Try to append __c into output sequence in one of two ways. + // Order these tests done in is unspecified by the standard. + if (!__testput) + { + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // Then, in virtue of DR 169 (TC) we are allowed to grow more + // than one char. + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); + __string_type __tmp; + __tmp.reserve(__len); + __tmp.assign(_M_string.data(), this->epptr() - this->pbase()); + _M_string.swap(__tmp); + _M_sync(const_cast(_M_string.data()), + this->gptr() - this->eback(), this->pptr() - this->pbase()); + } + return this->sputc(traits_type::to_char_type(__c)); + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin) + { + // Update egptr() to match the actual string end. + _M_update_egptr(); + + if (this->gptr() < this->egptr()) + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + const bool __testboth = __testin && __testout && __way != ios_base::cur; + __testin &= !(__mode & ios_base::out); + __testout &= !(__mode & ios_base::in); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 453. basic_stringbuf::seekoff need not always fail for an empty stream. + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if ((__beg || !__off) && (__testin || __testout || __testboth)) + { + _M_update_egptr(); + + off_type __newoffi = 0; + off_type __newoffo = 0; + if (__way == ios_base::cur) + { + __newoffi = this->gptr() - __beg; + __newoffo = this->pptr() - __beg; + } + else if (__way == ios_base::end) + __newoffo = __newoffi = this->egptr() - __beg; + + if ((__testin || __testboth) + && __newoffi + __off >= 0 + && this->egptr() - __beg >= __newoffi + __off) + { + this->gbump((__beg + __newoffi + __off) - this->gptr()); + __ret = pos_type(__newoffi); + } + if ((__testout || __testboth) + && __newoffo + __off >= 0 + && this->egptr() - __beg >= __newoffo + __off) + { + this->pbump((__beg + __newoffo + __off) - this->pptr()); + __ret = pos_type(__newoffo); + } + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekpos(pos_type __sp, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if (__beg) + { + _M_update_egptr(); + + off_type __pos(__sp); + const bool __testpos = 0 <= __pos + && __pos <= this->egptr() - __beg; + if ((__testin || __testout) && __testpos) + { + if (__testin) + this->gbump((__beg + __pos) - this->gptr()); + if (__testout) + this->pbump((__beg + __pos) - this->pptr()); + __ret = __sp; + } + } + return __ret; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_stringbuf; + extern template class basic_istringstream; + extern template class basic_ostringstream; + extern template class basic_stringstream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_stringbuf; + extern template class basic_istringstream; + extern template class basic_ostringstream; + extern template class basic_stringstream; +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/stl_algo.h b/src/include.new/c++/3.4/bits/stl_algo.h new file mode 100644 index 0000000..74956d7 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_algo.h @@ -0,0 +1,5148 @@ +// Algorithm implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algo.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGO_H +#define _ALGO_H 1 + +#include +#include // for _Temporary_buffer +#include + +// See concept_check.h for the __glibcxx_*_requires macros. + +namespace std +{ + /** + * @brief Find the median of three values. + * @param a A value. + * @param b A value. + * @param c A value. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n + * then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; + else + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; + else + return __b; + } + + /** + * @brief Find the median of three values using a predicate for comparison. + * @param a A value. + * @param b A value. + * @param c A value. + * @param comp A binary predicate. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) + * and @p comp(m,n) are both true then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>) + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; + else + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; + else + return __b; + } + + /** + * @brief Apply a function to every element of a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param f A unary function object. + * @return @p f. + * + * Applies the function object @p f to each element in the range + * @p [first,last). @p f must not modify the order of the sequence. + * If @p f has a return value it is ignored. + */ + template + _Function + for_each(_InputIterator __first, _InputIterator __last, _Function __f) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; + } + + /** + * @if maint + * This is an overload used by find() for the Input Iterator case. + * @endif + */ + template + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val, input_iterator_tag) + { + while (__first != __last && !(*__first == __val)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find_if() for the Input Iterator case. + * @endif + */ + template + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, input_iterator_tag) + { + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find() for the RAI case. + * @endif + */ + template + _RandomAccessIterator + find(_RandomAccessIterator __first, _RandomAccessIterator __last, + const _Tp& __val, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (*__first == __val) + return __first; + ++__first; + case 2: + if (*__first == __val) + return __first; + ++__first; + case 1: + if (*__first == __val) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @if maint + * This is an overload used by find_if() for the RAI case. + * @endif + */ + template + _RandomAccessIterator + find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Predicate __pred, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (__pred(*__first)) + return __first; + ++__first; + case 2: + if (__pred(*__first)) + return __first; + ++__first; + case 1: + if (__pred(*__first)) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @brief Find the first occurrence of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last) + * such that @c *i == @p val, or @p last if no such iterator exists. + */ + template + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + return std::find(__first, __last, __val, + std::__iterator_category(__first)); + } + + /** + * @brief Find the first element in a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The first iterator @c i in the range @p [first,last) + * such that @p pred(*i) is true, or @p last if no such iterator exists. + */ + template + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + return std::find_if(__first, __last, __pred, + std::__iterator_category(__first)); + } + + /** + * @brief Find two adjacent values in a sequence that are equal. + * @param first A forward iterator. + * @param last A forward iterator. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that @c *i == @c *(i+1), + * or @p last if no such iterator exists. + */ + template + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (*__first == *__next) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Find two adjacent values in a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that + * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator + * exists. + */ + template + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Count the number of copies of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be counted. + * @return The number of iterators @c i in the range @p [first,last) + * for which @c *i == @p value + */ + template + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; + } + + /** + * @brief Count the elements of a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The number of iterators @c i in the range @p [first,last) + * for which @p pred(*i) is true. + */ + template + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; + } + + /** + * @brief Search a sequence for a matching sub-sequence. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return std::find(__first1, __last1, *__first2); + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + __first1 = std::find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @brief Search a sequence for a matching sub-sequence using a predicate. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @param predicate A binary predicate. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that + * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range + * @p [0,last2-first2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2), + * using @p predicate to determine equality, and returns an iterator + * to the first element of the sub-sequence, or @p last1 if no such + * iterator exists. + * + * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) + */ + template + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + { + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + return __first1; + } + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + while (__first1 != __last1) + { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(*__current, *__p)) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @brief Search a sequence for a number of consecutive values. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @c *(i+N) == @p val for each @c N in the range @p [0,count), + * or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * equal to @p val. + */ + template + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + else + { + __first = std::find(__first, __last, __val); + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && *__i == __val) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + __first = std::find(__i, __last, __val); + } + return __last; + } + } + + /** + * @brief Search a sequence for a number of consecutive values using a + * predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @param binary_pred A binary predicate. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @p binary_pred(*(i+N),val) is true for each @c N in the + * range @p [0,count), or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * for which the predicate returns true. + */ + template + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + else + { + while (__first != __last) + { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && __binary_pred(*__i, __val)) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + { + while (__i != __last) + { + if (__binary_pred(*__i, __val)) + break; + ++__i; + } + __first = __i; + } + } + return __last; + } + } + + /** + * @brief Swap the elements of two sequences. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @return An iterator equal to @p first2+(last1-first1). + * + * Swaps each element in the range @p [first1,last1) with the + * corresponding element in the range @p [first2,(last1-first1)). + * The ranges must not overlap. + */ + template + _ForwardIterator2 + swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator2>::value_type, + typename iterator_traits<_ForwardIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + std::iter_swap(__first1, __first2); + return __first2; + } + + /** + * @brief Perform an operation on a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param unary_op A unary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to each element in the input range and assigns + * the results to successive elements of the output sequence. + * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the + * range @p [0,last-first). + * + * @p unary_op must not alter its argument. + */ + template + _OutputIterator + transform(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _UnaryOperation __unary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _UnaryOperation" + __typeof__(__unary_op(*__first))>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __unary_op(*__first); + return __result; + } + + /** + * @brief Perform an operation on corresponding elements of two sequences. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param result An output iterator. + * @param binary_op A binary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to the corresponding elements in the two + * input ranges and assigns the results to successive elements of the + * output sequence. + * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each + * @c N in the range @p [0,last1-first1). + * + * @p binary_op must not alter either of its arguments. + */ + template + _OutputIterator + transform(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _OutputIterator __result, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _BinaryOperation" + __typeof__(__binary_op(*__first1,*__first2))>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; + } + + /** + * @brief Replace each occurrence of one value in a sequence with another + * value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return replace() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @c *i == + * @p old_value then the assignment @c *i = @p new_value is performed. + */ + template + void + replace(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; + } + + /** + * @brief Replace each value in a sequence for which a predicate returns + * true with another value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return replace_if() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @p pred(*i) + * is true then the assignment @c *i = @p new_value is performed. + */ + template + void + replace_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; + } + + /** + * @brief Copy a sequence, replacing each element of one value with another + * value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the input range @p [first,last) to the + * output range @p [result,result+(last-first)) replacing elements + * equal to @p old_value with @p new_value. + */ + template + _OutputIterator + replace_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; + } + + /** + * @brief Copy a sequence, replacing each value for which a predicate + * returns true with another value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the range @p [first,last) to the range + * @p [result,result+(last-first)) replacing elements for which + * @p pred returns true with @p new_value. + */ + template + _OutputIterator + replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param gen A function object taking no arguments. + * @return generate() returns no value. + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,last). + */ + template + void + generate(_ForwardIterator __first, _ForwardIterator __last, + _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_GeneratorConcept<_Generator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + *__first = __gen(); + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param n The length of the sequence. + * @param gen A function object taking no arguments. + * @return The end of the sequence, @p first+n + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,first+n). + */ + template + _OutputIterator + generate_n(_OutputIterator __first, _Size __n, _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _Generator" + __typeof__(__gen())>) + + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; + } + + /** + * @brief Copy a sequence, removing elements of a given value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) not equal to @p value + * to the range beginning at @p result. + * remove_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + _OutputIterator + remove_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!(*__first == __value)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Copy a sequence, removing elements for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) for which + * @p pred returns true to the range beginning at @p result. + * + * remove_copy_if() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + _OutputIterator + remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Remove elements from a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * All elements equal to @p value are removed from the range + * @p [first,last). + * + * remove() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + remove(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find(__first, __last, __value); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy(++__i, __last, + __first, __value); + } + + /** + * @brief Remove elements from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * All elements for which @p pred returns true are removed from the range + * @p [first,last). + * + * remove_if() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + remove_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find_if(__first, __last, __pred); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy_if(++__i, __last, + __first, __pred); + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for output iterators. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + output_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!(__value == *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for forward iterators. + * @endif + */ + template + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + forward_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + *__result = *__first; + while (++__first != __last) + if (!(*__result == *__first)) + *++__result = *__first; + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for output iterators. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for forward iterators. + * @endif + */ + template + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; + } + + /** + * @brief Copy a sequence, removing consecutive duplicate values. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements that compare equal. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; + + if (__first == __last) return __result; + return std::__unique_copy(__first, __last, __result, _IterType()); + } + + /** + * @brief Copy a sequence, removing consecutive values using a predicate. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements for which @p binary_pred returns + * true. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _BinaryPredicate __binary_pred) + { + // concept requirements -- predicates checked later + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; + + if (__first == __last) return __result; + return std::__unique_copy(__first, __last, __result, + __binary_pred, _IterType()); + } + + /** + * @brief Remove consecutive duplicate values from a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values that compare equal. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!(*__dest == *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @brief Remove consecutive values from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values for which @p binary_pred returns true. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!__binary_pred(*__dest, *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for bidirectional iterators. + * @endif + */ + template + void + __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + while (true) + if (__first == __last || __first == --__last) + return; + else + std::iter_swap(__first++, __last); + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for bidirectional iterators. + * @endif + */ + template + void + __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + while (__first < __last) + std::iter_swap(__first++, --__last); + } + + /** + * @brief Reverse a sequence. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @return reverse() returns no value. + * + * Reverses the order of the elements in the range @p [first,last), + * so that the first element becomes the last etc. + * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse() + * swaps @p *(first+i) and @p *(last-(i+1)) + */ + template + inline void + reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); + std::__reverse(__first, __last, std::__iterator_category(__first)); + } + + /** + * @brief Copy a sequence, reversing its elements. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements in the range @p [first,last) to the range + * @p [result,result+(last-first)) such that the order of the + * elements is reversed. + * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy() + * performs the assignment @p *(result+(last-first)-i) = *(first+i). + * The ranges @p [first,last) and @p [result,result+(last-first)) + * must not overlap. + */ + template + _OutputIterator + reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + while (__first != __last) + { + --__last; + *__result = *__last; + ++__result; + } + return __result; + } + + + /** + * @if maint + * This is a helper function for the rotate algorithm specialized on RAIs. + * It returns the greatest common divisor of two integer values. + * @endif + */ + template + _EuclideanRingElement + __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) + { + while (__n != 0) + { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + forward_iterator_tag) + { + if ((__first == __middle) || (__last == __middle)) + return; + + _ForwardIterator __first2 = __middle; + do + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } + while (__first2 != __last); + + __first2 = __middle; + + while (__first2 != __last) + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + + if ((__first == __middle) || (__last == __middle)) + return; + + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap(*__first++, *--__last); + + if (__first == __middle) + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + else + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + + if ((__first == __middle) || (__last == __middle)) + return; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + const _Distance __n = __last - __first; + const _Distance __k = __middle - __first; + const _Distance __l = __n - __k; + + if (__k == __l) + { + std::swap_ranges(__first, __middle, __middle); + return; + } + + const _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) + { + const _ValueType __tmp = *__first; + _RandomAccessIterator __p = __first; + + if (__k < __l) + { + for (_Distance __j = 0; __j < __l / __d; __j++) + { + if (__p > __first + __l) + { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + else + { + for (_Distance __j = 0; __j < __k / __d - 1; __j ++) + { + if (__p < __last - __k) + { + *__p = *(__p + __k); + __p += __k; + } + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + } + + /** + * @brief Rotate the elements of a sequence. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Rotates the elements of the range @p [first,last) by @p (middle-first) + * positions so that the element at @p middle is moved to @p first, the + * element at @p middle+1 is moved to @first+1 and so on for each element + * in the range @p [first,last). + * + * This effectively swaps the ranges @p [first,middle) and + * @p [middle,last). + * + * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template + inline void + rotate(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + typedef typename iterator_traits<_ForwardIterator>::iterator_category + _IterType; + std::__rotate(__first, __middle, __last, _IterType()); + } + + /** + * @brief Copy a sequence, rotating its elements. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements of the range @p [first,last) to the range + * beginning at @result, rotating the copied elements by @p (middle-first) + * positions so that the element at @p middle is moved to @p result, the + * element at @p middle+1 is moved to @result+1 and so on for each element + * in the range @p [first,last). + * + * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template + _OutputIterator + rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + return std::copy(__first, __middle, copy(__middle, __last, __result)); + } + + /** + * @brief Randomly shuffle the elements of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Reorder the elements in the range @p [first,last) using a random + * distribution, so that every possible ordering of the sequence is + * equally likely. + */ + template + inline void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); + } + + /** + * @brief Shuffle the elements of a sequence using a random number + * generator. + * @param first A forward iterator. + * @param last A forward iterator. + * @param rand The RNG functor or function. + * @return Nothing. + * + * Reorders the elements in the range @p [first,last) using @p rand to + * provide a random distribution. Calling @p rand(N) for a positive + * integer @p N should return a randomly chosen integer from the + * range [0,N). + */ + template + void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + __rand((__i - __first) + 1)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, + forward_iterator_tag) + { + if (__first == __last) + return __first; + + while (__pred(*__first)) + if (++__first == __last) + return __first; + + _ForwardIterator __next = __first; + + while (++__next != __last) + if (__pred(*__next)) + { + swap(*__first, *__next); + ++__first; + } + + return __first; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _BidirectionalIterator + __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, + _Predicate __pred, + bidirectional_iterator_tag) + { + while (true) + { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * @p pred must not modify its operand. @p partition() does not preserve + * the relative ordering of elements in each group, use + * @p stable_partition() if this is needed. + */ + template + inline _ForwardIterator + partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__partition(__first, __last, __pred, + std::__iterator_category(__first)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __inplace_stable_partition(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len) + { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = std::__inplace_stable_partition(__first, + __middle, + __pred, + __len / 2); + _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last, + __pred, + __len + - __len / 2); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __stable_partition_adaptive(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) + { + if (__len <= __buffer_size) + { + _ForwardIterator __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) + { + *__result1 = *__first; + ++__result1; + } + else + { + *__result2 = *__first; + ++__result2; + } + std::copy(__buffer, __result2, __result1); + return __result1; + } + else + { + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = + std::__stable_partition_adaptive(__first, __middle, __pred, + __len / 2, __buffer, + __buffer_size); + _ForwardIterator __end = + std::__stable_partition_adaptive(__middle, __last, __pred, + __len - __len / 2, + __buffer, __buffer_size); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence, preserving relative ordering. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * Performs the same function as @p partition() with the additional + * guarantee that the relative ordering of elements in each group is + * preserved, so any two elements @p x and @p y in the range + * @p [first,last) such that @p pred(x)==pred(y) will have the same + * relative ordering after calling @p stable_partition(). + */ + template + _ForwardIterator + stable_partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + else + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, + __last); + if (__buf.size() > 0) + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), __buf.size()); + else + return + std::__inplace_stable_partition(__first, __last, __pred, + _DistanceType(__buf.requested_size())); + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __pivot) + { + while (true) + { + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Tp __pivot, _Compare __comp) + { + while (true) + { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * @doctodo + * This controls some aspect of the sort routines. + * @endif + */ + enum { _S_threshold = 16 }; + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val) + { + _RandomAccessIterator __next = __last; + --__next; + while (__val < *__next) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val, + _Compare __comp) + { + _RandomAccessIterator __next = __last; + --__next; + while (__comp(__val, *__next)) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__first == __last) + return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__val < *__first) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__first == __last) return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__comp(__val, *__first)) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val, __comp); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i)); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold); + std::__unguarded_insertion_sort(__first + _S_threshold, __last); + } + else + std::__insertion_sort(__first, __last); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold, __comp); + std::__unguarded_insertion_sort(__first + _S_threshold, __last, + __comp); + } + else + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline _Size + __lg(_Size __n) + { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) + ++__k; + return __k; + } + + /** + * @brief Sort the smallest elements of a sequence. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false. + */ + template + void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::make_heap(__first, __middle); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i)); + std::sort_heap(__first, __middle); + } + + /** + * @brief Sort the smallest elements of a sequence using a predicate + * for comparison. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i) + * are both false. + */ + template + void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::make_heap(__first, __middle, __comp); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp); + std::sort_heap(__first, __middle, __comp); + } + + /** + * @brief Copy the smallest elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p *j<*i is false. + * The value returned is @p result_first+N. + */ + template + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_InputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last); + while (__first != __last) + { + if (*__first < *__result_first) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first)); + ++__first; + } + std::sort_heap(__result_first, __result_real_last); + return __result_real_last; + } + + /** + * @brief Copy the smallest elements of a sequence using a predicate for + * comparison. + * @param first An input iterator. + * @param last Another input iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @param comp A comparison functor. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p comp(*j,*i) is false. + * The value returned is @p result_first+N. + */ + template + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _OutputValueType, _OutputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(*__first, *__result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), + __comp); + ++__first; + } + std::sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + std::__introsort_loop(__cut, __last, __depth_limit); + __last = __cut; + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), + __comp); + std::__introsort_loop(__cut, __last, __depth_limit, __comp); + __last = __cut; + } + } + + /** + * @brief Sort the elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2); + std::__final_insertion_sort(__first, __last); + } + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for every iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2, + __comp); + std::__final_insertion_sort(__first, __last, __comp); + } + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + */ + template + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // Note that these are slightly stricter than those of the 4-argument + // version, defined next. The difference is in the strictness of the + // comparison operations... so for looser checking, define your own + // comparison function, as was intended. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + */ + template + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (*__middle < *__first) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22); + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Compare __comp) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (__comp(*__middle, *__first)) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22, __comp); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22, __comp); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle); + std::__inplace_stable_sort(__middle, __last); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle, __comp); + std::__inplace_stable_sort(__middle, __last, __comp); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + */ + template + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + template + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _Distance __step_size) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; + } + + __step_size = std::min(_Distance(__last - __first), __step_size); + std::merge(__first, __first + __step_size, __first + __step_size, __last, + __result); + } + + template + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, _Distance __step_size, + _Compare __comp) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = std::min(_Distance(__last - __first), __step_size); + + std::merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); + } + + enum { _S_chunk_size = 7 }; + + template + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last); + } + + template + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size, _Compare __comp) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last, __comp); + } + + template + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } + } + + template + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, + __step_size, __comp); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, + __step_size, __comp); + __step_size *= 2; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (*__last2 < *__last1) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result, + _Compare __comp) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (__comp(*__last2, *__last1)) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator1 + __rotate_adaptive(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __middle, + _BidirectionalIterator1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIterator2 __buffer, + _Distance __buffer_size) + { + _BidirectionalIterator2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) + { + __buffer_end = std::copy(__middle, __last, __buffer); + std::copy_backward(__first, __middle, __last); + return std::copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) + { + __buffer_end = std::copy(__first, __middle, __buffer); + std::copy(__middle, __last, __first); + return std::copy_backward(__buffer, __buffer_end, __last); + } + else + { + std::rotate(__first, __middle, __last); + std::advance(__first, std::distance(__middle, __last)); + return __first; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, + __buffer_end, __last); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, + *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, + *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, __buffer_end, + __last, __comp); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, + __buffer_size, __comp); + } + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + */ + template + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_sorted(__first, __middle); + __glibcxx_requires_sorted(__middle, __last); + + if (__first == __middle || __middle == __last) + return; + + _DistanceType __len1 = std::distance(__first, __middle); + _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size())); + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A functor to use for comparisons. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_sorted_pred(__first, __middle, __comp); + __glibcxx_requires_sorted_pred(__middle, __last, __comp); + + if (__first == __middle || __middle == __last) + return; + + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, + __len2, __comp); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size()), + __comp); + } + + template + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, + __buffer, __buffer_size); + std::__stable_sort_adaptive(__middle, __last, + __buffer, __buffer_size); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer); + std::__merge_sort_with_buffer(__middle, __last, __buffer); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size); + } + + template + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, __buffer, + __buffer_size, __comp); + std::__stable_sort_adaptive(__middle, __last, __buffer, + __buffer_size, __comp); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size, + __comp); + } + + /** + * @brief Sort the elements of a sequence, preserving the relative order + * of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p x + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> + buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size())); + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison, + * preserving the relative order of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for each iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p comp(x,y) is false and @p comp(y,x) is false will have the same + * relative ordering after calling @p stable_sort(). + */ + template + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size()), __comp); + } + + /** + * @brief Sort a sequence just enough to find a particular position. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p *j<*i is false. + */ + template + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last); + } + + /** + * @brief Sort a sequence just enough to find a particular position + * using a predicate for comparison. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p comp(*j,*i) is false. + */ + template + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val), + * upper_bound(first, last, val)) + * @endcode + * but does not actually call those functions. + */ + template + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val, comp), + * upper_bound(first, last, val, comp)) + * @endcode + * but does not actually call those functions. + */ + template + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val, __comp); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + */ + template + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); + } + + // Set algorithms: includes, set_union, set_intersection, set_difference, + // set_symmetric_difference. All of these algorithms have the precondition + // that their input ranges are sorted and the postcondition that their output + // ranges are sorted. + + /** + * @brief Determines whether all elements of a sequence exists in a range. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1). False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1). The iterators over each range only move forward, + * so this is a linear algorithm. If an element in [first2,last2) is not + * found before the search iterator reaches @a last2, false is returned. + */ + template + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + return false; + else if(*__first1 < *__first2) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Determines whether all elements of a sequence exists in a range + * using comparison. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @param comp Comparison function to use. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1) according to comp. False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1), using comp to decide. The iterators over each + * range only move forward, so this is a linear algorithm. If an element + * in [first2,last2) is not found before the search iterator reaches @a + * last2, false is returned. + */ + template + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + return false; + else if(__comp(*__first1, *__first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Return the union of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that element is copied and the iterator advanced. If an element is + * contained in both ranges, the element from the first range is copied and + * both ranges advance. The output range may not overlap either input + * range. + */ + template + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the union of two sorted ranges using a comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that element is copied and the iterator advanced. + * If an equivalent element according to @a comp is contained in both + * ranges, the element from the first range is copied and both ranges + * advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the intersection of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that iterator advances. If an element is contained in both ranges, the + * element from the first range is copied and both ranges advance. The + * output range may not overlap either input range. + */ + template + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the intersection of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that iterator advances. If an element is + * contained in both ranges according to @a comp, the element from the + * first range is copied and both ranges advance. The output range may not + * overlap either input range. + */ + template + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second, that element is copied and the + * iterator advances. If the current element of the second range is less, + * the iterator advances, but no element is copied. If an element is + * contained in both ranges, no elements are copied and both ranges + * advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the difference of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second according to @a comp, that element + * is copied and the iterator advances. If the current element of the + * second range is less, no element is copied and the iterator advances. + * If an element is contained in both ranges according to @a comp, no + * elements are copied and both ranges advance. The output range may not + * overlap either input range. + */ + template + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the symmetric difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other, that element is copied and the iterator advances. If an + * element is contained in both ranges, no elements are copied and both + * ranges advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + /** + * @brief Return the symmetric difference of two sorted ranges using + * comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other according to @a comp, that element is copied and the + * iterator advances. If an element is contained in both ranges according + * to @a comp, no elements are copied and both ranges advance. The output + * range may not overlap either input range. + */ + template + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + // min_element and max_element, with and without an explicitly supplied + // comparison function. + + /** + * @brief Return the maximum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the largest value. + */ + template + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; + } + + /** + * @brief Return the maximum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the largest value + * according to comp. + */ + template + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the smallest value. + */ + template + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the smallest value + * according to comp. + */ + template + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; + } + + // next_permutation and prev_permutation, with and without an explicitly + // supplied comparison function. + + /** + * @brief Permute range into the next "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__i < *__ii) + { + _BidirectionalIterator __j = __last; + while (!(*__i < *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the next "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the next one of this set. Returns true if there are more + * sequences to generate. If the sequence is the largest of the set, the + * smallest is generated and false returned. + */ + template + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__i, *__ii)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the previous one of this + * set. Returns true if there are more sequences to generate. If the + * sequence is the smallest of the set, the largest is generated and false + * returned. + */ + template + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__ii < *__i) + { + _BidirectionalIterator __j = __last; + while (!(*--__j < *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the previous one of this set. Returns true if there are + * more sequences to generate. If the sequence is the smallest of the set, + * the largest is generated and false returned. + */ + template + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__ii, *__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + // find_first_of, with and without an explicitly supplied comparison function. + + /** + * @brief Find element from a set in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator + * in the range [first1,last1), otherwise returns @p last1. + */ + template + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; + } + + /** + * @brief Find element from a set in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @param comp Predicate to use. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator in + * the range [first1,last1), otherwise returns @p last1. + */ + template + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; + } + + + // find_end, with and without an explicitly supplied comparison function. + // Search [first2, last2) as a subsequence in [first1, last1), and return + // the *last* possible match. Note that find_end for bidirectional iterators + // is much faster than for forward iterators. + + // find_end for forward iterators. + template + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + template + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + // find_end for bidirectional iterators. Requires partial specialization. + template + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + template + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2, + __comp); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + // Dispatching functions for find_end. + + /** + * @brief Find last matching subsequence in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. The sub-sequence will be the + * last such subsequence contained in [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2)); + } + + /** + * @brief Find last matching subsequence in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @param comp The predicate to use. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p + * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or + * @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) using + * comp as a predicate and returns an iterator to the first element of the + * sub-sequence, or @p last1 if the sub-sequence is not found. The + * sub-sequence will be the last such subsequence contained in + * [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2), + __comp); + } + +} // namespace std + +#endif /* _ALGO_H */ diff --git a/src/include.new/c++/3.4/bits/stl_algobase.h b/src/include.new/c++/3.4/bits/stl_algobase.h new file mode 100644 index 0000000..d482529 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_algobase.h @@ -0,0 +1,842 @@ +// Bits and pieces used in algorithms -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algobase.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGOBASE_H +#define _ALGOBASE_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std +{ + /** + * @brief Swaps the contents of two iterators. + * @param a An iterator. + * @param b Another iterator. + * @return Nothing. + * + * This function swaps the values pointed to by two iterators, not the + * iterators themselves. + */ + template + inline void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, + _ValueType2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, + _ValueType1>) + + const _ValueType1 __tmp = *__a; + *__a = *__b; + *__b = __tmp; + } + + /** + * @brief Swaps two values. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return Nothing. + * + * This is the simple classic generic implementation. It will work on + * any type which has a copy constructor and an assignment operator. + */ + template + inline void + swap(_Tp& __a, _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) + + const _Tp __tmp = __a; + __a = __b; + __b = __tmp; + } + + #undef min + #undef max + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The lesser of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __b < __a ? __b : __a; + if (__b < __a) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The greater of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __a < __b ? __b : __a; + if (__a < __b) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The lesser of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__b, __a) ? __b : __a; + if (__comp(__b, __a)) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The greater of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__a, __b) ? __b : __a; + if (__comp(__a, __b)) + return __b; + return __a; + } + + // All of these auxiliary functions serve two purposes. (1) Replace + // calls to copy with memmove whenever possible. (Memmove, not memcpy, + // because the input and output ranges are permitted to overlap.) + // (2) If we're using random access iterators, then write the loop as + // a for loop with an explicit count. + + template + inline _OutputIterator + __copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, input_iterator_tag) + { + for (; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; + } + + template + inline _OutputIterator + __copy(_RandomAccessIterator __first, _RandomAccessIterator __last, + _OutputIterator __result, random_access_iterator_tag) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + for (_Distance __n = __last - __first; __n > 0; --__n) + { + *__result = *__first; + ++__first; + ++__result; + } + return __result; + } + + template + inline _Tp* + __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + std::memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); + } + + template + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } + + template + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } + + template + inline _Tp* + __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type) + { return std::__copy_trivial(__first, __last, __result); } + + template + inline _Tp* + __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, + __true_type) + { return std::__copy_trivial(__first, __last, __result); } + + template + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { + typedef typename iterator_traits<_InputIterator>::value_type + _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return _OutputIterator(std::__copy_aux2(__first, __last, __result.base(), + _Trivial())); + } + + template + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return std::__copy_aux2(__first, __last, __result, _Trivial()); + } + + template + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first.base(), __last.base(), + __result, __Normal()); + } + + template + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first, __last, __result, __Normal()); + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). Result may not be contained within + * [first,last); the copy_backward function should be used instead. + * + * Note that the end of the output range is permitted to be contained + * within [first,last). + */ + template + inline _OutputIterator + copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal; + return std::__copy_ni1(__first, __last, __result, __Normal()); + } + + template + inline _BidirectionalIterator2 + __copy_backward(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result, + bidirectional_iterator_tag) + { + while (__first != __last) + *--__result = *--__last; + return __result; + } + + template + inline _BidirectionalIterator + __copy_backward(_RandomAccessIterator __first, _RandomAccessIterator __last, + _BidirectionalIterator __result, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type __n; + for (__n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; + } + + + // This dispatch class is a workaround for compilers that do not + // have partial ordering of function templates. All we're doing is + // creating a specialization so that we can turn a call to copy_backward + // into a memmove whenever possible. + template + struct __copy_backward_dispatch + { + static _BidirectionalIterator2 + copy(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) + { return std::__copy_backward(__first, __last, __result, + std::__iterator_category(__first)); } + }; + + template + struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + { + static _Tp* + copy(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + const ptrdiff_t _Num = __last - __first; + std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } + }; + + template + struct __copy_backward_dispatch + { + static _Tp* + copy(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + return std::__copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); + } + }; + + template + inline _BI2 + __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) + { + typedef typename __type_traits::value_type> + ::has_trivial_assignment_operator _Trivial; + return + std::__copy_backward_dispatch<_BI1, _BI2, _Trivial>::copy(__first, + __last, + __result); + } + + template + inline _BI2 + __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) + { return _BI2(std::__copy_backward_aux(__first, __last, __result.base())); } + + template + inline _BI2 + __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type) + { return std::__copy_backward_aux(__first, __last, __result); } + + template + inline _BI2 + __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) + { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return std::__copy_backward_output_normal_iterator(__first.base(), + __last.base(), + __result, __Normal()); + } + + template + inline _BI2 + __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type) + { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return std::__copy_backward_output_normal_iterator(__first, __last, + __result, __Normal()); + } + + /** + * @brief Copies the range [first,last) into result. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result A bidirectional iterator. + * @return result - (first - last) + * + * The function has the same effect as copy, but starts at the end of the + * range and works its way to the start, returning the start of the result. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * + * Result may not be in the range [first,last). Use copy instead. Note + * that the start of the output range may overlap [first,last). + */ + template + inline _BI2 + copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_BI1>::value_type, + typename iterator_traits<_BI2>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal; + return std::__copy_backward_input_normal_iterator(__first, __last, + __result, __Normal()); + } + + + /** + * @brief Fills the range [first,last) with copies of value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param value A reference-to-const of arbitrary type. + * @return Nothing. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template + void + fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + *__first = __value; + } + + /** + * @brief Fills the range [first,first+n) with copies of value. + * @param first An output iterator. + * @param n The count of copies to perform. + * @param value A reference-to-const of arbitrary type. + * @return The iterator at first+n. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template + _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>) + + for ( ; __n > 0; --__n, ++__first) + *__first = __value; + return __first; + } + + // Specialization: for one-byte types we can use memset. + inline void + fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const unsigned char __tmp = __c; + std::memset(__first, __tmp, __last - __first); + } + + inline void + fill(signed char* __first, signed char* __last, const signed char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const signed char __tmp = __c; + std::memset(__first, static_cast(__tmp), __last - __first); + } + + inline void + fill(char* __first, char* __last, const char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const char __tmp = __c; + std::memset(__first, static_cast(__tmp), __last - __first); + } + + template + inline unsigned char* + fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template + inline signed char* + fill_n(char* __first, _Size __n, const signed char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template + inline char* + fill_n(char* __first, _Size __n, const char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using @c == and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && *__first1 == *__first2) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A boolean true or false. + * + * This compares the elements of two ranges using @c == and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A boolean true or false. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) + return false; + return true; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return A boolean true or false. + * + * "Returns true if the sequence of elements defined by the range + * [first1,last1) is lexicographically less than the sequence of elements + * defined by the range [first2,last2). Returns false otherwise." + * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, + * then this is an inline call to @c memcmp. + */ + template + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for (;__first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return A boolean true or false. + * + * The same as the four-parameter @c lexigraphical_compare, but uses the + * comp parameter instead of @c <. + */ + template + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) + { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + inline bool + lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, + std::min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; + } + + inline bool + lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + +#if CHAR_MAX == SCHAR_MAX + return std::lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return std::lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ + } + +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/stl_bvector.h b/src/include.new/c++/3.4/bits/stl_bvector.h new file mode 100644 index 0000000..afae738 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_bvector.h @@ -0,0 +1,876 @@ +// vector specialization -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_bvector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BVECTOR_H +#define _BVECTOR_H 1 + +namespace _GLIBCXX_STD +{ + typedef unsigned long _Bit_type; + enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; + + struct _Bit_reference + { + _Bit_type * _M_p; + _Bit_type _M_mask; + + _Bit_reference(_Bit_type * __x, _Bit_type __y) + : _M_p(__x), _M_mask(__y) { } + + _Bit_reference() : _M_p(0), _M_mask(0) { } + + operator bool() const { return !!(*_M_p & _M_mask); } + + _Bit_reference& + operator=(bool __x) + { + if (__x) + *_M_p |= _M_mask; + else + *_M_p &= ~_M_mask; + return *this; + } + + _Bit_reference& + operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + + bool + operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + + bool + operator<(const _Bit_reference& __x) const + { return !bool(*this) && bool(__x); } + + void + flip() { *_M_p ^= _M_mask; } + }; + + struct _Bit_iterator_base : public iterator + { + _Bit_type * _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(_Bit_type * __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) { } + + void + _M_bump_up() + { + if (_M_offset++ == _S_word_bit - 1) + { + _M_offset = 0; + ++_M_p; + } + } + + void + _M_bump_down() + { + if (_M_offset-- == 0) + { + _M_offset = _S_word_bit - 1; + --_M_p; + } + } + + void + _M_incr(ptrdiff_t __i) + { + difference_type __n = __i + _M_offset; + _M_p += __n / _S_word_bit; + __n = __n % _S_word_bit; + if (__n < 0) + { + _M_offset = static_cast(__n + _S_word_bit); + --_M_p; + } + else + _M_offset = static_cast(__n); + } + + bool + operator==(const _Bit_iterator_base& __i) const + { return _M_p == __i._M_p && _M_offset == __i._M_offset; } + + bool + operator<(const _Bit_iterator_base& __i) const + { + return _M_p < __i._M_p + || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + + bool + operator!=(const _Bit_iterator_base& __i) const + { return !(*this == __i); } + + bool + operator>(const _Bit_iterator_base& __i) const + { return __i < *this; } + + bool + operator<=(const _Bit_iterator_base& __i) const + { return !(__i < *this); } + + bool + operator>=(const _Bit_iterator_base& __i) const + { return !(*this < __i); } + }; + + inline ptrdiff_t + operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) + { + return _S_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; + } + + struct _Bit_iterator : public _Bit_iterator_base + { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + _Bit_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + reference + operator*() const { return reference(_M_p, 1UL << _M_offset); } + + iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + iterator + operator++(int) + { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + iterator + operator--(int) + { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + iterator + operator+(difference_type __i) const + { + iterator __tmp = *this; + return __tmp += __i; + } + + iterator + operator-(difference_type __i) const + { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_iterator + operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } + + + struct _Bit_const_iterator : public _Bit_iterator_base + { + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_const_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) { } + + const_reference + operator*() const + { return _Bit_reference(_M_p, 1UL << _M_offset); } + + const_iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + const_iterator + operator++(int) + { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + const_iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + const_iterator + operator--(int) + { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + const_iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + const_iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + const_iterator + operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; + } + + const_iterator + operator-(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp -= __i; + } + + const_reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_const_iterator + operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) + { return __x + __n; } + + template + class _Bvector_base + { + typedef typename _Alloc::template rebind<_Bit_type>::other + _Bit_alloc_type; + + struct _Bvector_impl : public _Bit_alloc_type + { + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + _Bit_type* _M_end_of_storage; + _Bvector_impl(const _Bit_alloc_type& __a) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } + + ~_Bvector_base() { this->_M_deallocate(); } + + protected: + _Bvector_impl _M_impl; + + _Bit_type* + _M_allocate(size_t __n) + { return _M_impl.allocate((__n + _S_word_bit - 1) / _S_word_bit); } + + void + _M_deallocate() + { + if (_M_impl._M_start._M_p) + _M_impl.deallocate(_M_impl._M_start._M_p, + _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + } + }; +} // namespace std + +// Declare a partial specialization of vector. +#include + +namespace _GLIBCXX_STD +{ + /** + * @brief A specialization of vector for booleans which offers fixed time + * access to individual elements in any order. + * + * Note that vector does not actually meet the requirements for being + * a container. This is because the reference and pointer types are not + * really references and pointers to bool. See DR96 for details. @see + * vector for function documentation. + * + * @ingroup Containers + * @ingroup Sequences + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ +template + class vector : public _Bvector_base<_Alloc> + { + public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + typedef typename _Bvector_base<_Alloc>::allocator_type allocator_type; + + allocator_type get_allocator() const + { return _Bvector_base<_Alloc>::get_allocator(); } + + protected: + using _Bvector_base<_Alloc>::_M_allocate; + using _Bvector_base<_Alloc>::_M_deallocate; + + protected: + void _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = __q + + (__n + _S_word_bit - 1) / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } + + void _M_insert_aux(iterator __position, bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } + else + { + const size_type __len = size() ? 2 * size() + : static_cast(_S_word_bit); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + template + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + this->_M_impl._M_start = iterator(); + this->_M_impl._M_finish = iterator(); + this->_M_impl._M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + _M_initialize(__n); + std::copy(__first, __last, this->_M_impl._M_start); + } + + template + void _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + void _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + __i = std::copy(__first, __last, __i); + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + } + + public: + iterator begin() + { return this->_M_impl._M_start; } + + const_iterator begin() const + { return this->_M_impl._M_start; } + + iterator end() + { return this->_M_impl._M_finish; } + + const_iterator end() const + { return this->_M_impl._M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + + size_type max_size() const + { return size_type(-1); } + + size_type capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + - begin()); } + bool empty() const + { return begin() == end(); } + + reference operator[](size_type __n) + { return *(begin() + difference_type(__n)); } + + const_reference operator[](size_type __n) const + { return *(begin() + difference_type(__n)); } + + void _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector::_M_range_check")); + } + + reference at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + const_reference at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } + + explicit vector(const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) { } + + vector(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); + } + + explicit vector(size_type __n) + : _Bvector_base<_Alloc>(allocator_type()) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, 0); + } + + vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator()) + { + _M_initialize(__x.size()); + std::copy(__x.begin(), __x.end(), this->_M_impl._M_start); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + ~vector() { } + + vector& operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + std::copy(__x.begin(), __x.end(), begin()); + this->_M_impl._M_finish = begin() + difference_type(__x.size()); + return *this; + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else + { + erase(begin() + __n, end()); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + } + + void assign(size_t __n, bool __x) + { _M_fill_assign(__n, __x); } + + template + void assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_t) __n, (bool) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len < size()) + erase(std::copy(__first, __last, begin()), end()); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + + void reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = std::copy(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit; + } + } + + reference front() + { return *begin(); } + + const_reference front() const + { return *begin(); } + + reference back() + { return *(end() - 1); } + + const_reference back() const + { return *(end() - 1); } + + void push_back(bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + + void swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); + } + + // [23.2.5]/1, third-to-last entry in synopsis listing + static void swap(reference __x, reference __y) + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } + + iterator insert(iterator __position, bool __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { _M_fill_insert(__pos, __n, __x); } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } + + template + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + void _M_fill_insert(iterator __position, size_type __n, bool __x) + { + if (__n == 0) + return; + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::fill(__position, __position + difference_type(__n), __x); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + std::fill_n(__i, __n, __x); + this->_M_impl._M_finish = std::copy(__position, end(), + __i + difference_type(__n)); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, size_type __n, bool __x) + { _M_fill_insert(__position, __n, __x); } + + void pop_back() + { --this->_M_impl._M_finish; } + + iterator erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + return __position; + } + + iterator erase(iterator __first, iterator __last) + { + this->_M_impl._M_finish = std::copy(__last, end(), __first); + return __first; + } + + void resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); + else + insert(end(), __new_size - size(), __x); + } + + void flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void clear() + { erase(begin(), end()); } + }; +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/stl_construct.h b/src/include.new/c++/3.4/bits/stl_construct.h new file mode 100644 index 0000000..afb3387 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_construct.h @@ -0,0 +1,157 @@ +// nonstandard construct and destroy functions -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_construct.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_CONSTRUCT_H +#define _STL_CONSTRUCT_H 1 + +#include +#include + +namespace std +{ + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's constructor with an initializer. + * @endif + */ + template + inline void + _Construct(_T1* __p, const _T2& __value) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast(__p)) _T1(__value); + } + + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's default constructor (no initializers). + * @endif + */ + template + inline void + _Construct(_T1* __p) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast(__p)) _T1(); + } + + /** + * @if maint + * Destroy the object pointed to by a pointer type. + * @endif + */ + template + inline void + _Destroy(_Tp* __pointer) + { __pointer->~_Tp(); } + + /** + * @if maint + * Destroy a range of objects with nontrivial destructors. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template + inline void + __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, + __false_type) + { for ( ; __first != __last; ++__first) std::_Destroy(&*__first); } + + /** + * @if maint + * Destroy a range of objects with trivial destructors. Since the destructors + * are trivial, there's nothing to do and hopefully this function will be + * entirely optimized away. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template + inline void + __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) + { } + + /** + * @if maint + * Destroy a range of objects. If the value_type of the object has + * a trivial destructor, the compiler should optimize all of this + * away, otherwise the objects' destructors must be invoked. + * @endif + */ + template + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _Value_type; + typedef typename __type_traits<_Value_type>::has_trivial_destructor + _Has_trivial_destructor; + + std::__destroy_aux(__first, __last, _Has_trivial_destructor()); + } +} // namespace std + +#endif /* _STL_CONSTRUCT_H */ + diff --git a/src/include.new/c++/3.4/bits/stl_deque.h b/src/include.new/c++/3.4/bits/stl_deque.h new file mode 100644 index 0000000..54dadf2 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_deque.h @@ -0,0 +1,1501 @@ +// Deque implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_deque.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_H +#define _DEQUE_H 1 + +#include +#include +#include + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * @brief This function controls the size of memory nodes. + * @param size The size of an element. + * @return The number (not byte size) of elements per node. + * + * This function started off as a compiler kludge from SGI, but seems to + * be a useful wrapper around a repeated constant expression. The '512' is + * tuneable (and no other code needs to change), but no investigation has + * been done since inheriting the SGI code. + * @endif + */ + inline size_t + __deque_buf_size(size_t __size) + { return __size < 512 ? size_t(512 / __size) : size_t(1); } + + + /** + * @brief A deque::iterator. + * + * Quite a bit of intelligence here. Much of the functionality of deque is + * actually passed off to this class. A deque holds two of these internally, + * marking its valid range. Access to elements is done as offsets of either + * of those two, relying on operator overloading in this class. + * + * @if maint + * All the functions are op overloads except for _M_set_node. + * @endif + */ + template + struct _Deque_iterator + { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} + + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& + operator-=(difference_type __n) + { return *this += -__n; } + + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + + /** @if maint + * Prepares to traverse new_node. Sets everything except _M_cur, which + * should therefore be set by the caller immediately afterwards, based on + * _M_first and _M_last. + * @endif + */ + void + _M_set_node(_Map_pointer __new_node) + { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } + }; + + // Note: we also provide overloads whose operands are of the same type in + // order to avoid ambiguous overload resolution when std::rel_ops operators + // are in scope (for additional details, see libstdc++/3628) + template + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } + + /** + * @if maint + * Deque base class. This class provides the unified face for %deque's + * allocation. This class's constructor and destructor allocate and + * deallocate (but do not initialize) storage. This makes %exception + * safety easier. + * + * Nothing in this class ever constructs or destroys an actual Tp element. + * (Deque handles that itself.) Only/All memory management is performed + * here. + * @endif + */ + template + class _Deque_base + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _M_impl(__a) + { _M_initialize_map(__num_elements); } + + _Deque_base(const allocator_type& __a) + : _M_impl(__a) + { } + + ~_Deque_base(); + + protected: + //This struct encapsulates the implementation of the std::deque + //standard container and at the same time makes use of the EBO + //for empty allocators. + struct _Deque_impl + : public _Alloc { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl(const _Alloc& __a) + : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish() + { } + }; + + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + _Map_alloc_type _M_get_map_allocator() const + { return _Map_alloc_type(this->get_allocator()); } + + _Tp* + _M_allocate_node() + { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } + + void + _M_deallocate_node(_Tp* __p) + { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + + _Tp** + _M_allocate_map(size_t __n) + { return _M_get_map_allocator().allocate(__n); } + + void + _M_deallocate_map(_Tp** __p, size_t __n) + { _M_get_map_allocator().deallocate(__p, __n); } + + protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + + _Deque_impl _M_impl; + }; + + template + _Deque_base<_Tp,_Alloc>::~_Deque_base() + { + if (this->_M_impl._M_map) + { + _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + } + } + + /** + * @if maint + * @brief Layout storage. + * @param num_elements The count of T's for which to allocate space + * at first. + * @return Nothing. + * + * The initial underlying memory layout is a bit complicated... + * @endif + */ + template + void + _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) + { + size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; + + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, + __num_nodes + 2); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); + + // For "small" maps (needing less than _M_map_size nodes), allocation + // starts in the middle elements and grows outwards. So nstart may be + // the beginning of _M_map, but for small maps it may be as far in as + // _M_map+3. + + _Tp** __nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; + __throw_exception_again; + } + + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements + % __deque_buf_size(sizeof(_Tp)); + } + + template + void + _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + __throw_exception_again; + } + } + + template + void + _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } + + /** + * @brief A standard container using fixed-size memory allocation and + * constant-time manipulation of elements at either end. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements. + * + * In previous HP/SGI versions of deque, there was an extra template + * parameter so users could control the node size. This extension turned + * out to violate the C++ standard (it can be detected using template + * template parameters), and it was removed. + * + * @if maint + * Here's how a deque manages memory. Each deque has 4 members: + * + * - Tp** _M_map + * - size_t _M_map_size + * - iterator _M_start, _M_finish + * + * map_size is at least 8. %map is an array of map_size pointers-to-"nodes". + * (The name %map has nothing to do with the std::map class, and "nodes" + * should not be confused with std::list's usage of "node".) + * + * A "node" has no specific type name as such, but it is referred to as + * "node" in this file. It is a simple array-of-Tp. If Tp is very large, + * there will be one Tp element per node (i.e., an "array" of one). + * For non-huge Tp's, node size is inversely related to Tp size: the + * larger the Tp, the fewer Tp's will fit in a node. The goal here is to + * keep the total size of a node relatively small and constant over different + * Tp's, to improve allocator efficiency. + * + * **** As I write this, the nodes are /not/ allocated using the high-speed + * memory pool. There are 20 hours left in the year; perhaps I can fix + * this before 2002. + * + * Not every pointer in the %map array will point to a node. If the initial + * number of elements in the deque is small, the /middle/ %map pointers will + * be valid, and the ones at the edges will be unused. This same situation + * will arise as the %map grows: available %map pointers, if any, will be on + * the ends. As new nodes are created, only a subset of the %map's pointers + * need to be copied "outward". + * + * Class invariants: + * - For any nonsingular iterator i: + * - i.node points to a member of the %map array. (Yes, you read that + * correctly: i.node does not actually point to a node.) The member of + * the %map array is what actually points to the node. + * - i.first == *(i.node) (This points to the node (first Tp element).) + * - i.last == i.first + node_size + * - i.cur is a pointer in the range [i.first, i.last). NOTE: + * the implication of this is that i.cur is always a dereferenceable + * pointer, even if i is a past-the-end iterator. + * - Start and Finish are always nonsingular iterators. NOTE: this means that + * an empty deque must have one node, a deque with > + class deque : protected _Deque_base<_Tp, _Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Deque_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + // Functions controlling memory layout, and nothing else. + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + /** @if maint + * A total of four data members accumulated down the heirarchy. + * May be accessed via _M_impl.* + * @endif + */ + using _Base::_M_impl; + + public: + // [23.2.1.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + + /** + * @brief Create a %deque with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %deque with @a n copies of @a value. + */ + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a, __n) + { _M_fill_initialize(__value); } + + /** + * @brief Create a %deque with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %deque with @a n copies of a + * default-constructed element. + */ + explicit + deque(size_type __n) + : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } + + /** + * @brief %Deque copy constructor. + * @param x A %deque of identical element and allocator types. + * + * The newly-created %deque uses a copy of the allocation object used + * by @a x. + */ + deque(const deque& __x) + : _Base(__x.get_allocator(), __x.size()) + { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_impl._M_start); } + + /** + * @brief Builds a %deque from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %deque consisting of copies of the elements from [first, + * last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. + */ + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + ~deque() + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + + /** + * @brief %Deque assignment operator. + * @param x A %deque of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + deque& + operator=(const deque& __x); + + /** + * @brief Assigns a given value to a %deque. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %deque with @a n copies of the given value. + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements assigned. + * Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %deque with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements + * assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %deque. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_start; } + + /** + * Returns a read/write iterator that points one past the last element in + * the %deque. Iteration is done in ordinary element order. + */ + iterator + end() + { return this->_M_impl._M_finish; } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + end() const + { return this->_M_impl._M_finish; } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %deque. Iteration is done in reverse element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse element + * order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first element in the %deque. Iteration is done in reverse element + * order. + */ + reverse_iterator + rend() { return reverse_iterator(this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %deque. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_impl._M_start); } + + // [23.2.1.2] capacity + /** Returns the number of elements in the %deque. */ + size_type + size() const + { return this->_M_impl._M_finish - this->_M_impl._M_start; } + + /** Returns the size() of the largest possible %deque. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x) + { + const size_type __len = size(); + if (__new_size < __len) + erase(this->_M_impl._M_start + __new_size, this->_M_impl._M_finish); + else + insert(this->_M_impl._M_finish, __new_size - __len, __x); + } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * + * This function will resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are default-constructed. + */ + void + resize(size_type new_size) + { resize(new_size, value_type()); } + + /** + * Returns true if the %deque is empty. (Thus begin() would equal end().) + */ + bool + empty() const + { return this->_M_impl._M_finish == this->_M_impl._M_start; } + + // element access + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + reference + operator[](size_type __n) + { return this->_M_impl._M_start[difference_type(__n)]; } + + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + const_reference + operator[](size_type __n) const + { return this->_M_impl._M_start[difference_type(__n)]; } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("deque::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * Returns a read/write reference to the data at the first element of the + * %deque. + */ + reference + front() + { return *this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %deque. + */ + const_reference + front() const + { return *this->_M_impl._M_start; } + + /** + * Returns a read/write reference to the data at the last element of the + * %deque. + */ + reference + back() + { + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %deque. + */ + const_reference + back() const + { + const_iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; + } + + // [23.2.1.2] modifiers + /** + * @brief Add data to the front of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the front of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ + void + push_front(const value_type& __x) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + std::_Construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(__x); + } + + /** + * @brief Add data to the end of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the end of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) + { + std::_Construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(__x); + } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the first element's data is + * needed, it should be retrieved before pop_front() is called. + */ + void + pop_front() + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) + { + std::_Destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; + } + else + _M_pop_front_aux(); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) + { + --this->_M_impl._M_finish._M_cur; + std::_Destroy(this->_M_impl._M_finish._M_cur); + } + else + _M_pop_back_aux(); + } + + /** + * @brief Inserts given value into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before the + * specified location. + */ + iterator + insert(iterator position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %deque. + * @param position An iterator into the %deque. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %deque. + * @param position An iterator into the %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [first,last) + * into the %deque before the location specified by @a pos. This is + * known as "range insert." + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %deque by one. + * + * The user is cautioned that + * this function only erases the element, and that if the element is + * itself a pointer, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %deque accordingly. + * + * The user is cautioned that + * this function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %deque. + * @param x A %deque of the same element and allocator types. + * + * This exchanges the elements between two deques in constant time. + * (Four pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(d1,d2) will feed to this function. + */ + void + swap(deque& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void clear(); + + protected: + // Internal constructor functions follow. + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // called by the second initialize_dispatch above + //@{ + /** + * @if maint + * @brief Fills the deque with whatever is in [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @return Nothing. + * + * If the iterators are actually forward iterators (or better), then the + * memory layout can be done all at once. Else we move forward using + * push_back on each value from the iterator. + * @endif + */ + template + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second initialize_dispatch above + template + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + //@} + + /** + * @if maint + * @brief Fills the %deque with copies of value. + * @param value Initial value. + * @return Nothing. + * @pre _M_start and _M_finish have already been initialized, but none of + * the %deque's elements have yet been constructed. + * + * This function is called only when the user provides an explicit size + * (with or without an explicit exemplar value). + * @endif + */ + void + _M_fill_initialize(const value_type& __value); + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(std::copy(__first, __last, begin()), end()); + } + + // Called by assign(n,t), and the range assign when it turns out to be the + // same thing. + void + _M_fill_assign(size_type __n, const value_type& __val) + { + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + erase(begin() + __n, end()); + std::fill(begin(), end(), __val); + } + } + + //@{ + /** + * @if maint + * @brief Helper functions for push_* and pop_*. + * @endif + */ + void _M_push_back_aux(const value_type&); + void _M_push_front_aux(const value_type&); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + //@} + + // Internal insert functions follow. The *_aux functions do the actual + // insertion work when all shortcuts fail. + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. Can use fill functions in optimal situations, + // otherwise passes off to insert_aux(p,n,x). + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // called by insert(p,x) + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + // called by insert(p,n,x) via fill_insert + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + // called by range_insert_aux for forward iterators + template + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the previous internal insert + * functions. + * @endif + */ + iterator + _M_reserve_elements_at_front(size_type __n) + { + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_impl._M_start - difference_type(__n); + } + + iterator + _M_reserve_elements_at_back(size_type __n) + { + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_impl._M_finish + difference_type(__n); + } + + void + _M_new_elements_at_front(size_type __new_elements); + + void + _M_new_elements_at_back(size_type __new_elements); + //@} + + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the major %map. + * + * Makes sure the _M_map has space for new nodes. Does not actually add + * the nodes. Can invalidate _M_map pointers. (And consequently, %deque + * iterators.) + * @endif + */ + void + _M_reserve_map_at_back (size_type __nodes_to_add = 1) + { + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void + _M_reserve_map_at_front (size_type __nodes_to_add = 1) + { + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + //@} + }; + + + /** + * @brief Deque equality comparison. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff the size and elements of the deques are equal. + * + * This is an equivalence relation. It is linear in the size of the + * deques. Deques are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } + + /** + * @brief Deque ordering relation. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * deques. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::deque::swap(). + template + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _DEQUE_H */ diff --git a/src/include.new/c++/3.4/bits/stl_function.h b/src/include.new/c++/3.4/bits/stl_function.h new file mode 100644 index 0000000..74ddcce --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_function.h @@ -0,0 +1,898 @@ +// Functor implementations -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_function.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _FUNCTION_H +#define _FUNCTION_H 1 + +namespace std +{ + // 20.3.1 base classes + /** @defgroup s20_3_1_base Functor Base Classes + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to "functors," then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functiors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct unary_function + { + typedef _Arg argument_type; ///< @c argument_type is the type of the + /// argument (no surprises here) + + typedef _Result result_type; ///< @c result_type is the return type + }; + + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct binary_function + { + typedef _Arg1 first_argument_type; ///< the type of the first argument + /// (no surprises here) + + typedef _Arg2 second_argument_type; ///< the type of the second argument + typedef _Result result_type; ///< type of the return type + }; + /** @} */ + + // 20.3.2 arithmetic + /** @defgroup s20_3_2_arithmetic Arithmetic Classes + * Because basic math often needs to be done during an algorithm, the library + * provides functors for those operations. See the documentation for + * @link s20_3_1_base the base classes@endlink for examples of their use. + * + * @{ + */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + /** @} */ + + // 20.3.3 comparisons + /** @defgroup s20_3_3_comparisons Comparison Classes + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct not_equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + /** @} */ + + // 20.3.4 logical operations + /** @defgroup s20_3_4_logical Boolean Operations Classes + * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. + * + * @{ + */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + /** @} */ + + // 20.3.5 negators + /** @defgroup s20_3_5_negators Negators + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * "!(v[i] > 3)" is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class unary_negate + : public unary_function + { + protected: + _Predicate _M_pred; + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) {} + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class binary_negate + : public binary_function + { + protected: + _Predicate _M_pred; + public: + explicit + binary_negate(const _Predicate& __x) + : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.6 binders + /** @defgroup s20_3_6_binder Binder Classes + * Binders turn functions/functors with two arguments into functors with + * a single argument, storing an argument to be applied later. For + * example, an variable @c B of type @c binder1st is constructed from a + * functor @c f and an argument @c x. Later, B's @c operator() is called + * with a single argument @c y. The return value is the value of @c f(x,y). + * @c B can be "called" with various arguments (y1, y2, ...) and will in + * turn call @c f(x,y1), @c f(x,y2), ... + * + * The function @c bind1st is provided to save some typing. It takes the + * function and an argument as parameters, and returns an instance of + * @c binder1st. + * + * The type @c binder2nd and its creator function @c bind2nd do the same + * thing, but the stored argument is passed as the second parameter instead + * of the first, e.g., @c bind2nd(std::minus,1.3) will create a + * functor whose @c operator() accepts a floating-point number, subtracts + * 1.3 from it, and returns the result. (If @c bind1st had been used, + * the functor would perform "1.3 - x" instead. + * + * Creator-wrapper functions like @c bind1st are intended to be used in + * calling algorithms. Their return values will be temporary objects. + * (The goal is to not require you to type names like + * @c std::binder1st> for declaring a variable to hold the + * return value from @c bind1st(std::plus,5). + * + * These become more useful when combined with the composition functions. + * + * @{ + */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder1st + : public unary_function + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); + } + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder2nd + : public unary_function + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + public: + pointer_to_unary_function() {} + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + public: + pointer_to_binary_function() {} + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + /** @} */ + + template + struct _Identity : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template + struct _Select1st : public unary_function<_Pair, + typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } + }; + + template + struct _Select2nd : public unary_function<_Pair, + typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; + + // 20.3.8 adaptors pointers members + /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members + * There are a total of 16 = 2^4 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Member function with void return type vs member function with + * non-void return type. + * (4) Const vs non-const member function. + * + * Note that choice (3) is nothing more than a workaround: according + * to the draft, compilers should handle void and non-void the same way. + * This feature is not yet widely implemented, though. You can only use + * member functions returning void if your compiler supports partial + * specialization. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t : public binary_function + { + public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, void> + { + public: + explicit + mem_fun_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit + mem_fun_ref_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit + const_mem_fun_ref_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, void> + { + public: + explicit + mem_fun1_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t + : public binary_function + { + public: + explicit + const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit + mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit + const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + template + inline mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret, _Tp>(__f); } + + template + inline mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + /** @} */ + +} // namespace std + +#endif /* _FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/stl_heap.h b/src/include.new/c++/3.4/bits/stl_heap.h new file mode 100644 index 0000000..eff7fd3 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_heap.h @@ -0,0 +1,467 @@ +// Heap implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_heap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_HEAP_H +#define _STL_HEAP_H 1 + +#include + +namespace std +{ + // is_heap, a predicate testing whether or not a range is + // a heap. This function is an extension, not part of the C++ + // standard. + template + bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, + _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + + // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + + template + void + __push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap. + * @param first Start of heap. + * @param last End of heap + element. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + */ + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last - 1); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1))); + } + + template + void + __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap + element. + * @param comp Comparison functor. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + * Compare operations are performed using comp. + */ + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1)), __comp); + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value); + } + + /** + * @brief Pop an element off a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. + */ + template + inline void + pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); + + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1))); + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (__comp(*(__first + __secondChild), + *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); + } + + /** + * @brief Pop an element off a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. Comparisons are + * made using comp. + */ + template + inline void + pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1)), __comp); + } + + /** + * @brief Construct a heap over a range. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + */ + template + void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent))); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Construct a heap over a range using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + * Comparisons are made using comp. + */ + template + inline void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent)), __comp); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Sort a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + */ + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last); + + while (__last - __first > 1) + std::pop_heap(__first, __last--); + } + + /** + * @brief Sort a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + * Comparisons are made using comp. + */ + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + while (__last - __first > 1) + std::pop_heap(__first, __last--, __comp); + } + +} // namespace std + +#endif /* _STL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/stl_iterator.h b/src/include.new/c++/3.4/bits/stl_iterator.h new file mode 100644 index 0000000..cc56431 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_iterator.h @@ -0,0 +1,772 @@ +// Iterators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file implements reverse_iterator, back_insert_iterator, + * front_insert_iterator, insert_iterator, __normal_iterator, and their + * supporting functions and overloaded operators. + */ + +#ifndef _ITERATOR_H +#define _ITERATOR_H 1 + +namespace std +{ + // 24.4.1 Reverse iterators + /** + * "Bidirectional and random access iterators have corresponding reverse + * %iterator adaptors that iterate through the data structure in the + * opposite direction. They have the same signatures as the corresponding + * iterators. The fundamental relation between a reverse %iterator and its + * corresponding %iterator @c i is established by the identity: + * @code + * &*(reverse_iterator(i)) == &*(i - 1) + * @endcode + * + * This mapping is dictated by the fact that while there is always a + * pointer past the end of an array, there might not be a valid pointer + * before the beginning of an array." [24.4.1]/1,2 + * + * Reverse iterators can be tricky and surprising at first. Their + * semantics make sense, however, and the trickiness is a side effect of + * the requirement that the iterators must be safe. + */ + template + class reverse_iterator + : public iterator::iterator_category, + typename iterator_traits<_Iterator>::value_type, + typename iterator_traits<_Iterator>::difference_type, + typename iterator_traits<_Iterator>::pointer, + typename iterator_traits<_Iterator>::reference> + { + protected: + _Iterator current; + + public: + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + public: + /** + * The default constructor default-initializes member @p current. + * If it is a pointer, that means it is zero-initialized. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 235 No specification of default ctor for reverse_iterator + reverse_iterator() : current() { } + + /** + * This %iterator will move in the opposite direction that @p x does. + */ + explicit + reverse_iterator(iterator_type __x) : current(__x) { } + + /** + * The copy constructor is normal. + */ + reverse_iterator(const reverse_iterator& __x) + : current(__x.current) { } + + /** + * A reverse_iterator across other types can be copied in the normal + * fashion. + */ + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) { } + + /** + * @return @c current, the %iterator used for underlying work. + */ + iterator_type + base() const + { return current; } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator*() const + { + _Iterator __tmp = current; + return *--__tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + pointer + operator->() const + { return &(operator*()); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator++() + { + --current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator++(int) + { + reverse_iterator __tmp = *this; + --current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator--() + { + ++current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator operator--(int) + { + reverse_iterator __tmp = *this; + ++current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator+(difference_type __n) const + { return reverse_iterator(current - __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator+=(difference_type __n) + { + current -= __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator-(difference_type __n) const + { return reverse_iterator(current + __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator-=(difference_type __n) + { + current += __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator[](difference_type __n) const + { return *(*this + __n); } + }; + + //@{ + /** + * @param x A %reverse_iterator. + * @param y A %reverse_iterator. + * @return A simple bool. + * + * Reverse iterators forward many operations to their underlying base() + * iterators. Others are implemented in terms of one another. + * + */ + template + inline bool + operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __x.base() == __y.base(); } + + template + inline bool + operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() < __x.base(); } + + template + inline bool + operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x < __y); } + + template + inline typename reverse_iterator<_Iterator>::difference_type + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() - __x.base(); } + + template + inline reverse_iterator<_Iterator> + operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) + { return reverse_iterator<_Iterator>(__x.base() - __n); } + //@} + + // 24.4.2.2.1 back_insert_iterator + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator appends it to the container using + * push_back. + * + * Tip: Using the back_inserter function to create these iterators can + * save typing. + */ + template + class back_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit + back_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the end, if you like). Assigning a value to the %iterator will + * always append the value to the end of the container. + */ + back_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_back(__value); + return *this; + } + + /// Simply returns *this. + back_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of back_insert_iterator working on @p x. + * + * This wrapper function helps in creating back_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline back_insert_iterator<_Container> + back_inserter(_Container& __x) + { return back_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator prepends it to the container using + * push_front. + * + * Tip: Using the front_inserter function to create these iterators can + * save typing. + */ + template + class front_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit front_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the front, if you like). Assigning a value to the %iterator will + * always prepend the value to the front of the container. + */ + front_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_front(__value); + return *this; + } + + /// Simply returns *this. + front_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of front_insert_iterator working on @p x. + * + * This wrapper function helps in creating front_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline front_insert_iterator<_Container> + front_inserter(_Container& __x) + { return front_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator inserts it in the container at the + * %iterator's position, rather than overwriting the value at that + * position. + * + * (Sequences will actually insert a @e copy of the value before the + * %iterator's position.) + * + * Tip: Using the inserter function to create these iterators can + * save typing. + */ + template + class insert_iterator + : public iterator + { + protected: + _Container* container; + typename _Container::iterator iter; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /** + * The only way to create this %iterator is with a container and an + * initial position (a normal %iterator into the container). + */ + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator maintains its own position in the + * container. Assigning a value to the %iterator will insert the + * value into the container at the place before the %iterator. + * + * The position is maintained such that subsequent assignments will + * insert values immediately after one another. For example, + * @code + * // vector v contains A and Z + * + * insert_iterator i (v, ++v.begin()); + * i = 1; + * i = 2; + * i = 3; + * + * // vector v contains A, 1, 2, 3, and Z + * @endcode + */ + insert_iterator& + operator=(const typename _Container::const_reference __value) + { + iter = container->insert(iter, __value); + ++iter; + return *this; + } + + /// Simply returns *this. + insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of insert_iterator working on @p x. + * + * This wrapper function helps in creating insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline insert_iterator<_Container> + inserter(_Container& __x, _Iterator __i) + { + return insert_iterator<_Container>(__x, + typename _Container::iterator(__i)); + } +} // namespace std + +namespace __gnu_cxx +{ + // This iterator adapter is 'normal' in the sense that it does not + // change the semantics of any of the operators of its iterator + // parameter. Its primary purpose is to convert an iterator that is + // not a class, e.g. a pointer, into an iterator that is a class. + // The _Container parameter exists solely so that different containers + // using this template can instantiate different types, even if the + // _Iterator parameter is the same. + using std::iterator_traits; + using std::iterator; + template + class __normal_iterator + { + protected: + _Iterator _M_current; + + public: + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + __normal_iterator() : _M_current(_Iterator()) { } + + explicit + __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + // Allow iterator to const_iterator conversion + template + inline __normal_iterator(const __normal_iterator<_Iter, + _Container>& __i) + : _M_current(__i.base()) { } + + // Forward iterator requirements + reference + operator*() const + { return *_M_current; } + + pointer + operator->() const + { return _M_current; } + + __normal_iterator& + operator++() + { + ++_M_current; + return *this; + } + + __normal_iterator + operator++(int) + { return __normal_iterator(_M_current++); } + + // Bidirectional iterator requirements + __normal_iterator& + operator--() + { + --_M_current; + return *this; + } + + __normal_iterator + operator--(int) + { return __normal_iterator(_M_current--); } + + // Random access iterator requirements + reference + operator[](const difference_type& __n) const + { return _M_current[__n]; } + + __normal_iterator& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + __normal_iterator + operator+(const difference_type& __n) const + { return __normal_iterator(_M_current + __n); } + + __normal_iterator& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + __normal_iterator + operator-(const difference_type& __n) const + { return __normal_iterator(_M_current - __n); } + + const _Iterator& + base() const + { return _M_current; } + }; + + // Note: In what follows, the left- and right-hand-side iterators are + // allowed to vary in types (conceptually in cv-qualification) so that + // comparaison between cv-qualified and non-cv-qualified iterators be + // valid. However, the greedy and unfriendly operators in std::rel_ops + // will make overload resolution ambiguous (when in scope) if we don't + // provide overloads whose operands are of the same type. Can someone + // remind me what generic programming is about? -- Gaby + + // Forward iterator requirements + template + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + // Random access iterator requirements + template + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } +} // namespace __gnu_cxx + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/stl_iterator_base_funcs.h b/src/include.new/c++/3.4/bits/stl_iterator_base_funcs.h new file mode 100644 index 0000000..c514e81 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_iterator_base_funcs.h @@ -0,0 +1,179 @@ +// Functions used by iterators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_funcs.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility + * functions, such as distance() and advance(). + */ + +#ifndef _ITERATOR_BASE_FUNCS_H +#define _ITERATOR_BASE_FUNCS_H 1 + +#pragma GCC system_header +#include + +namespace std +{ + template + inline typename iterator_traits<_InputIterator>::difference_type + __distance(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) + { + ++__first; + ++__n; + } + return __n; + } + + template + inline typename iterator_traits<_RandomAccessIterator>::difference_type + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + return __last - __first; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param first An input iterator. + * @param last An input iterator. + * @return The distance between them. + * + * Returns @c n such that first + n == last. This requires that @p last + * must be reachable from @p first. Note that @c n may be negative. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + // concept requirements -- taken care of in __distance + return std::__distance(__first, __last, + std::__iterator_category(__first)); + } + + template + inline void + __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__n--) + ++__i; + } + + template + inline void + __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + if (__n > 0) + while (__n--) + ++__i; + else + while (__n++) + --__i; + } + + template + inline void + __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __i += __n; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param i An input iterator. + * @param n The "delta" by which to change @p i. + * @return Nothing. + * + * This increments @p i by @p n. For bidirectional and random access + * iterators, @p n may be negative, in which case @p i is decremented. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template + inline void + advance(_InputIterator& __i, _Distance __n) + { + // concept requirements -- taken care of in __advance + std::__advance(__i, __n, std::__iterator_category(__i)); + } +} // namespace std + +#endif /* _ITERATOR_BASE_FUNCS_H */ diff --git a/src/include.new/c++/3.4/bits/stl_iterator_base_types.h b/src/include.new/c++/3.4/bits/stl_iterator_base_types.h new file mode 100644 index 0000000..c3bb1c5 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_iterator_base_types.h @@ -0,0 +1,170 @@ +// Types used in iterator implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_types.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility types, + * such as iterator_traits and struct iterator. + */ + +#ifndef _ITERATOR_BASE_TYPES_H +#define _ITERATOR_BASE_TYPES_H 1 + +#pragma GCC system_header + +namespace std +{ + //@{ + /** + * @defgroup iterator_tags Iterator Tags + * These are empty types, used to distinguish different iterators. The + * distinction is not made by what they contain, but simply by what they + * are. Different underlying algorithms can then be used based on the + * different operations supporetd by different iterator types. + */ + /// Marking input iterators. + struct input_iterator_tag {}; + /// Marking output iterators. + struct output_iterator_tag {}; + /// Forward iterators support a superset of input iterator operations. + struct forward_iterator_tag : public input_iterator_tag {}; + /// Bidirectional iterators support a superset of forward iterator + /// operations. + struct bidirectional_iterator_tag : public forward_iterator_tag {}; + /// Random-access iterators support a superset of bidirectional iterator + /// operations. + struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + //@} + + + /** + * @brief Common %iterator class. + * + * This class does nothing but define nested typedefs. %Iterator classes + * can inherit from this class to save some work. The typedefs are then + * used in specializations and overloading. + * + * In particular, there are no default implementations of requirements + * such as @c operator++ and the like. (How could there be?) + */ + template + struct iterator + { + /// One of the @link iterator_tags tag types@endlink. + typedef _Category iterator_category; + /// The type "pointed to" by the iterator. + typedef _Tp value_type; + /// Distance between iterators is represented as this type. + typedef _Distance difference_type; + /// This type represents a pointer-to-value_type. + typedef _Pointer pointer; + /// This type represents a reference-to-value_type. + typedef _Reference reference; + }; + + /** + * This class does nothing but define nested typedefs. The general + * version simply "forwards" the nested typedefs from the Iterator + * argument. Specialized versions for pointers and pointers-to-const + * provide tighter, more correct semantics. + */ + template + struct iterator_traits + { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; + }; + + template + struct iterator_traits<_Tp*> + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + + template + struct iterator_traits + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + }; + + /** + * @if maint + * This function is not a part of the C++ standard but is syntactic + * sugar for internal library use only. + * @endif + */ + template + inline typename iterator_traits<_Iter>::iterator_category + __iterator_category(const _Iter&) + { return typename iterator_traits<_Iter>::iterator_category(); } + +} // namespace std + +#endif /* _ITERATOR_BASE_TYPES_H */ + diff --git a/src/include.new/c++/3.4/bits/stl_list.h b/src/include.new/c++/3.4/bits/stl_list.h new file mode 100644 index 0000000..afb118b --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_list.h @@ -0,0 +1,1255 @@ +// List implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_list.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_H +#define _LIST_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Supporting structures are split into common and templated types; the + // latter publicly inherits from the former in an effort to reduce code + // duplication. This results in some "needless" static_cast'ing later on, + // but it's all safe downcasting. + + /// @if maint Common part of a node in the %list. @endif + struct _List_node_base + { + _List_node_base* _M_next; ///< Self-explanatory + _List_node_base* _M_prev; ///< Self-explanatory + + static void + swap(_List_node_base& __x, _List_node_base& __y); + + void + transfer(_List_node_base * const __first, + _List_node_base * const __last); + + void + reverse(); + + void + hook(_List_node_base * const __position); + + void + unhook(); + }; + + /// @if maint An actual node in the %list. @endif + template + struct _List_node : public _List_node_base + { + _Tp _M_data; ///< User's data. + }; + + /** + * @brief A list::iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template + struct _List_iterator + { + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() + : _M_node() { } + + _List_iterator(_List_node_base* __x) + : _M_node(__x) { } + + // Must downcast from List_node_base to _List_node to get to _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + _List_node_base* _M_node; + }; + + /** + * @brief A list::const_iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template + struct _List_const_iterator + { + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + _List_const_iterator() + : _M_node() { } + + _List_const_iterator(const _List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + // Must downcast from List_node_base to _List_node to get to + // _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + const _List_node_base* _M_node; + }; + + template + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template + class _List_base + { + protected: + // NOTA BENE + // The stored instance is not actually of "allocator_type"'s + // type. Instead we rebind the type to + // Allocator>, which according to [20.1.5]/4 + // should probably be the same. List_node is not the same + // size as Tp (it's two pointers larger), and specializations on + // Tp may go unused because List_node is being bound + // instead. + // + // We put this to the test in the constructors and in + // get_allocator, where we use conversions between + // allocator_type and _Node_Alloc_type. The conversion is + // required by table 32 in [20.1.5]. + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + + _Node_Alloc_type; + + struct _List_impl + : public _Node_Alloc_type { + _List_node_base _M_node; + _List_impl (const _Node_Alloc_type& __a) + : _Node_Alloc_type(__a) + { } + }; + + _List_impl _M_impl; + + _List_node<_Tp>* + _M_get_node() + { return _M_impl._Node_Alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _M_impl._Node_Alloc_type::deallocate(__p, 1); } + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return allocator_type(*static_cast(&this->_M_impl)); } + + _List_base(const allocator_type& __a) + : _M_impl(__a) + { _M_init(); } + + // This is what actually destroys the list. + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + + void + _M_init() + { + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; + } + }; + + /** + * @brief A standard container with linear time access to elements, + * and fixed time insertion/deletion at any point in the sequence. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements with the + * %exception of @c at and @c operator[]. + * + * This is a @e doubly @e linked %list. Traversal up and down the + * %list requires linear time, but adding and removing elements (or + * @e nodes) is done in constant time, regardless of where the + * change takes place. Unlike std::vector and std::deque, + * random-access iterators are not provided, so subscripting ( @c + * [] ) access is not allowed. For algorithms which only need + * sequential access, this lack makes no difference. + * + * Also unlike the other standard containers, std::list provides + * specialized algorithms %unique to linked lists, such as + * splicing, sorting, and in-place reversal. + * + * @if maint + * A couple points on memory allocation for list: + * + * First, we never actually allocate a Tp, we allocate + * List_node's and trust [20.1.5]/4 to DTRT. This is to ensure + * that after elements from %list are spliced into + * %list, destroying the memory of the second %list is a + * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. + * + * Second, a %list conceptually represented as + * @code + * A <---> B <---> C <---> D + * @endcode + * is actually circular; a link exists between A and D. The %list + * class holds (as its only data member) a private list::iterator + * pointing to @e D, not to @e A! To get to the head of the %list, + * we start at the tail and move forward by one. When this member + * iterator's next/previous pointers refer to itself, the %list is + * %empty. @endif + */ + template > + class list : protected _List_base<_Tp, _Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _List_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + // Note that pointers-to-_Node's can be ctor-converted to + // iterator types. + typedef _List_node<_Tp> _Node; + + /** @if maint + * One data member plus two memory-handling functions. If the + * _Alloc type requires separate instances, then one of those + * will also be included, accumulated from the topmost parent. + * @endif + */ + using _Base::_M_impl; + using _Base::_M_put_node; + using _Base::_M_get_node; + + /** + * @if maint + * @param x An instance of user data. + * + * Allocates space for a new node and constructs a copy of @a x in it. + * @endif + */ + _Node* + _M_create_node(const value_type& __x) + { + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data, __x); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; + } + + /** + * @if maint + * Allocates space for a new node and default-constructs a new + * instance of @c value_type in it. + * @endif + */ + _Node* + _M_create_node() + { + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; + } + + public: + // [23.2.2.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + list(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %list with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %list with @a n copies of @a value. + */ + list(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __n, __value); } + + /** + * @brief Create a %list with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %list with @a n copies of a + * default-constructed element. + */ + explicit + list(size_type __n) + : _Base(allocator_type()) + { this->insert(begin(), __n, value_type()); } + + /** + * @brief %List copy constructor. + * @param x A %list of identical element and allocator types. + * + * The newly-created %list uses a copy of the allocation object used + * by @a x. + */ + list(const list& __x) + : _Base(__x.get_allocator()) + { this->insert(begin(), __x.begin(), __x.end()); } + + /** + * @brief Builds a %list from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %list consisting of copies of the elements from + * [@a first,@a last). This is linear in N (where N is + * distance(@a first,@a last)). + * + * @if maint + * We don't need any dispatching tricks here, because insert does all of + * that anyway. + * @endif + */ + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } + + /** + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base dtor only erases the elements, and note + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + + /** + * @brief %List assignment operator. + * @param x A %list of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. + */ + list& + operator=(const list& __x); + + /** + * @brief Assigns a given value to a %list. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %list with copies of the elements in the + * range [@a first,@a last). + * + * Note that the assignment completely changes the %list and + * that the resulting %list's size is the same as the number of + * elements assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %list. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. + */ + iterator + end() { return &this->_M_impl._M_node; } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + end() const + { return &this->_M_impl._M_node; } + + /** + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.2.2] capacity + /** + * Returns true if the %list is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } + + /** Returns the number of elements in the %list. */ + size_type + size() const + { return std::distance(begin(), end()); } + + /** Returns the size() of the largest possible %list. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x); + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * + * This function will resize the %list to the specified number of + * elements. If the number is smaller than the %list's current + * size the %list is truncated, otherwise the %list is extended + * and new elements are default-constructed. + */ + void + resize(size_type __new_size) + { this->resize(__new_size, value_type()); } + + // element access + /** + * Returns a read/write reference to the data at the first + * element of the %list. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %list. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element + * of the %list. + */ + reference + back() + { return *(--end()); } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %list. + */ + const_reference + back() const + { return *(--end()); } + + // [23.2.2.3] modifiers + /** + * @brief Add data to the front of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. + */ + void + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. + */ + void + pop_front() + { this->_M_erase(begin()); } + + /** + * @brief Add data to the end of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. + */ + void + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the last element's data + * is needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { this->_M_erase(this->_M_impl._M_node._M_prev); } + + /** + * @brief Inserts given value into %list before specified iterator. + * @param position An iterator into the %list. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %list. + * @param position An iterator into the %list. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %list. + * @param position An iterator into the %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %list by one. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + iterator + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = erase(__first); + return __last; + } + + /** + * @brief Swaps data with another %list. + * @param x A %list of the same element and allocator types. + * + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. + */ + void + swap(list& __x) + { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); } + + /** + * Erases all the elements. Note that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + void + clear() + { + _Base::_M_clear(); + _Base::_M_init(); + } + + // [23.2.2.4] list operations + /** + * @brief Insert contents of another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. + */ + void + splice(iterator __position, list& __x) + { + if (!__x.empty()) + this->_M_transfer(__position, __x.begin(), __x.end()); + } + + /** + * @brief Insert element from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param i Iterator referencing the element to move. + * + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. + */ + void + splice(iterator __position, list&, iterator __i) + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) + return; + this->_M_transfer(__position, __i, __j); + } + + /** + * @brief Insert range from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param first Iterator referencing the start of range in x. + * @param last Iterator referencing the end of range in x. + * + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. + * + * Undefined if @a position is in [first,last). + */ + void + splice(iterator __position, list&, iterator __first, iterator __last) + { + if (__first != __last) + this->_M_transfer(__position, __first, __last); + } + + /** + * @brief Remove all elements equal to value. + * @param value The value to remove. + * + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + remove(const _Tp& __value); + + /** + * @brief Remove all elements satisfying a predicate. + * @param Predicate Unary predicate function or object. + * + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + template + void + remove_if(_Predicate); + + /** + * @brief Remove consecutive duplicate elements. + * + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in + * list order. Note that this function only erases the + * elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + void + unique(); + + /** + * @brief Remove consecutive elements satisfying a predicate. + * @param BinaryPredicate Binary predicate function or object. + * + * For each consecutive set of elements [first,last) that + * satisfy predicate(first,i) where i is an iterator in + * [first,last), remove all but the first one. Remaining + * elements stay in list order. Note that this function only + * erases the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + template + void + unique(_BinaryPredicate); + + /** + * @brief Merge sorted lists. + * @param x Sorted list to merge. + * + * Assumes that both @a x and this list are sorted according to + * operator<(). Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equal. + */ + void + merge(list& __x); + + /** + * @brief Merge sorted lists according to comparison function. + * @param x Sorted list to merge. + * @param StrictWeakOrdering Comparison function definining + * sort order. + * + * Assumes that both @a x and this list are sorted according to + * StrictWeakOrdering. Merges elements of @a x into this list + * in sorted order, leaving @a x empty when complete. Elements + * in this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). + */ + template + void + merge(list&, _StrictWeakOrdering); + + /** + * @brief Reverse the elements in list. + * + * Reverse the order of elements in the list in linear time. + */ + void + reverse() + { this->_M_impl._M_node.reverse(); } + + /** + * @brief Sort the elements. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + void + sort(); + + /** + * @brief Sort the elements according to comparison function. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + template + void + sort(_StrictWeakOrdering); + + protected: + // Internal assign functions follow. + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + for ( ; __first != __last; ++__first) + _M_insert(__pos, *__first); + } + + // Called by insert(p,n,x), and the range insert when it turns out + // to be the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + for ( ; __n > 0; --__n) + _M_insert(__pos, __x); + } + + + // Moves the elements from [first,last) before position. + void + _M_transfer(iterator __position, iterator __first, iterator __last) + { __position._M_node->transfer(__first._M_node,__last._M_node); } + + // Inserts new element at position given and with value given. + void + _M_insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + } + + // Erases element at position given. + void + _M_erase(iterator __position) + { + __position._M_node->unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + std::_Destroy(&__n->_M_data); + _M_put_node(__n); + } + }; + + /** + * @brief List equality comparison. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff the size and elements of the lists are equal. + * + * This is an equivalence relation. It is linear in the size of + * the lists. Lists are considered equivalent if their sizes are + * equal, and if corresponding elements compare equal. + */ + template + inline bool + operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { + typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } + + /** + * @brief List ordering relation. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * lists. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template + inline bool + operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::list::swap(). + template + inline void + swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _LIST_H */ + diff --git a/src/include.new/c++/3.4/bits/stl_map.h b/src/include.new/c++/3.4/bits/stl_map.h new file mode 100644 index 0000000..8535ae5 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_map.h @@ -0,0 +1,694 @@ +// Map implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_map.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MAP_H +#define _MAP_H 1 + +#include + +namespace _GLIBCXX_STD +{ + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using unique keys). + * For a @c map the key_type is Key, the mapped_type is T, and the + * value_type is std::pair. + * + * Maps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template , + typename _Alloc = allocator > > + class map + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function + { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.1.1] construct/copy/destroy + // (get_allocator() is normally listed in this section, but seems to have + // been accidentally omitted in the printed standard) + /** + * @brief Default constructor creates no elements. + */ + map() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + map(const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Map copy constructor. + * @param x A %map of identical element and allocator types. + * + * The newly-created %map uses a copy of the allocation object used + * by @a x. + */ + map(const map& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_unique(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief Map assignment operator. + * @param x A %map of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %map. + * Iteration is done in ascending order according to the keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %map. Iteration is done in ascending order according to the + * keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %map. Iteration is done in ascending order according to the keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %map. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %map. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %map. Iteration is done in descending + * order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %map is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %map. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %map. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // [23.3.1.2] element access + /** + * @brief Subscript ( @c [] ) access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] ) operator. Returns + * data associated with the key specified in subscript. If the key does + * not exist, a pair with that key is created using default values, which + * is then returned. + * + * Lookup requires logarithmic time. + */ + mapped_type& + operator[](const key_type& __k) + { + // concept requirements + __glibcxx_function_requires(_DefaultConstructibleConcept) + + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, mapped_type())); + return (*__i).second; + } + + // modifiers + /** + * @brief Attempts to insert a std::pair into the %map. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted pair, and the second is a bool that + * is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the %map. + * A %map relies on unique keys and thus a %pair is only inserted if its + * first element (the key) is not already present in the %map. + * + * Insertion requires logarithmic time. + */ + pair + insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + + /** + * @brief Attempts to insert a std::pair into the %map. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return An iterator that points to the element with key of @a x (may + * or may not be the %pair passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument + * insert() does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %map. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %map. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %map. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %map. + * @param x A %map of the same element and allocator types. + * + * This exchanges the elements between two maps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(map& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %map. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %map was + * constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %map was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // [23.3.1.3] map operations + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + * + * This function only makes sense for multimaps; for map the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + + template + friend bool + operator< (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + }; + + /** + * @brief Map equality comparison. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * maps. Maps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Map ordering relation. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::map::swap(). + template + inline void + swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _MAP_H */ diff --git a/src/include.new/c++/3.4/bits/stl_multimap.h b/src/include.new/c++/3.4/bits/stl_multimap.h new file mode 100644 index 0000000..e080f9a --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_multimap.h @@ -0,0 +1,677 @@ +// Multimap implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multimap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTIMAP_H +#define _MULTIMAP_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Forward declaration of operators < and ==, needed for friend declaration. + + template , + typename _Alloc = allocator > > + class multimap; + + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using equivalent + * keys). For a @c multimap the key_type is Key, the mapped_type + * is T, and the value_type is std::pair. + * + * Multimaps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class multimap + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function + { + friend class multimap<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.2] construct/copy/destroy + // (get_allocator() is also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + multimap() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief %Multimap copy constructor. + * @param x A %multimap of identical element and allocator types. + * + * The newly-created %multimap uses a copy of the allocation object used + * by @a x. + */ + multimap(const multimap& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_equal(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief %Multimap assignment operator. + * @param x A %multimap of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %multimap. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %multimap. Iteration is done in ascending order according + * to the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %multimap. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %multimap. Iteration is done in + * descending order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %multimap is empty. */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %multimap. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %multimap. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // modifiers + /** + * @brief Inserts a std::pair into the %multimap. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts a std::pair into the %multimap. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t.insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multimap. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multimap. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multimap. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multimap. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multimap. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %multimap. + * @param x A %multimap of the same element and allocator types. + * + * This exchanges the elements between two multimaps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %multimap. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %multimap + * was constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %multimap was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // multimap operations + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to sought-after element, + * or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful the iterator will point + * to the next greatest element or, if no such greater element exists, to + * end(). + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + + template + friend bool + operator< (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + }; + + /** + * @brief Multimap equality comparison. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multimaps. Multimaps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multimap ordering relation. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * multimaps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::multimap::swap(). + template + inline void + swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _MULTIMAP_H */ diff --git a/src/include.new/c++/3.4/bits/stl_multiset.h b/src/include.new/c++/3.4/bits/stl_multiset.h new file mode 100644 index 0000000..c82dee6 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_multiset.h @@ -0,0 +1,585 @@ +// Multiset implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multiset.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTISET_H +#define _MULTISET_H 1 + +#include + +namespace _GLIBCXX_STD +{ + + // Forward declaration of operators < and ==, needed for friend declaration. + template , + class _Alloc = allocator<_Key> > + class multiset; + + template + inline bool + operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of elements, which can be retrieved + * in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using equivalent + * keys). For a @c multiset the key_type and value_type are Key. + * + * Multisets support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class multiset + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + + private: + /// @if maint This turns a red-black tree into a [multi]set. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + /** + * @brief Default constructor creates no elements. + */ + multiset() + : _M_t(_Compare(), allocator_type()) { } + + explicit + multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief %Multiset copy constructor. + * @param x A %multiset of identical element and allocator types. + * + * The newly-created %multiset uses a copy of the allocation object used + * by @a x. + */ + multiset(const multiset<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief %Multiset assignment operator. + * @param x A %multiset of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %multiset. + * @param x A %multiset of the same element and allocator types. + * + * This exchanges the elements between two multisets in constant time. + * (It is only swapping a pointer, an integer, and an instance of the @c + * Compare type (which itself is often stateless and empty), so it should + * be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(multiset<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Inserts an element into the %multiset. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts an element into the %multiset. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multiset. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multiset. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multiset. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multiset. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multiset. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %multiset. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // multiset operations: + + /** + * @brief Finds the number of elements with given key. + * @param x Key of elements to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + + template + friend bool + operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + }; + + /** + * @brief Multiset equality comparison. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff the size and elements of the multisets are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multisets. + * Multisets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template + inline bool + operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multiset ordering relation. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template + inline bool + operator!=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template + inline bool + operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template + inline bool + operator<=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template + inline bool + operator>=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::multiset::swap(). + template + inline void + swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } + +} // namespace std + +#endif /* _MULTISET_H */ diff --git a/src/include.new/c++/3.4/bits/stl_numeric.h b/src/include.new/c++/3.4/bits/stl_numeric.h new file mode 100644 index 0000000..58762a4 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_numeric.h @@ -0,0 +1,326 @@ +// Numeric functions implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_numeric.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_NUMERIC_H +#define _STL_NUMERIC_H 1 + +#include + +namespace std +{ + + /** + * @brief Accumulate values in a range. + * + * Accumulates the values in the range [first,last) using operator+(). The + * initial value is @a init. The values are processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @return The final sum. + */ + template + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; + } + + /** + * @brief Accumulate values in a range with operation. + * + * Accumulates the values in the range [first,last) using the function + * object @a binary_op. The initial value is @a init. The values are + * processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @param binary_op Function object to accumulate with. + * @return The final sum. + */ + template + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, multiplies successive + * elements from the two ranges and adds each product into the accumulated + * value using operator+(). The values in the ranges are processed in + * order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @return The final inner product. + */ + template + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, applies @a binary_op2 to + * successive elements from the two ranges and accumulates each result into + * the accumulated value using @a binary_op1. The values in the ranges are + * processed in order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @param binary_op1 Function object to accumulate with. + * @param binary_op2 Function object to apply to pairs of input values. + * @return The final inner product. + */ + template + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using operator-() and writes the result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + _ValueType __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using the function object @a binary_op and writes the + * result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + _ValueType __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; + } + return ++__result; + } + +} // namespace std + +#endif /* _STL_NUMERIC_H */ diff --git a/src/include.new/c++/3.4/bits/stl_pair.h b/src/include.new/c++/3.4/bits/stl_pair.h new file mode 100644 index 0000000..d5146bb --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_pair.h @@ -0,0 +1,147 @@ +// Pair implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_pair.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _PAIR_H +#define _PAIR_H 1 + +namespace std +{ + /// pair holds two objects of arbitrary type. + template + struct pair + { + typedef _T1 first_type; ///< @c first_type is the first bound type + typedef _T2 second_type; ///< @c second_type is the second bound type + + _T1 first; ///< @c first is a copy of the first object + _T2 second; ///< @c second is a copy of the second object + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 265. std::pair::pair() effects overly restrictive + /** The default constructor creates @c first and @c second using their + * respective default constructors. */ + pair() + : first(), second() { } + + /** Two objects may be passed to a @c pair constructor to be copied. */ + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + /** There is also a templated copy ctor for the @c pair class itself. */ + template + pair(const pair<_U1, _U2>& __p) + : first(__p.first), second(__p.second) { } + }; + + /// Two pairs of the same type are equal iff their members are equal. + template + inline bool + operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first == __y.first && __x.second == __y.second; } + + /// + template + inline bool + operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first < __y.first + || (!(__y.first < __x.first) && __x.second < __y.second); } + + /// Uses @c operator== to find the result. + template + inline bool + operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x == __y); } + + /// Uses @c operator< to find the result. + template + inline bool + operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __y < __x; } + + /// Uses @c operator< to find the result. + template + inline bool + operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__y < __x); } + + /// Uses @c operator< to find the result. + template + inline bool + operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x < __y); } + + /** + * @brief A convenience wrapper for creating a pair from two objects. + * @param x The first object. + * @param y The second object. + * @return A newly-constructed pair<> object of the appropriate type. + * + * The standard requires that the objects be passed by reference-to-const, + * but LWG issue #181 says they should be passed by const value. We follow + * the LWG by default. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 181. make_pair() unintended behavior + template + inline pair<_T1, _T2> + make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); } +} // namespace std + +#endif /* _PAIR_H */ diff --git a/src/include.new/c++/3.4/bits/stl_queue.h b/src/include.new/c++/3.4/bits/stl_queue.h new file mode 100644 index 0000000..3583547 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_queue.h @@ -0,0 +1,472 @@ +// Queue implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_queue.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _QUEUE_H +#define _QUEUE_H 1 + +#include +#include + +namespace std +{ + // Forward declarations of operators < and ==, needed for friend declaration. + template > + class queue; + + template + inline bool + operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + + template + inline bool + operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + + /** + * @brief A standard container giving FIFO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * container, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds another + * container, and provides a wrapper interface to that container. The + * wrapper is what enforces strict first-in-first-out %queue behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be any type + * that supports @c front, @c back, @c push_back, and @c pop_front, + * such as std::list or an appropriate user-defined type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c push and + * @c pop, which are standard %queue/FIFO operations. + */ + template + class queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + /** + * 'c' is the underlying container. Maintainers wondering why + * this isn't uglified as per style guidelines should note that + * this name is specified in the standard, [23.2.3.1]. (Why? + * Presumably for the same reason that it's protected instead + * of private: to allow derivation. But none of the other + * containers allow for derivation. Odd.) + */ + _Sequence c; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + queue(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %queue. + */ + reference + front() + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + front() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read/write reference to the data at the last + * element of the %queue. + */ + reference + back() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %queue. + */ + const_reference + back() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the end of the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. The function creates an + * element at the end of the %queue and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue by one. + * The time complexity of the operation depends on the underlying + * sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_front(); + } + }; + + + /** + * @brief Queue equality comparison. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff the size and elements of the queues are equal. + * + * This is an equivalence relation. Complexity and semantics depend on the + * underlying sequence type, but the expected rules are: this relation is + * linear in the size of the sequences, and queues are considered equivalent + * if their sequences compare equal. + */ + template + inline bool + operator==(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return __x.c == __y.c; } + + /** + * @brief Queue ordering relation. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template + inline bool + operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template + inline bool + operator!=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__x < __y); } + + /** + * @brief A standard container automatically sorting its contents. + * + * @ingroup Containers + * @ingroup Sequences + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces sorting and + * first-in-first-out %queue behavior. Very few of the standard + * container/sequence interface requirements are met (e.g., + * iterators). + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::vector, but it can be + * any type that supports @c front(), @c push_back, @c pop_back, + * and random-access iterators, such as std::deque or an + * appropriate user-defined type. + * + * The third template parameter supplies the means of making + * priority comparisons. It defaults to @c less but + * can be anything defining a strict weak ordering. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %queue/FIFO + * operations. + * + * @note No equality/comparison operators are provided for + * %priority_queue. + * + * @note Sorting of the elements takes place as they are added to, + * and removed from, the %priority_queue using the + * %priority_queue's member functions. If you access the elements + * by other means, and change their data such that the sorting + * order would be different, the %priority_queue will not re-sort + * the elements for you. (How could it know to do so?) + */ + template, + typename _Compare = less > + class priority_queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _SequenceConcept) + __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + __glibcxx_class_requires4(_Compare, bool, _Tp,_Tp,_BinaryFunctionConcept) + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on these names. + _Sequence c; + _Compare comp; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { std::make_heap(c.begin(), c.end(), comp); } + + /** + * @brief Builds a %queue from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param x A comparison functor describing a strict weak ordering. + * @param s An initial sequence with which to start. + * + * Begins by copying @a s, inserting a copy of the elements + * from @a [first,last) into the copy of @a s, then ordering + * the copy according to @a x. + * + * For more information on function objects, see the + * documentation on @link s20_3_1_base functor base + * classes@endlink. + */ + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { + __glibcxx_requires_valid_range(__first, __last); + c.insert(c.end(), __first, __last); + std::make_heap(c.begin(), c.end(), comp); + } + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * @brief Add data to the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. + * The time complexity of the operation depends on the underlying + * sequence. + */ + void + push(const value_type& __x) + { + try + { + c.push_back(__x); + std::push_heap(c.begin(), c.end(), comp); + } + catch(...) + { + c.clear(); + __throw_exception_again; + } + } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + try + { + std::pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + catch(...) + { + c.clear(); + __throw_exception_again; + } + } + }; + + // No equality/comparison operators are provided for priority_queue. +} // namespace std + +#endif /* _QUEUE_H */ diff --git a/src/include.new/c++/3.4/bits/stl_raw_storage_iter.h b/src/include.new/c++/3.4/bits/stl_raw_storage_iter.h new file mode 100644 index 0000000..732142e --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_raw_storage_iter.h @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_raw_storage_iter.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_RAW_STORAGE_ITERATOR_H +#define _STL_RAW_STORAGE_ITERATOR_H 1 + +namespace std +{ + /** + * This iterator class lets algorithms store their results into + * uninitialized memory. + */ + template + class raw_storage_iterator + : public iterator + { + protected: + _ForwardIterator _M_iter; + + public: + explicit + raw_storage_iterator(_ForwardIterator __x) + : _M_iter(__x) {} + + raw_storage_iterator& + operator*() { return *this; } + + raw_storage_iterator& + operator=(const _Tp& __element) + { + std::_Construct(&*_M_iter, __element); + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp>& + operator++() + { + ++_M_iter; + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp> + operator++(int) + { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } + }; +} // namespace std + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/stl_relops.h b/src/include.new/c++/3.4/bits/stl_relops.h new file mode 100644 index 0000000..3e9f060 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_relops.h @@ -0,0 +1,137 @@ +// std::rel_ops implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file stl_relops.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * @if maint + * Inclusion of this file has been removed from + * all of the other STL headers for safety reasons, except std_utility.h. + * For more information, see the thread of about twenty messages starting + * with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html , or the + * FAQ at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4 . + * + * Short summary: the rel_ops operators should be avoided for the present. + * @endif + */ + +#ifndef _STL_RELOPS_H +#define _STL_RELOPS_H 1 + +namespace std +{ + namespace rel_ops + { + /** @namespace std::rel_ops + * @brief The generated relational operators are sequestered here. + */ + + /** + * @brief Defines @c != for arbitrary types, in terms of @c ==. + * @param x A thing. + * @param y Another thing. + * @return x != y + * + * This function uses @c == to determine its result. + */ + template + inline bool + operator!=(const _Tp& __x, const _Tp& __y) + { return !(__x == __y); } + + /** + * @brief Defines @c > for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x > y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>(const _Tp& __x, const _Tp& __y) + { return __y < __x; } + + /** + * @brief Defines @c <= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x <= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator<=(const _Tp& __x, const _Tp& __y) + { return !(__y < __x); } + + /** + * @brief Defines @c >= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x >= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>=(const _Tp& __x, const _Tp& __y) + { return !(__x < __y); } + + } // namespace rel_ops +} // namespace std + +#endif /* _STL_RELOPS_H */ diff --git a/src/include.new/c++/3.4/bits/stl_set.h b/src/include.new/c++/3.4/bits/stl_set.h new file mode 100644 index 0000000..bb28bdd --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_set.h @@ -0,0 +1,593 @@ +// Set implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_set.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SET_H +#define _SET_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Forward declarations of operators < and ==, needed for friend declaration. + template, + class _Alloc = allocator<_Key> > + class set; + + template + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of unique keys, which can be + * retrieved in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using unique keys). + * + * Sets support bidirectional iterators. + * + * @param Key Type of key objects. + * @param Compare Comparison function object type, defaults to less. + * @param Alloc Allocator type, defaults to allocator. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class set + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + //@} + + private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set + public: + //@{ + /// Iterator-related typedefs. + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + //@} + + // allocation/deallocation + /// Default constructor creates no elements. + set() + : _M_t(_Compare(), allocator_type()) {} + + /** + * @brief Default constructor creates no elements. + * + * @param comp Comparator to use. + * @param a Allocator to use. + */ + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Set copy constructor. + * @param x A %set of identical element and allocator types. + * + * The newly-created %set uses a copy of the allocation object used + * by @a x. + */ + set(const set<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Set assignment operator. + * @param x A %set of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + set<_Key,_Compare,_Alloc>& + operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object with which the %set was constructed. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object with which the %set was constructed. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the allocator object with which the %set was constructed. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %set. Iteration is done in ascending order according to the keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %set. Iteration is done in ascending order according to the keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %set. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %set. + * @param x A %set of the same element and allocator types. + * + * This exchanges the elements between two sets in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(set<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Attempts to insert an element into the %set. + * @param x Element to be inserted. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to insert an element into the %set. A %set + * relies on unique keys and thus an element is only inserted if it is + * not already present in the %set. + * + * Insertion requires logarithmic time. + */ + pair + insert(const value_type& __x) + { + pair __p = _M_t.insert_unique(__x); + return pair(__p.first, __p.second); + } + + /** + * @brief Attempts to insert an element into the %set. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the element with key of @a x (may + * or may not be the element passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %set. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %set. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %set. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %set. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // set operations: + + /** + * @brief Finds the number of elements. + * @param x Element to located. + * @return Number of elements with specified key. + * + * This function only makes sense for multisets; for set the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + //@} + + template + friend bool + operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + + template + friend bool + operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + }; + + + /** + * @brief Set equality comparison. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff the size and elements of the sets are equal. + * + * This is an equivalence relation. It is linear in the size of the sets. + * Sets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Set ordering relation. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template + inline bool + operator!=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template + inline bool + operator>(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template + inline bool + operator<=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template + inline bool + operator>=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::set::swap(). + template + inline void + swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } + +} // namespace std + +#endif /* _SET_H */ diff --git a/src/include.new/c++/3.4/bits/stl_stack.h b/src/include.new/c++/3.4/bits/stl_stack.h new file mode 100644 index 0000000..ada50ee --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_stack.h @@ -0,0 +1,272 @@ +// Stack implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_stack.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STACK_H +#define _STACK_H 1 + +#include +#include + +namespace std +{ + // Forward declarations of operators == and <, needed for friend + // declaration. + template > + class stack; + + template + inline bool + operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + template + inline bool + operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + /** + * @brief A standard container giving FILO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * container, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces strict + * first-in-last-out %stack behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be + * any type that supports @c back, @c push_back, and @c pop_front, + * such as std::list, std::vector, or an appropriate user-defined + * type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %stack/FILO + * operations. + */ + template + class stack + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template + friend bool + operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + template + friend bool + operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on this name. + _Sequence c; + + public: + // XXX removed old def ctor, added def arg to this one to match 14882 + /** + * @brief Default constructor creates no elements. + */ + explicit + stack(const _Sequence& __c = _Sequence()) + : c(__c) {} + + /** + * Returns true if the %stack is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %stack. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %stack. + */ + reference + top() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %stack. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the top of the %stack. + * @param x Data to be added. + * + * This is a typical %stack operation. The function creates an + * element at the top of the %stack and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %stack operation. It shrinks the %stack + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_back(); + } + }; + + /** + * @brief Stack equality comparison. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff the size and elements of the stacks are equal. + * + * This is an equivalence relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, and + * stacks are considered equivalent if their sequences compare + * equal. + */ + template + inline bool + operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c == __y.c; } + + /** + * @brief Stack ordering relation. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template + inline bool + operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template + inline bool + operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x < __y); } +} // namespace std + +#endif /* _STACK_H */ diff --git a/src/include.new/c++/3.4/bits/stl_tempbuf.h b/src/include.new/c++/3.4/bits/stl_tempbuf.h new file mode 100644 index 0000000..399cffb --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_tempbuf.h @@ -0,0 +1,171 @@ +// Temporary buffer implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_tempbuf.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TEMPBUF_H +#define _TEMPBUF_H 1 + +#include + +namespace std +{ + /** + * @if maint + * This class is used in two places: stl_algo.h and ext/memory, + * where it is wrapped as the temporary_buffer class. See + * temporary_buffer docs for more notes. + * @endif + */ + template + class _Temporary_buffer + { + // concept requirements + __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef pointer iterator; + typedef ptrdiff_t size_type; + + protected: + size_type _M_original_len; + size_type _M_len; + pointer _M_buffer; + + void + _M_initialize_buffer(const _Tp&, __true_type) { } + + void + _M_initialize_buffer(const _Tp& val, __false_type) + { std::uninitialized_fill_n(_M_buffer, _M_len, val); } + + public: + /// As per Table mumble. + size_type + size() const + { return _M_len; } + + /// Returns the size requested by the constructor; may be >size(). + size_type + requested_size() const + { return _M_original_len; } + + /// As per Table mumble. + iterator + begin() + { return _M_buffer; } + + /// As per Table mumble. + iterator + end() + { return _M_buffer + _M_len; } + + /** + * Constructs a temporary buffer of a size somewhere between + * zero and the size of the given range. + */ + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); + + ~_Temporary_buffer() + { + std::_Destroy(_M_buffer, _M_buffer + _M_len); + std::return_temporary_buffer(_M_buffer); + } + + private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&); + + void + operator=(const _Temporary_buffer&); + }; + + + template + _Temporary_buffer<_ForwardIterator, _Tp>:: + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _M_original_len(std::distance(__first, __last)), + _M_len(0), _M_buffer(0) + { + // Workaround for a __type_traits bug in the pre-7.3 compiler. + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; + + try + { + pair __p(get_temporary_buffer< + value_type>(_M_original_len)); + _M_buffer = __p.first; + _M_len = __p.second; + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + catch(...) + { + std::return_temporary_buffer(_M_buffer); + _M_buffer = 0; + _M_len = 0; + __throw_exception_again; + } + } +} // namespace std + +#endif /* _TEMPBUF_H */ + diff --git a/src/include.new/c++/3.4/bits/stl_threads.h b/src/include.new/c++/3.4/bits/stl_threads.h new file mode 100644 index 0000000..04baf0a --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_threads.h @@ -0,0 +1,150 @@ +// Threading support -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_threads.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_THREADS_H +#define _STL_THREADS_H 1 + +#include + +// The only supported threading model is GCC's own gthr.h abstraction +// layer. +#include "bits/gthr.h" + +namespace __gnu_internal +{ +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + extern __gthread_mutex_t _GLIBCXX_mutex; + extern __gthread_mutex_t *_GLIBCXX_mutex_address; + extern __gthread_once_t _GLIBCXX_once; + extern void _GLIBCXX_mutex_init(void); + extern void _GLIBCXX_mutex_address_init(void); +#endif +} // namespace __gnu_internal + +namespace __gnu_cxx +{ + // Locking class. Note that this class *does not have a + // constructor*. It must be initialized either statically, with + // __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling + // the _M_initialize member function. (This is similar to the ways + // that a pthreads mutex can be initialized.) There are explicit + // member functions for acquiring and releasing the lock. + + // There is no constructor because static initialization is + // essential for some uses, and only a class aggregate (see section + // 8.5.1 of the C++ standard) can be initialized that way. That + // means we must have no constructors, no base classes, no virtual + // functions, and no private or protected members. + struct _STL_mutex_lock + { + // The class must be statically initialized with __STL_MUTEX_INITIALIZER. +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + volatile int _M_init_flag; + __gthread_once_t _M_once; +#endif + __gthread_mutex_t _M_lock; + + void + _M_initialize() + { +#ifdef __GTHREAD_MUTEX_INIT + // There should be no code in this path given the usage rules above. +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (_M_init_flag) return; + if (__gthread_once(&__gnu_internal::_GLIBCXX_once, + __gnu_internal::_GLIBCXX_mutex_init) != 0 + && __gthread_active_p()) + abort (); + __gthread_mutex_lock(&__gnu_internal::_GLIBCXX_mutex); + if (!_M_init_flag) + { + // Even though we have a global lock, we use __gthread_once to be + // absolutely certain the _M_lock mutex is only initialized once on + // multiprocessor systems. + __gnu_internal::_GLIBCXX_mutex_address = &_M_lock; + if (__gthread_once(&_M_once, + __gnu_internal::_GLIBCXX_mutex_address_init) != 0 + && __gthread_active_p()) + abort(); + _M_init_flag = 1; + } + __gthread_mutex_unlock(&__gnu_internal::_GLIBCXX_mutex); +#endif + } + + void + _M_acquire_lock() + { +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (!_M_init_flag) _M_initialize(); +#endif + __gthread_mutex_lock(&_M_lock); + } + + void + _M_release_lock() + { +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (!_M_init_flag) _M_initialize(); +#endif + __gthread_mutex_unlock(&_M_lock); + } + }; + +#ifdef __GTHREAD_MUTEX_INIT +#define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT } +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) +#ifdef __GTHREAD_MUTEX_INIT_DEFAULT +#define __STL_MUTEX_INITIALIZER \ + = { 0, __GTHREAD_ONCE_INIT, __GTHREAD_MUTEX_INIT_DEFAULT } +#else +#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT } +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/src/include.new/c++/3.4/bits/stl_tree.h b/src/include.new/c++/3.4/bits/stl_tree.h new file mode 100644 index 0000000..cea16f1 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_tree.h @@ -0,0 +1,1283 @@ +// RB tree implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +/** @file stl_tree.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TREE_H +#define _TREE_H 1 + +#include +#include +#include +#include +#include + +namespace std +{ + // Red-black tree class, designed for use in implementing STL + // associative containers (set, multiset, map, and multimap). The + // insertion and deletion algorithms are based on those in Cormen, + // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, + // 1990), except that + // + // (1) the header cell is maintained with links not only to the root + // but also to the leftmost node of the tree, to enable constant + // time begin(), and to the rightmost node of the tree, to enable + // linear time performance when used with the generic set algorithms + // (set_union, etc.) + // + // (2) when a node being deleted has two children its successor node + // is relinked into its place, rather than copied, so that the only + // iterators invalidated are those referring to the deleted node. + + enum _Rb_tree_color { _S_red = false, _S_black = true }; + + struct _Rb_tree_node_base + { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + }; + + template + struct _Rb_tree_node : public _Rb_tree_node_base + { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + }; + + _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); + + _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); + + template + struct _Rb_tree_iterator + { + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_iterator() + : _M_node() { } + + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; + + typedef _Rb_tree_iterator<_Tp> iterator; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_const_iterator() + : _M_node() { } + + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } + + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + void + _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_insert_and_rebalance(const bool __insert_left, + _Rb_tree_node_base* __x, + _Rb_tree_node_base* __p, + _Rb_tree_node_base& __header); + + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header); + + + template > + class _Rb_tree + { + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + + protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + typedef _Rb_tree_node<_Val> _Rb_tree_node; + + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef const _Rb_tree_node* _Const_Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + protected: + _Rb_tree_node* + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Rb_tree_node* __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + + _Link_type + _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + try + { std::_Construct(&__tmp->_M_value_field, __x); } + catch(...) + { + _M_put_node(__tmp); + __throw_exception_again; + } + return __tmp; + } + + _Link_type + _M_clone_node(_Const_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + void + destroy_node(_Link_type __p) + { + std::_Destroy(&__p->_M_value_field); + _M_put_node(__p); + } + + protected: + template::_M_type> + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + // Specialization for _Comparison types that are not capable of + // being base classes / super classes. + template + struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + _Rb_tree_impl<_Compare> _M_impl; + + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } + + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } + + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } + + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } + + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } + + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } + + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } + + _Const_Link_type + _M_begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_parent); } + + _Link_type + _M_end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } + + _Const_Link_type + _M_end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } + + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } + + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } + + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } + + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } + + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } + + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_const_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + private: + iterator + _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); + + void + _M_erase(_Link_type __x); + + public: + // allocation/deallocation + _Rb_tree() + { } + + _Rb_tree(const _Compare& __comp) + : _M_impl(allocator_type(), __comp) + { } + + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _M_impl(__a, __comp) + { } + + _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + : _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare) + { + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + + ~_Rb_tree() + { _M_erase(_M_begin()); } + + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); + + // Accessors. + _Compare + key_comp() const + { return _M_impl._M_key_compare; } + + iterator + begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_left); } + + const_iterator + begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_left); } + + iterator + end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } + + const_iterator + end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + bool + empty() const + { return _M_impl._M_node_count == 0; } + + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return size_type(-1); } + + void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t); + + // Insert/erase. + pair + insert_unique(const value_type& __x); + + iterator + insert_equal(const value_type& __x); + + iterator + insert_unique(iterator __position, const value_type& __x); + + iterator + insert_equal(iterator __position, const value_type& __x); + + template + void + insert_unique(_InputIterator __first, _InputIterator __last); + + template + void + insert_equal(_InputIterator __first, _InputIterator __last); + + void + erase(iterator __position); + + size_type + erase(const key_type& __x); + + void + erase(iterator __first, iterator __last); + + void + erase(const key_type* __first, const key_type* __last); + + void + clear() + { + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } + + // Set operations. + iterator + find(const key_type& __x); + + const_iterator + find(const key_type& __x) const; + + size_type + count(const key_type& __x) const; + + iterator + lower_bound(const key_type& __x); + + const_iterator + lower_bound(const key_type& __x) const; + + iterator + upper_bound(const key_type& __x); + + const_iterator + upper_bound(const key_type& __x) const; + + pair + equal_range(const key_type& __x); + + pair + equal_range(const key_type& __x) const; + + // Debugging. + bool + __rb_verify() const; + }; + + template + inline bool + operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); + } + + template + inline bool + operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + template + inline bool + operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + template + inline void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { __x.swap(__y); } + + template + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + { + if (this != &__x) + { + // Note that _Key may be a constant type. + clear(); + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + return *this; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + { + _Link_type __z = _M_create_node(__v); + bool __insert_left; + + __insert_left = __x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t) + { + if (_M_root() == 0) + { + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); + } + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + // No need to swap header's color as it does not change. + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + } + + template + pair::iterator, + bool> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_unique(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + bool __comp = true; + while (__x != 0) + { + __y = __x; + __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + else + return insert_unique(__v).first; + } + else if (__position._M_node == _M_end()) + { + // end() + if (_M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_unique(__v).first; + } + else + { + iterator __before = __position; + --__before; + if (_M_impl._M_key_compare(_S_key(__before._M_node), + _KeyOfValue()(__v)) + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return insert_unique(__v).first; + } + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_equal(__v); + } + else if (__position._M_node == _M_end()) + { + // end() + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_equal(__v); + } + else + { + iterator __before = __position; + --__before; + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__before._M_node)) + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return insert_equal(__v); + } + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_equal(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_equal(*__first); + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_unique(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_unique(*__first); + } + + template + inline void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node, + this->_M_impl._M_header)); + destroy_node(__y); + --_M_impl._M_node_count; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) + { + pair __p = equal_range(__x); + size_type __n = std::distance(__p.first, __p.second); + erase(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>:: + _M_copy(_Const_Link_type __x, _Link_type __p) + { + // Structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + catch(...) + { + _M_erase(__top); + __throw_exception_again; + } + return __top; + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x) + { + // Erase without rebalancing. + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; + } + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + find(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + { + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + count(const _Key& __k) const + { + pair __p = equal_range(__k); + const size_type __n = std::distance(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + inline + pair::iterator, + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + equal_range(const _Key& __k) + { return pair(lower_bound(__k), upper_bound(__k)); } + + template + inline + pair::const_iterator, + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { return pair(lower_bound(__k), + upper_bound(__k)); } + + unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root); + + template + bool + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const + { + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); + + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; + + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; + } +} // namespace std + +#endif + diff --git a/src/include.new/c++/3.4/bits/stl_uninitialized.h b/src/include.new/c++/3.4/bits/stl_uninitialized.h new file mode 100644 index 0000000..f4f8d18 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_uninitialized.h @@ -0,0 +1,297 @@ +// Raw memory manipulators -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_uninitialized.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_UNINITIALIZED_H +#define _STL_UNINITIALIZED_H 1 + +#include + +namespace std +{ + // uninitialized_copy + template + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __true_type) + { return std::copy(__first, __last, __result); } + + template + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __false_type) + { + _ForwardIterator __cur = __result; + try + { + for ( ; __first != __last; ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * Like copy(), but does not require an initialized output range. + */ + template + inline _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + return std::__uninitialized_copy_aux(__first, __last, __result, + _Is_POD()); + } + + inline char* + uninitialized_copy(const char* __first, const char* __last, char* __result) + { + std::memmove(__result, __first, __last - __first); + return __result + (__last - __first); + } + + inline wchar_t* + uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) + { + std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template + inline void + __uninitialized_fill_aux(_ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __x, __true_type) + { std::fill(__first, __last, __x); } + + template + void + __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for ( ; __cur != __last; ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @param x The source value. + * @return Nothing. + * + * Like fill(), but does not require an initialized output range. + */ + template + inline void + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template + inline _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __true_type) + { return std::fill_n(__first, __n, __x); } + + template + _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for ( ; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, __x); + return __cur; + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,first+n). + * @param first An input iterator. + * @param n The number of copies to make. + * @param x The source value. + * @return first+n + * + * Like fill_n(), but does not require an initialized output range. + */ + template + inline _ForwardIterator + uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + return std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); + } + + // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, + // __uninitialized_fill_copy. + + // __uninitialized_copy_copy + // Copies [first1, last1) into [result, result + (last1 - first1)), and + // copies [first2, last2) into + // [result, result + (last1 - first1) + (last2 - first2)). + + template + inline _ForwardIterator + __uninitialized_copy_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result) + { + _ForwardIterator __mid = std::uninitialized_copy(__first1, __last1, + __result); + try + { + return std::uninitialized_copy(__first2, __last2, __mid); + } + catch(...) + { + std::_Destroy(__result, __mid); + __throw_exception_again; + } + } + + // __uninitialized_fill_copy + // Fills [result, mid) with x, and copies [first, last) into + // [mid, mid + (last - first)). + template + inline _ForwardIterator + __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + const _Tp& __x, _InputIterator __first, + _InputIterator __last) + { + std::uninitialized_fill(__result, __mid, __x); + try + { + return std::uninitialized_copy(__first, __last, __mid); + } + catch(...) + { + std::_Destroy(__result, __mid); + __throw_exception_again; + } + } + + // __uninitialized_copy_fill + // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and + // fills [first2 + (last1 - first1), last2) with x. + template + inline void + __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, const _Tp& __x) + { + _ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1, + __first2); + try + { + std::uninitialized_fill(__mid2, __last2, __x); + } + catch(...) + { + std::_Destroy(__first2, __mid2); + __throw_exception_again; + } + } + +} // namespace std + +#endif /* _STL_UNINITIALIZED_H */ diff --git a/src/include.new/c++/3.4/bits/stl_vector.h b/src/include.new/c++/3.4/bits/stl_vector.h new file mode 100644 index 0000000..fee413d --- /dev/null +++ b/src/include.new/c++/3.4/bits/stl_vector.h @@ -0,0 +1,932 @@ +// Vector implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_vector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_H +#define _VECTOR_H 1 + +#include +#include +#include + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template + struct _Vector_base + { + struct _Vector_impl + : public _Alloc { + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + _Vector_impl (_Alloc const& __a) + : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast(&this->_M_impl); } + + _Vector_base(const allocator_type& __a) : _M_impl(__a) + { } + + _Vector_base(size_t __n, const allocator_type& __a) + : _M_impl(__a) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + + ~_Vector_base() + { _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } + + public: + _Vector_impl _M_impl; + + _Tp* + _M_allocate(size_t __n) { return _M_impl.allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_impl.deallocate(__p, __n); } + }; + + + /** + * @brief A standard container which offers fixed time access to + * individual elements in any order. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements with the + * %exception of @c push_front and @c pop_front. + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ + template > + class vector : protected _Vector_base<_Tp, _Alloc> + { + // Concept requirements. + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + /** @if maint + * These two functions and three data members are all from the + * base class. They should be pretty self-explanatory, as + * %vector uses a simple contiguous allocation scheme. @endif + */ + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_impl; + + public: + // [23.2.4.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %vector with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %vector with @a n copies of @a value. + */ + vector(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); } + + /** + * @brief Create a %vector with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %vector with @a n copies of a + * default-constructed element. + */ + explicit + vector(size_type __n) + : _Base(__n, allocator_type()) + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, value_type()); } + + /** + * @brief %Vector copy constructor. + * @param x A %vector of identical element and allocator types. + * + * The newly-created %vector uses a copy of the allocation + * object used by @a x. All the elements of @a x are copied, + * but any extra memory in + * @a x (for fast expansion) will not be copied. + */ + vector(const vector& __x) + : _Base(__x.size(), __x.get_allocator()) + { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(), + this->_M_impl._M_start); + } + + /** + * @brief Builds a %vector from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %vector consisting of copies of the elements from + * [first,last). + * + * If the iterators are forward, bidirectional, or + * random-access, then this will call the elements' copy + * constructor N times (where N is distance(first,last)) and do + * no memory reallocation. But if only input iterators are + * used, then this will do at most 2N calls to the copy + * constructor, and logN memory reallocations. + */ + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + + /** + * @brief %Vector assignment operator. + * @param x A %vector of identical element and allocator types. + * + * All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. Unlike the + * copy constructor, the allocator object is not copied. + */ + vector& + operator=(const vector& __x); + + /** + * @brief Assigns a given value to a %vector. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %vector with @a n copies of the given + * value. Note that the assignment completely changes the + * %vector and that the resulting %vector's size is the same as + * the number of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %vector with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %vector and + * that the resulting %vector's size is the same as the number + * of elements assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + using _Base::get_allocator; + + // iterators + /** + * Returns a read/write iterator that points to the first + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + begin() { return iterator (this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %vector. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const { return const_iterator (this->_M_impl._M_start); } + + /** + * Returns a read/write iterator that points one past the last + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + end() { return iterator (this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %vector. Iteration is done in + * ordinary element order. + */ + const_iterator + end() const { return const_iterator (this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to the + * last element in the %vector. Iteration is done in reverse + * element order. + */ + reverse_iterator + rbegin() { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last element in the %vector. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %vector. Iteration is done + * in reverse element order. + */ + reverse_iterator + rend() { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first element in the %vector. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const { return const_reverse_iterator(begin()); } + + // [23.2.4.2] capacity + /** Returns the number of elements in the %vector. */ + size_type + size() const { return size_type(end() - begin()); } + + /** Returns the size() of the largest possible %vector. */ + size_type + max_size() const { return size_type(-1) / sizeof(value_type); } + + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %vector to the specified + * number of elements. If the number is smaller than the + * %vector's current size the %vector is truncated, otherwise + * the %vector is extended and new elements are populated with + * given data. + */ + void + resize(size_type __new_size, const value_type& __x) + { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + insert(end(), __new_size - size(), __x); + } + + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * + * This function will resize the %vector to the specified + * number of elements. If the number is smaller than the + * %vector's current size the %vector is truncated, otherwise + * the %vector is extended and new elements are + * default-constructed. + */ + void + resize(size_type __new_size) { resize(__new_size, value_type()); } + + /** + * Returns the total number of elements that the %vector can + * hold before needing to allocate more memory. + */ + size_type + capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); } + + /** + * Returns true if the %vector is empty. (Thus begin() would + * equal end().) + */ + bool + empty() const { return begin() == end(); } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * elements. + * @param n Number of elements required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %vector to hold the specified number of elements. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the number of elements + * that will be required, the user can reserve the memory in + * %advance, and thus prevent a possible reallocation of memory + * and copying of %vector data. + */ + void + reserve(size_type __n); + + // element access + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __n) { return *(begin() + __n); } + + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[](size_type __n) const { return *(begin() + __n); } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + reference + at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } + + /** + * Returns a read/write reference to the data at the first + * element of the %vector. + */ + reference + front() { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %vector. + */ + const_reference + front() const { return *begin(); } + + /** + * Returns a read/write reference to the data at the last + * element of the %vector. + */ + reference + back() { return *(end() - 1); } + + /** + * Returns a read-only (constant) reference to the data at the + * last element of the %vector. + */ + const_reference + back() const { return *(end() - 1); } + + // [23.2.4.3] modifiers + /** + * @brief Add data to the end of the %vector. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %vector and assigns the given data + * to it. Due to the nature of a %vector this operation can be + * done in constant time if the %vector has preallocated space + * available. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(end(), __x); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %vector by one. + * + * Note that no data is returned, and if the last element's + * data is needed, it should be retrieved before pop_back() is + * called. + */ + void + pop_back() + { + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); + } + + /** + * @brief Inserts given value into %vector before specified iterator. + * @param position An iterator into the %vector. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Note that this kind of operation + * could be expensive for a %vector and if it is frequently + * used the user should consider using std::list. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %vector. + * @param position An iterator into the %vector. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of + * the given data before the location specified by @a position. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %vector. + * @param position An iterator into the %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range + * [first,last) into the %vector before the location specified + * by @a pos. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %vector by one. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the element, and that if the element is itself a pointer, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %vector accordingly. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %vector. + * @param x A %vector of the same element and allocator types. + * + * This exchanges the elements between two vectors in constant time. + * (Three pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(v1,v2) will feed to this function. + */ + void + swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() { erase(begin(), end()); } + + protected: + /** + * @if maint + * Memory expansion handler. Uses the member allocation function to + * obtain @a n bytes of memory, and then copies [first,last) into it. + * @endif + */ + template + pointer + _M_allocate_and_copy(size_type __n, + _ForwardIterator __first, _ForwardIterator __last) + { + pointer __result = this->_M_allocate(__n); + try + { + std::uninitialized_copy(__first, __last, __result); + return __result; + } + catch(...) + { + _M_deallocate(__result, __n); + __throw_exception_again; + } + } + + + // Internal constructor functions follow. + + // Called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) + { + this->_M_impl._M_start = _M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); + } + + // Called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // Called by the second initialize_dispatch above + template + void + _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // Called by the second initialize_dispatch above + template + void + _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = std::distance(__first, __last); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_copy(__first, __last, + this->_M_impl._M_start); + } + + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // Called by the second assign_dispatch above + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // Called by the second assign_dispatch above + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__val)); + } + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _InputIterator __first, + _InputIterator __last, __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert(__pos, __first, __last, _IterCategory()); + } + + // Called by the second insert_dispatch above + template + void + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // Called by the second insert_dispatch above + template + void + _M_range_insert(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // Called by insert(p,x) + void + _M_insert_aux(iterator __position, const value_type& __x); + }; + + + /** + * @brief Vector equality comparison. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff the size and elements of the vectors are equal. + * + * This is an equivalence relation. It is linear in the size of the + * vectors. Vectors are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { + return __x.size() == __y.size() && + std::equal(__x.begin(), __x.end(), __y.begin()); + } + + /** + * @brief Vector ordering relation. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * vectors. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + /// Based on operator== + template + inline bool + operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::vector::swap(). + template + inline void + swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _VECTOR_H */ diff --git a/src/include.new/c++/3.4/bits/stream_iterator.h b/src/include.new/c++/3.4/bits/stream_iterator.h new file mode 100644 index 0000000..fa11bd6 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stream_iterator.h @@ -0,0 +1,214 @@ +// Stream iterators + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file stream_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAM_ITERATOR_H +#define _STREAM_ITERATOR_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + /// Provides input iterator semantics for streams. + template, typename _Dist = ptrdiff_t> + class istream_iterator + : public iterator + { + public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + + private: + istream_type* _M_stream; + _Tp _M_value; + bool _M_ok; + + public: + /// Construct end of input stream iterator. + istream_iterator() + : _M_stream(0), _M_ok(false) {} + + /// Construct start of input stream iterator. + istream_iterator(istream_type& __s) + : _M_stream(&__s) + { _M_read(); } + + istream_iterator(const istream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_value(__obj._M_value), + _M_ok(__obj._M_ok) + { } + + const _Tp& + operator*() const + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_deref_istream) + ._M_iterator(*this)); + return _M_value; + } + + const _Tp* + operator->() const { return &(operator*()); } + + istream_iterator& + operator++() + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + _M_read(); + return *this; + } + + istream_iterator + operator++(int) + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + istream_iterator __tmp = *this; + _M_read(); + return __tmp; + } + + bool + _M_equal(const istream_iterator& __x) const + { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } + + private: + void + _M_read() + { + _M_ok = (_M_stream && *_M_stream) ? true : false; + if (_M_ok) + { + *_M_stream >> _M_value; + _M_ok = *_M_stream ? true : false; + } + } + }; + + /// Return true if x and y are both end or not end, or x and y are the same. + template + inline bool + operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return __x._M_equal(__y); } + + /// Return false if x and y are both end or not end, or x and y are the same. + template + inline bool + operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return !__x._M_equal(__y); } + + /** + * @brief Provides output iterator semantics for streams. + * + * This class provides an iterator to write to an ostream. The type Tp is + * the only type written by this iterator and there must be an + * operator<<(Tp) defined. + * + * @param Tp The type to write to the ostream. + * @param CharT The ostream char_type. + * @param Traits The ostream char_traits. + */ + template > + class ostream_iterator + : public iterator + { + public: + //@{ + /// Public typedef + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + private: + ostream_type* _M_stream; + const _CharT* _M_string; + + public: + /// Construct from an ostream. + ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} + + /** + * Construct from an ostream. + * + * The delimiter string @a c is written to the stream after every Tp + * written to the stream. The delimiter is not copied, and thus must + * not be destroyed while this iterator is in use. + * + * @param s Underlying ostream to write to. + * @param c CharT delimiter string to insert. + */ + ostream_iterator(ostream_type& __s, const _CharT* __c) + : _M_stream(&__s), _M_string(__c) { } + + /// Copy constructor. + ostream_iterator(const ostream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } + + /// Writes @a value to underlying ostream using operator<<. If + /// constructed with delimiter string, writes delimiter to ostream. + ostream_iterator& + operator=(const _Tp& __value) + { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__msg_output_ostream) + ._M_iterator(*this)); + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + + ostream_iterator& + operator*() + { return *this; } + + ostream_iterator& + operator++() + { return *this; } + + ostream_iterator& + operator++(int) + { return *this; } + }; +} // namespace std +#endif diff --git a/src/include.new/c++/3.4/bits/streambuf.tcc b/src/include.new/c++/3.4/bits/streambuf.tcc new file mode 100644 index 0000000..554d061 --- /dev/null +++ b/src/include.new/c++/3.4/bits/streambuf.tcc @@ -0,0 +1,163 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _STREAMBUF_TCC +#define _STREAMBUF_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsgetn(char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const size_t __buf_len = this->egptr() - this->gptr(); + if (__buf_len) + { + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(__s, this->gptr(), __len); + __ret += __len; + __s += __len; + this->gbump(__len); + } + + if (__ret < __n) + { + const int_type __c = this->uflow(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; + } + else + break; + } + } + return __ret; + } + + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsputn(const char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const size_t __buf_len = this->epptr() - this->pptr(); + if (__buf_len) + { + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(this->pptr(), __s, __len); + __ret += __len; + __s += __len; + this->pbump(__len); + } + + if (__ret < __n) + { + int_type __c = this->overflow(traits_type::to_int_type(*__s)); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + ++__ret; + ++__s; + } + else + break; + } + } + return __ret; + } + + // Conceivably, this could be used to implement buffer-to-buffer + // copies, if this was ever desired in an un-ambiguous way by the + // standard. If so, then checks for __ios being zero would be + // necessary. + template + streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + streamsize __ret = 0; + typename _Traits::int_type __c = __sbin->sgetc(); + while (!_Traits::eq_int_type(__c, _Traits::eof())) + { + const size_t __n = __sbin->egptr() - __sbin->gptr(); + if (__n > 1) + { + const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); + __sbin->gbump(__wrote); + __ret += __wrote; + if (__wrote < __n) + break; + __c = __sbin->underflow(); + } + else + { + __c = __sbout->sputc(_Traits::to_char_type(__c)); + if (_Traits::eq_int_type(__c, _Traits::eof())) + break; + ++__ret; + __c = __sbin->snextc(); + } + } + return __ret; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, basic_streambuf*); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, basic_streambuf*); +#endif +#endif +} // namespace std + +#endif diff --git a/src/include.new/c++/3.4/bits/streambuf_iterator.h b/src/include.new/c++/3.4/bits/streambuf_iterator.h new file mode 100644 index 0000000..9709335 --- /dev/null +++ b/src/include.new/c++/3.4/bits/streambuf_iterator.h @@ -0,0 +1,258 @@ +// Streambuf iterators + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file streambuf_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAMBUF_ITERATOR_H +#define _STREAMBUF_ITERATOR_H 1 + +#pragma GCC system_header + +#include +#include + +// NB: Should specialize copy, find algorithms for streambuf iterators. + +namespace std +{ + // 24.5.3 Template class istreambuf_iterator + /// Provides input iterator semantics for streambufs. + template + class istreambuf_iterator + : public iterator + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + //@} + + private: + // 24.5.3 istreambuf_iterator + // p 1 + // If the end of stream is reached (streambuf_type::sgetc() + // returns traits_type::eof()), the iterator becomes equal to + // the "end of stream" iterator value. + // NB: This implementation assumes the "end of stream" value + // is EOF, or -1. + mutable streambuf_type* _M_sbuf; + int_type _M_c; + + public: + /// Construct end of input stream iterator. + istreambuf_iterator() throw() + : _M_sbuf(0), _M_c(traits_type::eof()) { } + + /// Construct start of input stream iterator. + istreambuf_iterator(istream_type& __s) throw() + : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } + + /// Construct start of streambuf iterator. + istreambuf_iterator(streambuf_type* __s) throw() + : _M_sbuf(__s), _M_c(traits_type::eof()) { } + + /// Return the current character pointed to by iterator. This returns + /// streambuf.sgetc(). It cannot be assigned. NB: The result of + /// operator*() on an end of stream is undefined. + char_type + operator*() const + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + // Dereferencing a past-the-end istreambuf_iterator is a + // libstdc++ extension + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_deref_istreambuf) + ._M_iterator(*this)); +#endif + return traits_type::to_char_type(_M_get()); + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator& + operator++() + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + const int_type __eof = traits_type::eof(); + if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) + _M_sbuf = 0; + else + _M_c = __eof; + return *this; + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator + operator++(int) + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + + const int_type __eof = traits_type::eof(); + istreambuf_iterator __old = *this; + if (_M_sbuf + && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), + __eof)) + _M_sbuf = 0; + else + _M_c = __eof; + return __old; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 110 istreambuf_iterator::equal not const + // NB: there is also number 111 (NAD, Future) pending on this function. + /// Return true both iterators are end or both are not end. + bool + equal(const istreambuf_iterator& __b) const + { + const bool __thiseof = _M_at_eof(); + const bool __beof = __b._M_at_eof(); + return (__thiseof && __beof || (!__thiseof && !__beof)); + } + + private: + int_type + _M_get() const + { + const int_type __eof = traits_type::eof(); + int_type __ret = __eof; + if (_M_sbuf) + { + if (!traits_type::eq_int_type(_M_c, __eof)) + __ret = _M_c; + else if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), + __eof)) + _M_sbuf = 0; + } + return __ret; + } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } + }; + + template + inline bool + operator==(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return __a.equal(__b); } + + template + inline bool + operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return !__a.equal(__b); } + + /// Provides output iterator semantics for streambufs. + template + class ostreambuf_iterator + : public iterator + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + + public: + /// Construct output iterator from ostream. + ostreambuf_iterator(ostream_type& __s) throw () + : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } + + /// Construct output iterator from streambuf. + ostreambuf_iterator(streambuf_type* __s) throw () + : _M_sbuf(__s), _M_failed(!_M_sbuf) { } + + /// Write character to streambuf. Calls streambuf.sputc(). + ostreambuf_iterator& + operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) + _M_failed = true; + return *this; + } + + /// Return *this. + ostreambuf_iterator& + operator*() + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++(int) + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++() + { return *this; } + + /// Return true if previous operator=() failed. + bool + failed() const throw() + { return _M_failed; } + + ostreambuf_iterator& + _M_put(const _CharT* __ws, streamsize __len) + { + if (__builtin_expect(!_M_failed, true) + && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, + false)) + _M_failed = true; + return *this; + } + }; +} // namespace std +#endif diff --git a/src/include.new/c++/3.4/bits/stringfwd.h b/src/include.new/c++/3.4/bits/stringfwd.h new file mode 100644 index 0000000..99d3ce3 --- /dev/null +++ b/src/include.new/c++/3.4/bits/stringfwd.h @@ -0,0 +1,69 @@ +// String support -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file stringfwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STRINGFWD_H +#define _STRINGFWD_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + class allocator; + + template + struct char_traits; + + template, + typename _Alloc = allocator<_CharT> > + class basic_string; + + template<> struct char_traits; + + typedef basic_string string; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> struct char_traits; + + typedef basic_string wstring; +#endif +} // namespace std + +#endif // _STRINGFWD_H diff --git a/src/include.new/c++/3.4/bits/time_members.h b/src/include.new/c++/3.4/bits/time_members.h new file mode 100644 index 0000000..9801300 --- /dev/null +++ b/src/include.new/c++/3.4/bits/time_members.h @@ -0,0 +1,71 @@ +// std::time_get, std::time_put implementation, generic version -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.5.1.2 - time_get functions +// ISO C++ 14882: 22.2.5.3.2 - time_put functions +// + +// Written by Benjamin Kosnik + + template + __timepunct<_CharT>::__timepunct(size_t __refs) + : facet(__refs), _M_data(NULL) + { + _M_name_timepunct = _S_get_c_name(); + _M_initialize_timepunct(); + } + + template + __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) + : facet(__refs), _M_data(__cache) + { + _M_name_timepunct = _S_get_c_name(); + _M_initialize_timepunct(); + } + + template + __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, + size_t __refs) + : facet(__refs), _M_data(NULL) + { + char* __tmp = new char[std::strlen(__s) + 1]; + std::strcpy(__tmp, __s); + _M_name_timepunct = __tmp; + _M_initialize_timepunct(__cloc); + } + + template + __timepunct<_CharT>::~__timepunct() + { + if (_M_name_timepunct != _S_get_c_name()) + delete [] _M_name_timepunct; + delete _M_data; + _S_destroy_c_locale(_M_c_locale_timepunct); + } diff --git a/src/include.new/c++/3.4/bits/type_traits.h b/src/include.new/c++/3.4/bits/type_traits.h new file mode 100644 index 0000000..9b91e5c --- /dev/null +++ b/src/include.new/c++/3.4/bits/type_traits.h @@ -0,0 +1,405 @@ +// Type traits implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file type_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TYPE_TRAITS_H +#define _TYPE_TRAITS_H 1 + +#pragma GCC system_header + +#include + +/* +This header file provides a framework for allowing compile time dispatch +based on type attributes. This is useful when writing template code. +For example, when making a copy of an array of an unknown type, it helps +to know if the type has a trivial copy constructor or not, to help decide +if a memcpy can be used. + +The class template __type_traits provides a series of typedefs each of +which is either __true_type or __false_type. The argument to +__type_traits can be any type. The typedefs within this template will +attain their correct values by one of these means: + 1. The general instantiation contain conservative values which work + for all types. + 2. Specializations may be declared to make distinctions between types. + 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) + will automatically provide the appropriate specializations for all + types. + +EXAMPLE: + +//Copy an array of elements which have non-trivial copy constructors +template void + copy(_Tp* __source,_Tp* __destination,int __n,__false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template void + copy(_Tp* __source,_Tp* __destination,int __n,__true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template inline void copy(_Tp* __source,_Tp* __destination,int __n) { + copy(__source,__destination,__n, + typename __type_traits<_Tp>::has_trivial_copy_constructor()); +} +*/ + +struct __true_type {}; +struct __false_type {}; + +template + struct __type_traits + { + typedef __true_type this_dummy_member_must_be_first; + /* Do not remove this member. It informs a compiler which + automatically specializes __type_traits that this + __type_traits template is special. It just makes sure that + things work if an implementation is using a template + called __type_traits for something unrelated. */ + + /* The following restrictions should be observed for the sake of + compilers which automatically produce type specific specializations + of this class: + - You may reorder the members below if you wish + - You may remove any of the members below if you wish + - You must not rename members without making the corresponding + name change in the compiler + - Members you add will be treated like regular members unless + you add the appropriate support in the compiler. */ + + + typedef __false_type has_trivial_default_constructor; + typedef __false_type has_trivial_copy_constructor; + typedef __false_type has_trivial_assignment_operator; + typedef __false_type has_trivial_destructor; + typedef __false_type is_POD_type; + }; + + +// Provide some specializations. + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template + struct __type_traits<_Tp*> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template + struct _Is_integer + { + typedef __false_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template + struct _Is_normal_iterator + { + typedef __false_type _Normal; + }; + +// Forward declaration hack, should really include this from somewhere. +namespace __gnu_cxx +{ + template + class __normal_iterator; +} + +template + struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, + _Container> > + { + typedef __true_type _Normal; + }; + +#endif /* _TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/include.new/c++/3.4/bits/valarray_after.h b/src/include.new/c++/3.4/bits/valarray_after.h new file mode 100644 index 0000000..b74cab5 --- /dev/null +++ b/src/include.new/c++/3.4/bits/valarray_after.h @@ -0,0 +1,499 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_AFTER_H +#define _VALARRAY_AFTER_H 1 + +#pragma GCC system_header + +namespace std +{ + + // + // gslice_array closure. + // + template class _GBase { + public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray& _M_index; + }; + + template class _GBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray& __i) + : _M_array (__a), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Array<_Tp> _M_array; + const valarray& _M_index; + }; + + template struct _GClos<_Expr,_Dom> : _GBase<_Dom> { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} + }; + + template + struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray& __i) + : _Base (__a, __i) {} + }; + + // + // indirect_array closure + // + template class _IBase { + public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index (__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size() const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray& _M_index; + }; + + template struct _IClos<_Expr,_Dom> : _IBase<_Dom> { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} + }; + + template + struct _IClos<_ValArray,_Tp> : _IBase > { + typedef _IBase > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray& __i) + : _Base (__a, __i) {} + }; + + // + // class _Expr + // + template + class _Expr + { + public: + typedef _Tp value_type; + + _Expr(const _Clos&); + + const _Clos& operator()() const; + + value_type operator[](size_t) const; + valarray operator[](slice) const; + valarray operator[](const gslice&) const; + valarray operator[](const valarray&) const; + valarray operator[](const valarray&) const; + + _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type> + operator+() const; + + _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> + operator-() const; + + _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> + operator~() const; + + _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool> + operator!() const; + + size_t size() const; + value_type sum() const; + + valarray shift(int) const; + valarray cshift(int) const; + + value_type min() const; + value_type max() const; + + valarray apply(value_type (*)(const value_type&)) const; + valarray apply(value_type (*)(value_type)) const; + + private: + const _Clos _M_closure; + }; + + template + inline + _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} + + template + inline const _Clos& + _Expr<_Clos,_Tp>::operator()() const + { return _M_closure; } + + template + inline _Tp + _Expr<_Clos,_Tp>::operator[](size_t __i) const + { return _M_closure[__i]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](slice __s) const + { return _M_closure[__s]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const + { return _M_closure[__gs]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const valarray& __m) const + { return _M_closure[__m]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const valarray& __i) const + { return _M_closure[__i]; } + + template + inline size_t + _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::shift(int __n) const + { return valarray<_Tp>(_M_closure).shift(__n); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::cshift(int __n) const + { return valarray<_Tp>(_M_closure).cshift(__n); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + // XXX: replace this with a more robust summation algorithm. + template + inline _Tp + _Expr<_Clos,_Tp>::sum() const + { + size_t __n = _M_closure.size(); + if (__n == 0) + return _Tp(); + else + { + _Tp __s = _M_closure[--__n]; + while (__n != 0) + __s += _M_closure[--__n]; + return __s; + } + } + + template + inline _Tp + _Expr<_Clos, _Tp>::min() const + { return __valarray_min(_M_closure); } + + template + inline _Tp + _Expr<_Clos, _Tp>::max() const + { return __valarray_max(_M_closure); } + + template + inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> + _Expr<_Dom,_Tp>::operator!() const + { + typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure; + return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); + } + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \ + _Expr<_Dom,_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \ + } + + _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ + typename __fun<_Name, typename _Dom1::value_type>::result_type>\ + operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ + { \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \ + } \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__t, __v())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef typename __fun<_Name, _Tp>::result_type _Value; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) + _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) + _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) + _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(<, __less) + _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) + _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) + _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ + template \ + inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ + _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e())); \ + } \ + \ + template \ + inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ + _Name(const valarray<_Tp>& __v) \ + { \ + typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v)); \ + } + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ + template \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Dom1::value_type> \ + _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ + { \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ + return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +} // std:: + + +#endif /* _CPP_VALARRAY_AFTER_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/valarray_array.h b/src/include.new/c++/3.4/bits/valarray_array.h new file mode 100644 index 0000000..e18e8e8 --- /dev/null +++ b/src/include.new/c++/3.4/bits/valarray_array.h @@ -0,0 +1,625 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_ARRAY_H +#define _VALARRAY_ARRAY_H 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include + +namespace std +{ + // + // Helper functions on raw pointers + // + + // We get memory by the old fashion way + inline void* + __valarray_get_memory(size_t __n) + { return operator new(__n); } + + template + inline _Tp*__restrict__ + __valarray_get_storage(size_t __n) + { + return static_cast<_Tp*__restrict__> + (std::__valarray_get_memory(__n * sizeof(_Tp))); + } + + // Return memory to the system + inline void + __valarray_release_memory(void* __p) + { operator delete(__p); } + + // Turn a raw-memory into an array of _Tp filled with _Tp() + // This is required in 'valarray v(n);' + template + struct _Array_default_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { while (__b != __e) new(__b++) _Tp(); } + }; + + template + struct _Array_default_ctor<_Tp, true> + { + // For fundamental types, it suffices to say 'memset()' + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { std::memset(__b, 0, (__e - __b)*sizeof(_Tp)); } + }; + + template + inline void + __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e); + } + + // Turn a raw-memory into an array of _Tp filled with __t + // This is the required in valarray v(n, t). Also + // used in valarray<>::resize(). + template + struct _Array_init_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) new(__b++) _Tp(__t); } + }; + + template + struct _Array_init_ctor<_Tp, true> + { + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) *__b++ = __t; } + }; + + template + inline void + __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, + const _Tp __t) + { + _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __t); + } + + // + // copy-construct raw array [__o, *) from plain array [__b, __e) + // We can't just say 'memcpy()' + // + template + struct _Array_copy_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { while (__b != __e) new(__o++) _Tp(*__b++); } + }; + + template + struct _Array_copy_ctor<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } + }; + + template + inline void + __valarray_copy_construct(const _Tp* __restrict__ __b, + const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { + _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __o); + } + + // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] + template + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, + size_t __s, _Tp* __restrict__ __o) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) { *__o++ = *__a; __a += __s; } + else + while (__n--) { new(__o++) _Tp(*__a); __a += __s; } + } + + // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] + template + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __o, size_t __n) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) *__o++ = __a[*__i++]; + else + while (__n--) new (__o++) _Tp(__a[*__i++]); + } + + // Do the necessary cleanup when we're done with arrays. + template + inline void + __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + if (!__is_fundamental<_Tp>::_M_type) + while (__b != __e) { __b->~_Tp(); ++__b; } + } + + // Fill a plain array __a[<__n>] with __t + template + inline void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) + { while (__n--) *__a++ = __t; } + + // fill strided array __a[<__n-1 : __s>] with __t + template + inline void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) + { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } + + // fill indir ect array __a[__i[<__n>]] with __i + template + inline void + __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) + { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } + + // copy plain array __a[<__n>] in __b[<__n>] + // For non-fundamental types, it is wrong to say 'memcpy()' + template + struct _Array_copier + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { while (__n--) *__b++ = *__a++; } + }; + + template + struct _Array_copier<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { std::memcpy (__b, __a, __n * sizeof (_Tp)); } + }; + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) + { + _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__a, __n, __b); + } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) + { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) + { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, + _Tp* __restrict__ __dst, size_t __s2) + { + for (size_t __i = 0; __i < __n; ++__i) + __dst[__i * __s2] = __src [ __i * __s1]; + } + + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template + inline void + __valarray_copy (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) + { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template + inline void + __valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) + { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, + const size_t* __restrict__ __i, + _Tp* __restrict__ __dst, const size_t* __restrict__ __j) + { + for (size_t __k = 0; __k < __n; ++__k) + __dst[*__j++] = __src[*__i++]; + } + + // + // Compute the sum of elements in range [__f, __l) + // This is a naive algorithm. It suffers from cancelling. + // In the future try to specialize + // for _Tp = float, double, long double using a more accurate + // algorithm. + // + template + inline _Tp + __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(); + while (__f != __l) __r += *__f++; + return __r; + } + + // Compute the product of all elements in range [__f, __l) + template + inline _Tp + __valarray_product(const _Tp* __restrict__ __f, + const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(1); + while (__f != __l) __r = __r * *__f++; + return __r; + } + + // Compute the min/max of an array-expression + template + inline typename _Ta::value_type + __valarray_min(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t < __r) + __r = __t; + } + return __r; + } + + template + inline typename _Ta::value_type + __valarray_max(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t > __r) + __r = __t; + } + return __r; + } + + // + // Helper class _Array, first layer of valarray abstraction. + // All operations on valarray should be forwarded to this class + // whenever possible. -- gdr + // + + template + struct _Array + { + explicit _Array (size_t); + explicit _Array (_Tp* const __restrict__); + explicit _Array (const valarray<_Tp>&); + _Array (const _Tp* __restrict__, size_t); + + _Tp* begin () const; + + _Tp* const __restrict__ _M_data; + }; + + template + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __n, __t); } + + template + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __n, __s, __t); } + + template + inline void + __valarray_fill (_Array<_Tp> __a, _Array __i, + size_t __n, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __i._M_data, __n, __t); } + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __b._M_data); } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template + inline void + __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) + { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, + _Array<_Tp> __b, size_t __s2) + { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } + + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template + inline void + __valarray_copy(_Array<_Tp> __a, _Array __i, + _Array<_Tp> __b, size_t __n) + { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array __i) + { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template + inline void + __valarray_copy(_Array<_Tp> __src, size_t __n, _Array __i, + _Array<_Tp> __dst, _Array __j) + { + std::__valarray_copy(__src._M_data, __n, __i._M_data, + __dst._M_data, __j._M_data); + } + + template + inline + _Array<_Tp>::_Array (size_t __n) + : _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_default_construct(_M_data, _M_data + __n); } + + template + inline + _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} + + template + inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + + template + inline + _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) + : _M_data(__valarray_get_storage<_Tp>(__s)) + { std::__valarray_copy_construct(__b, __s, _M_data); } + + template + inline _Tp* + _Array<_Tp>::begin () const + { return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ +{ \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ + *__p _Op##= __t; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ +{ \ + _Tp* __p = __a._M_data; \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + _Tp* __q (__b._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __i) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + size_t* __j (__i._M_data); \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __m) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ + while (! *ok) { \ + ++ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + bool* ok(__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ +} + + _DEFINE_ARRAY_FUNCTION(+, __plus) + _DEFINE_ARRAY_FUNCTION(-, __minus) + _DEFINE_ARRAY_FUNCTION(*, __multiplies) + _DEFINE_ARRAY_FUNCTION(/, __divides) + _DEFINE_ARRAY_FUNCTION(%, __modulus) + _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) + _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) + _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) + _DEFINE_ARRAY_FUNCTION(<<, __shift_left) + _DEFINE_ARRAY_FUNCTION(>>, __shift_right) + +#undef _DEFINE_VALARRAY_FUNCTION +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif /* _ARRAY_H */ diff --git a/src/include.new/c++/3.4/bits/valarray_array.tcc b/src/include.new/c++/3.4/bits/valarray_array.tcc new file mode 100644 index 0000000..fac5de6 --- /dev/null +++ b/src/include.new/c++/3.4/bits/valarray_array.tcc @@ -0,0 +1,240 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef _VALARRAY_ARRAY_TCC +#define _VALARRAY_ARRAY_TCC 1 + +namespace std +{ + template + void + __valarray_fill(_Array<_Tp> __a, size_t __n, _Array __m, + const _Tp& __t) + { + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p) + { + while (!*__ok) + { + ++__ok; + ++__p; + } + *__p = __t; + } + } + + // Copy n elements of a into consecutive elements of b. When m is + // false, the corresponding element of a is skipped. m must contain + // at least n true elements. a must contain at least n elements and + // enough elements to match up with m through the nth true element + // of m. I.e. if n is 10, m has 15 elements with 5 false followed + // by 10 true, a must have 15 elements. + template + void + __valarray_copy(_Array<_Tp> __a, _Array __m, _Array<_Tp> __b, + size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; + ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__q = *__p; + } + } + + // Copy n consecutive elements from a into elements of b. Elements + // of b are skipped if the corresponding element of m is false. m + // must contain at least n true elements. b must have at least as + // many elements as the index of the nth true element of m. I.e. if + // m has 15 elements with 5 false followed by 10 true, b must have + // at least 15 elements. + template + void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array __m) + { + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p = __a._M_data; __p < __a._M_data+__n; + ++__p, ++__ok, ++__q) + { + while (! *__ok) + { + ++__ok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n elements from a into elements of b. Elements of a are + // skipped if the corresponding element of m is false. Elements of + // b are skipped if the corresponding element of k is false. m and + // k must contain at least n true elements. a and b must have at + // least as many elements as the index of the nth true element of m. + template + void + __valarray_copy(_Array<_Tp> __a, _Array __m, size_t __n, + _Array<_Tp> __b, _Array __k) + { + _Tp* __p (__a._M_data); + _Tp* __q (__b._M_data); + bool* __srcok (__m._M_data); + bool* __dstok (__k._M_data); + for (size_t __i = 0; __i < __n; + ++__srcok, ++__p, ++__dstok, ++__q, ++__i) + { + while (! *__srcok) + { + ++__srcok; + ++__p; + } + while (! *__dstok) + { + ++__dstok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n consecutive elements of e into consecutive elements of a. + // I.e. a[i] = e[i]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a using stride + // s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, __p += __s) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a indexed by + // contents of i. I.e., a[i[0]] = e[0]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __i) + { + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j) + __a._M_data[*__j] = __e[__k]; + } + + // Copy n elements of e indexed by contents of f into elements of a + // indexed by contents of i. I.e., a[i[0]] = e[f[0]]. + template + void + __valarray_copy(_Array<_Tp> __e, _Array __f, + size_t __n, + _Array<_Tp> __a, _Array __i) + { + size_t* __g (__f._M_data); + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) + __a._M_data[*__j] = __e._M_data[*__g]; + } + + // Copy n consecutive elements of e into elements of a. Elements of + // a are skipped if the corresponding element of m is false. m must + // have at least n true elements and a must have at least as many + // elements as the index of the nth true element of m. I.e. if m + // has 5 false followed by 10 true elements and n == 10, a must have + // at least 15 elements. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __m) + { + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } + } + + + template + void + __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + new (__p) _Tp(__e[__i]); + } + + + template + void + __valarray_copy_construct(_Array<_Tp> __a, _Array __m, + _Array<_Tp> __b, size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + new (__q) _Tp(*__p); + } + } +} // namespace std + +#endif /* _VALARRAY_ARRAY_TCC */ diff --git a/src/include.new/c++/3.4/bits/valarray_before.h b/src/include.new/c++/3.4/bits/valarray_before.h new file mode 100644 index 0000000..263ac2f --- /dev/null +++ b/src/include.new/c++/3.4/bits/valarray_before.h @@ -0,0 +1,701 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_BEFORE_H +#define _VALARRAY_BEFORE_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + // + // Implementing a loosened valarray return value is tricky. + // First we need to meet 26.3.1/3: we should not add more than + // two levels of template nesting. Therefore we resort to template + // template to "flatten" loosened return value types. + // At some point we use partial specialization to remove one level + // template nesting due to _Expr<> + // + + // This class is NOT defined. It doesn't need to. + template class _Constant; + + // Implementations of unary functions applied to valarray<>s. + // I use hard-coded object functions here instead of a generic + // approach like pointers to function: + // 1) correctness: some functions take references, others values. + // we can't deduce the correct type afterwards. + // 2) efficiency -- object functions can be easily inlined + // 3) be Koenig-lookup-friendly + + struct __abs + { + template + _Tp operator()(const _Tp& __t) const { return abs(__t); } + }; + + struct __cos + { + template + _Tp operator()(const _Tp& __t) const { return cos(__t); } + }; + + struct __acos + { + template + _Tp operator()(const _Tp& __t) const { return acos(__t); } + }; + + struct __cosh + { + template + _Tp operator()(const _Tp& __t) const { return cosh(__t); } + }; + + struct __sin + { + template + _Tp operator()(const _Tp& __t) const { return sin(__t); } + }; + + struct __asin + { + template + _Tp operator()(const _Tp& __t) const { return asin(__t); } + }; + + struct __sinh + { + template + _Tp operator()(const _Tp& __t) const { return sinh(__t); } + }; + + struct __tan + { + template + _Tp operator()(const _Tp& __t) const { return tan(__t); } + }; + + struct __atan + { + template + _Tp operator()(const _Tp& __t) const { return atan(__t); } + }; + + struct __tanh + { + template + _Tp operator()(const _Tp& __t) const { return tanh(__t); } + }; + + struct __exp + { + template + _Tp operator()(const _Tp& __t) const { return exp(__t); } + }; + + struct __log + { + template + _Tp operator()(const _Tp& __t) const { return log(__t); } + }; + + struct __log10 + { + template + _Tp operator()(const _Tp& __t) const { return log10(__t); } + }; + + struct __sqrt + { + template + _Tp operator()(const _Tp& __t) const { return sqrt(__t); } + }; + + // In the past, we used to tailor operator applications semantics + // to the specialization of standard function objects (i.e. plus<>, etc.) + // That is incorrect. Therefore we provide our own surrogates. + + struct __unary_plus + { + template + _Tp operator()(const _Tp& __t) const { return +__t; } + }; + + struct __negate + { + template + _Tp operator()(const _Tp& __t) const { return -__t; } + }; + + struct __bitwise_not + { + template + _Tp operator()(const _Tp& __t) const { return ~__t; } + }; + + struct __plus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + struct __minus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + struct __multiplies + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + struct __divides + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + struct __modulus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + struct __bitwise_xor + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; + + struct __bitwise_and + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + struct __bitwise_or + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + struct __shift_left + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x << __y; } + }; + + struct __shift_right + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x >> __y; } + }; + + struct __logical_and + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + struct __logical_or + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + struct __logical_not + { + template + bool operator()(const _Tp& __x) const { return !__x; } + }; + + struct __equal_to + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + struct __not_equal_to + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + struct __less + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + struct __greater + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + struct __less_equal + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + + struct __greater_equal + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + // The few binary functions we miss. + struct __atan2 + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return atan2(__x, __y); } + }; + + struct __pow + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return pow(__x, __y); } + }; + + + // We need these bits in order to recover the return type of + // some functions/operators now that we're no longer using + // function templates. + template + struct __fun + { + typedef _Tp result_type; + }; + + // several specializations for relational operators. + template + struct __fun<__logical_not, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__logical_and, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__logical_or, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__less, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__greater, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__less_equal, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__greater_equal, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__equal_to, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__not_equal_to, _Tp> + { + typedef bool result_type; + }; + + // + // Apply function taking a value/const reference closure + // + + template + class _FunBase + { + public: + typedef typename _Dom::value_type value_type; + + _FunBase(const _Dom& __e, value_type __f(_Arg)) + : _M_expr(__e), _M_func(__f) {} + + value_type operator[](size_t __i) const + { return _M_func (_M_expr[__i]); } + + size_t size() const { return _M_expr.size ();} + + private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); + }; + + template + struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> + { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} + }; + + template + struct _ValFunClos<_ValArray,_Tp> : _FunBase, _Tp> + { + typedef _FunBase, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} + }; + + template + struct _RefFunClos<_Expr,_Dom> : + _FunBase<_Dom, const typename _Dom::value_type&> + { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) + : _Base(__e, __f) {} + }; + + template + struct _RefFunClos<_ValArray,_Tp> : _FunBase, const _Tp&> + { + typedef _FunBase, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base(__v, __f) {} + }; + + // + // Unary expression closure. + // + + template + class _UnBase + { + public: + typedef typename _Arg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _UnBase(const _Arg& __e) : _M_expr(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr[__i]); } + + size_t size() const { return _M_expr.size(); } + + private: + const _Arg& _M_expr; + }; + + template + struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> + { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + template + struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > + { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + + // + // Binary expression closure. + // + + template + class _BinBase + { + public: + typedef typename _FirstArg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1(__e1), _M_expr2(__e2) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; + }; + + + template + class _BinBase2 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase2(const _Clos& __e, const _Vt& __t) + : _M_expr1(__e), _M_expr2(__t) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; + }; + + template + class _BinBase1 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase1(const _Vt& __t, const _Clos& __e) + : _M_expr1(__t), _M_expr2(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1, _M_expr2[__i]); } + + size_t size() const { return _M_expr2.size(); } + + private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; + }; + + template + struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> + { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > + { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base(__v, __w) {} + }; + + template + struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray > + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinBase<_Oper,valarray,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) + : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > + { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} + }; + + template + struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > + { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} + }; + + + // + // slice_array closure. + // + template class _SBase { + public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + size_t size() const { return _M_slice.size (); } + + private: + const _Dom& _M_expr; + const slice& _M_slice; + }; + + template class _SBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + size_t size() const { return _M_size; } + + private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; + }; + + template struct _SClos<_Expr,_Dom> : _SBase<_Dom> { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} + }; + + template + struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} + }; + +} // std:: + + +#endif /* _CPP_VALARRAY_BEFORE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/src/include.new/c++/3.4/bits/vector.tcc b/src/include.new/c++/3.4/bits/vector.tcc new file mode 100644 index 0000000..786afab --- /dev/null +++ b/src/include.new/c++/3.4/bits/vector.tcc @@ -0,0 +1,414 @@ +// Vector implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file vector.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_TCC +#define _VECTOR_TCC 1 + +namespace _GLIBCXX_STD +{ + template + void + vector<_Tp,_Alloc>:: + reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + const size_type __old_size = size(); + pointer __tmp = _M_allocate_and_copy(__n, + this->_M_impl._M_start, + this->_M_impl._M_finish); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + insert(iterator __position, const value_type& __x) + { + size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) + { + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); + return __position; + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + erase(iterator __first, iterator __last) + { + iterator __i(std::copy(__last, end(), __first)); + std::_Destroy(__i, end()); + this->_M_impl._M_finish = this->_M_impl._M_finish - (__last - __first); + return __first; + } + + template + vector<_Tp,_Alloc>& + vector<_Tp,_Alloc>:: + operator=(const vector<_Tp,_Alloc>& __x) + { + if (&__x != this) + { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) + { + pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; + } + else if (size() >= __xlen) + { + iterator __i(std::copy(__x.begin(), __x.end(), begin())); + std::_Destroy(__i, end()); + } + else + { + std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start); + std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_impl._M_finish); + } + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; + } + return *this; + } + + template + void + vector<_Tp,_Alloc>:: + _M_fill_assign(size_t __n, const value_type& __val) + { + if (__n > capacity()) + { + vector __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) + { + std::fill(begin(), end(), __val); + this->_M_impl._M_finish + = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); + } + + template template + void + vector<_Tp,_Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag) + { + iterator __cur(begin()); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template template + void + vector<_Tp,_Alloc>:: + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + size_type __len = std::distance(__first, __last); + + if (__len > capacity()) + { + pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len; + } + else if (size() >= __len) + { + iterator __new_finish(std::copy(__first, __last, this->_M_impl._M_start)); + std::_Destroy(__new_finish, end()); + this->_M_impl._M_finish = __new_finish.base(); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + } + } + + template + void + vector<_Tp,_Alloc>:: + _M_insert_aux(iterator __position, const _Tp& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1)); + ++this->_M_impl._M_finish; + _Tp __x_copy = __x; + std::copy_backward(__position, + iterator(this->_M_impl._M_finish-2), + iterator(this->_M_impl._M_finish-1)); + *__position = __x_copy; + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, + __new_start); + std::_Construct(__new_finish.base(), __x); + ++__new_finish; + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(),__len); + __throw_exception_again; + } + std::_Destroy(begin(), end()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + + template + void + vector<_Tp,_Alloc>:: + _M_fill_insert(iterator __position, size_type __n, const value_type& __x) + { + if (__n != 0) + { + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) + { + value_type __x_copy = __x; + const size_type __elems_after = end() - __position; + iterator __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::fill(__position, __position + __n, __x_copy); + } + else + { + std::uninitialized_fill_n(this->_M_impl._M_finish, + __n - __elems_after, + __x_copy); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::fill(__position, __old_finish, __x_copy); + } + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(begin(), __position, + __new_start); + __new_finish = std::uninitialized_fill_n(__new_finish, __n, __x); + __new_finish = std::uninitialized_copy(__position, end(), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(),__len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + } + + template template + void + vector<_Tp,_Alloc>:: + _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + for ( ; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template template + void + vector<_Tp,_Alloc>:: + _M_range_insert(iterator __position,_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) + { + const size_type __elems_after = end() - __position; + iterator __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::copy(__first, __last, __position); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elems_after); + std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::copy(__first, __mid, __position); + } + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, __new_start); + __new_finish = std::uninitialized_copy(__first, __last, + __new_finish); + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(), __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + } +} // namespace std + +#endif /* _VECTOR_TCC */ diff --git a/src/include.new/c++/3.4/bitset b/src/include.new/c++/3.4/bitset new file mode 100644 index 0000000..01e3f90 --- /dev/null +++ b/src/include.new/c++/3.4/bitset @@ -0,0 +1,1229 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file bitset + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_BITSET +#define _GLIBCXX_BITSET 1 + +#pragma GCC system_header + +#include // For size_t +#include // For memset +#include // For numeric_limits +#include +#include // For invalid_argument, out_of_range, + // overflow_error +#include // For ostream (operator<<) +#include // For istream (operator>>) + +#define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits::digits +#define _GLIBCXX_BITSET_WORDS(__n) \ + ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * Base class, general case. It is a class inveriant that _Nw will be + * nonnegative. + * + * See documentation for bitset. + * @endif + */ + template + struct _Base_bitset + { + typedef unsigned long _WordT; + + /// 0 is the least significant word. + _WordT _M_w[_Nw]; + + _Base_bitset() { _M_do_reset(); } + _Base_bitset(unsigned long __val) + { + _M_do_reset(); + _M_w[0] = __val; + } + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t __pos) + { return _M_w[_S_whichword(__pos)]; } + + _WordT + _M_getword(size_t __pos) const + { return _M_w[_S_whichword(__pos)]; } + + _WordT& + _M_hiword() { return _M_w[_Nw - 1]; } + + _WordT + _M_hiword() const { return _M_w[_Nw - 1]; } + + void + _M_do_and(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] &= __x._M_w[__i]; + } + + void + _M_do_or(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] |= __x._M_w[__i]; + } + + void + _M_do_xor(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] ^= __x._M_w[__i]; + } + + void + _M_do_left_shift(size_t __shift); + + void + _M_do_right_shift(size_t __shift); + + void + _M_do_flip() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~_M_w[__i]; + } + + void + _M_do_set() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~static_cast<_WordT>(0); + } + + void + _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); } + + bool + _M_is_equal(const _Base_bitset<_Nw>& __x) const + { + for (size_t __i = 0; __i < _Nw; ++__i) + { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool + _M_is_any() const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + if (_M_w[__i] != static_cast<_WordT>(0)) + return true; + } + return false; + } + + size_t + _M_do_count() const + { + size_t __result = 0; + for (size_t __i = 0; __i < _Nw; __i++) + __result += __builtin_popcountl(_M_w[__i]); + return __result; + } + + unsigned long + _M_do_to_ulong() const; + + // find first "on" bit + size_t + _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const; + }; + + // Definitions of non-inline functions from _Base_bitset. + template + void + _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + + if (__offset == 0) + for (size_t __n = _Nw - 1; __n >= __wshift; --__n) + _M_w[__n] = _M_w[__n - __wshift]; + else + { + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + for (size_t __n = _Nw - 1; __n > __wshift; --__n) + _M_w[__n] = (_M_w[__n - __wshift] << __offset) | + (_M_w[__n - __wshift - 1] >> __sub_offset); + _M_w[__wshift] = _M_w[0] << __offset; + } + + std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); + } + } + + template + void + _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __limit = _Nw - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + _M_w[__n] = _M_w[__n + __wshift]; + else + { + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + for (size_t __n = 0; __n < __limit; ++__n) + _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | + (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + } + + std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); + } + } + + template + unsigned long + _Base_bitset<_Nw>::_M_do_to_ulong() const + { + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); + return _M_w[0]; + } + + template + size_t + _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + _WordT __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + } + // not found, so return an indication of failure. + return __not_found; + } + + template + size_t + _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const + { + // make bound inclusive + ++__prev; + + // check out of bounds + if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + + // check subsequent words + __i++; + for ( ; __i < _Nw; __i++ ) + { + __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + } + // not found, so return an indication of failure. + return __not_found; + } // end _M_do_find_next + + + /** + * @if maint + * Base class, specialization for a single word. + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<1> + { + typedef unsigned long _WordT; + _WordT _M_w; + + _Base_bitset( void ) : _M_w(0) {} + _Base_bitset(unsigned long __val) : _M_w(__val) {} + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t) { return _M_w; } + + _WordT + _M_getword(size_t) const { return _M_w; } + + _WordT& + _M_hiword() { return _M_w; } + + _WordT + _M_hiword() const { return _M_w; } + + void + _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; } + + void + _M_do_or(const _Base_bitset<1>& __x) { _M_w |= __x._M_w; } + + void + _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; } + + void + _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + + void + _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + + void + _M_do_flip() { _M_w = ~_M_w; } + + void + _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + + void + _M_do_reset() { _M_w = 0; } + + bool + _M_is_equal(const _Base_bitset<1>& __x) const + { return _M_w == __x._M_w; } + + bool + _M_is_any() const { return _M_w != 0; } + + size_t + _M_do_count() const { return __builtin_popcountl(_M_w); } + + unsigned long + _M_do_to_ulong() const { return _M_w; } + + size_t + _M_do_find_first(size_t __not_found) const + { + if (_M_w != 0) + return __builtin_ctzl(_M_w); + else + return __not_found; + } + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const + { + ++__prev; + if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) + return __not_found; + + _WordT __x = _M_w >> __prev; + if (__x != 0) + return __builtin_ctzl(__x) + __prev; + else + return __not_found; + } + }; + + + /** + * @if maint + * Base class, specialization for no storage (zero-length %bitset). + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<0> + { + typedef unsigned long _WordT; + + _Base_bitset() {} + _Base_bitset(unsigned long) {} + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + // This would normally give access to the data. The bounds-checking + // in the bitset class will prevent the user from getting this far, + // but (1) it must still return an lvalue to compile, and (2) the + // user might call _Unchecked_set directly, in which case this /needs/ + // to fail. Let's not penalize zero-length users unless they actually + // make an unchecked call; all the memory ugliness is therefore + // localized to this single should-never-get-this-far function. + _WordT& + _M_getword(size_t) const + { + __throw_out_of_range(__N("_Base_bitset::_M_getword")); + return *new _WordT; + } + + _WordT + _M_hiword() const { return 0; } + + void + _M_do_and(const _Base_bitset<0>&) { } + + void + _M_do_or(const _Base_bitset<0>&) { } + + void + _M_do_xor(const _Base_bitset<0>&) { } + + void + _M_do_left_shift(size_t) { } + + void + _M_do_right_shift(size_t) { } + + void + _M_do_flip() { } + + void + _M_do_set() { } + + void + _M_do_reset() { } + + // Are all empty bitsets equal to each other? Are they equal to + // themselves? How to compare a thing which has no state? What is + // the sound of one zero-length bitset clapping? + bool + _M_is_equal(const _Base_bitset<0>&) const { return true; } + + bool + _M_is_any() const { return false; } + + size_t + _M_do_count() const { return 0; } + + unsigned long + _M_do_to_ulong() const { return 0; } + + // Normally "not found" is the size, but that could also be + // misinterpreted as an index in this corner case. Oh well. + size_t + _M_do_find_first(size_t) const { return 0; } + + size_t + _M_do_find_next(size_t, size_t) const { return 0; } + }; + + + // Helper class to zero out the unused high-order bits in the highest word. + template + struct _Sanitize + { + static void _S_do_sanitize(unsigned long& __val) + { __val &= ~((~static_cast(0)) << _Extrabits); } + }; + + template<> + struct _Sanitize<0> + { static void _S_do_sanitize(unsigned long) { } }; + + + /** + * @brief The %bitset class represents a @e fixed-size sequence of bits. + * + * @ingroup Containers + * + * (Note that %bitset does @e not meet the formal requirements of a + * container. Mainly, it lacks iterators.) + * + * The template argument, @a Nb, may be any non-negative number, + * specifying the number of bits (e.g., "0", "12", "1024*1024"). + * + * In the general unoptimized case, storage is allocated in word-sized + * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B + * words will be used for storage. B - Nb%B bits are unused. (They are + * the high-order bits in the highest word.) It is a class invariant + * that those unused bits are always zero. + * + * If you think of %bitset as "a simple array of bits," be aware that + * your mental picture is reversed: a %bitset behaves the same way as + * bits in integers do, with the bit at index 0 in the "least significant + * / right-hand" position, and the bit at index Nb-1 in the "most + * significant / left-hand" position. Thus, unlike other containers, a + * %bitset's index "counts from right to left," to put it very loosely. + * + * This behavior is preserved when translating to and from strings. For + * example, the first line of the following program probably prints + * "b('a') is 0001100001" on a modern ASCII system. + * + * @code + * #include + * #include + * #include + * + * using namespace std; + * + * int main() + * { + * long a = 'a'; + * bitset<10> b(a); + * + * cout << "b('a') is " << b << endl; + * + * ostringstream s; + * s << b; + * string str = s.str(); + * cout << "index 3 in the string is " << str[3] << " but\n" + * << "index 3 in the bitset is " << b[3] << endl; + * } + * @endcode + * + * Also see http://gcc.gnu.org/onlinedocs/libstdc++/ext/sgiexts.html#ch23 + * for a description of extensions. + * + * @if maint + * Most of the actual code isn't contained in %bitset<> itself, but in the + * base class _Base_bitset. The base class works with whole words, not with + * individual bits. This allows us to specialize _Base_bitset for the + * important special case where the %bitset is only a single word. + * + * Extra confusion can result due to the fact that the storage for + * _Base_bitset @e is a regular array, and is indexed as such. This is + * carefully encapsulated. + * @endif + */ + template + class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> + { + private: + typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; + typedef unsigned long _WordT; + + void + _M_do_sanitize() + { + _Sanitize<_Nb%_GLIBCXX_BITSET_BITS_PER_WORD>:: + _S_do_sanitize(this->_M_hiword()); + } + + public: + /** + * This encapsulates the concept of a single bit. An instance of this + * class is a proxy for an actual bit; this way the individual bit + * operations are done as faster word-size bitwise instructions. + * + * Most users will never need to use this class directly; conversions + * to and from bool are automatic and should be transparent. Overloaded + * operators help to preserve the illusion. + * + * (On a typical system, this "bit %reference" is 64 times the size of + * an actual bit. Ha.) + */ + class reference + { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + public: + reference(bitset& __b, size_t __pos) + { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _Base::_S_whichbit(__pos); + } + + ~reference() { } + + // For b[i] = __x; + reference& + operator=(bool __x) + { + if ( __x ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // For b[i] = b[__j]; + reference& + operator=(const reference& __j) + { + if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // Flips the bit + bool + operator~() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } + + // For __x = b[i]; + operator bool() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + + // For b[i].flip(); + reference& + flip() + { + *_M_wp ^= _Base::_S_maskbit(_M_bpos); + return *this; + } + }; + friend class reference; + + // 23.3.5.1 constructors: + /// All bits set to zero. + bitset() { } + + /// Initial bits bitwise-copied from a single word (others set to zero). + bitset(unsigned long __val) : _Base(__val) + { _M_do_sanitize(); } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use; defaults + * to zero. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template + explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position = 0) : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, + basic_string<_CharT, _Traits, _Alloc>::npos); + } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use. + * @param n The number of characters to copy. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template + bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position, size_t __n) : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, __n); + } + + // 23.3.5.2 bitset operations: + //@{ + /** + * @brief Operations on bitsets. + * @param rhs A same-sized bitset. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + this->_M_do_and(__rhs); + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + this->_M_do_or(__rhs); + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + this->_M_do_xor(__rhs); + return *this; + } + //@} + + //@{ + /** + * @brief Operations on bitsets. + * @param position The number of places to shift. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator<<=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_left_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_right_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + //@} + + //@{ + /** + * These versions of single-bit set, reset, flip, and test are + * extensions from the SGI version. They do no range checking. + * @ingroup SGIextensions + */ + bitset<_Nb>& + _Unchecked_set(size_t __pos) + { + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_set(size_t __pos, int __val) + { + if (__val) + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + else + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_reset(size_t __pos) + { + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_flip(size_t __pos) + { + this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); + return *this; + } + + bool + _Unchecked_test(size_t __pos) const + { + return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) + != static_cast<_WordT>(0); + } + //@} + + // Set, reset, and flip. + /** + * @brief Sets every bit to true. + */ + bitset<_Nb>& + set() + { + this->_M_do_set(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Sets a given bit to a particular value. + * @param position The index of the bit. + * @param val Either true or false, defaults to true. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + set(size_t __position, bool __val = true) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::set")); + return _Unchecked_set(__position, __val); + } + + /** + * @brief Sets every bit to false. + */ + bitset<_Nb>& + reset() + { + this->_M_do_reset(); + return *this; + } + + /** + * @brief Sets a given bit to false. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + * + * Same as writing @c set(pos,false). + */ + bitset<_Nb>& + reset(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::reset")); + return _Unchecked_reset(__position); + } + + /** + * @brief Toggles every bit to its opposite value. + */ + bitset<_Nb>& + flip() + { + this->_M_do_flip(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Toggles a given bit to its opposite value. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + flip(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::flip")); + return _Unchecked_flip(__position); + } + + /// See the no-argument flip(). + bitset<_Nb> + operator~() const { return bitset<_Nb>(*this).flip(); } + + //@{ + /** + * @brief Array-indexing support. + * @param position Index into the %bitset. + * @return A bool for a 'const %bitset'. For non-const bitsets, an + * instance of the reference proxy class. + * @note These operators do no range checking and throw no exceptions, + * as required by DR 11 to the standard. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already + * resolves DR 11 (items 1 and 2), but does not do the range-checking + * required by that DR's resolution. -pme + * The DR has since been changed: range-checking is a precondition + * (users' responsibility), and these functions must not throw. -pme + * @endif + */ + reference + operator[](size_t __position) { return reference(*this,__position); } + + bool + operator[](size_t __position) const { return _Unchecked_test(__position); } + //@} + + /** + * @brief Retuns a numerical interpretation of the %bitset. + * @return The integral equivalent of the bits. + * @throw std::overflow_error If there are too many bits to be + * represented in an @c unsigned @c long. + */ + unsigned long + to_ulong() const { return this->_M_do_to_ulong(); } + + /** + * @brief Retuns a character interpretation of the %bitset. + * @return The string equivalent of the bits. + * + * Note the ordering of the bits: decreasing character positions + * correspond to increasing bit positions (see the main class notes for + * an example). + * + * Also note that you must specify the string's template parameters + * explicitly. Given a bitset @c bs and a string @s: + * @code + * s = bs.to_string,allocator >(); + * @endcode + */ + template + basic_string<_CharT, _Traits, _Alloc> + to_string() const + { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } + + // Helper functions for string operations. + template + void + _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, size_t); + + template + void + _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; + + /// Returns the number of bits which are set. + size_t + count() const { return this->_M_do_count(); } + + /// Returns the total number of bits. + size_t + size() const { return _Nb; } + + //@{ + /// These comparisons for equality/inequality are, well, @e bitwise. + bool + operator==(const bitset<_Nb>& __rhs) const + { return this->_M_is_equal(__rhs); } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return !this->_M_is_equal(__rhs); } + //@} + + /** + * @brief Tests the value of a bit. + * @param position The index of a bit. + * @return The value at @a pos. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bool + test(size_t __position) const + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::test")); + return _Unchecked_test(__position); + } + + /** + * @brief Tests whether any of the bits are on. + * @return True if at least one bit is set. + */ + bool + any() const { return this->_M_is_any(); } + + /** + * @brief Tests whether any of the bits are on. + * @return True if none of the bits are set. + */ + bool + none() const { return !this->_M_is_any(); } + + //@{ + /// Self-explanatory. + bitset<_Nb> + operator<<(size_t __position) const + { return bitset<_Nb>(*this) <<= __position; } + + bitset<_Nb> + operator>>(size_t __position) const + { return bitset<_Nb>(*this) >>= __position; } + //@} + + /** + * @brief Finds the index of the first "on" bit. + * @return The index of the first bit set, or size() if not found. + * @ingroup SGIextensions + * @sa _Find_next + */ + size_t + _Find_first() const + { return this->_M_do_find_first(_Nb); } + + /** + * @brief Finds the index of the next "on" bit after prev. + * @return The index of the next bit set, or size() if not found. + * @param prev Where to start searching. + * @ingroup SGIextensions + * @sa _Find_first + */ + size_t + _Find_next(size_t __prev ) const + { return this->_M_do_find_next(__prev, _Nb); } + }; + + // Definitions of non-inline member functions. + template + template + void + bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT, _Traits, + _Alloc>& __s, size_t __pos, size_t __n) + { + reset(); + const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) + { + switch(__s[__pos + __nbits - __i - 1]) + { + case '0': + break; + case '1': + set(__i); + break; + default: + __throw_invalid_argument(__N("bitset::_M_copy_from_string")); + } + } + } + + template + template + void + bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, + _Alloc>& __s) const + { + __s.assign(_Nb, '0'); + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; + } + + // 23.3.5.3 bitset operations: + //@{ + /** + * @brief Global bitwise operations on bitsets. + * @param x A bitset. + * @param y A bitset of the same size as @a x. + * @return A new bitset. + * + * These should be self-explanatory. + */ + template + inline bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result &= __y; + return __result; + } + + template + inline bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result |= __y; + return __result; + } + + template + inline bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result ^= __y; + return __result; + } + //@} + + //@{ + /** + * @brief Global I/O operators for bitsets. + * + * Direct I/O between streams and bitsets is supported. Output is + * straightforward. Input will skip whitespace, only accept '0' and '1' + * characters, and will only extract as many digits as the %bitset will + * hold. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { + typedef typename _Traits::char_type char_type; + basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(_Nb); + + ios_base::iostate __state = ios_base::goodbit; + typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); + if (__sentry) + { + try + { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 303. Bitset input operator underspecified + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + for (size_t __i = 0; __i < _Nb; ++__i) + { + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) + { + __state |= ios_base::eofbit; + break; + } + else + { + char_type __c2 = _Traits::to_char_type(__c1); + if (__c2 == __zero) + __tmp.push_back('0'); + else if (__c2 == __one) + __tmp.push_back('1'); + else if (_Traits::eq_int_type(__buf->sputbackc(__c2), + __eof)) + { + __state |= ios_base::failbit; + break; + } + } + } + } + catch(...) + { __is._M_setstate(ios_base::badbit); } + } + + if (__tmp.empty() && _Nb) + __state |= ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast(0), _Nb); + if (__state) + __is.setstate(__state); + return __is; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) + { + basic_string<_CharT, _Traits> __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; + } + //@} +} // namespace std + +#undef _GLIBCXX_BITSET_WORDS +#undef _GLIBCXX_BITSET_BITS_PER_WORD + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_BITSET */ diff --git a/src/include.new/c++/3.4/cassert b/src/include.new/c++/3.4/cassert new file mode 100644 index 0000000..9fc1079 --- /dev/null +++ b/src/include.new/c++/3.4/cassert @@ -0,0 +1,48 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.2 Assertions +// + +/** @file cassert + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c assert.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +// No include guards on this header... + +#pragma GCC system_header + +#include diff --git a/src/include.new/c++/3.4/cctype b/src/include.new/c++/3.4/cctype new file mode 100644 index 0000000..65a4214 --- /dev/null +++ b/src/include.new/c++/3.4/cctype @@ -0,0 +1,83 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: +// + +/** @file cctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c ctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 + +#pragma GCC system_header + +#include +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef isalnum +#undef isalpha +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit +#undef tolower +#undef toupper + +namespace std +{ + using ::isalnum; + using ::isalpha; + using ::iscntrl; + using ::isdigit; + using ::isgraph; + using ::islower; + using ::isprint; + using ::ispunct; + using ::isspace; + using ::isupper; + using ::isxdigit; + using ::tolower; + using ::toupper; +} + +#endif diff --git a/src/include.new/c++/3.4/cerrno b/src/include.new/c++/3.4/cerrno new file mode 100644 index 0000000..7915e14 --- /dev/null +++ b/src/include.new/c++/3.4/cerrno @@ -0,0 +1,55 @@ +// The -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.3 Error numbers +// + +/** @file cerrno + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c errno.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 + +#pragma GCC system_header + +#include + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef errno +#define errno errno +#endif + +#endif diff --git a/src/include.new/c++/3.4/cfloat b/src/include.new/c++/3.4/cfloat new file mode 100644 index 0000000..4c5bb00 --- /dev/null +++ b/src/include.new/c++/3.4/cfloat @@ -0,0 +1,50 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file cfloat + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c float.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 + +#pragma GCC system_header + +#include + +#endif diff --git a/src/include.new/c++/3.4/ciso646 b/src/include.new/c++/3.4/ciso646 new file mode 100644 index 0000000..0993a0a --- /dev/null +++ b/src/include.new/c++/3.4/ciso646 @@ -0,0 +1,37 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ciso646 + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c iso646.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ diff --git a/src/include.new/c++/3.4/climits b/src/include.new/c++/3.4/climits new file mode 100644 index 0000000..f4e1d8f --- /dev/null +++ b/src/include.new/c++/3.4/climits @@ -0,0 +1,51 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file climits + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c limits.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 + +#pragma GCC system_header + +#include + +#endif diff --git a/src/include.new/c++/3.4/clocale b/src/include.new/c++/3.4/clocale new file mode 100644 index 0000000..988b849 --- /dev/null +++ b/src/include.new/c++/3.4/clocale @@ -0,0 +1,62 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file clocale + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c locale.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef setlocale +#undef localeconv + +namespace std +{ + using ::lconv; + using ::setlocale; + using ::localeconv; +} + +#endif diff --git a/src/include.new/c++/3.4/cmath b/src/include.new/c++/3.4/cmath new file mode 100644 index 0000000..729f510 --- /dev/null +++ b/src/include.new/c++/3.4/cmath @@ -0,0 +1,595 @@ +// -*- C++ -*- C forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 26.5 C library +// + +/** @file cmath + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c math.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef abs +#undef div +#undef acos +#undef asin +#undef atan +#undef atan2 +#undef ceil +#undef cos +#undef cosh +#undef exp +#undef fabs +#undef floor +#undef fmod +#undef frexp +#undef ldexp +#undef log +#undef log10 +#undef modf +#undef pow +#undef sin +#undef sinh +#undef sqrt +#undef tan +#undef tanh + + +namespace std +{ + // Forward declaration of a helper function. This really should be + // an `exported' forward declaration. + template _Tp __cmath_power(_Tp, unsigned int); + + inline double + abs(double __x) + { return __builtin_fabs(__x); } + + inline float + abs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + abs(long double __x) + { return __builtin_fabsl(__x); } + + using ::acos; + + inline float + acos(float __x) + { return __builtin_acosf(__x); } + + inline long double + acos(long double __x) + { return __builtin_acosl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + acos(_Tp __x) + { + return __builtin_acos(__x); + } + + using ::asin; + + inline float + asin(float __x) + { return __builtin_asinf(__x); } + + inline long double + asin(long double __x) + { return __builtin_asinl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + asin(_Tp __x) + { return __builtin_asin(__x); } + + using ::atan; + + inline float + atan(float __x) + { return __builtin_atanf(__x); } + + inline long double + atan(long double __x) + { return __builtin_atanl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + atan(_Tp __x) + { return __builtin_atan(__x); } + + using ::atan2; + + inline float + atan2(float __y, float __x) + { return __builtin_atan2f(__y, __x); } + + inline long double + atan2(long double __y, long double __x) + { return __builtin_atan2l(__y, __x); } + + template + inline typename __enable_if::_M_type + && __is_integer<_Up>::_M_type>::_M_type + atan2(_Tp __y, _Up __x) + { return __builtin_atan2(__y, __x); } + + using ::ceil; + + inline float + ceil(float __x) + { return __builtin_ceilf(__x); } + + inline long double + ceil(long double __x) + { return __builtin_ceill(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + ceil(_Tp __x) + { return __builtin_ceil(__x); } + + using ::cos; + + inline float + cos(float __x) + { return __builtin_cosf(__x); } + + inline long double + cos(long double __x) + { return __builtin_cosl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + cos(_Tp __x) + { return __builtin_cos(__x); } + + using ::cosh; + + inline float + cosh(float __x) + { return __builtin_coshf(__x); } + + inline long double + cosh(long double __x) + { return __builtin_coshl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + cosh(_Tp __x) + { return __builtin_cosh(__x); } + + using ::exp; + + inline float + exp(float __x) + { return __builtin_expf(__x); } + + inline long double + exp(long double __x) + { return __builtin_expl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + exp(_Tp __x) + { return __builtin_exp(__x); } + + using ::fabs; + + inline float + fabs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + fabs(long double __x) + { return __builtin_fabsl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + fabs(_Tp __x) + { return __builtin_fabs(__x); } + + using ::floor; + + inline float + floor(float __x) + { return __builtin_floorf(__x); } + + inline long double + floor(long double __x) + { return __builtin_floorl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + floor(_Tp __x) + { return __builtin_floor(__x); } + + using ::fmod; + + inline float + fmod(float __x, float __y) + { return __builtin_fmodf(__x, __y); } + + inline long double + fmod(long double __x, long double __y) + { return __builtin_fmodl(__x, __y); } + + using ::frexp; + + inline float + frexp(float __x, int* __exp) + { return __builtin_frexpf(__x, __exp); } + + inline long double + frexp(long double __x, int* __exp) + { return __builtin_frexpl(__x, __exp); } + + template + inline typename __enable_if::_M_type>::_M_type + frexp(_Tp __x, int* __exp) + { return __builtin_frexp(__x, __exp); } + + using ::ldexp; + + inline float + ldexp(float __x, int __exp) + { return __builtin_ldexpf(__x, __exp); } + + inline long double + ldexp(long double __x, int __exp) + { return __builtin_ldexpl(__x, __exp); } + + template + inline typename __enable_if::_M_type>::_M_type + ldexp(_Tp __x, int __exp) + { return __builtin_ldexp(__x, __exp); } + + using ::log; + + inline float + log(float __x) + { return __builtin_logf(__x); } + + inline long double + log(long double __x) + { return __builtin_logl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + log(_Tp __x) + { return __builtin_log(__x); } + + using ::log10; + + inline float + log10(float __x) + { return __builtin_log10f(__x); } + + inline long double + log10(long double __x) + { return __builtin_log10l(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + log10(_Tp __x) + { return __builtin_log10(__x); } + + using ::modf; + + inline float + modf(float __x, float* __iptr) + { return __builtin_modff(__x, __iptr); } + + inline long double + modf(long double __x, long double* __iptr) + { return __builtin_modfl(__x, __iptr); } + + template + inline _Tp + __pow_helper(_Tp __x, int __n) + { + return __n < 0 + ? _Tp(1)/__cmath_power(__x, -__n) + : __cmath_power(__x, __n); + } + + using ::pow; + + inline float + pow(float __x, float __y) + { return __builtin_powf(__x, __y); } + + inline long double + pow(long double __x, long double __y) + { return __builtin_powl(__x, __y); } + + inline double + pow(double __x, int __i) + { return __pow_helper(__x, __i); } + + inline float + pow(float __x, int __n) + { return __pow_helper(__x, __n); } + + inline long double + pow(long double __x, int __n) + { return __pow_helper(__x, __n); } + + using ::sin; + + inline float + sin(float __x) + { return __builtin_sinf(__x); } + + inline long double + sin(long double __x) + { return __builtin_sinl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sin(_Tp __x) + { return __builtin_sin(__x); } + + using ::sinh; + + inline float + sinh(float __x) + { return __builtin_sinhf(__x); } + + inline long double + sinh(long double __x) + { return __builtin_sinhl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sinh(_Tp __x) + { return __builtin_sinh(__x); } + + using ::sqrt; + + inline float + sqrt(float __x) + { return __builtin_sqrtf(__x); } + + inline long double + sqrt(long double __x) + { return __builtin_sqrtl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sqrt(_Tp __x) + { return __builtin_sqrt(__x); } + + using ::tan; + + inline float + tan(float __x) + { return __builtin_tanf(__x); } + + inline long double + tan(long double __x) + { return __builtin_tanl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + tan(_Tp __x) + { return __builtin_tan(__x); } + + using ::tanh; + + inline float + tanh(float __x) + { return __builtin_tanhf(__x); } + + inline long double + tanh(long double __x) + { return __builtin_tanhl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + tanh(_Tp __x) + { return __builtin_tanh(__x); } +} + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +// These are possible macros imported from C99-land. For strict +// conformance, remove possible C99-injected names from the global +// namespace, and sequester them in the __gnu_cxx extension namespace. +namespace __gnu_cxx +{ + template + inline int + __capture_fpclassify(_Tp __f) { return fpclassify(__f); } + + template + inline int + __capture_isfinite(_Tp __f) { return isfinite(__f); } + + template + inline int + __capture_isinf(_Tp __f) { return isinf(__f); } + + template + inline int + __capture_isnan(_Tp __f) { return isnan(__f); } + + template + inline int + __capture_isnormal(_Tp __f) { return isnormal(__f); } + + template + inline int + __capture_signbit(_Tp __f) { return signbit(__f); } + + template + inline int + __capture_isgreater(_Tp __f1, _Tp __f2) + { return isgreater(__f1, __f2); } + + template + inline int + __capture_isgreaterequal(_Tp __f1, _Tp __f2) + { return isgreaterequal(__f1, __f2); } + + template + inline int + __capture_isless(_Tp __f1, _Tp __f2) { return isless(__f1, __f2); } + + template + inline int + __capture_islessequal(_Tp __f1, _Tp __f2) + { return islessequal(__f1, __f2); } + + template + inline int + __capture_islessgreater(_Tp __f1, _Tp __f2) + { return islessgreater(__f1, __f2); } + + template + inline int + __capture_isunordered(_Tp __f1, _Tp __f2) + { return isunordered(__f1, __f2); } +} + +// Only undefine the C99 FP macros, if actually captured for namespace movement +#undef fpclassify +#undef isfinite +#undef isinf +#undef isnan +#undef isnormal +#undef signbit +#undef isgreater +#undef isgreaterequal +#undef isless +#undef islessequal +#undef islessgreater +#undef isunordered +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +namespace __gnu_cxx +{ + template + inline int + fpclassify(_Tp __f) { return __capture_fpclassify(__f); } + + template + inline int + isfinite(_Tp __f) { return __capture_isfinite(__f); } + + template + inline int + isinf(_Tp __f) { return __capture_isinf(__f); } + + template + inline int + isnan(_Tp __f) { return __capture_isnan(__f); } + + template + inline int + isnormal(_Tp __f) { return __capture_isnormal(__f); } + + template + inline int + signbit(_Tp __f) { return __capture_signbit(__f); } + + template + inline int + isgreater(_Tp __f1, _Tp __f2) { return __capture_isgreater(__f1, __f2); } + + template + inline int + isgreaterequal(_Tp __f1, _Tp __f2) + { return __capture_isgreaterequal(__f1, __f2); } + + template + inline int + isless(_Tp __f1, _Tp __f2) { return __capture_isless(__f1, __f2); } + + template + inline int + islessequal(_Tp __f1, _Tp __f2) + { return __capture_islessequal(__f1, __f2); } + + template + inline int + islessgreater(_Tp __f1, _Tp __f2) + { return __capture_islessgreater(__f1, __f2); } + + template + inline int + isunordered(_Tp __f1, _Tp __f2) + { return __capture_isunordered(__f1, __f2); } +} + +namespace std +{ + using __gnu_cxx::fpclassify; + using __gnu_cxx::isfinite; + using __gnu_cxx::isinf; + using __gnu_cxx::isnan; + using __gnu_cxx::isnormal; + using __gnu_cxx::signbit; + using __gnu_cxx::isgreater; + using __gnu_cxx::isgreaterequal; + using __gnu_cxx::isless; + using __gnu_cxx::islessequal; + using __gnu_cxx::islessgreater; + using __gnu_cxx::isunordered; +} +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif diff --git a/src/include.new/c++/3.4/complex b/src/include.new/c++/3.4/complex new file mode 100644 index 0000000..244ed28 --- /dev/null +++ b/src/include.new/c++/3.4/complex @@ -0,0 +1,1226 @@ +// The template and inlines for the -*- C++ -*- complex number classes. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 26.2 Complex Numbers +// Note: this is not a conforming implementation. +// Initially implemented by Ulrich Drepper +// Improved by Gabriel Dos Reis +// + +/** @file complex + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_COMPLEX +#define _GLIBCXX_COMPLEX 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +namespace std +{ + // Forward declarations + template class complex; + template<> class complex; + template<> class complex; + template<> class complex; + + /// Return magnitude of @a z. + template _Tp abs(const complex<_Tp>&); + /// Return phase angle of @a z. + template _Tp arg(const complex<_Tp>&); + /// Return @a z magnitude squared. + template _Tp norm(const complex<_Tp>&); + + /// Return complex conjugate of @a z. + template complex<_Tp> conj(const complex<_Tp>&); + /// Return complex with magnitude @a rho and angle @a theta. + template complex<_Tp> polar(const _Tp&, const _Tp& = 0); + + // Transcendentals: + /// Return complex cosine of @a z. + template complex<_Tp> cos(const complex<_Tp>&); + /// Return complex hyperbolic cosine of @a z. + template complex<_Tp> cosh(const complex<_Tp>&); + /// Return complex base e exponential of @a z. + template complex<_Tp> exp(const complex<_Tp>&); + /// Return complex natural logarithm of @a z. + template complex<_Tp> log(const complex<_Tp>&); + /// Return complex base 10 logarithm of @a z. + template complex<_Tp> log10(const complex<_Tp>&); + /// Return complex cosine of @a z. + template complex<_Tp> pow(const complex<_Tp>&, int); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const complex<_Tp>&, const _Tp&); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const complex<_Tp>&, + const complex<_Tp>&); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const _Tp&, const complex<_Tp>&); + /// Return complex sine of @a z. + template complex<_Tp> sin(const complex<_Tp>&); + /// Return complex hyperbolic sine of @a z. + template complex<_Tp> sinh(const complex<_Tp>&); + /// Return complex square root of @a z. + template complex<_Tp> sqrt(const complex<_Tp>&); + /// Return complex tangent of @a z. + template complex<_Tp> tan(const complex<_Tp>&); + /// Return complex hyperbolic tangent of @a z. + template complex<_Tp> tanh(const complex<_Tp>&); + //@} + + + // 26.2.2 Primary template class complex + /** + * Template to represent complex numbers. + * + * Specializations for float, double, and long double are part of the + * library. Results with any other type are not guaranteed. + * + * @param Tp Type of real and imaginary values. + */ + template + class complex + { + public: + /// Value typedef. + typedef _Tp value_type; + + /// Default constructor. First parameter is x, second parameter is y. + /// Unspecified parameters default to 0. + complex(const _Tp& = _Tp(), const _Tp & = _Tp()); + + // Lets the compiler synthesize the copy constructor + // complex (const complex<_Tp>&); + /// Copy constructor. + template + complex(const complex<_Up>&); + + /// Return real part of complex number. + _Tp& real(); + /// Return real part of complex number. + const _Tp& real() const; + /// Return imaginary part of complex number. + _Tp& imag(); + /// Return imaginary part of complex number. + const _Tp& imag() const; + + /// Assign this complex number to scalar @a t. + complex<_Tp>& operator=(const _Tp&); + /// Add @a t to this complex number. + complex<_Tp>& operator+=(const _Tp&); + /// Subtract @a t from this complex number. + complex<_Tp>& operator-=(const _Tp&); + /// Multiply this complex number by @a t. + complex<_Tp>& operator*=(const _Tp&); + /// Divide this complex number by @a t. + complex<_Tp>& operator/=(const _Tp&); + + // Lets the compiler synthesize the + // copy and assignment operator + // complex<_Tp>& operator= (const complex<_Tp>&); + /// Assign this complex number to complex @a z. + template + complex<_Tp>& operator=(const complex<_Up>&); + /// Add @a z to this complex number. + template + complex<_Tp>& operator+=(const complex<_Up>&); + /// Subtract @a z from this complex number. + template + complex<_Tp>& operator-=(const complex<_Up>&); + /// Multiply this complex number by @a z. + template + complex<_Tp>& operator*=(const complex<_Up>&); + /// Divide this complex number by @a z. + template + complex<_Tp>& operator/=(const complex<_Up>&); + + private: + _Tp _M_real; + _Tp _M_imag; + }; + + template + inline _Tp& + complex<_Tp>::real() { return _M_real; } + + template + inline const _Tp& + complex<_Tp>::real() const { return _M_real; } + + template + inline _Tp& + complex<_Tp>::imag() { return _M_imag; } + + template + inline const _Tp& + complex<_Tp>::imag() const { return _M_imag; } + + template + inline + complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) + : _M_real(__r), _M_imag(__i) { } + + template + template + inline + complex<_Tp>::complex(const complex<_Up>& __z) + : _M_real(__z.real()), _M_imag(__z.imag()) { } + + template + complex<_Tp>& + complex<_Tp>::operator=(const _Tp& __t) + { + _M_real = __t; + _M_imag = _Tp(); + return *this; + } + + // 26.2.5/1 + template + inline complex<_Tp>& + complex<_Tp>::operator+=(const _Tp& __t) + { + _M_real += __t; + return *this; + } + + // 26.2.5/3 + template + inline complex<_Tp>& + complex<_Tp>::operator-=(const _Tp& __t) + { + _M_real -= __t; + return *this; + } + + // 26.2.5/5 + template + complex<_Tp>& + complex<_Tp>::operator*=(const _Tp& __t) + { + _M_real *= __t; + _M_imag *= __t; + return *this; + } + + // 26.2.5/7 + template + complex<_Tp>& + complex<_Tp>::operator/=(const _Tp& __t) + { + _M_real /= __t; + _M_imag /= __t; + return *this; + } + + template + template + complex<_Tp>& + complex<_Tp>::operator=(const complex<_Up>& __z) + { + _M_real = __z.real(); + _M_imag = __z.imag(); + return *this; + } + + // 26.2.5/9 + template + template + complex<_Tp>& + complex<_Tp>::operator+=(const complex<_Up>& __z) + { + _M_real += __z.real(); + _M_imag += __z.imag(); + return *this; + } + + // 26.2.5/11 + template + template + complex<_Tp>& + complex<_Tp>::operator-=(const complex<_Up>& __z) + { + _M_real -= __z.real(); + _M_imag -= __z.imag(); + return *this; + } + + // 26.2.5/13 + // XXX: This is a grammar school implementation. + template + template + complex<_Tp>& + complex<_Tp>::operator*=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); + _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); + _M_real = __r; + return *this; + } + + // 26.2.5/15 + // XXX: This is a grammar school implementation. + template + template + complex<_Tp>& + complex<_Tp>::operator/=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); + const _Tp __n = std::norm(__z); + _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; + _M_real = __r / __n; + return *this; + } + + // Operators: + //@{ + /// Return new complex value @a x plus @a y. + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r += __y; + return __r; + } + + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() += __y; + return __r; + } + + template + inline complex<_Tp> + operator+(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r.real() += __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x minus @a y. + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r -= __y; + return __r; + } + + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() -= __y; + return __r; + } + + template + inline complex<_Tp> + operator-(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r(__x, -__y.imag()); + __r.real() -= __y.real(); + return __r; + } + //@} + + //@{ + /// Return new complex value @a x times @a y. + template + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template + inline complex<_Tp> + operator*(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r *= __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x divided by @a y. + template + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template + inline complex<_Tp> + operator/(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + //@} + + /// Return @a x. + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x) + { return __x; } + + /// Return complex negation of @a x. + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x) + { return complex<_Tp>(-__x.real(), -__x.imag()); } + + //@{ + /// Return true if @a x is equal to @a y. + template + inline bool + operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() == __y.real() && __x.imag() == __y.imag(); } + + template + inline bool + operator==(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() == __y && __x.imag() == _Tp(); } + + template + inline bool + operator==(const _Tp& __x, const complex<_Tp>& __y) + { return __x == __y.real() && _Tp() == __y.imag(); } + //@} + + //@{ + /// Return false if @a x is equal to @a y. + template + inline bool + operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() != __y.real() || __x.imag() != __y.imag(); } + + template + inline bool + operator!=(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() != __y || __x.imag() != _Tp(); } + + template + inline bool + operator!=(const _Tp& __x, const complex<_Tp>& __y) + { return __x != __y.real() || _Tp() != __y.imag(); } + //@} + + /// Extraction operator for complex values. + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) + { + _Tp __re_x, __im_x; + _CharT __ch; + __is >> __ch; + if (__ch == '(') + { + __is >> __re_x >> __ch; + if (__ch == ',') + { + __is >> __im_x >> __ch; + if (__ch == ')') + __x = complex<_Tp>(__re_x, __im_x); + else + __is.setstate(ios_base::failbit); + } + else if (__ch == ')') + __x = __re_x; + else + __is.setstate(ios_base::failbit); + } + else + { + __is.putback(__ch); + __is >> __re_x; + __x = __re_x; + } + return __is; + } + + /// Insertion operator for complex values. + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) + { + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << '(' << __x.real() << ',' << __x.imag() << ')'; + return __os << __s.str(); + } + + // Values + template + inline _Tp& + real(complex<_Tp>& __z) + { return __z.real(); } + + template + inline const _Tp& + real(const complex<_Tp>& __z) + { return __z.real(); } + + template + inline _Tp& + imag(complex<_Tp>& __z) + { return __z.imag(); } + + template + inline const _Tp& + imag(const complex<_Tp>& __z) + { return __z.imag(); } + + template + inline _Tp + abs(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + const _Tp __s = std::max(abs(__x), abs(__y)); + if (__s == _Tp()) // well ... + return __s; + __x /= __s; + __y /= __s; + return __s * sqrt(__x * __x + __y * __y); + } + + template + inline _Tp + arg(const complex<_Tp>& __z) + { return atan2(__z.imag(), __z.real()); } + + // 26.2.7/5: norm(__z) returns the squared magintude of __z. + // As defined, norm() is -not- a norm is the common mathematical + // sens used in numerics. The helper class _Norm_helper<> tries to + // distinguish between builtin floating point and the rest, so as + // to deliver an answer as close as possible to the real value. + template + struct _Norm_helper + { + template + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return __x * __x + __y * __y; + } + }; + + template<> + struct _Norm_helper + { + template + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + _Tp __res = std::abs(__z); + return __res * __res; + } + }; + + template + inline _Tp + norm(const complex<_Tp>& __z) + { + return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); + } + + template + inline complex<_Tp> + polar(const _Tp& __rho, const _Tp& __theta) + { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } + + template + inline complex<_Tp> + conj(const complex<_Tp>& __z) + { return complex<_Tp>(__z.real(), -__z.imag()); } + + // Transcendentals + template + inline complex<_Tp> + cos(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); + } + + template + inline complex<_Tp> + cosh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); + } + + template + inline complex<_Tp> + exp(const complex<_Tp>& __z) + { return std::polar(exp(__z.real()), __z.imag()); } + + template + inline complex<_Tp> + log(const complex<_Tp>& __z) + { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } + + template + inline complex<_Tp> + log10(const complex<_Tp>& __z) + { return std::log(__z) / log(_Tp(10.0)); } + + template + inline complex<_Tp> + sin(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); + } + + template + inline complex<_Tp> + sinh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); + } + + template + complex<_Tp> + sqrt(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + + if (__x == _Tp()) + { + _Tp __t = sqrt(abs(__y) / 2); + return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); + } + else + { + _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); + _Tp __u = __t / 2; + return __x > _Tp() + ? complex<_Tp>(__u, __y / __t) + : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); + } + } + + template + inline complex<_Tp> + tan(const complex<_Tp>& __z) + { + return std::sin(__z) / std::cos(__z); + } + + template + inline complex<_Tp> + tanh(const complex<_Tp>& __z) + { + return std::sinh(__z) / std::cosh(__z); + } + + template + inline complex<_Tp> + pow(const complex<_Tp>& __z, int __n) + { + return std::__pow_helper(__z, __n); + } + + template + complex<_Tp> + pow(const complex<_Tp>& __x, const _Tp& __y) + { + if (__x.imag() == _Tp() && __x.real() > _Tp()) + return pow(__x.real(), __y); + + complex<_Tp> __t = std::log(__x); + return std::polar(exp(__y * __t.real()), __y * __t.imag()); + } + + template + inline complex<_Tp> + pow(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); + } + + template + inline complex<_Tp> + pow(const _Tp& __x, const complex<_Tp>& __y) + { + return __x > _Tp() ? std::polar(pow(__x, __y.real()), + __y.imag() * log(__x)) + : std::pow(complex<_Tp>(__x, _Tp()), __y); + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef float value_type; + + complex(float = 0.0f, float = 0.0f); + + explicit complex(const complex&); + explicit complex(const complex&); + + float& real(); + const float& real() const; + float& imag(); + const float& imag() const; + + complex& operator=(float); + complex& operator+=(float); + complex& operator-=(float); + complex& operator*=(float); + complex& operator/=(float); + + // Let's the compiler synthetize the copy and assignment + // operator. It always does a pretty good job. + // complex& operator= (const complex&); + template + complex&operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex&operator/=(const complex<_Tp>&); + + private: + typedef __complex__ float _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline float& + complex::real() + { return __real__ _M_value; } + + inline const float& + complex::real() const + { return __real__ _M_value; } + + inline float& + complex::imag() + { return __imag__ _M_value; } + + inline const float& + complex::imag() const + { return __imag__ _M_value; } + + inline + complex::complex(float r, float i) + { + __real__ _M_value = r; + __imag__ _M_value = i; + } + + inline complex& + complex::operator=(float __f) + { + __real__ _M_value = __f; + __imag__ _M_value = 0.0f; + return *this; + } + + inline complex& + complex::operator+=(float __f) + { + __real__ _M_value += __f; + return *this; + } + + inline complex& + complex::operator-=(float __f) + { + __real__ _M_value -= __f; + return *this; + } + + inline complex& + complex::operator*=(float __f) + { + _M_value *= __f; + return *this; + } + + inline complex& + complex::operator/=(float __f) + { + _M_value /= __f; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef double value_type; + + complex(double = 0.0, double = 0.0); + + complex(const complex&); + explicit complex(const complex&); + + double& real(); + const double& real() const; + double& imag(); + const double& imag() const; + + complex& operator=(double); + complex& operator+=(double); + complex& operator-=(double); + complex& operator*=(double); + complex& operator/=(double); + + // The compiler will synthetize this, efficiently. + // complex& operator= (const complex&); + template + complex& operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline double& + complex::real() + { return __real__ _M_value; } + + inline const double& + complex::real() const + { return __real__ _M_value; } + + inline double& + complex::imag() + { return __imag__ _M_value; } + + inline const double& + complex::imag() const + { return __imag__ _M_value; } + + inline + complex::complex(double __r, double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline complex& + complex::operator=(double __d) + { + __real__ _M_value = __d; + __imag__ _M_value = 0.0; + return *this; + } + + inline complex& + complex::operator+=(double __d) + { + __real__ _M_value += __d; + return *this; + } + + inline complex& + complex::operator-=(double __d) + { + __real__ _M_value -= __d; + return *this; + } + + inline complex& + complex::operator*=(double __d) + { + _M_value *= __d; + return *this; + } + + inline complex& + complex::operator/=(double __d) + { + _M_value /= __d; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef long double value_type; + + complex(long double = 0.0L, long double = 0.0L); + + complex(const complex&); + complex(const complex&); + + long double& real(); + const long double& real() const; + long double& imag(); + const long double& imag() const; + + complex& operator= (long double); + complex& operator+= (long double); + complex& operator-= (long double); + complex& operator*= (long double); + complex& operator/= (long double); + + // The compiler knows how to do this efficiently + // complex& operator= (const complex&); + template + complex& operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ long double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline + complex::complex(long double __r, long double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline long double& + complex::real() + { return __real__ _M_value; } + + inline const long double& + complex::real() const + { return __real__ _M_value; } + + inline long double& + complex::imag() + { return __imag__ _M_value; } + + inline const long double& + complex::imag() const + { return __imag__ _M_value; } + + inline complex& + complex::operator=(long double __r) + { + __real__ _M_value = __r; + __imag__ _M_value = 0.0L; + return *this; + } + + inline complex& + complex::operator+=(long double __r) + { + __real__ _M_value += __r; + return *this; + } + + inline complex& + complex::operator-=(long double __r) + { + __real__ _M_value -= __r; + return *this; + } + + inline complex& + complex::operator*=(long double __r) + { + _M_value *= __r; + return *this; + } + + inline complex& + complex::operator/=(long double __r) + { + _M_value /= __r; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // These bits have to be at the end of this file, so that the + // specializations have all been defined. + // ??? No, they have to be there because of compiler limitation at + // inlining. It suffices that class specializations be defined. + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } +} // namespace std + +#endif /* _GLIBCXX_COMPLEX */ diff --git a/src/include.new/c++/3.4/csetjmp b/src/include.new/c++/3.4/csetjmp new file mode 100644 index 0000000..d5fe073 --- /dev/null +++ b/src/include.new/c++/3.4/csetjmp @@ -0,0 +1,65 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file csetjmp + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c setjmp.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef longjmp + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef setjmp +#define setjmp(env) setjmp (env) +#endif + +namespace std +{ + using ::jmp_buf; + using ::longjmp; +} + +#endif diff --git a/src/include.new/c++/3.4/csignal b/src/include.new/c++/3.4/csignal new file mode 100644 index 0000000..5734cf6 --- /dev/null +++ b/src/include.new/c++/3.4/csignal @@ -0,0 +1,61 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file csignal + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c signal.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef raise + +namespace std +{ + using ::sig_atomic_t; + using ::signal; + using ::raise; +} + +#endif diff --git a/src/include.new/c++/3.4/cstdarg b/src/include.new/c++/3.4/cstdarg new file mode 100644 index 0000000..ca362e4 --- /dev/null +++ b/src/include.new/c++/3.4/cstdarg @@ -0,0 +1,60 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstdarg + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdarg.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 + +#pragma GCC system_header + +#include + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef va_end +#define va_end(ap) va_end (ap) +#endif + +namespace std +{ + using ::va_list; +} + +#endif diff --git a/src/include.new/c++/3.4/cstddef b/src/include.new/c++/3.4/cstddef new file mode 100644 index 0000000..4fa82c6 --- /dev/null +++ b/src/include.new/c++/3.4/cstddef @@ -0,0 +1,56 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.1 Types +// + +/** @file cstddef + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stddef.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 + +#pragma GCC system_header + +#include + +namespace std +{ + using ::ptrdiff_t; + using ::size_t; +} + +#endif diff --git a/src/include.new/c++/3.4/cstdio b/src/include.new/c++/3.4/cstdio new file mode 100644 index 0000000..f31e58e --- /dev/null +++ b/src/include.new/c++/3.4/cstdio @@ -0,0 +1,185 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8.2 C Library files +// + +/** @file cstdio + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdio.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef clearerr +#undef fclose +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgetpos +#undef fgets +#undef fopen +#undef fprintf +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef fsetpos +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef perror +#undef printf +#undef putc +#undef putchar +#undef puts +#undef remove +#undef rename +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +#undef sprintf +#undef sscanf +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vfprintf +#undef vprintf +#undef vsprintf + +namespace std +{ + using ::FILE; + using ::fpos_t; + + using ::clearerr; + using ::fclose; + using ::feof; + using ::ferror; + using ::fflush; + using ::fgetc; + using ::fgetpos; + using ::fgets; + using ::fopen; + using ::fprintf; + using ::fputc; + using ::fputs; + using ::fread; + using ::freopen; + using ::fscanf; + using ::fseek; + using ::fsetpos; + using ::ftell; + using ::fwrite; + using ::getc; + using ::getchar; + using ::gets; + using ::perror; + using ::printf; + using ::putc; + using ::putchar; + using ::puts; + using ::remove; + using ::rename; + using ::rewind; + using ::scanf; + using ::setbuf; + using ::setvbuf; + using ::sprintf; + using ::sscanf; + using ::tmpfile; + using ::tmpnam; + using ::ungetc; + using ::vfprintf; + using ::vprintf; + using ::vsprintf; +} + +#if _GLIBCXX_USE_C99 + +#undef snprintf +#undef vfscanf +#undef vscanf +#undef vsnprintf +#undef vsscanf + +namespace __gnu_cxx +{ +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" int + (snprintf)(char * restrict, size_t, const char * restrict, ...); + extern "C" int + (vfscanf)(FILE * restrict, const char * restrict, __gnuc_va_list); + extern "C" int (vscanf)(const char * restrict, __gnuc_va_list); + extern "C" int + (vsnprintf)(char * restrict, size_t, const char * restrict, __gnuc_va_list); + extern "C" int + (vsscanf)(const char * restrict, const char * restrict, __gnuc_va_list); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::snprintf; + using ::vfscanf; + using ::vscanf; + using ::vsnprintf; + using ::vsscanf; +#endif +} + +namespace std +{ + using __gnu_cxx::snprintf; + using __gnu_cxx::vfscanf; + using __gnu_cxx::vscanf; + using __gnu_cxx::vsnprintf; + using __gnu_cxx::vsscanf; +} +#endif + +#endif diff --git a/src/include.new/c++/3.4/cstdlib b/src/include.new/c++/3.4/cstdlib new file mode 100644 index 0000000..d2d6e37 --- /dev/null +++ b/src/include.new/c++/3.4/cstdlib @@ -0,0 +1,204 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstdlib + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdlib.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef abort +#undef abs +#undef atexit +#undef atof +#undef atoi +#undef atol +#undef bsearch +#undef calloc +#undef div +#undef exit +#undef free +#undef getenv +#undef labs +#undef ldiv +#undef malloc +#undef mblen +#undef mbstowcs +#undef mbtowc +#undef qsort +#undef rand +#undef realloc +#undef srand +#undef strtod +#undef strtol +#undef strtoul +#undef system +#undef wcstombs +#undef wctomb + +namespace std +{ + using ::div_t; + using ::ldiv_t; + + using ::abort; + using ::abs; + using ::atexit; + using ::atof; + using ::atoi; + using ::atol; + using ::bsearch; + using ::calloc; + using ::div; + using ::exit; + using ::free; + using ::getenv; + using ::labs; + using ::ldiv; + using ::malloc; +#ifdef _GLIBCXX_HAVE_MBSTATE_T + using ::mblen; + using ::mbstowcs; + using ::mbtowc; +#endif // _GLIBCXX_HAVE_MBSTATE_T + using ::qsort; + using ::rand; + using ::realloc; + using ::srand; + using ::strtod; + using ::strtol; + using ::strtoul; + using ::system; +#ifdef _GLIBCXX_USE_WCHAR_T + using ::wcstombs; + using ::wctomb; +#endif // _GLIBCXX_USE_WCHAR_T + + inline long + abs(long __i) { return labs(__i); } + + inline ldiv_t + div(long __i, long __j) { return ldiv(__i, __j); } +} + +#if _GLIBCXX_USE_C99 + +#undef _Exit +#undef llabs +#undef lldiv +#undef atoll +#undef strtoll +#undef strtoull +#undef strtof +#undef strtold + +namespace __gnu_cxx +{ +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::lldiv_t; +#endif +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" void (_Exit)(int); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::_Exit; +#endif + + inline long long + abs(long long __x) { return __x >= 0 ? __x : -__x; } + + inline long long + llabs(long long __x) { return __x >= 0 ? __x : -__x; } + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + inline lldiv_t + div(long long __n, long long __d) + { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } + + inline lldiv_t + lldiv(long long __n, long long __d) + { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } +#endif + +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int (atoll)(const char *); + extern "C" long long int + (strtoll)(const char * restrict, char ** restrict, int); + extern "C" unsigned long long int + (strtoull)(const char * restrict, char ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::atoll; + using ::strtoll; + using ::strtoull; +#endif + using ::strtof; + using ::strtold; +} + +namespace std +{ +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using __gnu_cxx::lldiv_t; +#endif + using __gnu_cxx::_Exit; + using __gnu_cxx::abs; + using __gnu_cxx::llabs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using __gnu_cxx::div; + using __gnu_cxx::lldiv; +#endif + using __gnu_cxx::atoll; + using __gnu_cxx::strtof; + using __gnu_cxx::strtoll; + using __gnu_cxx::strtoull; + using __gnu_cxx::strtold; +} +#endif + +#endif diff --git a/src/include.new/c++/3.4/cstring b/src/include.new/c++/3.4/cstring new file mode 100644 index 0000000..dad40c2 --- /dev/null +++ b/src/include.new/c++/3.4/cstring @@ -0,0 +1,128 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstring + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c string.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 + +#pragma GCC system_header + +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef memcpy +#undef memmove +#undef strcpy +#undef strncpy +#undef strcat +#undef strncat +#undef memcmp +#undef strcmp +#undef strcoll +#undef strncmp +#undef strxfrm +#undef memchr +#undef strchr +#undef strcspn +#undef strpbrk +#undef strrchr +#undef strspn +#undef strstr +#undef strtok +#undef memset +#undef strerror +#undef strlen + +namespace std +{ + using ::memcpy; + using ::memmove; + using ::strcpy; + using ::strncpy; + using ::strcat; + using ::strncat; + using ::memcmp; + using ::strcmp; + using ::strcoll; + using ::strncmp; + using ::strxfrm; + using ::strcspn; + using ::strspn; + using ::strtok; + using ::memset; + using ::strerror; + using ::strlen; + + using ::memchr; + + inline void* + memchr(void* __p, int __c, size_t __n) + { return memchr(const_cast(__p), __c, __n); } + + using ::strchr; + + inline char* + strchr(char* __s1, int __n) + { return __builtin_strchr(const_cast(__s1), __n); } + + using ::strpbrk; + + inline char* + strpbrk(char* __s1, const char* __s2) + { return __builtin_strpbrk(const_cast(__s1), __s2); } + + using ::strrchr; + + inline char* + strrchr(char* __s1, int __n) + { return __builtin_strrchr(const_cast(__s1), __n); } + + using ::strstr; + + inline char* + strstr(char* __s1, const char* __s2) + { return __builtin_strstr(const_cast(__s1), __s2); } +} + +#endif diff --git a/src/include.new/c++/3.4/ctime b/src/include.new/c++/3.4/ctime new file mode 100644 index 0000000..fe890df --- /dev/null +++ b/src/include.new/c++/3.4/ctime @@ -0,0 +1,81 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.5 Date and time +// + +/** @file ctime + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c time.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 + +#pragma GCC system_header + +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef clock +#undef difftime +#undef mktime +#undef time +#undef asctime +#undef ctime +#undef gmtime +#undef localtime +#undef strftime + +namespace std +{ + using ::clock_t; + using ::time_t; + using ::tm; + + using ::clock; + using ::difftime; + using ::mktime; + using ::time; + using ::asctime; + using ::ctime; + using ::gmtime; + using ::localtime; + using ::strftime; +} + +#endif diff --git a/src/include.new/c++/3.4/cwchar b/src/include.new/c++/3.4/cwchar new file mode 100644 index 0000000..d9e11e9 --- /dev/null +++ b/src/include.new/c++/3.4/cwchar @@ -0,0 +1,273 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21.4 +// + +/** @file cwchar + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wchar.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 + +#pragma GCC system_header + +#include +#include +#include + +#if _GLIBCXX_HAVE_WCHAR_H +#include +#endif + +// Need to do a bit of trickery here with mbstate_t as char_traits +// assumes it is in wchar.h, regardless of wchar_t specializations. +#ifndef _GLIBCXX_HAVE_MBSTATE_T +extern "C" +{ + typedef struct + { + int __fill[6]; + } mbstate_t; +} +#endif + +namespace std +{ + using ::mbstate_t; +} + +// Get rid of those macros defined in in lieu of real functions. +#undef btowc +#undef fgetwc +#undef fgetws +#undef fputwc +#undef fputws +#undef fwide +#undef fwprintf +#undef fwscanf +#undef getwc +#undef getwchar +#undef mbrlen +#undef mbrtowc +#undef mbsinit +#undef mbsrtowcs +#undef putwc +#undef putwchar +#undef swprintf +#undef swscanf +#undef ungetwc +#undef vfwprintf +#if _GLIBCXX_HAVE_VFWSCANF +# undef vfwscanf +#endif +#undef vswprintf +#if _GLIBCXX_HAVE_VSWSCANF +# undef vswscanf +#endif +#undef vwprintf +#if _GLIBCXX_HAVE_VWSCANF +# undef vwscanf +#endif +#undef wcrtomb +#undef wcscat +#undef wcschr +#undef wcscmp +#undef wcscoll +#undef wcscpy +#undef wcscspn +#undef wcsftime +#undef wcslen +#undef wcsncat +#undef wcsncmp +#undef wcsncpy +#undef wcspbrk +#undef wcsrchr +#undef wcsrtombs +#undef wcsspn +#undef wcsstr +#undef wcstod +#if _GLIBCXX_HAVE_WCSTOF +# undef wcstof +#endif +#undef wcstok +#undef wcstol +#undef wcstoul +#undef wcsxfrm +#undef wctob +#undef wmemchr +#undef wmemcmp +#undef wmemcpy +#undef wmemmove +#undef wmemset +#undef wprintf +#undef wscanf + +#if _GLIBCXX_USE_WCHAR_T +namespace std +{ + using ::wint_t; + + using ::btowc; + using ::fgetwc; + using ::fgetws; + using ::fputwc; + using ::fputws; + using ::fwide; + using ::fwprintf; + using ::fwscanf; + using ::getwc; + using ::getwchar; + using ::mbrlen; + using ::mbrtowc; + using ::mbsinit; + using ::mbsrtowcs; + using ::putwc; + using ::putwchar; + using ::swprintf; + using ::swscanf; + using ::ungetwc; + using ::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF + using ::vfwscanf; +#endif + using ::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF + using ::vswscanf; +#endif + using ::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF + using ::vwscanf; +#endif + using ::wcrtomb; + using ::wcscat; + using ::wcscmp; + using ::wcscoll; + using ::wcscpy; + using ::wcscspn; + using ::wcsftime; + using ::wcslen; + using ::wcsncat; + using ::wcsncmp; + using ::wcsncpy; + using ::wcsrtombs; + using ::wcsspn; + using ::wcstod; +#if _GLIBCXX_HAVE_WCSTOF + using ::wcstof; +#endif + using ::wcstok; + using ::wcstol; + using ::wcstoul; + using ::wcsxfrm; + using ::wctob; + using ::wmemcmp; + using ::wmemcpy; + using ::wmemmove; + using ::wmemset; + using ::wprintf; + using ::wscanf; + + using ::wcschr; + + inline wchar_t* + wcschr(wchar_t* __p, wchar_t __c) + { return wcschr(const_cast(__p), __c); } + + using ::wcspbrk; + + inline wchar_t* + wcspbrk(wchar_t* __s1, wchar_t* __s2) + { return wcspbrk(const_cast(__s1), __s2); } + + using ::wcsrchr; + + inline wchar_t* + wcsrchr(wchar_t* __p, wchar_t __c) + { return wcsrchr(const_cast(__p), __c); } + + using ::wcsstr; + + inline wchar_t* + wcsstr(wchar_t* __s1, const wchar_t* __s2) + { return wcsstr(const_cast(__s1), __s2); } + + using ::wmemchr; + + inline wchar_t* + wmemchr(wchar_t* __p, wchar_t __c, size_t __n) + { return wmemchr(const_cast(__p), __c, __n); } +} + +#if _GLIBCXX_USE_C99 + +#undef wcstold +#undef wcstoll +#undef wcstoull + +namespace __gnu_cxx +{ +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" long double + (wcstold)(const wchar_t * restrict, wchar_t ** restrict); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::wcstold; +#endif +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int + (wcstoll)(const wchar_t * restrict, wchar_t ** restrict, int); + extern "C" unsigned long long int + (wcstoull)(const wchar_t * restrict, wchar_t ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::wcstoll; + using ::wcstoull; +#endif +} + +namespace std +{ + using __gnu_cxx::wcstold; + using __gnu_cxx::wcstoll; + using __gnu_cxx::wcstoull; +} +#endif + +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/src/include.new/c++/3.4/cwctype b/src/include.new/c++/3.4/cwctype new file mode 100644 index 0000000..970c53a --- /dev/null +++ b/src/include.new/c++/3.4/cwctype @@ -0,0 +1,110 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: +// + +/** @file cwctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 + +#pragma GCC system_header + +#include + +#if _GLIBCXX_HAVE_WCTYPE_H +#include +#endif + +// Get rid of those macros defined in in lieu of real functions. +#undef iswalnum +#undef iswalpha +#if _GLIBCXX_HAVE_ISWBLANK +# undef iswblank +#endif +#undef iswcntrl +#undef iswdigit +#undef iswgraph +#undef iswlower +#undef iswprint +#undef iswprint +#undef iswpunct +#undef iswspace +#undef iswupper +#undef iswxdigit +#undef iswctype +#undef towlower +#undef towupper +#undef towctrans +#undef wctrans +#undef wctype + +#if _GLIBCXX_USE_WCHAR_T +namespace std +{ + using ::wint_t; // cwchar + + using ::wctype_t; + using ::wctrans_t; + + using ::iswalnum; + using ::iswalpha; +#if _GLIBCXX_HAVE_ISWBLANK + using ::iswblank; +#endif + using ::iswcntrl; + using ::iswdigit; + using ::iswgraph; + using ::iswlower; + using ::iswprint; + using ::iswprint; + using ::iswpunct; + using ::iswspace; + using ::iswupper; + using ::iswxdigit; + using ::iswctype; + using ::towlower; + using ::towupper; + using ::towctrans; + using ::wctrans; + using ::wctype; +} +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/src/include.new/c++/3.4/cxxabi.h b/src/include.new/c++/3.4/cxxabi.h new file mode 100644 index 0000000..3553549 --- /dev/null +++ b/src/include.new/c++/3.4/cxxabi.h @@ -0,0 +1,528 @@ +// new abi support -*- C++ -*- + +// Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Nathan Sidwell, Codesourcery LLC, + +/* This file declares the new abi entry points into the runtime. It is not + normally necessary for user programs to include this header, or use the + entry points directly. However, this header is available should that be + needed. + + Some of the entry points are intended for both C and C++, thus this header + is includable from both C and C++. Though the C++ specific parts are not + available in C, naturally enough. */ + +#ifndef _CXXABI_H +#define _CXXABI_H 1 + +#include + +#ifdef __cplusplus +namespace __cxxabiv1 +{ + extern "C" + { +#endif + + // Allocate array. + void* + __cxa_vec_new(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*)); + + void* + __cxa_vec_new2(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*), void *(*__alloc) (size_t), + void (*__dealloc) (void*)); + + void* + __cxa_vec_new3(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*), void *(*__alloc) (size_t), + void (*__dealloc) (void*, size_t)); + + // Construct array. + void + __cxa_vec_ctor(void* __array_address, size_t __element_count, + size_t __element_size, void (*__constructor) (void*), + void (*__destructor) (void*)); + + void + __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count, + size_t element_size, void (*constructor) (void*, void*), + void (*destructor) (void*)); + + // Destruct array. + void + __cxa_vec_dtor(void* __array_address, size_t __element_count, + size_t __element_size, void (*__destructor) (void*)); + + void + __cxa_vec_cleanup(void* __array_address, size_t __element_count, + size_t __element_size, void (*__destructor) (void*)); + + // Destruct and release array. + void + __cxa_vec_delete(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*)); + + void + __cxa_vec_delete2(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*), + void (*__dealloc) (void*)); + + void + __cxa_vec_delete3(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*), + void (*__dealloc) (void*, size_t)); + + // The ABI requires a 64-bit type. + __extension__ typedef int __guard __attribute__((mode (__DI__))); + + int + __cxa_guard_acquire(__guard*); + + void + __cxa_guard_release(__guard*); + + void + __cxa_guard_abort(__guard*); + + // Pure virtual functions. + void + __cxa_pure_virtual(void); + + // Exception handling. + void + __cxa_bad_cast(); + + void + __cxa_bad_typeid(); + + // DSO destruction. + int + __cxa_atexit(void (*)(void*), void*, void*); + + int + __cxa_finalize(void*); + + // Demangling routines. + char* + __cxa_demangle(const char* __mangled_name, char* __output_buffer, + size_t* __length, int* __status); +#ifdef __cplusplus + } +} // namespace __cxxabiv1 +#endif + +#ifdef __cplusplus + +#include + +namespace __cxxabiv1 +{ + // Type information for int, float etc. + class __fundamental_type_info : public std::type_info + { + public: + explicit + __fundamental_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__fundamental_type_info(); + }; + + // Type information for array objects. + class __array_type_info : public std::type_info + { + public: + explicit + __array_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__array_type_info(); + }; + + // Type information for functions (both member and non-member). + class __function_type_info : public std::type_info + { + public: + explicit + __function_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__function_type_info(); + + protected: + // Implementation defined member function. + virtual bool + __is_function_p() const; + }; + + // Type information for enumerations. + class __enum_type_info : public std::type_info + { + public: + explicit + __enum_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__enum_type_info(); + }; + + // Common type information for simple pointers and pointers to member. + class __pbase_type_info : public std::type_info + { + public: + unsigned int __flags; // Qualification of the target object. + const std::type_info* __pointee; // Type of pointed to object. + + explicit + __pbase_type_info(const char* __n, int __quals, + const std::type_info* __type) + : std::type_info(__n), __flags(__quals), __pointee(__type) + { } + + virtual + ~__pbase_type_info(); + + // Implementation defined type. + enum __masks + { + __const_mask = 0x1, + __volatile_mask = 0x2, + __restrict_mask = 0x4, + __incomplete_mask = 0x8, + __incomplete_class_mask = 0x10 + }; + + protected: + __pbase_type_info(const __pbase_type_info&); + + __pbase_type_info& + operator=(const __pbase_type_info&); + + // Implementation defined member functions. + virtual bool + __do_catch(const std::type_info* __thr_type, void** __thr_obj, + unsigned int __outer) const; + + inline virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Type information for simple pointers. + class __pointer_type_info : public __pbase_type_info + { + public: + explicit + __pointer_type_info(const char* __n, int __quals, + const std::type_info* __type) + : __pbase_type_info (__n, __quals, __type) { } + + + virtual + ~__pointer_type_info(); + + protected: + // Implementation defined member functions. + virtual bool + __is_pointer_p() const; + + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + class __class_type_info; + + // Type information for a pointer to member variable. + class __pointer_to_member_type_info : public __pbase_type_info + { + public: + __class_type_info* __context; // Class of the member. + + explicit + __pointer_to_member_type_info(const char* __n, int __quals, + const std::type_info* __type, + __class_type_info* __klass) + : __pbase_type_info(__n, __quals, __type), __context(__klass) { } + + virtual + ~__pointer_to_member_type_info(); + + protected: + __pointer_to_member_type_info(const __pointer_to_member_type_info&); + + __pointer_to_member_type_info& + operator=(const __pointer_to_member_type_info&); + + // Implementation defined member function. + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Helper class for __vmi_class_type. + class __base_class_type_info + { + public: + const __class_type_info* __base_type; // Base class type. + long __offset_flags; // Offset and info. + + enum __offset_flags_masks + { + __virtual_mask = 0x1, + __public_mask = 0x2, + __hwm_bit = 2, + __offset_shift = 8 // Bits to shift offset. + }; + + // Implementation defined member functions. + bool + __is_virtual_p() const + { return __offset_flags & __virtual_mask; } + + bool + __is_public_p() const + { return __offset_flags & __public_mask; } + + ptrdiff_t + __offset() const + { + // This shift, being of a signed type, is implementation + // defined. GCC implements such shifts as arithmetic, which is + // what we want. + return static_cast(__offset_flags) >> __offset_shift; + } + }; + + // Type information for a class. + class __class_type_info : public std::type_info + { + public: + explicit + __class_type_info (const char *__n) : type_info(__n) { } + + virtual + ~__class_type_info (); + + // Implementation defined types. + // The type sub_kind tells us about how a base object is contained + // within a derived object. We often do this lazily, hence the + // UNKNOWN value. At other times we may use NOT_CONTAINED to mean + // not publicly contained. + enum __sub_kind + { + // We have no idea. + __unknown = 0, + + // Not contained within us (in some circumstances this might + // mean not contained publicly) + __not_contained, + + // Contained ambiguously. + __contained_ambig, + + // Via a virtual path. + __contained_virtual_mask = __base_class_type_info::__virtual_mask, + + // Via a public path. + __contained_public_mask = __base_class_type_info::__public_mask, + + // Contained within us. + __contained_mask = 1 << __base_class_type_info::__hwm_bit, + + __contained_private = __contained_mask, + __contained_public = __contained_mask | __contained_public_mask + }; + + struct __upcast_result; + struct __dyncast_result; + + protected: + // Implementation defined member functions. + virtual bool + __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; + + virtual bool + __do_catch(const type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + + public: + // Helper for upcast. See if DST is us, or one of our bases. + // Return false if not found, true if found. + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + + // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly + // within OBJ_PTR. OBJ_PTR points to a base object of our type, + // which is the destination type. SRC2DST indicates how SRC + // objects might be contained within this type. If SRC_PTR is one + // of our SRC_TYPE bases, indicate the virtuality. Returns + // not_contained for non containment or private containment. + inline __sub_kind + __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + // Helper for dynamic cast. ACCESS_PATH gives the access from the + // most derived object to this base. DST_TYPE indicates the + // desired type we want. OBJ_PTR points to a base of our type + // within the complete object. SRC_TYPE indicates the static type + // started from and SRC_PTR points to that base within the most + // derived object. Fill in RESULT with what we find. Return true + // if we have located an ambiguous match. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE + // bases are inherited by the type started from -- which is not + // necessarily the current type. The current type will be a base + // of the destination type. OBJ_PTR points to the current base. + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + }; + + // Type information for a class with a single non-virtual base. + class __si_class_type_info : public __class_type_info + { + public: + const __class_type_info* __base_type; + + explicit + __si_class_type_info(const char *__n, const __class_type_info *__base) + : __class_type_info(__n), __base_type(__base) { } + + virtual + ~__si_class_type_info(); + + protected: + __si_class_type_info(const __si_class_type_info&); + + __si_class_type_info& + operator=(const __si_class_type_info&); + + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __sub_ptr) const; + + virtual bool + __do_upcast(const __class_type_info*__dst, const void*__obj, + __upcast_result& __restrict __result) const; + }; + + // Type information for a class with multiple and/or virtual bases. + class __vmi_class_type_info : public __class_type_info + { + public: + unsigned int __flags; // Details about the class hierarchy. + unsigned int __base_count; // Dumber of direct bases. + + // The array of bases uses the trailing array struct hack so this + // class is not constructable with a normal constructor. It is + // internally generated by the compiler. + __base_class_type_info __base_info[1]; // Array of bases. + + explicit + __vmi_class_type_info(const char* __n, int ___flags) + : __class_type_info(__n), __flags(___flags), __base_count(0) { } + + virtual + ~__vmi_class_type_info(); + + // Implementation defined types. + enum __flags_masks + { + __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. + __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. + __flags_unknown_mask = 0x10 + }; + + protected: + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + }; + + // Dynamic cast runtime. + // src2dst has the following possible values + // >-1: src_type is a unique public non-virtual base of dst_type + // dst_ptr + src2dst == src_ptr + // -1: unspecified relationship + // -2: src_type is not a public base of dst_type + // -3: src_type is a multiple public non-virtual base of dst_type + extern "C" void* + __dynamic_cast(const void* __src_ptr, // Starting object. + const __class_type_info* __src_type, // Static type of object. + const __class_type_info* __dst_type, // Desired target type. + ptrdiff_t __src2dst); // How src and dst are related. + + + // Returns the type_info for the currently handled exception [15.3/8], or + // null if there is none. + extern "C" std::type_info* + __cxa_current_exception_type(); +} // namespace __cxxabiv1 + +// User programs should use the alias `abi'. +namespace abi = __cxxabiv1; + +#endif // __cplusplus + +#endif // __CXXABI_H diff --git a/src/include.new/c++/3.4/debug/bitset b/src/include.new/c++/3.4/debug/bitset new file mode 100644 index 0000000..2e2364f --- /dev/null +++ b/src/include.new/c++/3.4/debug/bitset @@ -0,0 +1,299 @@ +// Debugging bitset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_BITSET +#define _GLIBCXX_DEBUG_BITSET + +#include +#include +#include + +namespace __gnu_debug_def +{ + template + class bitset + : public _GLIBCXX_STD::bitset<_Nb>, + public __gnu_debug::_Safe_sequence_base + { + typedef _GLIBCXX_STD::bitset<_Nb> _Base; + typedef __gnu_debug::_Safe_sequence_base _Safe_base; + + public: + // bit reference: + class reference + : private _Base::reference, public __gnu_debug::_Safe_iterator_base + { + typedef typename _Base::reference _Base_ref; + + friend class bitset; + reference(); + + reference(const _Base_ref& __base, bitset* __seq) + : _Base_ref(__base), _Safe_iterator_base(__seq, false) + { } + + public: + reference(const reference& __x) + : _Base_ref(__x), _Safe_iterator_base(__x, false) + { } + + reference& + operator=(bool __x) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + reference& + operator=(const reference& __x) + { + _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + bool + operator~() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_flip) + ._M_iterator(*this)); + _Base_ref::flip(); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() : _Base() { } + + bitset(unsigned long __val) : _Base(__val) { } + + template + explicit + bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __pos = 0, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos)) + : _Base(__str, __pos, __n) { } + + bitset(const _Base& __x) : _Base(__x), _Safe_base() { } + + // 23.3.5.2 bitset operations: + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + _M_base() &= __rhs; + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + _M_base() |= __rhs; + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + _M_base() ^= __rhs; + return *this; + } + + bitset<_Nb>& + operator<<=(size_t __pos) + { + _M_base() <<= __pos; + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __pos) + { + _M_base() >>= __pos; + return *this; + } + + bitset<_Nb>& + set() + { + _Base::set(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 186. bitset::set() second parameter should be bool + bitset<_Nb>& + set(size_t __pos, bool __val = true) + { + _Base::set(__pos, __val); + return *this; + } + + bitset<_Nb>& + reset() + { + _Base::reset(); + return *this; + } + + bitset<_Nb>& + reset(size_t __pos) + { + _Base::reset(__pos); + return *this; + } + + bitset<_Nb> operator~() const { return bitset(~_M_base()); } + + bitset<_Nb>& + flip() + { + _Base::flip(); + return *this; + } + + bitset<_Nb>& + flip(size_t __pos) + { + _Base::flip(__pos); + return *this; + } + + // element access: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + reference + operator[](size_t __pos) + { + __glibcxx_check_subscript(__pos); + return reference(_M_base()[__pos], this); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + bool + operator[](size_t __pos) const + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::to_ulong; + + template + std::basic_string<_CharT, _Traits, _Allocator> + to_string() const + { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); } + + using _Base::count; + using _Base::size; + + bool + operator==(const bitset<_Nb>& __rhs) const + { return _M_base() == __rhs; } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return _M_base() != __rhs; } + + using _Base::test; + using _Base::any; + using _Base::none; + + bitset<_Nb> + operator<<(size_t __pos) const + { return bitset<_Nb>(_M_base() << __pos); } + + bitset<_Nb> + operator>>(size_t __pos) const + { return bitset<_Nb>(_M_base() >> __pos); } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template + bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template + bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template + bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { return __os << __x._M_base(); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/debug.h b/src/include.new/c++/3.4/debug/debug.h new file mode 100644 index 0000000..87bbcfa --- /dev/null +++ b/src/include.new/c++/3.4/debug/debug.h @@ -0,0 +1,531 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEBUG_H +#define _GLIBCXX_DEBUG_DEBUG_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +/** Macros used by the implementation outside of debug wrappers to + * verify certain properties. The __glibcxx_requires_xxx macros are + * merely wrappers around the __glibcxx_check_xxx wrappers when we + * are compiling with debug mode, but disappear when we are in + * release mode so that there is no checking performed in, e.g., the + * standard library algorithms. +*/ +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) + +# ifdef _GLIBXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition) +# else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# endif + +# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() +# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) +#else +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define __glibcxx_requires_cond(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() +# define __glibcxx_requires_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) +#endif + +#include // TBD: temporary + +#include // for ptrdiff_t +#include // for iterator_traits, categories +#include // for _Is_integer + +namespace __gnu_debug +{ + template + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return __gnu_debug::__valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#ifdef _GLIBCXX_DEBUG +// We need the error formatter +# include +#endif + +#endif diff --git a/src/include.new/c++/3.4/debug/deque b/src/include.new/c++/3.4/debug/deque new file mode 100644 index 0000000..c39a49c --- /dev/null +++ b/src/include.new/c++/3.4/debug/deque @@ -0,0 +1,386 @@ +// Debugging deque implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEQUE +#define _GLIBCXX_DEBUG_DEQUE 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class deque + : public _GLIBCXX_STD::deque<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.1.1 construct/copy/destroy: + explicit deque(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit deque(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template + deque(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } + + deque(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~deque() { } + + deque<_Tp,_Allocator>& + operator=(const deque<_Tp,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.1.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + bool __invalidate_all = __sz > this->size(); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + + _Base::resize(__sz, __c); + + if (__invalidate_all) + this->_M_invalidate_all(); + } + + using _Base::empty; + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.1.3 modifiers: + void + push_front(const _Tp& __x) + { + _Base::push_front(__x); + this->_M_invalidate_all(); + } + + void + push_back(const _Tp& __x) + { + _Base::push_back(__x); + this->_M_invalidate_all(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::insert(__position.base(), __x); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + this->_M_invalidate_all(); + } + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + if (__position == begin() || __position == end()-1) + { + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + else + { + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + if (__first == begin() || __last == end()) + { + this->_M_detach_singular(); + for (iterator __position = __first; __position != __last; ) + { + iterator __victim = __position++; + __victim._M_invalidate(); + } + try + { + return iterator(_Base::erase(__first.base(), __last.base()), + this); + } + catch (...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + else + { + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + void + swap(deque<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/formatter.h b/src/include.new/c++/3.4/debug/formatter.h new file mode 100644 index 0000000..db555b0 --- /dev/null +++ b/src/include.new/c++/3.4/debug/formatter.h @@ -0,0 +1,391 @@ +// Debug-mode error formatting implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_FORMATTER_H +#define _GLIBCXX_DEBUG_FORMATTER_H 1 + +#include +#include + +namespace __gnu_debug +{ + using std::type_info; + + /** Determine if the two types are the same. */ + template + struct __is_same + { + static const bool value = false; + }; + + template + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template struct __truth { }; + + class _Safe_sequence_base; + + template + class _Safe_iterator; + + template + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator { }; + struct _Is_sequence { }; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param), _M_variant() { } + + _Parameter(long __value, const char* __name) + : _M_kind(__integer), _M_variant() + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) + : _M_kind(__string), _M_variant() + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + + friend struct _Parameter; + + public: + template + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + template + void + _M_format_word(char*, int, const char*, _Tp) const; + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; +} // namespace __gnu_debug + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_map b/src/include.new/c++/3.4/debug/hash_map new file mode 100644 index 0000000..570a9af --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_map @@ -0,0 +1,38 @@ +// Debugging hash_map/hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP +#define _GLIBCXX_DEBUG_HASH_MAP 1 + +#include +#include +#include + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_map.h b/src/include.new/c++/3.4/debug/hash_map.h new file mode 100644 index 0000000..c2cd7b8 --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_map.h @@ -0,0 +1,270 @@ +// Debugging hash_map implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP_H +#define _GLIBCXX_DEBUG_HASH_MAP_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_map + : public __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_map() { } + + explicit hash_map(size_type __n) : _Base(__n) { } + + hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_map& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __res = _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::operator[]; + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_multimap.h b/src/include.new/c++/3.4/debug/hash_multimap.h new file mode 100644 index 0000000..83b4425 --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_multimap.h @@ -0,0 +1,261 @@ +// Debugging hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H +#define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multimap + : public __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multimap() { } + + explicit hash_multimap(size_type __n) : _Base(__n) { } + + hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multimap& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair __victims = this->equal_range(__key); + size_t __num_victims = 0; + while (__victims.first != __victims.second) + { + this->erase(__victims.first++); + ++__num_victims; + } + return __num_victims; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_multiset.h b/src/include.new/c++/3.4/debug/hash_multiset.h new file mode 100644 index 0000000..705d8da --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_multiset.h @@ -0,0 +1,236 @@ +// Debugging hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H +#define _GLIBCXX_DEBUG_HASH_MULTISET_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multiset + : public __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multiset() { } + + explicit hash_multiset(size_type __n) : _Base(__n) { } + + hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multiset& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair __victims = this->equal_range(__key); + while (__victims.first != __victims.second) + { + this->erase(__victims++); + ++__count; + } + return __count; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + +template + inline bool + operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + +template + inline bool + operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + +template + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_set b/src/include.new/c++/3.4/debug/hash_set new file mode 100644 index 0000000..282cba2 --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_set @@ -0,0 +1,38 @@ +// Debugging hash_set/hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET +#define _GLIBCXX_DEBUG_HASH_SET 1 + +#include +#include +#include + +#endif diff --git a/src/include.new/c++/3.4/debug/hash_set.h b/src/include.new/c++/3.4/debug/hash_set.h new file mode 100644 index 0000000..0f56d88 --- /dev/null +++ b/src/include.new/c++/3.4/debug/hash_set.h @@ -0,0 +1,245 @@ +// Debugging hash_set implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET_H +#define _GLIBCXX_DEBUG_HASH_SET_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_set + : public __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_set() { } + + explicit hash_set(size_type __n) : _Base(__n) { } + + hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_set(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_set& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() const { return iterator(_Base::begin(), this); } + + iterator + end() const { return iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __res = + _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/list b/src/include.new/c++/3.4/debug/list new file mode 100644 index 0000000..556c9d9 --- /dev/null +++ b/src/include.new/c++/3.4/debug/list @@ -0,0 +1,505 @@ +// Debugging list implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_LIST +#define _GLIBCXX_DEBUG_LIST 1 + +#include +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class list + : public _GLIBCXX_STD::list<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.2.1 construct/copy/destroy: + explicit list(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit list(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template + list(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + + list(const list& __x) : _Base(__x), _Safe_base() { } + + list(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~list() { } + + list& + operator=(const list& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.2.2 capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + this->_M_detach_singular(); + + // if __sz < size(), invalidate all iterators in [begin+__sz, end()) + iterator __victim = begin(); + iterator __end = end(); + for (size_type __i = __sz; __victim != __end && __i > 0; --__i) + ++__victim; + + while (__victim != __end) + { + iterator __real_victim = __victim++; + __real_victim._M_invalidate(); + } + + try + { + _Base::resize(__sz, __c); + } + catch(...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + + // element access: + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.2.3 modifiers: + using _Base::push_front; + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + using _Base::push_back; + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + } + + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + + iterator + erase(iterator __position, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__position, __last); + for (iterator __victim = __position; __victim != __last; ) + { + iterator __old = __victim; + ++__victim; + __old._M_invalidate(); + } + return iterator(_Base::erase(__position.base(), __last.base()), this); + } + + void + swap(list& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + // 23.2.2.4 list operations: + void + splice(iterator __position, list& __x) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this, + _M_message(::__gnu_debug::__msg_self_splice) + ._M_sequence(*this, "this")); + this->splice(__position, __x, __x.begin(), __x.end()); + } + + void + splice(iterator __position, list& __x, iterator __i) + { + __glibcxx_check_insert(__position); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x, "__x")); + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(::__gnu_debug::__msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__i); + _Base::splice(__position.base(), __x._M_base(), __i.base()); + } + + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + __glibcxx_check_insert(__position); + __glibcxx_check_valid_range(__first, __last); + _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_sequence(__x, "x") + ._M_iterator(__first, "first")); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x)); + + for (iterator __tmp = __first; __tmp != __last; ) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position, + _M_message(::__gnu_debug::__msg_splice_overlap) + ._M_iterator(__tmp, "position") + ._M_iterator(__first, "first") + ._M_iterator(__last, "last")); + iterator __victim = __tmp++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__victim); + } + + _Base::splice(__position.base(), __x._M_base(), __first.base(), + __last.base()); + } + + void + remove(const _Tp& __value) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (*__x == __value) + __x = erase(__x); + else + ++__x; + } + } + + template + void + remove_if(_Predicate __pred) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (__pred(*__x)) + __x = erase(__x); + else + ++__x; + } + } + + void + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + void + merge(list& __x) + { + __glibcxx_check_sorted(_Base::begin(), _Base::end()); + __glibcxx_check_sorted(__x.begin().base(), __x.end().base()); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base()); + } + + template + void + merge(list& __x, _Compare __comp) + { + __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); + __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), + __comp); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base(), __comp); + } + + void + sort() { _Base::sort(); } + + template + void + sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } + + using _Base::reverse; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/map b/src/include.new/c++/3.4/debug/map new file mode 100644 index 0000000..2c38404 --- /dev/null +++ b/src/include.new/c++/3.4/debug/map @@ -0,0 +1,38 @@ +// Debugging map/multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP +#define _GLIBCXX_DEBUG_MAP 1 + +#include +#include +#include + +#endif diff --git a/src/include.new/c++/3.4/debug/map.h b/src/include.new/c++/3.4/debug/map.h new file mode 100644 index 0000000..0171584 --- /dev/null +++ b/src/include.new/c++/3.4/debug/map.h @@ -0,0 +1,323 @@ +// Debugging map implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP_H +#define _GLIBCXX_DEBUG_MAP_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator > > + class map + : public _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit map(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a), _Safe_base() { } + + map(const map<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + map(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~map() { } + + map<_Key,_Tp,_Compare,_Allocator>& + operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 133. map missing get_allocator() + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // 23.3.1.2 element access: + using _Base::operator[]; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(map<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 map operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/multimap.h b/src/include.new/c++/3.4/debug/multimap.h new file mode 100644 index 0000000..4de1e3b --- /dev/null +++ b/src/include.new/c++/3.4/debug/multimap.h @@ -0,0 +1,314 @@ +// Debugging multimap implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTIMAP_H +#define _GLIBCXX_DEBUG_MULTIMAP_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator > > + class multimap + : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit multimap(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multimap(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multimap() { } + + multimap<_Key,_Tp,_Compare,_Allocator>& + operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 multimap operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/multiset.h b/src/include.new/c++/3.4/debug/multiset.h new file mode 100644 index 0000000..92042fe --- /dev/null +++ b/src/include.new/c++/3.4/debug/multiset.h @@ -0,0 +1,320 @@ +// Debugging multiset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTISET_H +#define _GLIBCXX_DEBUG_MULTISET_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator<_Key> > + class multiset + : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit multiset(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multiset(const multiset<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multiset() { } + + multiset<_Key,_Compare,_Allocator>& + operator=(const multiset<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multiset<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // multiset operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/safe_base.h b/src/include.new/c++/3.4/debug/safe_base.h new file mode 100644 index 0000000..a1af33a --- /dev/null +++ b/src/include.new/c++/3.4/debug/safe_base.h @@ -0,0 +1,207 @@ +// Safe sequence/iterator base implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H +#define _GLIBCXX_DEBUG_SAFE_BASE_H 1 + +namespace __gnu_debug +{ + class _Safe_sequence_base; + + /** \brief Basic functionality for a "safe" iterator. + * + * The %_Safe_iterator_base base class implements the functionality + * of a safe iterator that is not specific to a particular iterator + * type. It contains a pointer back to the sequence it references + * along with iterator version information and pointers to form a + * doubly-linked list of iterators referenced by the container. + * + * This class must not perform any operations that can throw an + * exception, or the exception guarantees of derived iterators will + * be broken. + */ + class _Safe_iterator_base + { + public: + /** The sequence this iterator references; may be NULL to indicate + a singular iterator. */ + _Safe_sequence_base* _M_sequence; + + /** The version number of this iterator. The sentinel value 0 is + * used to indicate an invalidated iterator (i.e., one that is + * singular because of an operation on the container). This + * version number must equal the version number in the sequence + * referenced by _M_sequence for the iterator to be + * non-singular. + */ + unsigned int _M_version; + + /** Pointer to the previous iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_prior; + + /** Pointer to the next iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_next; + + protected: + /** Initializes the iterator and makes it singular. */ + _Safe_iterator_base() + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { } + + /** Initialize the iterator to reference the sequence pointed to + * by @p__seq. @p __constant is true when we are initializing a + * constant iterator, and false if it is a mutable iterator. Note + * that @p __seq may be NULL, in which case the iterator will be + * singular. Otherwise, the iterator will reference @p __seq and + * be nonsingular. + */ + _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + + /** Initializes the iterator to reference the same sequence that + @p __x does. @p __constant is true if this is a constant + iterator, and false if it is mutable. */ + _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(__x._M_sequence, __constant); } + + _Safe_iterator_base& + operator=(const _Safe_iterator_base&); + + explicit + _Safe_iterator_base(const _Safe_iterator_base&); + + ~_Safe_iterator_base() { this->_M_detach(); } + + public: + /** Attaches this iterator to the given sequence, detaching it + * from whatever sequence it was attached to originally. If the + * new sequence is the NULL pointer, the iterator is left + * unattached. + */ + void _M_attach(_Safe_sequence_base* __seq, bool __constant); + + /** Detach the iterator for whatever sequence it is attached to, + * if any. + */ + void _M_detach(); + + /** Determines if we are attached to the given sequence. */ + bool _M_attached_to(const _Safe_sequence_base* __seq) const + { return _M_sequence == __seq; } + + /** Is this iterator singular? */ + bool _M_singular() const; + + /** Can we compare this iterator to the given iterator @p __x? + Returns true if both iterators are nonsingular and reference + the same sequence. */ + bool _M_can_compare(const _Safe_iterator_base& __x) const; + }; + + /** + * @brief Base class that supports tracking of iterators that + * reference a sequence. + * + * The %_Safe_sequence_base class provides basic support for + * tracking iterators into a sequence. Sequences that track + * iterators must derived from %_Safe_sequence_base publicly, so + * that safe iterators (which inherit _Safe_iterator_base) can + * attach to them. This class contains two linked lists of + * iterators, one for constant iterators and one for mutable + * iterators, and a version number that allows very fast + * invalidation of all iterators that reference the container. + * + * This class must ensure that no operation on it may throw an + * exception, otherwise "safe" sequences may fail to provide the + * exception-safety guarantees required by the C++ standard. + */ + class _Safe_sequence_base + { + public: + /// The list of mutable iterators that reference this container + _Safe_iterator_base* _M_iterators; + + /// The list of constant iterators that reference this container + _Safe_iterator_base* _M_const_iterators; + + /// The container version number. This number may never be 0. + mutable unsigned int _M_version; + + protected: + // Initialize with a version number of 1 and no iterators + _Safe_sequence_base() + : _M_iterators(0), _M_const_iterators(0), _M_version(1) + { } + + /** Notify all iterators that reference this sequence that the + sequence is being destroyed. */ + ~_Safe_sequence_base() + { this->_M_detach_all(); } + + /** Detach all iterators, leaving them singular. */ + void + _M_detach_all(); + + /** Detach all singular iterators. + * @post for all iterators i attached to this sequence, + * i->_M_version == _M_version. + */ + void + _M_detach_singular(); + + /** Revalidates all attached singular iterators. This method may + * be used to validate iterators that were invalidated before + * (but for some reasion, such as an exception, need to become + * valid again). + */ + void + _M_revalidate_singular(); + + /** Swap this sequence with the given sequence. This operation + * also swaps ownership of the iterators, so that when the + * operation is complete all iterators that originally referenced + * one container now reference the other container. + */ + void + _M_swap(_Safe_sequence_base& __x); + + public: + /** Invalidates all iterators. */ + void + _M_invalidate_all() const + { if (++_M_version == 0) _M_version = 1; } + }; +} // namespace __gnu_debug + +#endif diff --git a/src/include.new/c++/3.4/debug/safe_iterator.h b/src/include.new/c++/3.4/debug/safe_iterator.h new file mode 100644 index 0000000..8a4123a --- /dev/null +++ b/src/include.new/c++/3.4/debug/safe_iterator.h @@ -0,0 +1,618 @@ +// Safe iterator implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 + +#include +#include +#include +#include +#include + +namespace __gnu_debug +{ + using std::iterator_traits; + using std::pair; + + /** Iterators that derive from _Safe_iterator_base but that aren't + * _Safe_iterators can be determined singular or non-singular via + * _Safe_iterator_base. + */ + inline bool __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + + /** \brief Safe iterator wrapper. + * + * The class template %_Safe_iterator is a wrapper around an + * iterator that tracks the iterator's movement among sequences and + * checks that operations performed on the "safe" iterator are + * legal. In additional to the basic iterator operations (which are + * validated, and then passed to the underlying iterator), + * %_Safe_iterator has member functions for iterator invalidation, + * attaching/detaching the iterator from sequences, and querying + * the iterator's state. + */ + template + class _Safe_iterator : public _Safe_iterator_base + { + typedef _Safe_iterator _Self; + + /** The precision to which we can calculate the distance between + * two iterators. + */ + enum _Distance_precision + { + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_exact //< Can determine distance precisely + }; + + /// The underlying iterator + _Iterator _M_current; + + /// Determine if this is a constant iterator. + bool + _M_constant() const + { + typedef typename _Sequence::const_iterator const_iterator; + return __is_same::value; + } + + typedef iterator_traits<_Iterator> _Traits; + + public: + typedef _Iterator _Base_iterator; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + + /// @post the iterator is singular and unattached + _Safe_iterator() : _M_current() { } + + /** + * @brief Safe iterator construction from an unsafe iterator and + * its sequence. + * + * @pre @p seq is not NULL + * @post this is not singular + */ + _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__msg_init_singular) + ._M_iterator(*this, "this")); + } + + /** + * @brief Copy construction. + * @pre @p x is not singular + */ + _Safe_iterator(const _Safe_iterator& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Converting constructor from a mutable iterator to a + * constant iterator. + * + * @pre @p x is not singular + */ + template + _Safe_iterator( + const _Safe_iterator<_MutableIterator, + typename std::__enable_if< + _Sequence, + (std::__are_same<_MutableIterator, + typename _Sequence::iterator::_Base_iterator>::_M_type) + >::_M_type>& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_const_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Copy assignment. + * @pre @p x is not singular + */ + _Safe_iterator& + operator=(const _Safe_iterator& __x) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + _M_current = __x._M_current; + this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); + return *this; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + */ + reference + operator*() const + { + + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + * @todo Make this correct w.r.t. iterators that return proxies + * @todo Use addressof() instead of & operator + */ + pointer + operator->() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return &*_M_current; + } + + // ------ Input iterator requirements ------ + /** + * @brief Iterator preincrement + * @pre iterator is incrementable + */ + _Safe_iterator& + operator++() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + ++_M_current; + return *this; + } + + /** + * @brief Iterator postincrement + * @pre iterator is incrementable + */ + _Safe_iterator + operator++(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + ++_M_current; + return __tmp; + } + + // ------ Bidirectional iterator requirements ------ + /** + * @brief Iterator predecrement + * @pre iterator is decrementable + */ + _Safe_iterator& + operator--() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + --_M_current; + return *this; + } + + /** + * @brief Iterator postdecrement + * @pre iterator is decrementable + */ + _Safe_iterator + operator--(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + --_M_current; + return __tmp; + } + + // ------ Random access iterator requirements ------ + reference + operator[](const difference_type& __n) const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) + && this->_M_can_advance(__n+1), + _M_message(__msg_iter_subscript_oob) + ._M_iterator(*this)._M_integer(__n)); + + return _M_current[__n]; + } + + _Safe_iterator& + operator+=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), + _M_message(__msg_advance_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += __n; + return *this; + } + + _Safe_iterator + operator+(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp += __n; + return __tmp; + } + + _Safe_iterator& + operator-=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), + _M_message(__msg_retreat_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += -__n; + return *this; + } + + _Safe_iterator + operator-(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp -= __n; + return __tmp; + } + + // ------ Utilities ------ + /** + * @brief Return the underlying iterator + */ + _Iterator + base() const { return _M_current; } + + /** + * @brief Conversion to underlying non-debug iterator to allow + * better interaction with non-debug containers. + */ + operator _Iterator() const { return _M_current; } + + /** Attach iterator to the given sequence. */ + void + _M_attach(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Invalidate the iterator, making it singular. */ + void + _M_invalidate(); + + /// Is the iterator dereferenceable? + bool + _M_dereferenceable() const + { return !this->_M_singular() && !_M_is_end(); } + + /// Is the iterator incrementable? + bool + _M_incrementable() const { return this->_M_dereferenceable(); } + + // Is the iterator decrementable? + bool + _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } + + // Can we advance the iterator @p __n steps (@p __n may be negative) + bool + _M_can_advance(const difference_type& __n) const; + + // Is the iterator range [*this, __rhs) valid? + template + bool + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + + // The sequence this iterator references. + const _Sequence* + _M_get_sequence() const + { return static_cast(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + { + typedef typename iterator_traits<_Iterator1>::iterator_category + _Category; + return _M_get_distance(__lhs, __rhs, _Category()); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::random_access_iterator_tag) + { + return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::forward_iterator_tag) + { + return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, + __dp_equality); + } + + /// Is this iterator equal to the sequence's begin() iterator? + bool _M_is_begin() const + { return *this == static_cast(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast(_M_sequence)->end(); } + }; + + template + inline bool + operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type + operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template + inline _Safe_iterator<_Iterator, _Sequence> + operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, + const _Safe_iterator<_Iterator, _Sequence>& __i) + { return __i + __n; } +} // namespace __gnu_debug + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif diff --git a/src/include.new/c++/3.4/debug/safe_iterator.tcc b/src/include.new/c++/3.4/debug/safe_iterator.tcc new file mode 100644 index 0000000..cede969 --- /dev/null +++ b/src/include.new/c++/3.4/debug/safe_iterator.tcc @@ -0,0 +1,140 @@ +// Debugging iterator implementation (out of line) -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file safe_iterator.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1 + +namespace __gnu_debug +{ + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_can_advance(const difference_type& __n) const + { + typedef typename _Sequence::const_iterator const_iterator; + + if (this->_M_singular()) + return false; + if (__n == 0) + return true; + if (__n < 0) + { + const_iterator __begin = + static_cast(_M_sequence)->begin(); + pair __dist = + this->_M_get_distance(__begin, *this); + bool __ok = (__dist.second == __dp_exact && __dist.first >= -__n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + else + { + const_iterator __end = + static_cast(_M_sequence)->end(); + pair __dist = + this->_M_get_distance(*this, __end); + bool __ok = (__dist.second == __dp_exact && __dist.first >= __n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + } + + template + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + + /* Determine if we can order the iterators without the help of + the container */ + pair __dist = + this->_M_get_distance(*this, __rhs); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) + return true; + break; + + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; + } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + if (_M_is_begin() || __rhs._M_is_end()) + return true; + else if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } + + template + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate() + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + if (!this->_M_singular()) + { + for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter; ) + { + iterator* __victim = static_cast(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + for (_Safe_iterator_base* iter2 = _M_sequence->_M_const_iterators; + iter2; /* increment in loop */) + { + const_iterator* __victim = static_cast(iter2); + iter2 = iter2->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } +} // namespace __gnu_debug + +#endif + diff --git a/src/include.new/c++/3.4/debug/safe_sequence.h b/src/include.new/c++/3.4/debug/safe_sequence.h new file mode 100644 index 0000000..f050530 --- /dev/null +++ b/src/include.new/c++/3.4/debug/safe_sequence.h @@ -0,0 +1,180 @@ +// Safe sequence implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H +#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 + +#include +#include + +namespace __gnu_debug +{ + template + class _Safe_iterator; + + /** A simple function object that returns true if the passed-in + * value is not equal to the stored value. It saves typing over + * using both bind1st and not_equal. + */ + template + class _Not_equal_to + { + _Type __value; + + public: + explicit _Not_equal_to(const _Type& __v) : __value(__v) { } + + bool + operator()(const _Type& __x) const + { return __value != __x; } + }; + + /** A function object that returns true when the given random access + iterator is at least @c n steps away from the given iterator. */ + template + class _After_nth_from + { + typedef typename std::iterator_traits<_Iterator>::difference_type + difference_type; + + _Iterator _M_base; + difference_type _M_n; + + public: + _After_nth_from(const difference_type& __n, const _Iterator& __base) + : _M_base(__base), _M_n(__n) { } + + bool + operator()(const _Iterator& __x) const + { return __x - _M_base >= _M_n; } + }; + + /** + * @brief Base class for constructing a "safe" sequence type that + * tracks iterators that reference it. + * + * The class template %_Safe_sequence simplifies the construction of + * "safe" sequences that track the iterators that reference the + * sequence, so that the iterators are notified of changes in the + * sequence that may affect their operation, e.g., if the container + * invalidates its iterators or is destructed. This class template + * may only be used by deriving from it and passing the name of the + * derived class as its template parameter via the curiously + * recurring template pattern. The derived class must have @c + * iterator and @const_iterator types that are instantiations of + * class template _Safe_iterator for this sequence. Iterators will + * then be tracked automatically. + */ + template + class _Safe_sequence : public _Safe_sequence_base + { + public: + /** Invalidates all iterators @c x that reference this sequence, + are not singular, and for which @c pred(x) returns @c + true. The user of this routine should be careful not to make + copies of the iterators passed to @p pred, as the copies may + interfere with the invalidation. */ + template + void + _M_invalidate_if(_Predicate __pred); + + /** Transfers all iterators that reference this memory location + to this sequence from whatever sequence they are attached + to. */ + template + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template + template + void + _Safe_sequence<_Sequence>:: + _M_invalidate_if(_Predicate __pred) + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + } + + template + template + void + _Safe_sequence<_Sequence>:: + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x) + { + _Safe_sequence_base* __from = __x._M_sequence; + if (!__from) + return; + + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + + for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; + __iter2;) + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + } +} // namespace __gnu_debug + +#endif diff --git a/src/include.new/c++/3.4/debug/set b/src/include.new/c++/3.4/debug/set new file mode 100644 index 0000000..a1a69ef --- /dev/null +++ b/src/include.new/c++/3.4/debug/set @@ -0,0 +1,38 @@ +// Debugging set/multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET +#define _GLIBCXX_DEBUG_SET 1 + +#include +#include +#include + +#endif diff --git a/src/include.new/c++/3.4/debug/set.h b/src/include.new/c++/3.4/debug/set.h new file mode 100644 index 0000000..8656cb0 --- /dev/null +++ b/src/include.new/c++/3.4/debug/set.h @@ -0,0 +1,325 @@ +// Debugging set implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET_H +#define _GLIBCXX_DEBUG_SET_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator<_Key> > + class set + : public _GLIBCXX_STD::set<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::set<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit set(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + set(const set<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + set(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~set() { } + + set<_Key,_Compare,_Allocator>& + operator=(const set<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + while (__first != __last) + this->erase(__first++); + } + + void + swap(set<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // set operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/debug/string b/src/include.new/c++/3.4/debug/string new file mode 100644 index 0000000..a91c004 --- /dev/null +++ b/src/include.new/c++/3.4/debug/string @@ -0,0 +1,1001 @@ +// Debugging string implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_STRING +#define _GLIBCXX_DEBUG_STRING 1 + +#include +#include +#include + +namespace __gnu_debug +{ + template + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::npos; + + // 21.3.1 construct/copy/destroy: + explicit basic_string(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + // Provides conversion from a release-mode string to a debug-mode string + basic_string(const _Base& __base) : _Base(__base), _Safe_base() { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str) + : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base() + { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str, size_type __pos, + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) + { } + + basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) + { } + + basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s), __a) + { this->assign(__s); } + + basic_string(size_type __n, _CharT __c, + const _Allocator& __a = _Allocator()) + : _Base(__n, __c, __a) + { } + + template + basic_string(_InputIterator __begin, _InputIterator __end, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a) + { } + + ~basic_string() { } + + basic_string& + operator=(const basic_string& __str) + { + *static_cast<_Base*>(this) = __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(const _CharT* __s) + { + __glibcxx_check_string(__s); + *static_cast<_Base*>(this) = __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(_CharT __c) + { + *static_cast<_Base*>(this) = __c; + this->_M_invalidate_all(); + return *this; + } + + // 21.3.2 iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 21.3.3 capacity: + using _Base::size; + using _Base::length; + using _Base::max_size; + + void + resize(size_type __n, _CharT __c) + { + _Base::resize(__n, __c); + this->_M_invalidate_all(); + } + + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + using _Base::capacity; + using _Base::reserve; + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::empty; + + // 21.3.4 element access: + const_reference + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(::__gnu_debug::__msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); + return _M_base()[__pos]; + } + + reference + operator[](size_type __pos) + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::at; + + // 21.3.5 modifiers: + basic_string& + operator+=(const basic_string& __str) + { + _M_base() += __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(const _CharT* __s) + { + __glibcxx_check_string(__s); + _M_base() += __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(_CharT __c) + { + _M_base() += __c; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str) + { + _Base::append(__str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::append(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::append(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::append(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(size_type __n, _CharT __c) + { + _Base::append(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::append(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 7. string clause minor problems + void + push_back(_CharT __c) + { + _Base::push_back(__c); + this->_M_invalidate_all(); + } + + basic_string& + assign(const basic_string& __x) + { + _Base::assign(__x); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::assign(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::assign(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::assign(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(size_type __n, _CharT __c) + { + _Base::assign(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + _Base::insert(__pos1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + _Base::insert(__pos1, __str, __pos2, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + _Base::insert(__pos, __n, __c); + this->_M_invalidate_all(); + return *this; + } + + iterator + insert(iterator __p, _CharT __c) + { + __glibcxx_check_insert(__p); + typename _Base::iterator __res = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __p, size_type __n, _CharT __c) + { + __glibcxx_check_insert(__p); + _Base::insert(__p.base(), __n, __c); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __p, _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__p, __first, __last); + _Base::insert(__p.base(), __first, __last); + this->_M_invalidate_all(); + } + + basic_string& + erase(size_type __pos = 0, size_type __n = _Base::npos) + { + _Base::erase(__pos, __n); + this->_M_invalidate_all(); + return *this; + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str) + { + _Base::replace(__pos1, __n1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + _Base::replace(__pos1, __n1, __str, __pos2, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_check_string_len(__s, __n2); + _Base::replace(__pos, __n1, __s, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::replace(__pos, __n1, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + _Base::replace(__pos, __n1, __n2, __c); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string_len(__s, __n); + _Base::replace(__i1.base(), __i2.base(), __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string(__s); + _Base::replace(__i1.base(), __i2.base(), __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __j1, _InputIterator __j2) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_valid_range(__j1, __j2); + _Base::replace(__i1.base(), __i2.base(), __j1, __j2); + this->_M_invalidate_all(); + return *this; + } + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::copy(__s, __n, __pos); + } + + void + swap(basic_string<_CharT,_Traits,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + this->_M_invalidate_all(); + __x._M_invalidate_all(); + } + + // 21.3.6 string operations: + const _CharT* + c_str() const + { + const _CharT* __res = _Base::c_str(); + this->_M_invalidate_all(); + return __res; + } + + const _CharT* + data() const + { + const _CharT* __res = _Base::data(); + this->_M_invalidate_all(); + return __res; + } + + using _Base::get_allocator; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return _Base::find(__str, __pos); } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos, __n); + } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos); + } + + size_type + find(_CharT __c, size_type __pos = 0) const + { return _Base::find(__c, __pos); } + + size_type + rfind(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::rfind(__str, __pos); } + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::rfind(__s, __pos, __n); + } + + size_type + rfind(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::rfind(__s, __pos); + } + + size_type + rfind(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::rfind(__c, __pos); } + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_of(__str, __pos); } + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos, __n); + } + + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos); + } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_of(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__str, __pos); } + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos, __n); + } + + size_type + find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos); + } + + size_type + find_last_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_not_of(__str, __pos); } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::find_first_not_of(__s, __pos, __n); + } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_not_of(__s, __pos); + } + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_not_of(__c, __pos); } + + size_type + find_last_not_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__str, __pos); } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos, __n); + } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos); + } + + size_type + find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__c, __pos); } + + basic_string + substr(size_type __pos = 0, size_type __n = _Base::npos) const + { return basic_string(_Base::substr(__pos, __n)); } + + int + compare(const basic_string& __str) const + { return _Base::compare(__str); } + + int + compare(size_type __pos1, size_type __n1, + const basic_string& __str) const + { return _Base::compare(__pos1, __n1, __str); } + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } + + int + compare(const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__pos1, __n1, __s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1,const _CharT* __s, + size_type __n2) const + { + __glibcxx_check_string_len(__s, __n2); + return _Base::compare(__pos1, __n1, __s, __n2); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + using _Safe_base::_M_invalidate_all; + }; + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(_CharT __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + _CharT __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() > __rhs; + } + + // 21.3.7.8: + template + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Allocator>& __str) + { return __os << __str._M_base(); } + + template + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __res; + } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __res; + } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __res; + } +} // namespace __gnu_debug + +#endif diff --git a/src/include.new/c++/3.4/debug/vector b/src/include.new/c++/3.4/debug/vector new file mode 100644 index 0000000..0cc2997 --- /dev/null +++ b/src/include.new/c++/3.4/debug/vector @@ -0,0 +1,412 @@ +// Debugging vector implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_VECTOR +#define _GLIBCXX_DEBUG_VECTOR 1 + +#include +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class vector + : public _GLIBCXX_STD::vector<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.4.1 construct/copy/destroy: + explicit vector(const _Allocator& __a = _Allocator()) + : _Base(__a), _M_guaranteed_capacity(0) { } + + explicit vector(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } + + template + vector(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), + __last, __a), + _M_guaranteed_capacity(0) + { _M_update_guaranteed_capacity(); } + + vector(const vector<_Tp,_Allocator>& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + /// Construction from a release-mode vector + vector(const _Base& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + ~vector() { } + + vector<_Tp,_Allocator>& + operator=(const vector<_Tp,_Allocator>& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.4.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + bool __realloc = _M_requires_reallocation(__sz); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + _Base::resize(__sz, __c); + if (__realloc) + this->_M_invalidate_all(); + } + + using _Base::capacity; + using _Base::empty; + + void + reserve(size_type __n) + { + bool __realloc = _M_requires_reallocation(__n); + _Base::reserve(__n); + if (__n > _M_guaranteed_capacity) + _M_guaranteed_capacity = __n; + if (__realloc) + this->_M_invalidate_all(); + } + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.4.3 modifiers: + void + push_back(const _Tp& __x) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(__x); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end() - 1; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::insert(__position.base(),__x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + __n); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __n, __x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + + /* Hard to guess if invalidation will occur, because __last + - __first can't be calculated in all cases, so we just + punt here by checking if it did occur. */ + typename _Base::iterator __old_begin = _M_base().begin(); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __first, __last); + + if (_M_base().begin() != __old_begin) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + difference_type __offset = __first - begin(); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + void + swap(vector<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + _M_guaranteed_capacity = 0; + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + size_type _M_guaranteed_capacity; + + bool + _M_requires_reallocation(size_type __elements) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + return __elements > this->capacity(); +#else + return __elements > _M_guaranteed_capacity; +#endif + } + + void + _M_update_guaranteed_capacity() + { + if (this->size() > _M_guaranteed_capacity) + _M_guaranteed_capacity = this->size(); + } + }; + + template + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/src/include.new/c++/3.4/deque b/src/include.new/c++/3.4/deque new file mode 100644 index 0000000..80817f6 --- /dev/null +++ b/src/include.new/c++/3.4/deque @@ -0,0 +1,81 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file deque + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_DEQUE +#define _GLIBCXX_DEQUE 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_DEQUE */ diff --git a/src/include.new/c++/3.4/exception b/src/include.new/c++/3.4/exception new file mode 100644 index 0000000..6a1a194 --- /dev/null +++ b/src/include.new/c++/3.4/exception @@ -0,0 +1,120 @@ +// Exception Handling support header for -*- C++ -*- + +// Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file exception + * This header defines several types and functions relating to the + * handling of exceptions in a C++ program. + */ + +#ifndef __EXCEPTION__ +#define __EXCEPTION__ + +extern "C++" { + +namespace std +{ + /** + * @brief Base class for all library exceptions. + * + * This is the base class for all exceptions thrown by the standard + * library, and by certain language expressions. You are free to derive + * your own %exception classes, or use a different hierarchy, or to + * throw non-class data (e.g., fundamental types). + */ + class exception + { + public: + exception() throw() { } + virtual ~exception() throw(); + /** Returns a C-style character string describing the general cause + * of the current error. */ + virtual const char* what() const throw(); + }; + + /** If an %exception is thrown which is not listed in a function's + * %exception specification, one of these may be thrown. */ + class bad_exception : public exception + { + public: + bad_exception() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_exception() throw(); + }; + + /// If you write a replacement %terminate handler, it must be of this type. + typedef void (*terminate_handler) (); + /// If you write a replacement %unexpected handler, it must be of this type. + typedef void (*unexpected_handler) (); + + /// Takes a new handler function as an argument, returns the old function. + terminate_handler set_terminate(terminate_handler) throw(); + /** The runtime will call this function if %exception handling must be + * abandoned for any reason. It can also be called by the user. */ + void terminate() __attribute__ ((__noreturn__)); + + /// Takes a new handler function as an argument, returns the old function. + unexpected_handler set_unexpected(unexpected_handler) throw(); + /** The runtime will call this function if an %exception is thrown which + * violates the function's %exception specification. */ + void unexpected() __attribute__ ((__noreturn__)); + + /** [18.6.4]/1: "Returns true after completing evaluation of a + * throw-expression until either completing initialization of the + * exception-declaration in the matching handler or entering @c unexpected() + * due to the throw; or after entering @c terminate() for any reason + * other than an explicit call to @c terminate(). [Note: This includes + * stack unwinding [15.2]. end note]" + * + * 2: "When @c uncaught_exception() is true, throwing an %exception can + * result in a call of @c terminate() (15.5.1)." + */ + bool uncaught_exception() throw(); +} // namespace std + +namespace __gnu_cxx +{ + /** A replacement for the standard terminate_handler which prints more + information about the terminating exception (if any) on stderr. Call + @code + std::set_terminate (__gnu_cxx::__verbose_terminate_handler) + @endcode + to use. For more info, see + http://gcc.gnu.org/onlinedocs/libstdc++/19_diagnostics/howto.html#4 + + In 3.4 and later, this is on by default. + */ + void __verbose_terminate_handler (); +} // namespace __gnu_cxx + +} // extern "C++" + +#endif diff --git a/src/include.new/c++/3.4/exception_defines.h b/src/include.new/c++/3.4/exception_defines.h new file mode 100644 index 0000000..1466486 --- /dev/null +++ b/src/include.new/c++/3.4/exception_defines.h @@ -0,0 +1,47 @@ +// -fno-exceptions Support -*- C++ -*- + +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#ifndef _EXCEPTION_DEFINES_H +#define _EXCEPTION_DEFINES_H 1 + +#ifndef __EXCEPTIONS +// Iff -fno-exceptions, transform error handling code to work without it. +# define try if (true) +# define catch(X) if (false) +# define __throw_exception_again +#else +// Else proceed normally. +# define __throw_exception_again throw +#endif + +#endif diff --git a/src/include.new/c++/3.4/ext/algorithm b/src/include.new/c++/3.4/ext/algorithm new file mode 100644 index 0000000..07ac4cb --- /dev/null +++ b/src/include.new/c++/3.4/ext/algorithm @@ -0,0 +1,518 @@ +// Algorithm extensions -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/algorithm + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_ALGORITHM +#define _EXT_ALGORITHM 1 + +#pragma GCC system_header + +#include + +namespace __gnu_cxx +{ + using std::ptrdiff_t; + using std::min; + using std::pair; + using std::input_iterator_tag; + using std::random_access_iterator_tag; + using std::iterator_traits; + + //-------------------------------------------------- + // copy_n (not part of the C++ standard) + + template + pair<_InputIterator, _OutputIterator> + __copy_n(_InputIterator __first, _Size __count, + _OutputIterator __result, + input_iterator_tag) + { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIterator, _OutputIterator>(__first, __result); + } + + template + inline pair<_RAIterator, _OutputIterator> + __copy_n(_RAIterator __first, _Size __count, + _OutputIterator __result, + random_access_iterator_tag) + { + _RAIterator __last = __first + __count; + return pair<_RAIterator, _OutputIterator>(__last, + std::copy(__first, __last, __result)); + } + + /** + * @brief Copies the range [first,first+count) into [result,result+count). + * @param first An input iterator. + * @param count The number of elements to copy. + * @param result An output iterator. + * @return A std::pair composed of first+count and result+count. + * + * This is an SGI extension. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * @ingroup SGIextensions + */ + template + inline pair<_InputIterator, _OutputIterator> + copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + + return __copy_n(__first, __count, __result, + std::__iterator_category(__first)); + } + + template + int + __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) { + return !(__first1 == __last1); + } + else { + return -1; + } + } + + inline int + __lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); + } + + inline int + __lexicographical_compare_3way(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { +#if CHAR_MAX == SCHAR_MAX + return __lexicographical_compare_3way( + (const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif + } + + /** + * @brief @c memcmp on steroids. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return An int, as with @c memcmp. + * + * The return value will be less than zero if the first range is + * "lexigraphically less than" the second, greater than zero if the second + * range is "lexigraphically less than" the first, and zero otherwise. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + int + lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); + } + + // count and count_if: this version, whose return type is void, was present + // in the HP STL, and is retained as an extension for backward compatibility. + + template + void + count(_InputIterator __first, _InputIterator __last, + const _Tp& __value, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + } + + template + void + count_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + } + + // random_sample and random_sample_n (extensions, not part of the standard). + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if ((std::rand() % __remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; + } + + template + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + const _Distance __n) + { + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = std::rand() % (__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; + } + + template + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + _RandomNumberGenerator& __rand, + const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __last - __first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __comp, __last - __first); + } + + // is_sorted, a predicated testing whether a range is sorted in + // nondescending order. This is an extension, not part of the C++ + // standard. + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) + return false; + } + + return true; + } +} // namespace __gnu_cxx + +#endif /* _EXT_ALGORITHM */ diff --git a/src/include.new/c++/3.4/ext/bitmap_allocator.h b/src/include.new/c++/3.4/ext/bitmap_allocator.h new file mode 100644 index 0000000..9a0d162 --- /dev/null +++ b/src/include.new/c++/3.4/ext/bitmap_allocator.h @@ -0,0 +1,859 @@ +// Bitmapped Allocator. -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + + +#if !defined _BITMAP_ALLOCATOR_H +#define _BITMAP_ALLOCATOR_H 1 + +#include +//For std::size_t, and ptrdiff_t. +#include +//For std::pair. +#include +//std::find_if, and std::lower_bound. +#include +//For the free list of exponentially growing memory blocks. At max, +//size of the vector should be not more than the number of bits in an +//integer or an unsigned integer. +#include +//For greater_equal, and less_equal. +#include +//For operator new. +#include +//For __gthread_mutex_t, __gthread_mutex_lock and __gthread_mutex_unlock. +#include +//For __gnu_cxx::new_allocator for std::vector. + +#include +#define NDEBUG + +//#define CHECK_FOR_ERRORS +//#define __CPU_HAS_BACKWARD_BRANCH_PREDICTION + +namespace __gnu_cxx +{ + namespace { +#if defined __GTHREADS + bool const __threads_enabled = __gthread_active_p(); +#endif + + } + +#if defined __GTHREADS + class _Mutex { + __gthread_mutex_t _M_mut; + //Prevent Copying and assignment. + _Mutex (_Mutex const&); + _Mutex& operator= (_Mutex const&); + public: + _Mutex () + { + if (__threads_enabled) + { +#if !defined __GTHREAD_MUTEX_INIT + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mut); +#else + __gthread_mutex_t __mtemp = __GTHREAD_MUTEX_INIT; + _M_mut = __mtemp; +#endif + } + } + ~_Mutex () + { + //Gthreads does not define a Mutex Destruction Function. + } + __gthread_mutex_t *_M_get() { return &_M_mut; } + }; + + class _Lock { + _Mutex* _M_pmt; + bool _M_locked; + //Prevent Copying and assignment. + _Lock (_Lock const&); + _Lock& operator= (_Lock const&); + public: + _Lock(_Mutex* __mptr) + : _M_pmt(__mptr), _M_locked(false) + { this->_M_lock(); } + void _M_lock() + { + if (__threads_enabled) + { + _M_locked = true; + __gthread_mutex_lock(_M_pmt->_M_get()); + } + } + void _M_unlock() + { + if (__threads_enabled) + { + if (__builtin_expect(_M_locked, true)) + { + __gthread_mutex_unlock(_M_pmt->_M_get()); + _M_locked = false; + } + } + } + ~_Lock() { this->_M_unlock(); } + }; +#endif + + + + namespace __aux_balloc { + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + template + inline size_t __balloc_num_blocks (_Addr_Pair_t __ap) + { + return (__ap.second - __ap.first) + 1; + } + + template + inline size_t __balloc_num_bit_maps (_Addr_Pair_t __ap) + { + return __balloc_num_blocks(__ap) / _Bits_Per_Block; + } + + //T should be a pointer type. + template + class _Inclusive_between : public std::unary_function, bool> { + typedef _Tp pointer; + pointer _M_ptr_value; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + public: + _Inclusive_between (pointer __ptr) : _M_ptr_value(__ptr) { } + bool operator () (_Block_pair __bp) const throw () + { + if (std::less_equal ()(_M_ptr_value, __bp.second) && + std::greater_equal ()(_M_ptr_value, __bp.first)) + return true; + else + return false; + } + }; + + //Used to pass a Functor to functions by reference. + template + class _Functor_Ref : + public std::unary_function { + _Functor& _M_fref; + + public: + typedef typename _Functor::argument_type argument_type; + typedef typename _Functor::result_type result_type; + + _Functor_Ref (_Functor& __fref) : _M_fref(__fref) { } + result_type operator() (argument_type __arg) { return _M_fref (__arg); } + }; + + + //T should be a pointer type, and A is the Allocator for the vector. + template + class _Ffit_finder + : public std::unary_function, bool> { + typedef typename std::vector, _Alloc> _BPVector; + typedef typename _BPVector::difference_type _Counter_type; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + unsigned int *_M_pbitmap; + unsigned int _M_data_offset; + + public: + _Ffit_finder () + : _M_pbitmap (0), _M_data_offset (0) + { } + + bool operator() (_Block_pair __bp) throw() + { + //Set the _rover to the last unsigned integer, which is the + //bitmap to the first free block. Thus, the bitmaps are in exact + //reverse order of the actual memory layout. So, we count down + //the bimaps, which is the same as moving up the memory. + + //If the used count stored at the start of the Bit Map headers + //is equal to the number of Objects that the current Block can + //store, then there is definitely no space for another single + //object, so just return false. + _Counter_type __diff = __gnu_cxx::__aux_balloc::__balloc_num_bit_maps (__bp); + + assert (*(reinterpret_cast(__bp.first) - (__diff + 1)) <= + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)); + + if (*(reinterpret_cast(__bp.first) - (__diff + 1)) == + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)) + return false; + + unsigned int *__rover = reinterpret_cast(__bp.first) - 1; + for (_Counter_type __i = 0; __i < __diff; ++__i) + { + _M_data_offset = __i; + if (*__rover) + { + _M_pbitmap = __rover; + return true; + } + --__rover; + } + return false; + } + + unsigned int *_M_get () { return _M_pbitmap; } + unsigned int _M_offset () { return _M_data_offset * _Bits_Per_Block; } + }; + + //T should be a pointer type. + template + class _Bit_map_counter { + + typedef typename std::vector, _Alloc> _BPVector; + typedef typename _BPVector::size_type _Index_type; + typedef _Tp pointer; + + _BPVector& _M_vbp; + unsigned int *_M_curr_bmap; + unsigned int *_M_last_bmap_in_block; + _Index_type _M_curr_index; + + public: + //Use the 2nd parameter with care. Make sure that such an entry + //exists in the vector before passing that particular index to + //this ctor. + _Bit_map_counter (_BPVector& Rvbp, int __index = -1) + : _M_vbp(Rvbp) + { + this->_M_reset(__index); + } + + void _M_reset (int __index = -1) throw() + { + if (__index == -1) + { + _M_curr_bmap = 0; + _M_curr_index = (_Index_type)-1; + return; + } + + _M_curr_index = __index; + _M_curr_bmap = reinterpret_cast(_M_vbp[_M_curr_index].first) - 1; + + assert (__index <= (int)_M_vbp.size() - 1); + + _M_last_bmap_in_block = _M_curr_bmap - + ((_M_vbp[_M_curr_index].second - _M_vbp[_M_curr_index].first + 1) / _Bits_Per_Block - 1); + } + + //Dangerous Function! Use with extreme care. Pass to this + //function ONLY those values that are known to be correct, + //otherwise this will mess up big time. + void _M_set_internal_bit_map (unsigned int *__new_internal_marker) throw() + { + _M_curr_bmap = __new_internal_marker; + } + + bool _M_finished () const throw() + { + return (_M_curr_bmap == 0); + } + + _Bit_map_counter& operator++ () throw() + { + if (_M_curr_bmap == _M_last_bmap_in_block) + { + if (++_M_curr_index == _M_vbp.size()) + { + _M_curr_bmap = 0; + } + else + { + this->_M_reset (_M_curr_index); + } + } + else + { + --_M_curr_bmap; + } + return *this; + } + + unsigned int *_M_get () + { + return _M_curr_bmap; + } + + pointer _M_base () { return _M_vbp[_M_curr_index].first; } + unsigned int _M_offset () + { + return _Bits_Per_Block * ((reinterpret_cast(this->_M_base()) - _M_curr_bmap) - 1); + } + + unsigned int _M_where () { return _M_curr_index; } + }; + } + + //Generic Version of the bsf instruction. + typedef unsigned int _Bit_map_type; + static inline unsigned int _Bit_scan_forward (register _Bit_map_type __num) + { + return static_cast(__builtin_ctz(__num)); + } + + struct _OOM_handler { + static std::new_handler _S_old_handler; + static bool _S_handled_oom; + typedef void (*_FL_clear_proc)(void); + static _FL_clear_proc _S_oom_fcp; + + _OOM_handler (_FL_clear_proc __fcp) + { + _S_oom_fcp = __fcp; + _S_old_handler = std::set_new_handler (_S_handle_oom_proc); + _S_handled_oom = false; + } + + static void _S_handle_oom_proc() + { + _S_oom_fcp(); + std::set_new_handler (_S_old_handler); + _S_handled_oom = true; + } + + ~_OOM_handler () + { + if (!_S_handled_oom) + std::set_new_handler (_S_old_handler); + } + }; + + std::new_handler _OOM_handler::_S_old_handler; + bool _OOM_handler::_S_handled_oom = false; + _OOM_handler::_FL_clear_proc _OOM_handler::_S_oom_fcp = 0; + + + class _BA_free_list_store { + struct _LT_pointer_compare { + template + bool operator() (_Tp* __pt, _Tp const& __crt) const throw() + { + return *__pt < __crt; + } + }; + +#if defined __GTHREADS + static _Mutex _S_bfl_mutex; +#endif + static std::vector _S_free_list; + typedef std::vector::iterator _FLIter; + + static void _S_validate_free_list(unsigned int *__addr) throw() + { + const unsigned int __max_size = 64; + if (_S_free_list.size() >= __max_size) + { + //Ok, the threshold value has been reached. + //We determine which block to remove from the list of free + //blocks. + if (*__addr >= *_S_free_list.back()) + { + //Ok, the new block is greater than or equal to the last + //block in the list of free blocks. We just free the new + //block. + operator delete((void*)__addr); + return; + } + else + { + //Deallocate the last block in the list of free lists, and + //insert the new one in it's correct position. + operator delete((void*)_S_free_list.back()); + _S_free_list.pop_back(); + } + } + + //Just add the block to the list of free lists + //unconditionally. + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + *__addr, _LT_pointer_compare ()); + //We may insert the new free list before _temp; + _S_free_list.insert(__temp, __addr); + } + + static bool _S_should_i_give(unsigned int __block_size, unsigned int __required_size) throw() + { + const unsigned int __max_wastage_percentage = 36; + if (__block_size >= __required_size && + (((__block_size - __required_size) * 100 / __block_size) < __max_wastage_percentage)) + return true; + else + return false; + } + + public: + typedef _BA_free_list_store _BFL_type; + + static inline void _S_insert_free_list(unsigned int *__addr) throw() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + //Call _S_validate_free_list to decide what should be done with this + //particular free list. + _S_validate_free_list(--__addr); + } + + static unsigned int *_S_get_free_list(unsigned int __sz) throw (std::bad_alloc) + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + __sz, _LT_pointer_compare()); + if (__temp == _S_free_list.end() || !_S_should_i_give (**__temp, __sz)) + { + //We hold the lock because the OOM_Handler is a stateless + //entity. + _OOM_handler __set_handler(_BFL_type::_S_clear); + unsigned int *__ret_val = reinterpret_cast + (operator new (__sz + sizeof(unsigned int))); + *__ret_val = __sz; + return ++__ret_val; + } + else + { + unsigned int* __ret_val = *__temp; + _S_free_list.erase (__temp); + return ++__ret_val; + } + } + + //This function just clears the internal Free List, and gives back + //all the memory to the OS. + static void _S_clear() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __iter = _S_free_list.begin(); + while (__iter != _S_free_list.end()) + { + operator delete((void*)*__iter); + ++__iter; + } + _S_free_list.clear(); + } + + }; + +#if defined __GTHREADS + _Mutex _BA_free_list_store::_S_bfl_mutex; +#endif + std::vector _BA_free_list_store::_S_free_list; + + template class bitmap_allocator; + // specialize for void: + template <> class bitmap_allocator { + public: + typedef void* pointer; + typedef const void* const_pointer; + // reference-to-void members are impossible. + typedef void value_type; + template struct rebind { typedef bitmap_allocator<_Tp1> other; }; + }; + + template class bitmap_allocator : private _BA_free_list_store { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + template struct rebind { typedef bitmap_allocator<_Tp1> other; }; + + private: + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + static inline void _S_bit_allocate(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + __mask = ~__mask; + *__pbmap &= __mask; + } + + static inline void _S_bit_free(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + *__pbmap |= __mask; + } + + static inline void *_S_memory_get(size_t __sz) throw (std::bad_alloc) + { + return operator new(__sz); + } + + static inline void _S_memory_put(void *__vptr) throw () + { + operator delete(__vptr); + } + + typedef typename std::pair _Block_pair; + typedef typename __gnu_cxx::new_allocator<_Block_pair> _BPVec_allocator_type; + typedef typename std::vector<_Block_pair, _BPVec_allocator_type> _BPVector; + + +#if defined CHECK_FOR_ERRORS + //Complexity: O(lg(N)). Where, N is the number of block of size + //sizeof(value_type). + static void _S_check_for_free_blocks() throw() + { + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + assert(__bpi == _S_mem_blocks.end()); + } +#endif + + + //Complexity: O(1), but internally depends upon the complexity of + //the function _BA_free_list_store::_S_get_free_list. The part + //where the bitmap headers are written is of worst case complexity: + //O(X),where X is the number of blocks of size sizeof(value_type) + //within the newly acquired block. Having a tight bound. + static void _S_refill_pool() throw (std::bad_alloc) + { +#if defined CHECK_FOR_ERRORS + _S_check_for_free_blocks(); +#endif + + const unsigned int __num_bit_maps = _S_block_size / _Bits_Per_Block; + const unsigned int __size_to_allocate = sizeof(unsigned int) + + _S_block_size * sizeof(value_type) + __num_bit_maps*sizeof(unsigned int); + + unsigned int *__temp = + reinterpret_cast(_BA_free_list_store::_S_get_free_list(__size_to_allocate)); + *__temp = 0; + ++__temp; + + //The Header information goes at the Beginning of the Block. + _Block_pair __bp = std::make_pair(reinterpret_cast(__temp + __num_bit_maps), + reinterpret_cast(__temp + __num_bit_maps) + + _S_block_size - 1); + + //Fill the Vector with this information. + _S_mem_blocks.push_back(__bp); + + unsigned int __bit_mask = 0; //0 Indicates all Allocated. + __bit_mask = ~__bit_mask; //1 Indicates all Free. + + for (unsigned int __i = 0; __i < __num_bit_maps; ++__i) + __temp[__i] = __bit_mask; + + //On some implementations, operator new might throw bad_alloc, or + //malloc might fail if the size passed is too large, therefore, we + //limit the size passed to malloc or operator new. + _S_block_size *= 2; + } + + static _BPVector _S_mem_blocks; + static unsigned int _S_block_size; + static __gnu_cxx::__aux_balloc::_Bit_map_counter _S_last_request; + static typename _BPVector::size_type _S_last_dealloc_index; +#if defined __GTHREADS + static _Mutex _S_mut; +#endif + + //Complexity: Worst case complexity is O(N), but that is hardly ever + //hit. if and when this particular case is encountered, the next few + //cases are guaranteed to have a worst case complexity of O(1)! + //That's why this function performs very well on the average. you + //can consider this function to be having a complexity refrred to + //commonly as: Amortized Constant time. + static pointer _S_allocate_single_object() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + //The algorithm is something like this: The last_requst variable + //points to the last accessed Bit Map. When such a condition + //occurs, we try to find a free block in the current bitmap, or + //succeeding bitmaps until the last bitmap is reached. If no free + //block turns up, we resort to First Fit method. + + //WARNING: Do not re-order the condition in the while statement + //below, because it relies on C++'s short-circuit + //evaluation. The return from _S_last_request->_M_get() will NOT + //be dereferenceable if _S_last_request->_M_finished() returns + //true. This would inevitibly lead to a NULL pointer dereference + //if tinkered with. + while (_S_last_request._M_finished() == false && (*(_S_last_request._M_get()) == 0)) + { + _S_last_request.operator++(); + } + + if (__builtin_expect(_S_last_request._M_finished() == true, false)) + { + //Fall Back to First Fit algorithm. + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + + if (__bpi != _S_mem_blocks.end()) + { + //Search was successful. Ok, now mark the first bit from + //the right as 0, meaning Allocated. This bit is obtained + //by calling _M_get() on __fff. + unsigned int __nz_bit = _Bit_scan_forward(*__fff._M_get()); + _S_bit_allocate(__fff._M_get(), __nz_bit); + + _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); + + //Now, get the address of the bit we marked as allocated. + pointer __ret_val = __bpi->first + __fff._M_offset() + __nz_bit; + unsigned int *__puse_count = reinterpret_cast(__bpi->first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(*__bpi) + 1); + ++(*__puse_count); + return __ret_val; + } + else + { + //Search was unsuccessful. We Add more memory to the pool + //by calling _S_refill_pool(). + _S_refill_pool(); + + //_M_Reset the _S_last_request structure to the first free + //block's bit map. + _S_last_request._M_reset(_S_mem_blocks.size() - 1); + + //Now, mark that bit as allocated. + } + } + //_S_last_request holds a pointer to a valid bit map, that points + //to a free block in memory. + unsigned int __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); + _S_bit_allocate(_S_last_request._M_get(), __nz_bit); + + pointer __ret_val = _S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit; + + unsigned int *__puse_count = reinterpret_cast + (_S_mem_blocks[_S_last_request._M_where()].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[_S_last_request._M_where()]) + 1); + ++(*__puse_count); + return __ret_val; + } + + //Complexity: O(lg(N)), but the worst case is hit quite often! I + //need to do something about this. I'll be able to work on it, only + //when I have some solid figures from a few real apps. + static void _S_deallocate_single_object(pointer __p) throw() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + typedef typename _BPVector::iterator _Iterator; + typedef typename _BPVector::difference_type _Difference_type; + + _Difference_type __diff; + int __displacement; + + assert(_S_last_dealloc_index >= 0); + + if (__gnu_cxx::__aux_balloc::_Inclusive_between(__p)(_S_mem_blocks[_S_last_dealloc_index])) + { + assert(_S_last_dealloc_index <= _S_mem_blocks.size() - 1); + + //Initial Assumption was correct! + __diff = _S_last_dealloc_index; + __displacement = __p - _S_mem_blocks[__diff].first; + } + else + { + _Iterator _iter = (std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Inclusive_between(__p))); + assert(_iter != _S_mem_blocks.end()); + + __diff = _iter - _S_mem_blocks.begin(); + __displacement = __p - _S_mem_blocks[__diff].first; + _S_last_dealloc_index = __diff; + } + + //Get the position of the iterator that has been found. + const unsigned int __rotate = __displacement % _Bits_Per_Block; + unsigned int *__bit_mapC = reinterpret_cast(_S_mem_blocks[__diff].first) - 1; + __bit_mapC -= (__displacement / _Bits_Per_Block); + + _S_bit_free(__bit_mapC, __rotate); + unsigned int *__puse_count = reinterpret_cast + (_S_mem_blocks[__diff].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[__diff]) + 1); + + assert(*__puse_count != 0); + + --(*__puse_count); + + if (__builtin_expect(*__puse_count == 0, false)) + { + _S_block_size /= 2; + + //We may safely remove this block. + _Block_pair __bp = _S_mem_blocks[__diff]; + _S_insert_free_list(__puse_count); + _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); + + //We reset the _S_last_request variable to reflect the erased + //block. We do this to protect future requests after the last + //block has been removed from a particular memory Chunk, + //which in turn has been returned to the free list, and + //hence had been erased from the vector, so the size of the + //vector gets reduced by 1. + if ((_Difference_type)_S_last_request._M_where() >= __diff--) + { + _S_last_request._M_reset(__diff); + // assert(__diff >= 0); + } + + //If the Index into the vector of the region of memory that + //might hold the next address that will be passed to + //deallocated may have been invalidated due to the above + //erase procedure being called on the vector, hence we try + //to restore this invariant too. + if (_S_last_dealloc_index >= _S_mem_blocks.size()) + { + _S_last_dealloc_index =(__diff != -1 ? __diff : 0); + assert(_S_last_dealloc_index >= 0); + } + } + } + + public: + bitmap_allocator() throw() + { } + + bitmap_allocator(const bitmap_allocator&) { } + + template bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() + { } + + ~bitmap_allocator() throw() + { } + + //Complexity: O(1), but internally the complexity depends upon the + //complexity of the function(s) _S_allocate_single_object and + //_S_memory_get. + pointer allocate(size_type __n) + { + if (__builtin_expect(__n == 1, true)) + return _S_allocate_single_object(); + else + return reinterpret_cast(_S_memory_get(__n * sizeof(value_type))); + } + + //Complexity: Worst case complexity is O(N) where N is the number of + //blocks of size sizeof(value_type) within the free lists that the + //allocator holds. However, this worst case is hit only when the + //user supplies a bogus argument to hint. If the hint argument is + //sensible, then the complexity drops to O(lg(N)), and in extreme + //cases, even drops to as low as O(1). So, if the user supplied + //argument is good, then this function performs very well. + pointer allocate(size_type __n, typename bitmap_allocator::const_pointer) + { + return allocate(__n); + } + + void deallocate(pointer __p, size_type __n) throw() + { + if (__builtin_expect(__n == 1, true)) + _S_deallocate_single_object(__p); + else + _S_memory_put(__p); + } + + pointer address(reference r) const { return &r; } + const_pointer address(const_reference r) const { return &r; } + + size_type max_size(void) const throw() { return (size_type()-1)/sizeof(value_type); } + + void construct (pointer p, const_reference __data) + { + ::new(p) value_type(__data); + } + + void destroy (pointer p) + { + p->~value_type(); + } + + }; + + template + typename bitmap_allocator<_Tp>::_BPVector bitmap_allocator<_Tp>::_S_mem_blocks; + + template + unsigned int bitmap_allocator<_Tp>::_S_block_size = bitmap_allocator<_Tp>::_Bits_Per_Block; + + template + typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type + bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + + template + __gnu_cxx::__aux_balloc::_Bit_map_counter + ::pointer, typename bitmap_allocator<_Tp>::_BPVec_allocator_type> + bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); + +#if defined __GTHREADS + template + __gnu_cxx::_Mutex + bitmap_allocator<_Tp>::_S_mut; +#endif + + template + bool operator== (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return true; + } + + template + bool operator!= (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return false; + } +} + + +#endif //_BITMAP_ALLOCATOR_H diff --git a/src/include.new/c++/3.4/ext/debug_allocator.h b/src/include.new/c++/3.4/ext/debug_allocator.h new file mode 100644 index 0000000..7ea6fb4 --- /dev/null +++ b/src/include.new/c++/3.4/ext/debug_allocator.h @@ -0,0 +1,121 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/debug_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _DEBUG_ALLOCATOR_H +#define _DEBUG_ALLOCATOR_H 1 + +#include + +namespace __gnu_cxx +{ + /** + * @brief A meta-allocator with debugging bits, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class debug_allocator + { + public: + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::value_type value_type; + + private: + // _M_extra is the number of objects that correspond to the + // extra space where debug information is stored. + size_type _M_extra; + + _Alloc _M_allocator; + + public: + debug_allocator() + { + const size_t __obj_size = sizeof(value_type); + _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; + } + + pointer + allocate(size_type __n) + { + pointer __res = _M_allocator.allocate(__n + _M_extra); + size_type* __ps = reinterpret_cast(__res); + *__ps = __n; + return __res + _M_extra; + } + + pointer + allocate(size_type __n, const void* __hint) + { + pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); + size_type* __ps = reinterpret_cast(__res); + *__ps = __n; + return __res + _M_extra; + } + + void + deallocate(pointer __p, size_type __n) + { + if (!__p) + abort(); + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast(__real_p) != __n) + abort(); + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + }; +} // namespace __gnu_cxx + +#endif diff --git a/src/include.new/c++/3.4/ext/demangle.h b/src/include.new/c++/3.4/ext/demangle.h new file mode 100644 index 0000000..5de4f04 --- /dev/null +++ b/src/include.new/c++/3.4/ext/demangle.h @@ -0,0 +1,2789 @@ +// C++ IA64 / g++ v3 demangler -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// Written by Carlo Wood +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file implements demangling of "C++ ABI for Itanium"-mangled symbol +// and type names as described in Revision 1.73 of the C++ ABI as can be found +// at http://www.codesourcery.com/cxx-abi/abi.html#mangling + +#ifndef _DEMANGLER_H +#define _DEMANGLER_H 1 + +#include +#include +#include + +#ifndef _GLIBCXX_DEMANGLER_DEBUG +#define _GLIBCXX_DEMANGLER_CWDEBUG 0 +#define _GLIBCXX_DEMANGLER_DEBUG(x) +#define _GLIBCXX_DEMANGLER_DOUT(cntrl, data) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x) +#define _GLIBCXX_DEMANGLER_RETURN return M_result +#define _GLIBCXX_DEMANGLER_RETURN2 return M_result +#define _GLIBCXX_DEMANGLER_RETURN3 +#define _GLIBCXX_DEMANGLER_FAILURE \ + do { M_result = false; return false; } while(0) +#else +#define _GLIBCXX_DEMANGLER_CWDEBUG 1 +#endif + +namespace __gnu_cxx +{ + namespace demangler + { + enum substitution_nt + { + type, + template_template_param, + nested_name_prefix, + nested_name_template_prefix, + unscoped_template_name + }; + + struct substitution_st + { + int M_start_pos; + substitution_nt M_type; + int M_number_of_prefixes; + + substitution_st(int start_pos, + substitution_nt type, + int number_of_prefixes) + : M_start_pos(start_pos), M_type(type), + M_number_of_prefixes(number_of_prefixes) + { } + }; + + enum simple_qualifier_nt + { + complex_or_imaginary = 'G', + pointer = 'P', + reference = 'R' + }; + + enum cv_qualifier_nt + { + cv_qualifier = 'K' + }; + + enum param_qualifier_nt + { + vendor_extension = 'U', + array = 'A', + pointer_to_member = 'M' + }; + + template > + class qualifier; + + template > + class qualifier_list; + + template > + class session; + + template + class qualifier + { + typedef typename Allocator::template rebind::other + char_Allocator; + typedef std::basic_string, char_Allocator> + string_type; + + private: + char M_qualifier1; + char M_qualifier2; + char M_qualifier3; + mutable unsigned char M_cnt; + string_type M_optional_type; + int M_start_pos; + bool M_part_of_substitution; + + public: + qualifier(int start_pos, + simple_qualifier_nt simple_qualifier, + int inside_substitution) + : M_qualifier1(simple_qualifier), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + qualifier(int start_pos, + cv_qualifier_nt, + char const* start, + int count, + int inside_substitution) + : M_qualifier1(start[0]), + M_qualifier2((count > 1) ? start[1] : '\0'), + M_qualifier3((count > 2) ? start[2] : '\0'), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + qualifier(int start_pos, + param_qualifier_nt param_qualifier, + string_type optional_type, + int inside_substitution) + : M_qualifier1(param_qualifier), + M_optional_type(optional_type), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + int + get_start_pos(void) const + { return M_start_pos; } + + char + first_qualifier(void) const + { M_cnt = 1; return M_qualifier1; } + + char + next_qualifier(void) const + { + return (++M_cnt == 2) ? M_qualifier2 + : ((M_cnt == 3) ? M_qualifier3 : 0); + } + + string_type const& + get_optional_type(void) const + { return M_optional_type; } + + bool + part_of_substitution(void) const + { return M_part_of_substitution; } + +#if _GLIBCXX_DEMANGLER_CWDEBUG + friend std::ostream& operator<<(std::ostream& os, qualifier const& qual) + { + os << (char)qual.M_qualifier1; + if (qual.M_qualifier1 == vendor_extension || + qual.M_qualifier1 == array || + qual.M_qualifier1 == pointer_to_member) + os << " [" << qual.M_optional_type << ']'; + else if (qual.M_qualifier1 == 'K' || + qual.M_qualifier1 == 'V' || + qual.M_qualifier1 == 'r') + { + if (qual.M_qualifier2) + { + os << (char)qual.M_qualifier2; + if (qual.M_qualifier3) + os << (char)qual.M_qualifier3; + } + } + return os; + } +#endif + }; + + template + class qualifier_list + { + typedef typename Allocator::template rebind::other + char_Allocator; + typedef std::basic_string, char_Allocator> + string_type; + + private: + mutable bool M_printing_suppressed; + typedef qualifier qual; + typedef typename Allocator::template rebind::other qual_Allocator; + typedef std::vector qual_vector; + qual_vector M_qualifier_starts; + session& M_demangler; + + void decode_KVrA(string_type& prefix, string_type& postfix, int cvq, + typename qual_vector:: + const_reverse_iterator const& iter_array) const; + + public: + qualifier_list(session& demangler_obj) + : M_printing_suppressed(false), M_demangler(demangler_obj) + { } + + void + add_qualifier_start(simple_qualifier_nt simple_qualifier, + int start_pos, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier(start_pos, + simple_qualifier, inside_substitution)); } + + void + add_qualifier_start(cv_qualifier_nt cv_qualifier, + int start_pos, + int count, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier(start_pos, + cv_qualifier, &M_demangler.M_str[start_pos], + count, inside_substitution)); } + + void + add_qualifier_start(param_qualifier_nt param_qualifier, + int start_pos, + string_type optional_type, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier(start_pos, + param_qualifier, optional_type, inside_substitution)); } + + void + decode_qualifiers(string_type& prefix, + string_type& postfix, + bool member_function_pointer_qualifiers) const; + + bool + suppressed(void) const + { return M_printing_suppressed; } + + void + printing_suppressed(void) + { M_printing_suppressed = true; } + + size_t + size(void) const + { return M_qualifier_starts.size(); } + +#if _GLIBCXX_DEMANGLER_CWDEBUG + friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list) + { + typename qual_vector::const_iterator + iter = list.M_qualifier_starts.begin(); + if (iter != list.M_qualifier_starts.end()) + { + os << "{ " << *iter; + while (++iter != list.M_qualifier_starts.end()) + os << ", " << *iter; + os << " }"; + } + else + os << "{ }"; + return os; + } +#endif + }; + + struct implementation_details + { + private: + unsigned int M_style; + + public: + // The following flags change the behaviour of the demangler. The + // default behaviour is that none of these flags is set. + + static unsigned int const style_void = 1; + // Default behaviour: int f() + // Use (void) instead of (): int f(void) + + static unsigned int const style_literal = 2; + // Default behaviour: (long)13, + // (unsigned long long)19 + // Use extensions 'u', 'l' and 'll' for integral + // literals (as in template arguments): 13l, 19ull + + static unsigned int const style_literal_int = 4; + // Default behaviour: 4 + // Use also an explicit + // cast for int in literals: (int)4 + + static unsigned int const style_compact_expr_ops = 8; + // Default behaviour: (i) < (3), sizeof (int) + // Don't output spaces around + // operators in expressions: (i)<(3), sizeof(int) + + static unsigned int const style_sizeof_typename = 16; + // Default behaviour: sizeof (X::t) + // Put 'typename' infront of + // types inside a 'sizeof': sizeof (typename X::t) + + public: + implementation_details(unsigned int style_flags = 0) : + M_style(style_flags) { } + virtual ~implementation_details() { } + bool get_style_void(void) const + { return (M_style & style_void); } + bool get_style_literal(void) const + { return (M_style & style_literal); } + bool get_style_literal_int(void) const + { return (M_style & style_literal_int); } + bool get_style_compact_expr_ops(void) const + { return (M_style & style_compact_expr_ops); } + bool get_style_sizeof_typename(void) const + { return (M_style & style_sizeof_typename); } + // This can be overridden by user implementations. + virtual bool decode_real(char* /* output */, unsigned long* /* input */, + size_t /* size_of_real */) const + { return false; } + }; + + template + class session + { + public: + friend class qualifier_list; + typedef typename Allocator::template rebind::other + char_Allocator; + typedef std::basic_string, char_Allocator> + string_type; + + private: + char const* M_str; + int M_pos; + int M_maxpos; + bool M_result; + int M_inside_template_args; + int M_inside_type; + int M_inside_substitution; + bool M_saw_destructor; + bool M_name_is_cdtor; + bool M_name_is_template; + bool M_name_is_conversion_operator; + bool M_template_args_need_space; + string_type M_function_name; + typedef typename Allocator::template rebind::other + int_Allocator; + typedef typename Allocator::template rebind::other + subst_Allocator; + std::vector M_template_arg_pos; + int M_template_arg_pos_offset; + std::vector M_substitutions_pos; + implementation_details const& M_implementation_details; + typedef typename Allocator::template + rebind >::other qualifier_list_Allocator; + qualifier_list_Allocator M_qualifier_list_alloc; +#if _GLIBCXX_DEMANGLER_CWDEBUG + bool M_inside_add_substitution; +#endif + + public: + explicit session(char const* in, int len, + implementation_details const& id = implementation_details()) + : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true), + M_inside_template_args(0), M_inside_type(0), + M_inside_substitution(0), M_saw_destructor(false), + M_name_is_cdtor(false), M_name_is_template(false), + M_name_is_conversion_operator(false), + M_template_args_need_space(false), M_template_arg_pos_offset(0), + M_implementation_details(id) +#if _GLIBCXX_DEMANGLER_CWDEBUG + , M_inside_add_substitution(false) +#endif + { } + + static int + decode_encoding(string_type& output, char const* input, int len, + implementation_details const& id = implementation_details()); + + bool + decode_type(string_type& output, + qualifier_list* qualifiers = NULL) + { + string_type postfix; + bool res = decode_type_with_postfix(output, postfix, qualifiers); + output += postfix; + return res; + } + + bool + remaining_input_characters(void) const + { return current() != 0; } + + private: + char + current(void) const + { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; } + + char + next_peek(void) const + { return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; } + + char + next(void) + { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; } + + char + eat_current(void) + { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; } + + void + store(int& saved_pos) + { saved_pos = M_pos; } + + void + restore(int saved_pos) + { M_pos = saved_pos; M_result = true; } + + void + add_substitution(int start_pos, + substitution_nt sub_type, + int number_of_prefixes); + + bool decode_type_with_postfix(string_type& prefix, + string_type& postfix, qualifier_list* qualifiers = NULL); + bool decode_bare_function_type(string_type& output); + bool decode_builtin_type(string_type& output); + bool decode_call_offset(string_type& output); + bool decode_class_enum_type(string_type& output); + bool decode_expression(string_type& output); + bool decode_literal(string_type& output); + bool decode_local_name(string_type& output); + bool decode_name(string_type& output, + string_type& nested_name_qualifiers); + bool decode_nested_name(string_type& output, + string_type& qualifiers); + bool decode_number(string_type& output); + bool decode_operator_name(string_type& output); + bool decode_source_name(string_type& output); + bool decode_substitution(string_type& output, + qualifier_list* qualifiers = NULL); + bool decode_template_args(string_type& output); + bool decode_template_param(string_type& output, + qualifier_list* qualifiers = NULL); + bool decode_unqualified_name(string_type& output); + bool decode_unscoped_name(string_type& output); + bool decode_non_negative_decimal_integer(string_type& output); + bool decode_special_name(string_type& output); + bool decode_real(string_type& output, size_t size_of_real); + }; + + template +#if !_GLIBCXX_DEMANGLER_CWDEBUG + inline +#endif + void + session::add_substitution(int start_pos, + substitution_nt sub_type, + int number_of_prefixes = 0) + { + if (!M_inside_substitution) + { +#if _GLIBCXX_DEMANGLER_CWDEBUG + if (M_inside_add_substitution) + return; +#endif + M_substitutions_pos. + push_back(substitution_st(start_pos, + sub_type, number_of_prefixes)); +#if _GLIBCXX_DEMANGLER_CWDEBUG + if (!DEBUGCHANNELS::dc::demangler.is_on()) + return; + string_type substitution_name("S"); + int n = M_substitutions_pos.size() - 1; + if (n > 0) + substitution_name += (n <= 10) ? (char)(n + '0' - 1) + : (char)(n + 'A' - 11); + substitution_name += '_'; + string_type subst; + int saved_pos = M_pos; + M_pos = start_pos; + M_inside_add_substitution = true; + _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() ); + switch(sub_type) + { + case type: + decode_type(subst); + break; + case template_template_param: + decode_template_param(subst); + break; + case nested_name_prefix: + case nested_name_template_prefix: + for (int cnt = number_of_prefixes; cnt > 0; --cnt) + { + if (current() == 'I') + { + subst += ' '; + decode_template_args(subst); + } + else + { + if (cnt < number_of_prefixes) + subst += "::"; + if (current() == 'S') + decode_substitution(subst); + else if (current() == 'T') + decode_template_param(subst); + else + decode_unqualified_name(subst); + } + } + break; + case unscoped_template_name: + decode_unscoped_name(subst); + break; + } + M_pos = saved_pos; + _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() ); + _GLIBCXX_DEMANGLER_DOUT(dc::demangler, + "Adding substitution " << substitution_name + << " : " << subst + << " (from " << location_ct((char*)__builtin_return_address(0) + + builtin_return_address_offset) + << " <- " << location_ct((char*)__builtin_return_address(1) + + builtin_return_address_offset) + << " <- " << location_ct((char*)__builtin_return_address(2) + + builtin_return_address_offset) + << ")."); + M_inside_add_substitution = false; +#endif + } + } + + // We don't want to depend on locale (or include for that matter). + // We also don't want to use "safe-ctype.h" because that headerfile is not + // available to the users. + inline bool isdigit(char c) { return c >= '0' && c <= '9'; } + inline bool islower(char c) { return c >= 'a' && c <= 'z'; } + inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; } + inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; } + + // + // ::= 0 + // ::= 1|2|3|4|5|6|7|8|9 [+] + // ::= 0|1|2|3|4|5|6|7|8|9 + // + template + bool + session:: + decode_non_negative_decimal_integer(string_type& output) + { + char c = current(); + if (c == '0') + { + output += '0'; + eat_current(); + } + else if (!isdigit(c)) + M_result = false; + else + { + do + { + output += c; + } + while (isdigit((c = next()))); + } + return M_result; + } + + // ::= [n] + // + template + bool + session::decode_number(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number"); + if (current() != 'n') + decode_non_negative_decimal_integer(output); + else + { + output += '-'; + eat_current(); + decode_non_negative_decimal_integer(output); + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= v # void + // ::= w # wchar_t + // ::= b # bool + // ::= c # char + // ::= a # signed char + // ::= h # unsigned char + // ::= s # short + // ::= t # unsigned short + // ::= i # int + // ::= j # unsigned int + // ::= l # long + // ::= m # unsigned long + // ::= x # long long, __int64 + // ::= y # unsigned long long, __int64 + // ::= n # __int128 + // ::= o # unsigned __int128 + // ::= f # float + // ::= d # double + // ::= e # long double, __float80 + // ::= g # __float128 + // ::= z # ellipsis + // ::= u # vendor extended type + // + char const* const builtin_type_c[26] = + { + "signed char", // a + "bool", // b + "char", // c + "double", // d + "long double", // e + "float", // f + "__float128", // g + "unsigned char", // h + "int", // i + "unsigned int", // j + NULL, // k + "long", // l + "unsigned long", // m + "__int128", // n + "unsigned __int128", // o + NULL, // p + NULL, // q + NULL, // r + "short", // s + "unsigned short", // t + NULL, // u + "void", // v + "wchar_t", // w + "long long", // x + "unsigned long long", // y + "..." // z + }; + + // + template + bool + session::decode_builtin_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type"); + char const* bt; + if (!islower(current()) || !(bt = builtin_type_c[current() - 'a'])) + _GLIBCXX_DEMANGLER_FAILURE; + output += bt; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= + // + template + bool + session::decode_class_enum_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type"); + string_type nested_name_qualifiers; + if (!decode_name(output, nested_name_qualifiers)) + _GLIBCXX_DEMANGLER_FAILURE; + output += nested_name_qualifiers; + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= + // S _ + // S_ + // St # ::std:: + // Sa # ::std::allocator + // Sb # ::std::basic_string + // Ss # ::std::basic_string, + // std::allocator > + // Si # ::std::basic_istream > + // So # ::std::basic_ostream > + // Sd # ::std::basic_iostream > + // + // ::= + // 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z + // [] # Base 36 number + // + template + bool + session::decode_substitution(string_type& output, + qualifier_list* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution"); + unsigned int value = 0; + char c = next(); + if (c != '_') + { + switch(c) + { + case 'a': + { + output += "std::allocator"; + if (!M_inside_template_args) + { + M_function_name = "allocator"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + } + case 'b': + { + output += "std::basic_string"; + if (!M_inside_template_args) + { + M_function_name = "basic_string"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + } + case 'd': + output += "std::iostream"; + if (!M_inside_template_args) + { + M_function_name = "iostream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 'i': + output += "std::istream"; + if (!M_inside_template_args) + { + M_function_name = "istream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 'o': + output += "std::ostream"; + if (!M_inside_template_args) + { + M_function_name = "ostream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 's': + output += "std::string"; + if (!M_inside_template_args) + { + M_function_name = "string"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 't': + output += "std"; + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + default: + for(;; c = next()) + { + if (isdigit(c)) + value = value * 36 + c - '0'; + else if (isupper(c)) + value = value * 36 + c - 'A' + 10; + else if (c == '_') + break; + else + _GLIBCXX_DEMANGLER_FAILURE; + } + ++value; + break; + } + } + eat_current(); + if (value >= M_substitutions_pos.size() || + M_inside_type > 20) // Rather than core dump. + _GLIBCXX_DEMANGLER_FAILURE; + ++M_inside_substitution; + int saved_pos = M_pos; + substitution_st& substitution(M_substitutions_pos[value]); + M_pos = substitution.M_start_pos; + switch(substitution.M_type) + { + case type: + decode_type(output, qualifiers); + break; + case template_template_param: + decode_template_param(output, qualifiers); + break; + case nested_name_prefix: + case nested_name_template_prefix: + for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt) + { + if (current() == 'I') + { + if (M_template_args_need_space) + output += ' '; + M_template_args_need_space = false; + if (!decode_template_args(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + if (cnt < substitution.M_number_of_prefixes) + output += "::"; + if (current() == 'S') + { + if (!decode_substitution(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (!decode_unqualified_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + } + if (qualifiers) + qualifiers->printing_suppressed(); + break; + case unscoped_template_name: + decode_unscoped_name(output); + if (qualifiers) + qualifiers->printing_suppressed(); + break; + } + M_pos = saved_pos; + --M_inside_substitution; + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= T_ # first template parameter + // ::= T _ + // + template + bool + session::decode_template_param(string_type& output, + qualifier_list* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter"); + if (current() != 'T') + _GLIBCXX_DEMANGLER_FAILURE; + unsigned int value = 0; + char c; + if ((c = next()) != '_') + { + while(isdigit(c)) + { + value = value * 10 + c - '0'; + c = next(); + } + ++value; + } + if (eat_current() != '_') + _GLIBCXX_DEMANGLER_FAILURE; + value += M_template_arg_pos_offset; + if (value >= M_template_arg_pos.size()) + _GLIBCXX_DEMANGLER_FAILURE; + int saved_pos = M_pos; + M_pos = M_template_arg_pos[value]; + if (M_inside_type > 20) // Rather than core dump. + _GLIBCXX_DEMANGLER_FAILURE; + ++M_inside_substitution; + if (current() == 'X') + { + eat_current(); + decode_expression(output); + } + else if (current() == 'L') + decode_literal(output); + else + decode_type(output, qualifiers); + --M_inside_substitution; + M_pos = saved_pos; + _GLIBCXX_DEMANGLER_RETURN; + } + + template + bool + session::decode_real(string_type& output, size_t size_of_real) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real"); + + unsigned long words[4]; // 32 bit per long, maximum of 128 bits. + unsigned long* word = &words[0]; + + int saved_pos; + store(saved_pos); + + // The following assumes that leading zeroes are also included in the + // mangled name, I am not sure that is conforming to the C++-ABI, but + // it is what g++ does. + unsigned char nibble, c = current(); + for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt) + { + for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt) + { + // Translate character into nibble. + if (c < '0' || c > 'f') + _GLIBCXX_DEMANGLER_FAILURE; + if (c <= '9') + nibble = c - '0'; + else if (c >= 'a') + nibble = c - 'a' + 10; + else + _GLIBCXX_DEMANGLER_FAILURE; + // Write nibble into word array. + if (nibble_cnt == 0) + *word = nibble << 28; + else + *word |= (nibble << (28 - 4 * nibble_cnt)); + c = next(); + } + ++word; + } + char buf[24]; + if (M_implementation_details.decode_real(buf, words, size_of_real)) + { + output += buf; + _GLIBCXX_DEMANGLER_RETURN; + } + restore(saved_pos); + + output += '['; + c = current(); + for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt) + { + if (c < '0' || c > 'f' || (c > '9' && c < 'a')) + _GLIBCXX_DEMANGLER_FAILURE; + output += c; + c = next(); + } + output += ']'; + + _GLIBCXX_DEMANGLER_RETURN; + } + + template + bool + session::decode_literal(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal"); + eat_current(); // Eat the 'L'. + if (current() == '_') + { + if (next() != 'Z') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + if ((M_pos += decode_encoding(output, M_str + M_pos, + M_maxpos - M_pos + 1, M_implementation_details)) < 0) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + // Special cases + if (current() == 'b') + { + if (next() == '0') + output += "false"; + else + output += "true"; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + char c = current(); + if ((c == 'i' || c == 'j' || c == 'l' || + c == 'm' || c == 'x' || c == 'y') && + M_implementation_details.get_style_literal()) + eat_current(); + else if (c == 'i' && + !M_implementation_details.get_style_literal_int()) + eat_current(); + else + { + output += '('; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + } + if (c >= 'd' && c <= 'g') + { + size_t size_of_real = (c == 'd') ? sizeof(double) : + ((c == 'f') ? sizeof(float) : + (c == 'e') ? sizeof(long double) : 16); + if (!decode_real(output, size_of_real)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (!decode_number(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (M_implementation_details.get_style_literal()) + { + if (c == 'j' || c == 'm' || c == 'y') + output += 'u'; + if (c == 'l' || c == 'm') + output += 'l'; + if (c == 'x' || c == 'y') + output += "ll"; + } + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= + // nw # new + // na # new[] + // dl # delete + // da # delete[] + // ps # + (unary) + // ng # - (unary) + // ad # & (unary) + // de # * (unary) + // co # ~ + // pl # + + // mi # - + // ml # * + // dv # / + // rm # % + // an # & + // or # | + // eo # ^ + // aS # = + // pL # += + // mI # -= + // mL # *= + // dV # /= + // rM # %= + // aN # &= + // oR # |= + // eO # ^= + // ls # << + // rs # >> + // lS # <<= + // rS # >>= + // eq # == + // ne # != + // lt # < + // gt # > + // le # <= + // ge # >= + // nt # ! + // aa # && + // oo # || + // pp # ++ + // mm # -- + // cm # , + // pm # ->* + // pt # -> + // cl # () + // ix # [] + // qu # ? + // st # sizeof (a type) + // sz # sizeof (an expression) + // cv # (cast) + // v # vendor extended operator + // + // Symbol operator codes exist of two characters, we need to find a + // quick hash so that their names can be looked up in a table. + // + // The puzzle :) + // Shift the rows so that there is at most one character per column. + // + // A perfect solution (Oh no, it's THE MATRIX!): + // horizontal + // ....................................... offset + 'a' + // a, a||d|||||||||n||||s|||||||||||||||||||| 0 + // c, || |||||||lm o||| |||||||||||||||||||| 0 + // d, || a|||e|| l|| ||||||v||||||||||||| 4 + // e, || ||| || || |||o|q ||||||||||||| 8 + // g, || ||| || || e|| | ||||||||t|||| 15 + // i, || ||| || || || | |||||||| |||x 15 + // l, |e ||| || st || | |||||||| ||| -2 + // m, | |i| lm || | |||||||| ||| -2 + // n, a e g t| w |||||||| ||| 1 + // o, | ||||o||r ||| 16 + // p, | ||lm |p st| 17 + // q, | u| | | 6 + // r, m s | | 9 + // s, t z 12 + // ....................................... + // ^ ^__ second character + // |___ first character + // + + // Putting that solution in tables: + + char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if (CHAR_MIN < 0) + // Add -CHAR_MIN extra zeroes (128): + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // a b c d e f g h i j k + 0, -97, 0, -97, -93, -89, 0, -82, 0, -82, 0, 0, + // l m n o p q r s t u v + -99, -99, -96, -81, -80, -91, -88, -85, 0, 0, 0, +#else + // a b c d e f g h i j k + 0, 159, 0, 159, 163, 167, 0, 174, 0, 174, 0, 0, + // l m n o p q r s t u v + 157, 157, 160, 175, 176, 165, 168, 171, 0, 0, 0, +#endif + // ... more zeros + }; + + enum xary_nt { + unary, + binary, + trinary + }; + + struct entry_st + { + char const* opcode; + char const* symbol_name; + xary_nt type; + }; + + entry_st const symbol_name_table_c[39] = { + { "aa", "operator&&", binary }, + { "na", "operator new[]", unary }, + { "le", "operator<=", binary }, + { "ad", "operator&", unary }, + { "da", "operator delete[]", unary }, + { "ne", "operator!=", binary }, + { "mi=", "operator-", binary }, + { "ng", "operator-", unary }, + { "de", "operator*", unary }, + { "ml=", "operator*", binary }, + { "mm", "operator--", unary }, + { "cl", "operator()", unary }, + { "cm", "operator,", binary }, + { "an=", "operator&", binary }, + { "co", "operator~", binary }, + { "dl", "operator delete", unary }, + { "ls=", "operator<<", binary }, + { "lt", "operator<", binary }, + { "as=", "operator", binary }, + { "ge", "operator>=", binary }, + { "nt", "operator!", unary }, + { "rm=", "operator%", binary }, + { "eo=", "operator^", binary }, + { "nw", "operator new", unary }, + { "eq", "operator==", binary }, + { "dv=", "operator/", binary }, + { "qu", "operator?", trinary }, + { "rs=", "operator>>", binary }, + { "pl=", "operator+", binary }, + { "pm", "operator->*", binary }, + { "oo", "operator||", binary }, + { "st", "sizeof", unary }, + { "pp", "operator++", unary }, + { "or=", "operator|", binary }, + { "gt", "operator>", binary }, + { "ps", "operator+", unary }, + { "pt", "operator->", binary }, + { "sz", "sizeof", unary }, + { "ix", "operator[]", unary } + }; + + template + bool + session::decode_operator_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name"); + + char opcode0 = current(); + char opcode1 = tolower(next()); + + register char hash; + if ((hash = offset_table_c[opcode0 - CHAR_MIN])) + { + hash += opcode1; + if ( +#if (CHAR_MIN < 0) + hash >= 0 && +#endif + hash < 39) + { + int index = static_cast(static_cast(hash)); + entry_st entry = symbol_name_table_c[index]; + if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1 + && (opcode1 == current() || entry.opcode[2] == '=')) + { + output += entry.symbol_name; + if (opcode1 != current()) + output += '='; + eat_current(); + if (hash == 16 || hash == 17) + M_template_args_need_space = true; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (opcode0 == 'c' && opcode1 == 'v') // casting operator + { + eat_current(); + output += "operator "; + if (current() == 'T') + { + // This is a templated cast operator. + // It must be of the form "cvT_I...E". + // Let M_template_arg_pos already point + // to the template argument. + M_template_arg_pos_offset = M_template_arg_pos.size(); + M_template_arg_pos.push_back(M_pos + 3); + } + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (!M_inside_template_args) + M_name_is_conversion_operator = true; + _GLIBCXX_DEMANGLER_RETURN; + } + } + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // + // ::= + // ::= + // ::= + // ::= st + // ::= + // ::= sr # dependent name + // ::= sr # dependent template-id + // ::= + // + // ::= L E # integer literal + // ::= L E # floating literal + // ::= L E # external name + // + template + bool + session::decode_expression(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_expression"); + if (current() == 'T') + { + if (!decode_template_param(output)) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 'L') + { + if (!decode_literal(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 's') + { + char opcode1 = next(); + if (opcode1 == 't' || opcode1 == 'z') + { + eat_current(); + if (M_implementation_details.get_style_compact_expr_ops()) + output += "sizeof("; + else + output += "sizeof ("; + if (opcode1 == 't') + { + // I cannot think of a mangled name that is valid for both cases + // when just replacing the 't' by a 'z' or vica versa, which + // indicates that there is no ambiguity that dictates the need + // for a seperate "st" case, except to be able catch invalid + // mangled names. However there CAN be ambiguity in the demangled + // name when there are both a type and a symbol of the same name, + // which then leads to different encoding (of course) with + // sizeof (type) or sizeof (expression) respectively, but that + // ambiguity is not per se related to "sizeof" except that that + // is the only place where both a type AND an expression are valid + // in as part of a (template function) type. + // + // Example: + // + // struct B { typedef int t; }; + // struct A : public B { static int t[2]; }; + // template struct C { typedef int q; }; + // template + // void f(typename C::q) { } + // void instantiate() { f<5, A>(0); } + // + // Leads to _Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE which + // demangles as + // void f<5, A>(C::q) + // + // This is ambiguity is very unlikely to happen and it is kind + // of fuzzy to detect when adding a 'typename' makes sense. + // + if (M_implementation_details.get_style_sizeof_typename()) + { + // We can only get here inside a template parameter, + // so this is syntactically correct if the given type is + // a typedef. The only disadvantage is that it is inconsistent + // with all other places where the 'typename' keyword should be + // used and we don't. + // With this, the above example will demangle as + // void f<5, A>(C::q) + if (current() == 'N' || // + // This should be a safe bet. + (current() == 'S' && + next_peek() == 't')) // std::something, guess that + // this involves a typedef. + output += "typename "; + } + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 'r') + { + eat_current(); + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += "::"; + if (!decode_unqualified_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'I' || decode_template_args(output)) + _GLIBCXX_DEMANGLER_RETURN; + } + } + else + { + char opcode0 = current(); + char opcode1 = tolower(next()); + + register char hash; + if ((hash = offset_table_c[opcode0 - CHAR_MIN])) + { + hash += opcode1; + if ( +#if (CHAR_MIN < 0) + hash >= 0 && +#endif + hash < 39) + { + int index = static_cast(static_cast(hash)); + entry_st entry = symbol_name_table_c[index]; + if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1 + && (opcode1 == current() || entry.opcode[2] == '=')) + { + char const* op = entry.symbol_name + 8; // Skip "operator". + if (*op == ' ') // operator new and delete. + ++op; + if (entry.type == unary) + output += op; + bool is_eq = (opcode1 != current()); + eat_current(); + if (index == 34 && M_inside_template_args) // operator> + output += '('; + output += '('; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + if (entry.type != unary) + { + if (!M_implementation_details.get_style_compact_expr_ops()) + output += ' '; + output += op; + if (is_eq) + output += '='; + if (!M_implementation_details.get_style_compact_expr_ops()) + output += ' '; + output += '('; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + if (index == 34 && M_inside_template_args) + output += ')'; + if (entry.type == trinary) + { + if (M_implementation_details.get_style_compact_expr_ops()) + output += ":("; + else + output += " : ("; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + } + } + _GLIBCXX_DEMANGLER_RETURN; + } + else if (opcode0 == 'c' && + opcode1 == 'v') // casting operator. + { + eat_current(); + output += '('; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ")("; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + } + } + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // + // ::= I + E + // ::= # type or template + // ::= L E # integer literal + // ::= L E # floating literal + // ::= L E # external name + // ::= X E # expression + template + bool + session::decode_template_args(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_args"); + if (eat_current() != 'I') + _GLIBCXX_DEMANGLER_FAILURE; + int prev_size = M_template_arg_pos.size(); + ++M_inside_template_args; + if (M_template_args_need_space) + { + output += ' '; + M_template_args_need_space = false; + } + output += '<'; + for(;;) + { + if (M_inside_template_args == 1 && !M_inside_type) + M_template_arg_pos.push_back(M_pos); + if (current() == 'X') + { + eat_current(); + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + } + else if (current() == 'L') + { + if (!decode_literal(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + } + else if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() == 'E') + break; + output += ", "; + } + eat_current(); + if (*(output.rbegin()) == '>') + output += ' '; + output += '>'; + --M_inside_template_args; + if (!M_inside_template_args && !M_inside_type) + { + M_name_is_template = true; + M_template_arg_pos_offset = prev_size; + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= + // + # Types are parameter types. + // + // Note that the possible return type of the + // has already been eaten before we call this function. This makes + // our slightly different from the one in + // the C++-ABI description. + // + template + bool + session::decode_bare_function_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_bare_function_type"); + if (M_saw_destructor) + { + if (eat_current() != 'v' || (current() != 'E' && current() != 0)) + _GLIBCXX_DEMANGLER_FAILURE; + output += "()"; + M_saw_destructor = false; + _GLIBCXX_DEMANGLER_RETURN; + } + if (current() == 'v' && !M_implementation_details.get_style_void()) + { + eat_current(); + if (current() != 'E' && current() != 0) + _GLIBCXX_DEMANGLER_FAILURE; + output += "()"; + M_saw_destructor = false; + _GLIBCXX_DEMANGLER_RETURN; + } + output += '('; + M_template_args_need_space = false; + if (!decode_type(output)) // Must have at least one parameter. + _GLIBCXX_DEMANGLER_FAILURE; + while (current() != 'E' && current() != 0) + { + output += ", "; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + + // ::= + // # Starts with a lower case character != r. + // # Starts with F + // # Starts with N, S, C, D, Z, a digit or a lower + // # case character. Since a lower case character + // # would be an operator name, that would be an + // # error. The S is a substitution or St + // # (::std::). A 'C' would be a constructor and + // # thus also an error. + // # Starts with T + // # Starts with S + // # Starts with T or S, + // # equivalent with the above. + // + // # Starts with A + // # Starts with M + // # Starts with r, V or K + // P # pointer-to # Starts with P + // R # reference-to # Starts with R + // C # complex (C 2000) # Starts with C + // G # imaginary (C 2000)# Starts with G + // U # vendor extended type qualifier, + // # starts with U + // + // ::= + // ::= + + // My own analysis of how to decode qualifiers: + // + // F is a , is a , , + // or . + // represents a series of qualifiers (not G or C). + // is an unqualified type. + // is a qualified type. + // is the bare-function-type without return type. + // is the array index. + // Substitutions: + // MFE ==> R (C::*Q)B Q2 "", "FE" + // ( and recursive), + // "MFE". + // FE ==> R (Q)B "", "" ( recursive) + // and "FE". + // + // Note that if has postfix qualifiers (an array or function), then + // those are added AFTER the (member) function type. For example: + // FPAE ==> R (*(Q)B) [], where the PA added the prefix + // "(*" and the postfix ") []". + // + // G ==> imaginary T Q "", "G" ( recursive). + // C ==> complex T Q "", "C" ( recursive). + // ==> T Q "" ( recursive). + // + // where is any of: + // + // P ==> *Q "P..." + // R ==> &Q "R..." + // [K|V|r]+ ==> [ const| volatile| restrict]+Q "KVr..." + // U ==> SQ "U..." + // M ==> C::*Q "M..." ( recurs.) + // A ==> [I] "A..." ( recurs.) + // A ==> (Q) [I] "A..." ( recurs.) + // Note that when ends on an A then the brackets are omitted + // and no space is written between the two: + // AA ==> [I2][I] + // If ends on [KVr]+, which can happen in combination with + // substitutions only, then special handling is required, see below. + // + // A is handled with an input position switch during which + // new substitutions are turned off. Because recursive handling of types + // (and therefore the order in which substitutions must be generated) must + // be done left to right, but the generation of Q needs processing right to + // left, substitutions per are generated by reading the input left + // to right and marking the starts of all substitutions only - implicitly + // finishing them at the end of the type. Then the output and real + // substitutions are generated. + // + // The following comment was for the demangling of g++ version 3.0.x. The + // mangling (and I believe even the ABI description) have been fixed now + // (as of g++ version 3.1). + // + // g++ 3.0.x only: + // The ABI specifies for pointer-to-member function types the format + // MFE. In other words, the qualifier (see above) is + // implicitely contained in instead of explicitly part of the M format. + // I am convinced that this is a bug in the ABI. Unfortunately, this is + // how we have to demangle things as it has a direct impact on the order + // in which substitutions are stored. This ill-formed design results in + // rather ill-formed demangler code too however :/ + // + // is now explicitely part of the M format. + // For some weird reason, g++ (3.2.1) does not add substitutions for + // qualified member function pointers. I think that is another bug. + // + + // In the case of + // A + // where ends on [K|V|r]+ then that part should be processed as + // if it was behind the A instead of in front of it. This is + // because a constant array of ints is normally always mangled as + // an array of constant ints. KVr qualifiers can end up in front + // of an array when the array is part of a substitution or template + // parameter, but the demangling should still result in the same + // syntax; thus KA2_i (const array of ints) must result in the same + // demangling as A2_Ki (array of const ints). As a result we must + // demangle ...[...[[KVr]+A][KVr]+A]...[KVr]+A[KVr]+ + // as AA...A[KVr]+ where each K, V and r in the series + // collapses to a single character at the right of the string. + // For example: + // VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6] + // Note that substitutions are still added as usual (the translation + // to A9_A6_KVri does not really happen). + // + // This decoding is achieved by delaying the decoding of any sequence + // of [KVrA]'s and processing them together in the order: first the + // short-circuited KVr part and then the arrays. + static int const cvq_K = 1; // Saw at least one K + static int const cvq_V = 2; // Saw at least one V + static int const cvq_r = 4; // Saw at least one r + static int const cvq_A = 8; // Saw at least one A + static int const cvq_last = 16; // No remaining qualifiers. + static int const cvq_A_cnt = 32; // Bit 5 and higher represent the + // number of A's in the series. + // In the function below, iter_array points to the first (right most) + // A in the series, if any. + template + void + qualifier_list::decode_KVrA( + string_type& prefix, string_type& postfix, int cvq, + typename qual_vector::const_reverse_iterator const& iter_array) const + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA"); + if ((cvq & cvq_K)) + prefix += " const"; + if ((cvq & cvq_V)) + prefix += " volatile"; + if ((cvq & cvq_r)) + prefix += " restrict"; + if ((cvq & cvq_A)) + { + int n = cvq >> 5; + for (typename qual_vector:: + const_reverse_iterator iter = iter_array; + iter != M_qualifier_starts.rend(); ++iter) + { + switch((*iter).first_qualifier()) + { + case 'K': + case 'V': + case 'r': + break; + case 'A': + { + string_type index = (*iter).get_optional_type(); + if (--n == 0 && (cvq & cvq_last)) + postfix = " [" + index + "]" + postfix; + else if (n > 0) + postfix = "[" + index + "]" + postfix; + else + { + prefix += " ("; + postfix = ") [" + index + "]" + postfix; + } + break; + } + default: + _GLIBCXX_DEMANGLER_RETURN3; + } + } + } + _GLIBCXX_DEMANGLER_RETURN3; + } + + template + void + qualifier_list::decode_qualifiers( + string_type& prefix, + string_type& postfix, + bool member_function_pointer_qualifiers = false) const + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers"); + int cvq = 0; + typename qual_vector::const_reverse_iterator iter_array; + for(typename qual_vector:: + const_reverse_iterator iter = M_qualifier_starts.rbegin(); + iter != M_qualifier_starts.rend(); ++iter) + { + if (!member_function_pointer_qualifiers + && !(*iter).part_of_substitution()) + { + int saved_inside_substitution = M_demangler.M_inside_substitution; + M_demangler.M_inside_substitution = 0; + M_demangler.add_substitution((*iter).get_start_pos(), type); + M_demangler.M_inside_substitution = saved_inside_substitution; + } + char qualifier_char = (*iter).first_qualifier(); + for(; qualifier_char; qualifier_char = (*iter).next_qualifier()) + { + switch(qualifier_char) + { + case 'P': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += "*"; + break; + case 'R': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += "&"; + break; + case 'K': + cvq |= cvq_K; + continue; + case 'V': + cvq |= cvq_V; + continue; + case 'r': + cvq |= cvq_r; + continue; + case 'A': + if (!(cvq & cvq_A)) + { + cvq |= cvq_A; + iter_array = iter; + } + cvq += cvq_A_cnt; + break; + case 'M': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += " "; + prefix += (*iter).get_optional_type(); + prefix += "::*"; + break; + case 'U': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += " "; + prefix += (*iter).get_optional_type(); + break; + case 'G': // Only here so we added a substitution. + break; + } + break; + } + } + if (cvq) + decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array); + M_printing_suppressed = false; + _GLIBCXX_DEMANGLER_RETURN3; + } + + // + template + bool + session::decode_type_with_postfix( + string_type& prefix, string_type& postfix, + qualifier_list* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING2("decode_type"); + ++M_inside_type; + bool recursive_template_param_or_substitution_call; + if (!(recursive_template_param_or_substitution_call = qualifiers)) + { + qualifier_list* raw_qualifiers = M_qualifier_list_alloc.allocate(1); + qualifiers = new (raw_qualifiers) qualifier_list(*this); + } + // First eat all qualifiers. + bool failure = false; + for(;;) // So we can use 'continue' to eat the next qualifier. + { + int start_pos = M_pos; + switch(current()) + { + case 'P': + qualifiers->add_qualifier_start(pointer, start_pos, + M_inside_substitution); + eat_current(); + continue; + case 'R': + qualifiers->add_qualifier_start(reference, start_pos, + M_inside_substitution); + eat_current(); + continue; + case 'K': + case 'V': + case 'r': + { + char c; + int count = 0; + do + { + ++count; + c = next(); + } + while(c == 'K' || c == 'V' || c == 'r'); + qualifiers->add_qualifier_start(cv_qualifier, start_pos, count, + M_inside_substitution); + continue; + } + case 'U': + { + eat_current(); + string_type source_name; + if (!decode_source_name(source_name)) + { + failure = true; + break; + } + qualifiers->add_qualifier_start(vendor_extension, start_pos, + source_name, M_inside_substitution); + continue; + } + case 'A': + { + // ::= A _ + // ::= A [] _ + // + string_type index; + int saved_pos; + store(saved_pos); + if (next() == 'n' || !decode_number(index)) + { + restore(saved_pos); + if (next() != '_' && !decode_expression(index)) + { + failure = true; + break; + } + } + if (eat_current() != '_') + { + failure = true; + break; + } + qualifiers->add_qualifier_start(array, start_pos, index, + M_inside_substitution); + continue; + } + case 'M': + { + // ::= M + // M or MFE + eat_current(); + string_type class_type; + if (!decode_type(class_type)) // Substitution: "". + { + failure = true; + break; + } + char c = current(); + if (c == 'F' || c == 'K' || c == 'V' || c == 'r') + // Must be CV-qualifiers and a member function pointer. + { + // MFE ==> R (C::*Q)B Q2 + // substitutions: "", "FE" ( and + // recursive), "MFE". + int count = 0; + int Q2_start_pos = M_pos; + while(c == 'K' || c == 'V' || c == 'r') // Decode . + { + ++count; + c = next(); + } + qualifier_list class_type_qualifiers(*this); + if (count) + class_type_qualifiers. + add_qualifier_start(cv_qualifier, Q2_start_pos, + count, M_inside_substitution); + string_type member_function_qualifiers; + // It is unclear why g++ doesn't add a substitution for + // "FE" as it should I think. + string_type member_function_qualifiers_postfix; + class_type_qualifiers. + decode_qualifiers(member_function_qualifiers, + member_function_qualifiers_postfix, true); + member_function_qualifiers += + member_function_qualifiers_postfix; + // I don't think this substitution is actually ever used. + int function_pos = M_pos; + if (eat_current() != 'F') + { + failure = true; + break; + } + // Return type. + // Constructors, destructors and conversion operators don't + // have a return type, but seem to never get here. + string_type return_type_postfix; + if (!decode_type_with_postfix(prefix, return_type_postfix)) + // substitution: recursive + { + failure = true; + break; + } + prefix += " ("; + prefix += class_type; + prefix += "::*"; + string_type bare_function_type; + if (!decode_bare_function_type(bare_function_type) + || eat_current() != 'E') // Substitution: recursive. + { + failure = true; + break; + } + // substitution: "FE". + add_substitution(function_pos, type); + // substitution: "MFE". + add_substitution(start_pos, type); + // substitution: all qualified types if any. + qualifiers->decode_qualifiers(prefix, postfix); + postfix += ")"; + postfix += bare_function_type; + postfix += member_function_qualifiers; + postfix += return_type_postfix; + goto decode_type_exit; + } + qualifiers->add_qualifier_start(pointer_to_member, start_pos, + class_type, M_inside_substitution); + continue; + } + default: + break; + } + break; + } + if (!failure) + { + // G ==> imaginary T Q + // substitutions: "", "G" ( recursive). + // C ==> complex T Q + // substitutions: "", "C" ( recursive). + if (current() == 'C' || current() == 'G') + { + prefix += current() == 'C' ? "complex " : "imaginary "; + qualifiers->add_qualifier_start(complex_or_imaginary, M_pos, + M_inside_substitution); + eat_current(); + } + int start_pos = M_pos; + switch(current()) + { + case 'F': + { + // ::= F [Y] E + // + // Note that g++ never generates the 'Y', but we try to + // demangle it anyway. + bool extern_C = (next() == 'Y'); + if (extern_C) + eat_current(); + + // FE ==> R (Q)B + // substitution: "", "" ( recursive) and "FE". + + // Return type. + string_type return_type_postfix; + if (!decode_type_with_postfix(prefix, return_type_postfix)) + // Substitution: "". + { + failure = true; + break; + } + // Only array and function (pointer) types have a postfix. + // In that case we don't want the space but expect something + // like prefix is "int (*" and postfix is ") [1]". + // We do want the space if this pointer is qualified. + if (return_type_postfix.size() == 0 || + (prefix.size() > 0 && *prefix.rbegin() != '*')) + prefix += ' '; + prefix += '('; + string_type bare_function_type; + if (!decode_bare_function_type(bare_function_type) + // substitution: "" ( recursive). + || eat_current() != 'E') + { + failure = true; + break; + } + add_substitution(start_pos, type); // Substitution: "FE". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + postfix += ")"; + if (extern_C) + postfix += " [extern \"C\"] "; + postfix += bare_function_type; + postfix += return_type_postfix; + break; + } + case 'T': + if (!decode_template_param(prefix, qualifiers)) + { + failure = true; + break; + } + if (current() == 'I') + { + add_substitution(start_pos, template_template_param); + // substitution: "". + if (!decode_template_args(prefix)) + { + failure = true; + break; + } + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + { + add_substitution(start_pos, type); + // substitution: "" or + // " ". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + } + break; + case 'S': + if (M_pos >= M_maxpos) + { + failure = true; + break; + } + if (M_str[M_pos + 1] != 't') + { + if (!decode_substitution(prefix, qualifiers)) + { + failure = true; + break; + } + if (current() == 'I') + { + if (!decode_template_args(prefix)) + { + failure = true; + break; + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + add_substitution(start_pos, type); + // Substitution: + // " ". + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + qualifiers->decode_qualifiers(prefix, postfix); + // Substitution: all qualified types, if any. + break; + } + /* Fall-through for St */ + case 'N': + case 'Z': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // ==> T Q + // substitutions: "" ( recursive). + if (!decode_class_enum_type(prefix)) + { + failure = true; + break; + } + if (!recursive_template_param_or_substitution_call) + { + add_substitution(start_pos, type); + // substitution: "". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + } + else + qualifiers->printing_suppressed(); + break; + default: + // ==> T Q + // substitutions: "" ( recursive). + if (!decode_builtin_type(prefix)) + { + failure = true; + break; + } + // If decode_type was called from decode_template_param then we + // need to suppress calling qualifiers here in order to get a + // substitution added anyway (for the ). + if (!recursive_template_param_or_substitution_call) + qualifiers->decode_qualifiers(prefix, postfix); + else + qualifiers->printing_suppressed(); + break; + } + } + decode_type_exit: + --M_inside_type; + if (!recursive_template_param_or_substitution_call) + { + qualifiers->~qualifier_list(); + M_qualifier_list_alloc.deallocate(qualifiers, 1); + } + if (failure) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN2; + } + + // ::= N [] E + // ::= N [] E + // + // ::= + // ::= + // ::= + // ::= # empty + // ::= + // + // ::=