diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..9235365 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,8 @@ +ne2k-rx.log +ne2k-rxdump.txt +ne2k-tx.log +ne2k-txdump.txt +ne2k.raw +ne2k.txt +snapshot.txt +ne2k-pktlog.txt diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..44a44c7 --- /dev/null +++ b/BUGS @@ -0,0 +1,14 @@ +$Id$ + +Bugs: + +10/27/06 - NEED TO IMPLIMENT ENV!!!! + +10/12/06 - + Tempermental Keyboard Driver + +10/12/06 - + UFS is hacked to get correct file size + +10/12/06 - + usrland ld.so forces path sys:/lib/ must make more automated diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ab2b30 --- /dev/null +++ b/Makefile @@ -0,0 +1,60 @@ +# $Id$ +# The System Makefile (C) 2002 The UbixOS Project + +all: kernel csu ubix_api libc_old libc ubix libcpp bin tools +# depend kernel tools + +csu: src + (cd src/lib/csu;make) + +ubix_api: src + (cd src/lib/ubix_api;make) + +libc_old: src + (cd src/lib/libc_old;make) + +libc: src + (cd src/lib/libc;make) + +objgfx40: src + (cd src/lib/objgfx40;make) + +views: src + (cd src/lib/views/sunlight;make) + +ubix: src + (cd src/lib/ubix;make) + +libcpp: src + (cd src/lib/libcpp;make) + +depend: src + (cd src/lib/ubix;make) + +bin: src + (cd src/bin;make) + +libstdc++: src + (cd src/lib/libstdc++;make) + +kernel: src + (cd src/sys;make) + +tools: src + (cd src/tools;make) + +install: + (cd src/sys;make install) + +clean: + (cd src/sys;make clean) + (cd src/lib/csu;make clean) + (cd src/lib/ubix_api;make clean) + (cd src/lib/libc_old;make clean) + (cd src/lib/libc;make clean) + (cd src/bin;make 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/README b/README new file mode 100644 index 0000000..59990bb --- /dev/null +++ b/README @@ -0,0 +1,12 @@ +Installation: + + make all install <- This will build the kernel and components and put them onto a floppy + + Do the following if and only if your boot disk is not bootable and you just need to do + it once + + To make a bootable floppy do the following: + 1) cd src/sys/boot/btx;make + 2) cd ../boot2;make + 3) cat boot1 boot2 > /dev/fd0 + 4) gcc -o test test.c;./test /dev/fd0 1;rm ./test diff --git a/TODO b/TODO new file mode 100644 index 0000000..c9d134e --- /dev/null +++ b/TODO @@ -0,0 +1,22 @@ +$Id$ + +11-28-06 - Make Web Site + +10-12-06 - + Wow a year later and now I'm working on it + Finish fdisk + + Work On Installer + + Put Close File Into VFS.... + + Fix File Descriptor Structure!! + +10-11-05 +Refamiliarize myself with all the code. +Take out current ip/stack +Clean up driver system +Look into Ubix resource management +Work on libc +Enhance shared libraries + diff --git a/src/Makefile.inc b/src/Makefile.inc new file mode 100644 index 0000000..dcb3dc0 --- /dev/null +++ b/src/Makefile.inc @@ -0,0 +1,12 @@ +# $Id$ +# Global 'Source' Options + +# allow you to change your default compiler without affecting your other work +CFLAGS = +CC = gcc +CXX = g++ +LD = ld +AR = ar +REMOVE = rm -rf + +FD_DEVICE = /dev/md0 diff --git a/src/README b/src/README new file mode 100644 index 0000000..74148ed --- /dev/null +++ b/src/README @@ -0,0 +1,7 @@ +Directory Structure: + + bin - Applications for UbixOS + include - Include files to build anything userland + lib - Userland libraries + sys - Kernel code + tools - Tool kit required to build and install UbixOS diff --git a/src/bin/Makefile b/src/bin/Makefile new file mode 100644 index 0000000..8016140 --- /dev/null +++ b/src/bin/Makefile @@ -0,0 +1,93 @@ +# $Id$ +# 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 edit-bin ld-bin ttyd-bin stat-bin cat-bin rtld-elf-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.inc b/src/bin/Makefile.inc new file mode 100644 index 0000000..2101f00 --- /dev/null +++ b/src/bin/Makefile.inc @@ -0,0 +1,11 @@ +# 'bin' options + +CFLAGS = -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/cat/Makefile b/src/bin/cat/Makefile new file mode 100644 index 0000000..5affcdf --- /dev/null +++ b/src/bin/cat/Makefile @@ -0,0 +1,49 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = cat + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = cat.o + +INCLUDES = -I../../include.new + +LIBRARIES = ../../lib/libc/libc.so + +STARTUP = ../../lib/csu/*.o + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/cat/cat b/src/bin/cat/cat new file mode 100755 index 0000000..0251360 --- /dev/null +++ b/src/bin/cat/cat Binary files differ diff --git a/src/bin/cat/cat.c b/src/bin/cat/cat.c new file mode 100644 index 0000000..443b222 --- /dev/null +++ b/src/bin/cat/cat.c @@ -0,0 +1,318 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Kevin Fall. + * + * 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. + * 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. + */ + +#if 0 +#ifndef lint +static char const copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ +#endif + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95"; +#endif +#endif /* not lint */ +#include +__FBSDID("$FreeBSD: src/bin/cat/cat.c,v 1.32 2005/01/10 08:39:20 imp Exp $"); + +#include +#include +#ifndef NO_UDOM_SUPPORT +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int bflag, eflag, nflag, sflag, tflag, vflag; +int rval; +const char *filename; + +static void usage(void); +static void scanfiles(char *argv[], int cooked); +static void cook_cat(FILE *); +static void raw_cat(int); + +#ifndef NO_UDOM_SUPPORT +static int udom_open(const char *path, int flags); +#endif + +int +main(int argc, char *argv[]) +{ + int ch; +printf("argc: [%i]\n",argc); + setlocale(LC_CTYPE, ""); +//printf("optind: [0x%X:%i]\n",&optind,optind); + while ((ch = getopt(argc, argv, "benstuv")) != -1) + switch (ch) { + case 'b': + bflag = nflag = 1; /* -b implies -n */ + break; + case 'e': + eflag = vflag = 1; /* -e implies -v */ + break; + case 'n': + nflag = 1; + break; + case 's': + sflag = 1; + break; + case 't': + tflag = vflag = 1; /* -t implies -v */ + break; + case 'u': + setbuf(stdout, NULL); + break; + case 'v': + vflag = 1; + break; + default: + usage(); + } +//printf("optind: [%i]\n",optind); +asm("nop"); + argv += optind; +asm("nop"); +// printf("optind: [%i]",optind); + if (bflag || eflag || nflag || sflag || tflag || vflag) + scanfiles(argv, 1); + else + scanfiles(argv, 0); + if (fclose(stdout)) + err(1, "stdout"); + exit(rval); + /* NOTREACHED */ +} + +static void +usage(void) +{ + fprintf(stderr, "usage: cat [-benstuv] [file ...]\n"); + exit(1); + /* NOTREACHED */ +} + +static void +scanfiles(char *argv[], int cooked) +{ + int i = 0; + char *path; + FILE *fp; + + while ((path = argv[i]) != NULL || i == 0) { + int fd; + + if (path == NULL || strcmp(path, "-") == 0) { + filename = "stdin"; + fd = STDIN_FILENO; + } else { + filename = path; + fd = open(path, O_RDONLY); +printf("A"); +#ifndef NO_UDOM_SUPPORT + if (fd < 0 && errno == EOPNOTSUPP) + fd = udom_open(path, O_RDONLY); +#endif + } + if (fd < 0) { + warn("%s", path); + rval = 1; + } else if (cooked) { + if (fd == STDIN_FILENO) + cook_cat(stdin); + else { + fp = fdopen(fd, "r"); + cook_cat(fp); + fclose(fp); + } + } else { + raw_cat(fd); + if (fd != STDIN_FILENO) + close(fd); + } + if (path == NULL) + break; + ++i; + } +} + +static void +cook_cat(FILE *fp) +{ + int ch, gobble, line, prev; + + /* Reset EOF condition on stdin. */ + if (fp == stdin && feof(stdin)) + clearerr(stdin); + + line = gobble = 0; + for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { + if (prev == '\n') { + if (sflag) { + if (ch == '\n') { + if (gobble) + continue; + gobble = 1; + } else + gobble = 0; + } + if (nflag && (!bflag || ch != '\n')) { + (void)fprintf(stdout, "%6d\t", ++line); + if (ferror(stdout)) + break; + } + } + if (ch == '\n') { + if (eflag && putchar('$') == EOF) + break; + } else if (ch == '\t') { + if (tflag) { + if (putchar('^') == EOF || putchar('I') == EOF) + break; + continue; + } + } else if (vflag) { + if (!isascii(ch) && !isprint(ch)) { + if (putchar('M') == EOF || putchar('-') == EOF) + break; + ch = toascii(ch); + } + if (iscntrl(ch)) { + if (putchar('^') == EOF || + putchar(ch == '\177' ? '?' : + ch | 0100) == EOF) + break; + continue; + } + } + if (putchar(ch) == EOF) + break; + } + if (ferror(fp)) { + warn("%s", filename); + rval = 1; + clearerr(fp); + } + if (ferror(stdout)) + err(1, "stdout"); +} + +static void +raw_cat(int rfd) +{ + int off, wfd; + ssize_t nr, nw; + static size_t bsize; + static char *buf = NULL; + struct stat sbuf; + + wfd = fileno(stdout); + if (buf == NULL) { + if (fstat(wfd, &sbuf)) + err(1, "%s", filename); + bsize = MAX(sbuf.st_blksize, 1024); + if ((buf = malloc(bsize)) == NULL) + err(1, "buffer"); + } + while ((nr = read(rfd, buf, bsize)) > 0) + for (off = 0; nr; nr -= nw, off += nw) + if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) + err(1, "stdout"); + if (nr < 0) { + warn("%s", filename); + rval = 1; + } +} + +#ifndef NO_UDOM_SUPPORT + +static int +udom_open(const char *path, int flags) +{ + struct sockaddr_un sou; + int fd; + unsigned int len; + + bzero(&sou, sizeof(sou)); + + /* + * Construct the unix domain socket address and attempt to connect + */ + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd >= 0) { + sou.sun_family = AF_UNIX; + if ((len = strlcpy(sou.sun_path, path, + sizeof(sou.sun_path))) >= sizeof(sou.sun_path)) { + errno = ENAMETOOLONG; + return (-1); + } + len = offsetof(struct sockaddr_un, sun_path[len+1]); + + if (connect(fd, (void *)&sou, len) < 0) { + close(fd); + fd = -1; + } + } + + /* + * handle the open flags by shutting down appropriate directions + */ + if (fd >= 0) { + switch(flags & O_ACCMODE) { + case O_RDONLY: + if (shutdown(fd, SHUT_WR) == -1) + warn(NULL); + break; + case O_WRONLY: + if (shutdown(fd, SHUT_RD) == -1) + warn(NULL); + break; + default: + break; + } + } + return(fd); +} + +#endif diff --git a/src/bin/clock/Makefile b/src/bin/clock/Makefile new file mode 100644 index 0000000..00f6bc5 --- /dev/null +++ b/src/bin/clock/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = clock + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/clock/main.c b/src/bin/clock/main.c new file mode 100644 index 0000000..45dcb2e --- /dev/null +++ b/src/bin/clock/main.c @@ -0,0 +1,104 @@ +/***************************************************************************************** + 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$ + +*****************************************************************************************/ + +#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); + for (i = 0x0;i < argc;i++) { + printf("argv[%i](0x%X:%s),__progrname(%s), argc: %i\n",i,argv[i],argv[i],__progname,argc); + } + return(0); + } + +/*** + END + ***/ + diff --git a/src/bin/cp/Makefile b/src/bin/cp/Makefile new file mode 100644 index 0000000..9a4b19d --- /dev/null +++ b/src/bin/cp/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = cp + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/cp/main.c b/src/bin/cp/main.c new file mode 100644 index 0000000..fddae81 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..427a0c3 --- /dev/null +++ b/src/bin/disklabel/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = disklabel + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/disklabel/main.c b/src/bin/disklabel/main.c new file mode 100644 index 0000000..d79c52c --- /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$ + +*****************************************************************************************/ + +#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$ + 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..d19f452 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..9ad8dfb --- /dev/null +++ b/src/bin/edit/Makefile @@ -0,0 +1,49 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(BINARY) diff --git a/src/bin/edit/main.c b/src/bin/edit/main.c new file mode 100644 index 0000000..b1c9d47 --- /dev/null +++ b/src/bin/edit/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$ + +*****************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + extern char *environ; + FILE *out; + printf("UbixOS Text Editor\n"); + printf("V1.0\n"); +#ifdef DEBUG + printf("ARGC: [%i]\n",argc); + printf("ARGV[0]: [%s]\n",argv[0]); + return(0x0); +#endif + + 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..0f7b18c --- /dev/null +++ b/src/bin/fdisk/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = fdisk + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/fdisk/main.c b/src/bin/fdisk/main.c new file mode 100644 index 0000000..5db9701 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..d19f452 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..f27ed98 --- /dev/null +++ b/src/bin/format/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(BINARY) diff --git a/src/bin/format/main.c b/src/bin/format/main.c new file mode 100644 index 0000000..b147a23 --- /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$ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include + + +int main(int argc,char **argv) { + printf("UbixOS Format V1.0\n"); + return(0); + } + +/*** + $Log$ + 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..7cdfc87 --- /dev/null +++ b/src/bin/init/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = init + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +#LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/init/main.c b/src/bin/init/main.c new file mode 100644 index 0000000..65b2107 --- /dev/null +++ b/src/bin/init/main.c @@ -0,0 +1,116 @@ +/***************************************************************************************** + 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$ + +*****************************************************************************************/ + +#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"); + +#if 0 + /* Start TTYD */ + i = fork(); + + if (0x0 == i) { + exec("sys:/ttyd",0x0); + printf("Error: Could not start TTYD\n"); + exit(0x0); + } + + while (pidStatus(i) > 0x0) + sched_yield(); +#endif + +/* + 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(); + if (0 == i) { + printf("Starting Login Daemon.\n"); + exec("sys:/bin/login",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..eca7b66 --- /dev/null +++ b/src/bin/launcher/Makefile @@ -0,0 +1,50 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +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 $@ $(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..8038f81 --- /dev/null +++ b/src/bin/ld/Makefile @@ -0,0 +1,46 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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) -nostdlib -shared -Wl,-soname,$(OUTPUT) -e _ld -o $(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 $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) $(OUTPUT) diff --git a/src/bin/ld/addlibrary.c b/src/bin/ld/addlibrary.c new file mode 100644 index 0000000..bda4116 --- /dev/null +++ b/src/bin/ld/addlibrary.c @@ -0,0 +1,162 @@ +#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) { +//HELP + if ((tmpLib->output = (char *)getPage((0x110000/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..1499bf1 --- /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$ + +**************************************************************************************/ + +#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..eace1a2 --- /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$ + +*****************************************************************************************/ + +.globl _ld +.text +.code32 + +_ld: + call ld + add $8,%esp + push %eax + ret + +/*** + $Log$ + 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..7ae8ed5 --- /dev/null +++ b/src/bin/ld/main.c @@ -0,0 +1,161 @@ +/***************************************************************************************** + 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$ + +*****************************************************************************************/ + +#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;ieShnum;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:0x%X)",binaryDynStr + binaryRelSymTab[x].dynName,*reMap); + //*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..5a857d9 --- /dev/null +++ b/src/bin/login/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(BINARY) diff --git a/src/bin/login/main.c b/src/bin/login/main.c new file mode 100644 index 0000000..e1bb267 --- /dev/null +++ b/src/bin/login/main.c @@ -0,0 +1,147 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#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/"); + exec(data[i].shell,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..70dd9a4 --- /dev/null +++ b/src/bin/ls/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = ls + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/ls/main.c b/src/bin/ls/main.c new file mode 100644 index 0000000..cbde456 --- /dev/null +++ b/src/bin/ls/main.c @@ -0,0 +1,132 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#include +#include +#include + + +#define permRead 0x8 +#define permWrite 0x4 +#define permExecute 0x2 +#define permHidden 0x1 + + +//UbixFS Directory Entry +struct directoryEntry { + u_int32_t startCluster; //Starting Cluster Of File + u_int32_t size; //Size Of File + u_int32_t creationDate; //Date Created + u_int32_t lastModified; //Date Last Modified + u_int32_t uid; //UID Of Owner + u_int32_t gid; //GID Of Owner + u_int16_t attributes; //Files Attributes + u_int16_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); + if ((fd = fopen(pwd,"rb")) == 0x0) { + printf("Error: Reading Directory\n"); + exit(1); + } + } + else if (argv[1] == 0x0) { + getcwd(pwd,256); + if ((fd = fopen(pwd,"rb")) == 0x0) { + printf("Error: Reading Directory\n"); + exit(1); + } + } + else { + 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++) { + 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..f54faa5 --- /dev/null +++ b/src/bin/mount/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(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..25d7562 --- /dev/null +++ b/src/bin/muffin/Makefile @@ -0,0 +1,52 @@ +# $Id$ +# Application Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(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..5c97230 --- /dev/null +++ b/src/bin/rtld-elf/Makefile @@ -0,0 +1,58 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +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 -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 $(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..c8fa19e --- /dev/null +++ b/src/bin/rtld-elf/malloc.c @@ -0,0 +1,502 @@ +/*- + * 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. 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/ +static char *rcsid = "$FreeBSD: src/libexec/rtld-elf/malloc.c,v 1.10 2003/08/22 02:22:59 imp Exp $"; +#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 +#ifndef BSD +#define MAP_COPY MAP_PRIVATE +#define MAP_FILE 0 +#define MAP_ANON 0 +#endif + +#ifndef BSD /* Need do better than this */ +#define NEED_DEV_ZERO 1 +#endif + +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 */ +static void xprintf(const char *, ...); +#define TRACE() xprintf("TRACE %s:%d\n", __FILE__, __LINE__) + +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 = getpagesize(); + 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)); +} + +/* + * 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; + +#ifdef NEED_DEV_ZERO + fd = open(_PATH_DEVZERO, O_RDWR, 0); + if (fd == -1) + perror(_PATH_DEVZERO); +#endif + + 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) + warn("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) { + xprintf("Cannot map anonymous memory"); + return 0; + } + pagepool_end = pagepool_start + n * pagesz; + pagepool_start += offset; + +#ifdef NEED_DEV_ZERO + close(fd); +#endif + return n; +} + +/* + * Non-mallocing printf, for use by malloc itself. + */ +static void +xprintf(const char *fmt, ...) +{ + char buf[256]; + va_list ap; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + (void)write(STDOUT_FILENO, buf, strlen(buf)); + va_end(ap); +} 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..7281c04 --- /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$ + */ + +/* + * 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; +} + +const 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..d8dd379 --- /dev/null +++ b/src/bin/rtld-elf/rtld.h @@ -0,0 +1,252 @@ +/*- + * 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: src/libexec/rtld-elf/rtld.h,v 1.35.2.1 2005/12/30 22:13:56 marcel Exp $ + */ + +#ifndef RTLD_H /* { */ +#define RTLD_H 1 + +#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(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; + +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); + +/* 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; + +/* 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; + +/* + * 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 */ + + /* 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 */ + + /* 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 */ + + 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 chains */ + + const char *rpath; /* Search path specified in object */ + Needed_Entry *needed; /* Shared objects needed by this one (%) */ + + Elf_Addr init; /* Initialization function to call */ + Elf_Addr fini; /* Termination function to call */ + + bool mainprog; /* True if this is the main program */ + bool rtld; /* True if this is the dynamic linker */ + bool textrel; /* True if there are relocations to text seg */ + bool symbolic; /* True if generated with "-Bsymbolic" */ + bool bind_now; /* True if all relocations should be made first */ + bool traced; /* Already printed in ldd trace output */ + bool jmpslots_done; /* Already have relocated the jump slots */ + bool init_done; /* Already have added object to init list */ + bool tls_done; /* Already allocated offset for static TLS */ + + 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-dependant */ +} Obj_Entry; + +#define RTLD_MAGIC 0xd550b87a +#define RTLD_VERSION 1 + +#define RTLD_STATIC_TLS_EXTRA 64 + +/* + * 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; + +extern void _rtld_error(const char *, ...) __printflike(1, 2); +extern Obj_Entry *map_object(int, const char *, const struct stat *); +extern void *xcalloc(size_t); +extern void *xmalloc(size_t); +extern char *xstrdup(const char *); +extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; + +extern void dump_relocations (Obj_Entry *); +extern void dump_obj_relocations (Obj_Entry *); +extern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long); +extern 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 **, bool, SymCache *); +void init_pltgot(Obj_Entry *); +void lockdflt_init(void); +void obj_free(Obj_Entry *); +Obj_Entry *obj_new(void); +void _rtld_bind_start(void); +const Elf_Sym *symlook_obj(const char *, unsigned long, + const Obj_Entry *, bool); +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); + +/* + * MD function declarations. + */ +int do_copy_relocations(Obj_Entry *); +int reloc_non_plt(Obj_Entry *, Obj_Entry *); +int reloc_plt(Obj_Entry *); +int reloc_jmpslots(Obj_Entry *); +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..9a9fa05 --- /dev/null +++ b/src/bin/rtld-elf/rtld_lock.c @@ -0,0 +1,317 @@ +/*- + * 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: src/libexec/rtld-elf/rtld_lock.c,v 1.3 2004/11/16 20:45:51 jhb Exp $ + */ + +/* + * 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 "debug.h" +#include "rtld.h" +#include "rtld_machdep.h" + +#define WAFLAG 0x1 /* A writer holds the lock */ +#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */ + +typedef struct Struct_Lock { + volatile 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 2 +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]; + +int +rlock_acquire(rtld_lock_t lock) +{ + if (thread_mask_set(lock->mask)) { + dbg("rlock_acquire: recursed"); + return (0); + } + lockinfo.rlock_acquire(lock->handle); + return (1); +} + +int +wlock_acquire(rtld_lock_t lock) +{ + if (thread_mask_set(lock->mask)) { + dbg("wlock_acquire: recursed"); + return (0); + } + lockinfo.wlock_acquire(lock->handle); + return (1); +} + +void +rlock_release(rtld_lock_t lock, int locked) +{ + if (locked == 0) + return; + thread_mask_clear(lock->mask); + lockinfo.lock_release(lock->handle); +} + +void +wlock_release(rtld_lock_t lock, int locked) +{ + if (locked == 0) + return; + thread_mask_clear(lock->mask); + lockinfo.lock_release(lock->handle); +} + +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"); +} diff --git a/src/bin/rtld-elf/rtld_lock.h b/src/bin/rtld-elf/rtld_lock.h new file mode 100644 index 0000000..906e472 --- /dev/null +++ b/src/bin/rtld-elf/rtld_lock.h @@ -0,0 +1,63 @@ +/*- + * 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: src/libexec/rtld-elf/rtld_lock.h,v 1.2 2003/06/19 02:39:37 mdodd Exp $ + */ + +#ifndef _RTLD_LOCK_H_ +#define _RTLD_LOCK_H_ + +#define RTLI_VERSION 0x01 + +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 *); + +#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; + +int rlock_acquire(rtld_lock_t); +int wlock_acquire(rtld_lock_t); +void rlock_release(rtld_lock_t, int); +void wlock_release(rtld_lock_t, int); + +#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..3bc939e --- /dev/null +++ b/src/bin/rtld-elf/rtld_machdep.h @@ -0,0 +1,77 @@ +/*- + * 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: src/libexec/rtld-elf/i386/rtld_machdep.h,v 1.10 2004/08/03 08:50:59 dfr Exp $ + */ + +#ifndef RTLD_MACHDEP_H +#define RTLD_MACHDEP_H 1 + +#include +#include + +#define CACHE_LINE_SIZE 32 + +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) +{ + dbg("reloc_jmpslot: *%p = %p", (void *)(where), + (void *)(target)); + (*(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 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; + +extern void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1))); +extern void *__tls_get_addr(tls_index *ti); + +#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..e2e25b7 --- /dev/null +++ b/src/bin/sh/Makefile @@ -0,0 +1,49 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 $@ $(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) $(BINARY) diff --git a/src/bin/sh/sh.h b/src/bin/sh/sh.h new file mode 100644 index 0000000..163cd57 --- /dev/null +++ b/src/bin/sh/sh.h @@ -0,0 +1,385 @@ +#include +#include +#include +#include + +#define _NSIG 10 + +/* Need a way to have void used for ANSI, nothing for K&R. */ +#ifndef _ANSI +#undef _VOID +#define _VOID +#endif + +/* -------- sh.h -------- */ +/* + * shell + */ + +#define LINELIM 2100 +#define NPUSH 8 /* limit to input nesting */ + +#define NOFILE 20 /* Number of open files */ +#define NUFILE 10 /* Number of user-accessible files */ +#define FDBASE 10 /* First file usable by Shell */ + +/* + * values returned by wait + */ +#define WAITSIG(s) ((s)&0177) +#define WAITVAL(s) (((s)>>8)&0377) +#define WAITCORE(s) (((s)&0200)!=0) + +/* + * library and system defintions + */ +#ifdef __STDC__ +typedef void xint; /* base type of jmp_buf, for not broken compilers */ +#else +typedef char * xint; /* base type of jmp_buf, for broken compilers */ +#endif + +/* + * shell components + */ +/* #include "area.h" */ +/* #include "word.h" */ +/* #include "io.h" */ +/* #include "var.h" */ + +#define QUOTE 0200 + +#define NOBLOCK ((struct op *)NULL) +#define NOWORD ((char *)NULL) +#define NOWORDS ((char **)NULL) +#define NOPIPE ((int *)NULL) + +/* + * Description of a command or an operation on commands. + * Might eventually use a union. + */ +struct op { + int type; /* operation type, see below */ + char **words; /* arguments to a command */ + struct ioword **ioact; /* IO actions (eg, < > >>) */ + struct op *left; + struct op *right; + char *str; /* identifier for case and for */ +}; + +#define TCOM 1 /* command */ +#define TPAREN 2 /* (c-list) */ +#define TPIPE 3 /* a | b */ +#define TLIST 4 /* a [&;] b */ +#define TOR 5 /* || */ +#define TAND 6 /* && */ +#define TFOR 7 +#define TDO 8 +#define TCASE 9 +#define TIF 10 +#define TWHILE 11 +#define TUNTIL 12 +#define TELIF 13 +#define TPAT 14 /* pattern in case */ +#define TBRACE 15 /* {c-list} */ +#define TASYNC 16 /* c & */ + +/* + * actions determining the environment of a process + */ +#define BIT(i) (1<<(i)) +#define FEXEC BIT(0) /* execute without forking */ + +/* + * flags to control evaluation of words + */ +#define DOSUB 1 /* interpret $, `, and quotes */ +#define DOBLANK 2 /* perform blank interpretation */ +#define DOGLOB 4 /* interpret [?* */ +#define DOKEY 8 /* move words with `=' to 2nd arg. list */ +#define DOTRIM 16 /* trim resulting string */ + +#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) + +Extern char **dolv; +Extern int dolc; +Extern int exstat; +Extern char gflg; +Extern int talking; /* interactive (talking-type wireless) */ +Extern int execflg; +Extern int multiline; /* \n changed to ; */ +Extern struct op *outtree; /* result from parser */ + +Extern xint *failpt; +Extern xint *errpt; + +struct brkcon { + jmp_buf brkpt; + struct brkcon *nextlev; +} ; +Extern struct brkcon *brklist; +Extern int isbreak; + +/* + * redirection + */ +struct ioword { + short io_unit; /* unit affected */ + short io_flag; /* action (below) */ + char *io_name; /* file name */ +}; +#define IOREAD 1 /* < */ +#define IOHERE 2 /* << (here file) */ +#define IOWRITE 4 /* > */ +#define IOCAT 8 /* >> */ +#define IOXHERE 16 /* ${}, ` in << */ +#define IODUP 32 /* >&digit */ +#define IOCLOSE 64 /* >&- */ + +#define IODEFAULT (-1) /* token for default IO unit */ + +Extern struct wdblock *wdlist; +Extern struct wdblock *iolist; + +/* + * parsing & execution environment + */ +extern struct env { + char *linep; + struct io *iobase; + struct io *iop; + xint *errpt; + int iofd; + struct env *oenv; +} e; + +/* + * flags: + * -e: quit on error + * -k: look for name=value everywhere on command line + * -n: no execution + * -t: exit after reading and executing one command + * -v: echo as read + * -x: trace + * -u: unset variables net diagnostic + */ +extern char *flag; + +extern char *null; /* null value for variable */ +extern int intr; /* interrupt pending */ + +Extern char *trap[_NSIG+1]; +Extern char ourtrap[_NSIG+1]; +Extern int trapset; /* trap pending */ + +extern int heedint; /* heed interrupt signals */ + +Extern int yynerrs; /* yacc */ + +Extern char line[LINELIM]; +extern char *elinep; + +/* + * other functions + */ +#ifdef __STDC__ +int (*inbuilt(char *s ))(void); +#else +int (*inbuilt())(); +#endif +_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp )); +_PROTOTYPE(char *space , (int n )); +_PROTOTYPE(char *strsave , (char *s , int a )); +_PROTOTYPE(char *evalstr , (char *cp , int f )); +_PROTOTYPE(char *putn , (int n )); +_PROTOTYPE(char *itoa , (unsigned u , int n )); +_PROTOTYPE(char *unquote , (char *as )); +_PROTOTYPE(struct var *lookup , (char *n )); +_PROTOTYPE(int rlookup , (char *n )); +_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb )); +_PROTOTYPE(int subgetc , (int ec , int quoted )); +_PROTOTYPE(char **makenv , (void)); +_PROTOTYPE(char **eval , (char **ap , int f )); +_PROTOTYPE(int setstatus , (int s )); +_PROTOTYPE(int waitfor , (int lastpid , int canintr )); + +_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */ + +_PROTOTYPE(int newenv , (int f )); +_PROTOTYPE(void quitenv , (void)); +_PROTOTYPE(void err , (char *s )); +_PROTOTYPE(int anys , (char *s1 , char *s2 )); +_PROTOTYPE(int any , (int c , char *s )); +_PROTOTYPE(void next , (int f )); +_PROTOTYPE(void setdash , (void)); +_PROTOTYPE(void onecommand , (void)); +_PROTOTYPE(void runtrap , (int i )); +_PROTOTYPE(void xfree , (char *s )); +_PROTOTYPE(int letter , (int c )); +_PROTOTYPE(int digit , (int c )); +_PROTOTYPE(int letnum , (int c )); +_PROTOTYPE(int gmatch , (char *s , char *p )); + +/* + * error handling + */ +_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */ +_PROTOTYPE(void fail , (void)); /* fail but return to process next command */ +_PROTOTYPE(void warn , (char *s )); +_PROTOTYPE(void sig , (int i )); /* default signal handler */ + +/* -------- var.h -------- */ + +struct var { + char *value; + char *name; + struct var *next; + char status; +}; +#define COPYV 1 /* flag to setval, suggesting copy */ +#define RONLY 01 /* variable is read-only */ +#define EXPORT 02 /* variable is to be exported */ +#define GETCELL 04 /* name & value space was got with getcell */ + +Extern struct var *vlist; /* dictionary */ + +Extern struct var *homedir; /* home directory */ +Extern struct var *prompt; /* main prompt */ +Extern struct var *cprompt; /* continuation prompt */ +Extern struct var *path; /* search path for commands */ +Extern struct var *shell; /* shell to interpret command files */ +Extern struct var *ifs; /* field separators */ + +_PROTOTYPE(int yyparse , (void)); +_PROTOTYPE(struct var *lookup , (char *n )); +_PROTOTYPE(void setval , (struct var *vp , char *val )); +_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name )); +_PROTOTYPE(void export , (struct var *vp )); +_PROTOTYPE(void ronly , (struct var *vp )); +_PROTOTYPE(int isassign , (char *s )); +_PROTOTYPE(int checkname , (char *cp )); +_PROTOTYPE(int assign , (char *s , int cf )); +_PROTOTYPE(void putvlist , (int f , int out )); +_PROTOTYPE(int eqname , (char *n1 , char *n2 )); + +_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act )); + +/* -------- io.h -------- */ +/* io buffer */ +struct iobuf { + unsigned id; /* buffer id */ + char buf[512]; /* buffer */ + char *bufp; /* pointer into buffer */ + char *ebufp; /* pointer to end of buffer */ +}; + +/* possible arguments to an IO function */ +struct ioarg { + char *aword; + char **awordlist; + int afile; /* file descriptor */ + unsigned afid; /* buffer id */ + long afpos; /* file position */ + struct iobuf *afbuf; /* buffer for this file */ +}; +Extern struct ioarg ioargstack[NPUSH]; +#define AFID_NOBUF (~0) +#define AFID_ID 0 + +/* an input generator's state */ +struct io { + int (*iofn)(_VOID); + struct ioarg *argp; + int peekc; + char prev; /* previous character read by readc() */ + char nlcount; /* for `'s */ + char xchar; /* for `'s */ + char task; /* reason for pushed IO */ +}; +Extern struct io iostack[NPUSH]; +#define XOTHER 0 /* none of the below */ +#define XDOLL 1 /* expanding ${} */ +#define XGRAVE 2 /* expanding `'s */ +#define XIO 3 /* file IO */ + +/* in substitution */ +#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) + +/* + * input generators for IO structure + */ +_PROTOTYPE(int nlchar , (struct ioarg *ap )); +_PROTOTYPE(int strchar , (struct ioarg *ap )); +_PROTOTYPE(int qstrchar , (struct ioarg *ap )); +_PROTOTYPE(int filechar , (struct ioarg *ap )); +_PROTOTYPE(int herechar , (struct ioarg *ap )); +_PROTOTYPE(int linechar , (struct ioarg *ap )); +_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop )); +_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop )); +_PROTOTYPE(int dolchar , (struct ioarg *ap )); +_PROTOTYPE(int wdchar , (struct ioarg *ap )); +_PROTOTYPE(void scraphere , (void)); +_PROTOTYPE(void freehere , (int area )); +_PROTOTYPE(void gethere , (void)); +_PROTOTYPE(void markhere , (char *s , struct ioword *iop )); +_PROTOTYPE(int herein , (char *hname , int xdoll )); +_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID))); + +/* + * IO functions + */ +_PROTOTYPE(int eofc , (void)); +_PROTOTYPE(int getc , (int ec )); +_PROTOTYPE(int readc , (void)); +_PROTOTYPE(void unget , (int c )); +_PROTOTYPE(void ioecho , (int c )); +_PROTOTYPE(void prs , (char *s )); +_PROTOTYPE(void putc , (int c )); +_PROTOTYPE(void prn , (unsigned u )); +_PROTOTYPE(void closef , (int i )); +_PROTOTYPE(void closeall , (void)); + +/* + * IO control + */ +_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID))); +_PROTOTYPE(int remap , (int fd )); +_PROTOTYPE(int openpipe , (int *pv )); +_PROTOTYPE(void closepipe , (int *pv )); +_PROTOTYPE(struct io *setbase , (struct io *ip )); + +extern struct ioarg temparg; /* temporary for PUSHIO */ +#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) +#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) + +/* -------- word.h -------- */ +#ifndef WORD_H +#define WORD_H 1 +struct wdblock { + short w_bsize; + short w_nword; + /* bounds are arbitrary */ + char *w_words[1]; +}; + +_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb )); +_PROTOTYPE(struct wdblock *newword , (int nw )); +_PROTOTYPE(char **getwords , (struct wdblock *wb )); +#endif + +/* -------- area.h -------- */ + +/* + * storage allocation + */ +_PROTOTYPE(char *getcell , (unsigned nbytes )); +_PROTOTYPE(void garbage , (void)); +_PROTOTYPE(void setarea , (char *cp , int a )); +_PROTOTYPE(int getarea , (char *cp )); +_PROTOTYPE(void freearea , (int a )); +_PROTOTYPE(void freecell , (char *cp )); + +Extern int areanum; /* current allocation area */ + +#define NEW(type) (type *)getcell(sizeof(type)) +#define DELETE(obj) freecell((char *)obj) diff --git a/src/bin/sh/sh1.c b/src/bin/sh/sh1.c new file mode 100644 index 0000000..cf45644 --- /dev/null +++ b/src/bin/sh/sh1.c @@ -0,0 +1,952 @@ +#define Extern extern +#include +#include +#include +#include +#include "sh.h" +/* -------- sh.c -------- */ +/* + * shell + */ + +/* #include "sh.h" */ + +int intr; +int inparse; +char flags['z'-'a'+1]; +char *flag = flags-'a'; +char *elinep = line+sizeof(line)-5; +char *null = ""; +int heedint =1; +struct env e ={line, iostack, iostack-1, + (xint *)NULL, FDBASE, (struct env *)NULL}; + +extern char **environ; /* environment pointer */ + +/* + * default shell, search rules + */ +char shellname[] = "/bin/sh"; +char search[] = ":/bin:/usr/bin"; + +_PROTOTYPE(void (*qflag), (int)) = SIG_IGN; + +_PROTOTYPE(int main, (int argc, char **argv )); +_PROTOTYPE(int newfile, (char *s )); +_PROTOTYPE(static char *findeq, (char *cp )); +_PROTOTYPE(static char *cclass, (char *p, int sub )); +_PROTOTYPE(void initarea, (void)); + +int main(argc, argv) +int argc; +register char **argv; +{ + register int f; + register char *s; + int cflag; + char *name, **ap; + int (*iof)(); + + initarea(); + if ((ap = environ) != NULL) { + while (*ap) + assign(*ap++, !COPYV); + for (ap = environ; *ap;) + export(lookup(*ap++)); + } + closeall(); + areanum = 1; + + shell = lookup("SHELL"); + if (shell->value == null) + setval(shell, shellname); + export(shell); + + homedir = lookup("HOME"); + if (homedir->value == null) + setval(homedir, "/"); + export(homedir); + + setval(lookup("$"), itoa(getpid(), 5)); + + path = lookup("PATH"); + if (path->value == null) + setval(path, search); + export(path); + + ifs = lookup("IFS"); + if (ifs->value == null) + setval(ifs, " \t\n"); + + prompt = lookup("PS1"); + if (prompt->value == null) +#ifndef UNIXSHELL + setval(prompt, "$ "); +#else + setval(prompt, "% "); +#endif + + if (geteuid() == 0) { + setval(prompt, "# "); + prompt->status &= ~EXPORT; + } + cprompt = lookup("PS2"); + if (cprompt->value == null) + setval(cprompt, "> "); + + iof = filechar; + cflag = 0; + name = *argv++; + if (--argc >= 1) { + if(argv[0][0] == '-' && argv[0][1] != '\0') { + for (s = argv[0]+1; *s; s++) + switch (*s) { + case 'c': + prompt->status &= ~EXPORT; + cprompt->status &= ~EXPORT; + setval(prompt, ""); + setval(cprompt, ""); + cflag = 1; + if (--argc > 0) + PUSHIO(aword, *++argv, iof = nlchar); + break; + + case 'q': + qflag = SIG_DFL; + break; + + case 's': + /* standard input */ + break; + + case 't': + prompt->status &= ~EXPORT; + setval(prompt, ""); + iof = linechar; + break; + + case 'i': + talking++; + default: + if (*s>='a' && *s<='z') + flag[*s]++; + } + } else { + argv--; + argc++; + } + if (iof == filechar && --argc > 0) { + setval(prompt, ""); + setval(cprompt, ""); + prompt->status &= ~EXPORT; + cprompt->status &= ~EXPORT; + if (newfile(name = *++argv)) + exit(1); + } + } + setdash(); + if (e.iop < iostack) { + PUSHIO(afile, 0, iof); + if (isatty(0) && isatty(1) && !cflag) + talking++; + } + signal(SIGQUIT, qflag); + if (name && name[0] == '-') { + talking++; + if ((f = open(".profile", 0)) >= 0) + next(remap(f)); + if ((f = open("/etc/profile", 0)) >= 0) + next(remap(f)); + } + if (talking) + signal(SIGTERM, sig); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, onintr); + dolv = argv; + dolc = argc; + dolv[0] = name; + if (dolc > 1) + for (ap = ++argv; --argc > 0;) + if (assign(*ap = *argv++, !COPYV)) + dolc--; /* keyword */ + else + ap++; + setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc)); + + for (;;) { + if (talking && e.iop <= iostack) + prs(prompt->value); + onecommand(); + } +} + +void +setdash() +{ + register char *cp, c; + char m['z'-'a'+1]; + + cp = m; + for (c='a'; c<='z'; c++) + if (flag[c]) + *cp++ = c; + *cp = 0; + setval(lookup("-"), m); +} + +int +newfile(s) +register char *s; +{ + register f; + + if (strcmp(s, "-") != 0) { + f = open(s, 0); + if (f < 0) { + prs(s); + err(": cannot open"); + return(1); + } + } else + f = 0; + next(remap(f)); + return(0); +} + +void +onecommand() +{ + register i; + jmp_buf m1; + + while (e.oenv) + quitenv(); + areanum = 1; + freehere(areanum); + freearea(areanum); + garbage(); + wdlist = 0; + iolist = 0; + e.errpt = 0; + e.linep = line; + yynerrs = 0; + multiline = 0; + inparse = 1; + intr = 0; + execflg = 0; + setjmp(failpt = m1); /* Bruce Evans' fix */ + if (setjmp(failpt = m1) || yyparse() || intr) { + while (e.oenv) + quitenv(); + scraphere(); + if (!talking && intr) + leave(); + inparse = 0; + intr = 0; + return; + } + inparse = 0; + brklist = 0; + intr = 0; + execflg = 0; + if (!flag['n']) + execute(outtree, NOPIPE, NOPIPE, 0); + if (!talking && intr) { + execflg = 0; + leave(); + } + if ((i = trapset) != 0) { + trapset = 0; + runtrap(i); + } +} + +void +fail() +{ + longjmp(failpt, 1); + /* NOTREACHED */ +} + +void +leave() +{ + if (execflg) + fail(); + scraphere(); + freehere(1); + runtrap(0); + exit(exstat); + /* NOTREACHED */ +} + +void +warn(s) +register char *s; +{ + if(*s) { + prs(s); + exstat = -1; + } + prs("\n"); + if (flag['e']) + leave(); +} + +void +err(s) +char *s; +{ + warn(s); + if (flag['n']) + return; + if (!talking) + leave(); + if (e.errpt) + longjmp(e.errpt, 1); + closeall(); + e.iop = e.iobase = iostack; +} + +int +newenv(f) +int f; +{ + register struct env *ep; + + if (f) { + quitenv(); + return(1); + } + ep = (struct env *) space(sizeof(*ep)); + if (ep == NULL) { + while (e.oenv) + quitenv(); + fail(); + } + *ep = e; + e.oenv = ep; + e.errpt = errpt; + return(0); +} + +void +quitenv() +{ + register struct env *ep; + register fd; + + if ((ep = e.oenv) != NULL) { + fd = e.iofd; + e = *ep; + /* should close `'d files */ + DELETE(ep); + while (--fd >= e.iofd) + close(fd); + } +} + +/* + * Is any character from s1 in s2? + */ +int +anys(s1, s2) +register char *s1, *s2; +{ + while (*s1) + if (any(*s1++, s2)) + return(1); + return(0); +} + +/* + * Is character c in s? + */ +int +any(c, s) +register int c; +register char *s; +{ + while (*s) + if (*s++ == c) + return(1); + return(0); +} + +char * +putn(n) +register int n; +{ + return(itoa(n, -1)); +} + +char * +itoa(u, n) +register unsigned u; +int n; +{ + register char *cp; + static char s[20]; + int m; + + m = 0; + if (n < 0 && (int) u < 0) { + m++; + u = -u; + } + cp = s+sizeof(s); + *--cp = 0; + do { + *--cp = u%10 + '0'; + u /= 10; + } while (--n > 0 || u); + if (m) + *--cp = '-'; + return(cp); +} + +void +next(f) +int f; +{ + PUSHIO(afile, f, filechar); +} + +void +onintr(s) +int s; /* ANSI C requires a parameter */ +{ + signal(SIGINT, onintr); + intr = 1; + if (talking) { + if (inparse) { + prs("\n"); + fail(); + } + } + else if (heedint) { + execflg = 0; + leave(); + } +} + +int +letter(c) +register c; +{ + return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'); +} + +int +digit(c) +register c; +{ + return(c >= '0' && c <= '9'); +} + +int +letnum(c) +register c; +{ + return(letter(c) || digit(c)); +} + +char * +space(n) +int n; +{ + register char *cp; + + if ((cp = getcell(n)) == 0) + err("out of string space"); + return(cp); +} + +char * +strsave(s, a) +register char *s; +int a; +{ + register char *cp, *xp; + + if ((cp = space(strlen(s)+1)) != NULL) { + setarea((char *)cp, a); + for (xp = cp; (*xp++ = *s++) != '\0';) + ; + return(cp); + } + return(""); +} + +void +xfree(s) +register char *s; +{ + DELETE(s); +} + +/* + * trap handling + */ +void +sig(i) +register int i; +{ + trapset = i; + signal(i, sig); +} + +void runtrap(i) +int i; +{ + char *trapstr; + + if ((trapstr = trap[i]) == NULL) + return; + if (i == 0) + trap[i] = 0; + RUN(aword, trapstr, nlchar); +} + +/* -------- var.c -------- */ +/* #include "sh.h" */ + +/* + * Find the given name in the dictionary + * and return its value. If the name was + * not previously there, enter it now and + * return a null value. + */ +struct var * +lookup(n) +register char *n; +{ + register struct var *vp; + register char *cp; + register int c; + static struct var dummy; + + if (digit(*n)) { + dummy.name = n; + for (c = 0; digit(*n) && c < 1000; n++) + c = c*10 + *n-'0'; + dummy.status = RONLY; + dummy.value = c <= dolc? dolv[c]: null; + return(&dummy); + } + for (vp = vlist; vp; vp = vp->next) + if (eqname(vp->name, n)) + return(vp); + cp = findeq(n); + vp = (struct var *)space(sizeof(*vp)); + if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) { + dummy.name = dummy.value = ""; + return(&dummy); + } + for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++) + ; + if (*cp == 0) + *cp = '='; + *++cp = 0; + setarea((char *)vp, 0); + setarea((char *)vp->name, 0); + vp->value = null; + vp->next = vlist; + vp->status = GETCELL; + vlist = vp; + return(vp); +} + +/* + * give variable at `vp' the value `val'. + */ +void +setval(vp, val) +struct var *vp; +char *val; +{ + nameval(vp, val, (char *)NULL); +} + +/* + * if name is not NULL, it must be + * a prefix of the space `val', + * and end with `='. + * this is all so that exporting + * values is reasonably painless. + */ +void +nameval(vp, val, name) +register struct var *vp; +char *val, *name; +{ + register char *cp, *xp; + char *nv; + int fl; + + if (vp->status & RONLY) { + for (xp = vp->name; *xp && *xp != '=';) + putc(*xp++); + err(" is read-only"); + return; + } + fl = 0; + if (name == NULL) { + xp = space(strlen(vp->name)+strlen(val)+2); + if (xp == 0) + return; + /* make string: name=value */ + setarea((char *)xp, 0); + name = xp; + for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++) + ; + if (*xp++ == 0) + xp[-1] = '='; + nv = xp; + for (cp = val; (*xp++ = *cp++) != '\0';) + ; + val = nv; + fl = GETCELL; + } + if (vp->status & GETCELL) + xfree(vp->name); /* form new string `name=value' */ + vp->name = name; + vp->value = val; + vp->status |= fl; +} + +void +export(vp) +struct var *vp; +{ + vp->status |= EXPORT; +} + +void +ronly(vp) +struct var *vp; +{ + if (letter(vp->name[0])) /* not an internal symbol ($# etc) */ + vp->status |= RONLY; +} + +int +isassign(s) +register char *s; +{ + if (!letter((int)*s)) + return(0); + for (; *s != '='; s++) + if (*s == 0 || !letnum(*s)) + return(0); + return(1); +} + +int +assign(s, cf) +register char *s; +int cf; +{ + register char *cp; + struct var *vp; + + if (!letter(*s)) + return(0); + for (cp = s; *cp != '='; cp++) + if (*cp == 0 || !letnum(*cp)) + return(0); + vp = lookup(s); + nameval(vp, ++cp, cf == COPYV? (char *)NULL: s); + if (cf != COPYV) + vp->status &= ~GETCELL; + return(1); +} + +int +checkname(cp) +register char *cp; +{ + if (!letter(*cp++)) + return(0); + while (*cp) + if (!letnum(*cp++)) + return(0); + return(1); +} + +void +putvlist(f, out) +register int f, out; +{ + register struct var *vp; + + for (vp = vlist; vp; vp = vp->next) + if (vp->status & f && letter(*vp->name)) { + if (vp->status & EXPORT) + write(out, "export ", 7); + if (vp->status & RONLY) + write(out, "readonly ", 9); + write(out, vp->name, (int)(findeq(vp->name) - vp->name)); + write(out, "\n", 1); + } +} + +int +eqname(n1, n2) +register char *n1, *n2; +{ + for (; *n1 != '=' && *n1 != 0; n1++) + if (*n2++ != *n1) + return(0); + return(*n2 == 0 || *n2 == '='); +} + +static char * +findeq(cp) +register char *cp; +{ + while (*cp != '\0' && *cp != '=') + cp++; + return(cp); +} + +/* -------- gmatch.c -------- */ +/* + * int gmatch(string, pattern) + * char *string, *pattern; + * + * Match a pattern as in sh(1). + */ + +#define CMASK 0377 +#define QUOTE 0200 +#define QMASK (CMASK&~QUOTE) +#define NOT '!' /* might use ^ */ + +int +gmatch(s, p) +register char *s, *p; +{ + register int sc, pc; + + if (s == NULL || p == NULL) + return(0); + while ((pc = *p++ & CMASK) != '\0') { + sc = *s++ & QMASK; + switch (pc) { + case '[': + if ((p = cclass(p, sc)) == NULL) + return(0); + break; + + case '?': + if (sc == 0) + return(0); + break; + + case '*': + s--; + do { + if (*p == '\0' || gmatch(s, p)) + return(1); + } while (*s++ != '\0'); + return(0); + + default: + if (sc != (pc&~QUOTE)) + return(0); + } + } + return(*s == 0); +} + +static char * +cclass(p, sub) +register char *p; +register int sub; +{ + register int c, d, not, found; + + if ((not = *p == NOT) != 0) + p++; + found = not; + do { + if (*p == '\0') + return((char *)NULL); + c = *p & CMASK; + if (p[1] == '-' && p[2] != ']') { + d = p[2] & CMASK; + p++; + } else + d = c; + if (c == sub || (c <= sub && sub <= d)) + found = !not; + } while (*++p != ']'); + return(found? p+1: (char *)NULL); +} + +/* -------- area.c -------- */ +#define REGSIZE sizeof(struct region) +#define GROWBY 256 +#undef SHRINKBY 64 +#define FREE 32767 +#define BUSY 0 +#define ALIGN (sizeof(int)-1) + +/* #include "area.h" */ + +struct region { + struct region *next; + int area; +}; + +/* + * All memory between (char *)areabot and (char *)(areatop+1) is + * exclusively administered by the area management routines. + * It is assumed that sbrk() and brk() manipulate the high end. + */ +static struct region *areabot; /* bottom of area */ +static struct region *areatop; /* top of area */ +static struct region *areanxt; /* starting point of scan */ + +void +initarea() +{ + while ((int)sbrk(0) & ALIGN) + sbrk(1); + areabot = (struct region *)sbrk(REGSIZE); + areabot->next = areabot; + areabot->area = BUSY; + areatop = areabot; + areanxt = areabot; +} + +char * +getcell(nbytes) +unsigned nbytes; +{ + register int nregio; + register struct region *p, *q; + register i; + + if (nbytes == 0) + abort(); /* silly and defeats the algorithm */ + /* + * round upwards and add administration area + */ + nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1; + for (p = areanxt;;) { + if (p->area > areanum) { + /* + * merge free cells + */ + while ((q = p->next)->area > areanum && q != areanxt) + p->next = q->next; + /* + * exit loop if cell big enough + */ + if (q >= p + nregio) + goto found; + } + p = p->next; + if (p == areanxt) + break; + } + i = nregio >= GROWBY ? nregio : GROWBY; + p = (struct region *)sbrk(i * REGSIZE); + if (p == (struct region *)-1) + return((char *)NULL); + p--; + if (p != areatop) + abort(); /* allocated areas are contiguous */ + q = p + i; + p->next = q; + p->area = FREE; + q->next = areabot; + q->area = BUSY; + areatop = q; +found: + /* + * we found a FREE area big enough, pointed to by 'p', and up to 'q' + */ + areanxt = p + nregio; + if (areanxt < q) { + /* + * split into requested area and rest + */ + if (areanxt+1 > q) + abort(); /* insufficient space left for admin */ + areanxt->next = q; + areanxt->area = FREE; + p->next = areanxt; + } + p->area = areanum; + return((char *)(p+1)); +} + +void +freecell(cp) +char *cp; +{ + register struct region *p; + + if ((p = (struct region *)cp) != NULL) { + p--; + if (p < areanxt) + areanxt = p; + p->area = FREE; + } +} + +void +freearea(a) +register int a; +{ + register struct region *p, *top; + + top = areatop; + for (p = areabot; p != top; p = p->next) + if (p->area >= a) + p->area = FREE; +} + +void +setarea(cp,a) +char *cp; +int a; +{ + register struct region *p; + + if ((p = (struct region *)cp) != NULL) + (p-1)->area = a; +} + +int +getarea(cp) +char *cp; +{ + return ((struct region*)cp-1)->area; +} + +void +garbage() +{ + register struct region *p, *q, *top; + + top = areatop; + for (p = areabot; p != top; p = p->next) { + if (p->area > areanum) { + while ((q = p->next)->area > areanum) + p->next = q->next; + areanxt = p; + } + } +#ifdef SHRINKBY + if (areatop >= q + SHRINKBY && q->area > areanum) { + brk((char *)(q+1)); + q->next = areabot; + q->area = BUSY; + areatop = q; + } +#endif +} diff --git a/src/bin/sh/sh2.c b/src/bin/sh/sh2.c new file mode 100644 index 0000000..2a9f80f --- /dev/null +++ b/src/bin/sh/sh2.c @@ -0,0 +1,800 @@ +#define Extern extern +#include +#include +#include +#include +#include "sh.h" + +/* -------- csyn.c -------- */ +/* + * shell: syntax (C version) + */ + +typedef union { + char *cp; + char **wp; + int i; + struct op *o; +} YYSTYPE; +#define WORD 256 +#define LOGAND 257 +#define LOGOR 258 +#define BREAK 259 +#define IF 260 +#define THEN 261 +#define ELSE 262 +#define ELIF 263 +#define FI 264 +#define CASE 265 +#define ESAC 266 +#define FOR 267 +#define WHILE 268 +#define UNTIL 269 +#define DO 270 +#define DONE 271 +#define IN 272 +#define YYERRCODE 300 + +/* flags to yylex */ +#define CONTIN 01 /* skip new lines to complete command */ + +/* #include "sh.h" */ +#define SYNTAXERR zzerr() +static int startl; +static int peeksym; +static int nlseen; +static int iounit = IODEFAULT; + +static YYSTYPE yylval; + +_PROTOTYPE(static struct op *pipeline, (int cf )); +_PROTOTYPE(static struct op *andor, (void)); +_PROTOTYPE(static struct op *c_list, (void)); +_PROTOTYPE(static int synio, (int cf )); +_PROTOTYPE(static void musthave, (int c, int cf )); +_PROTOTYPE(static struct op *simple, (void)); +_PROTOTYPE(static struct op *nested, (int type, int mark )); +_PROTOTYPE(static struct op *command, (int cf )); +_PROTOTYPE(static struct op *dogroup, (int onlydone )); +_PROTOTYPE(static struct op *thenpart, (void)); +_PROTOTYPE(static struct op *elsepart, (void)); +_PROTOTYPE(static struct op *caselist, (void)); +_PROTOTYPE(static struct op *casepart, (void)); +_PROTOTYPE(static char **pattern, (void)); +_PROTOTYPE(static char **wordlist, (void)); +_PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 )); +_PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp )); +_PROTOTYPE(static struct op *newtp, (void)); +_PROTOTYPE(static struct op *namelist, (struct op *t )); +_PROTOTYPE(static char **copyw, (void)); +_PROTOTYPE(static void word, (char *cp )); +_PROTOTYPE(static struct ioword **copyio, (void)); +_PROTOTYPE(static struct ioword *io, (int u, int f, char *cp )); +_PROTOTYPE(static void zzerr, (void)); +_PROTOTYPE(void yyerror, (char *s )); +_PROTOTYPE(static int yylex, (int cf )); +_PROTOTYPE(int collect, (int c, int c1 )); +_PROTOTYPE(int dual, (int c )); +_PROTOTYPE(static void diag, (int ec )); +_PROTOTYPE(static char *tree, (unsigned size )); +_PROTOTYPE(void printf, (char *s )); + +int +yyparse() +{ + startl = 1; + peeksym = 0; + yynerrs = 0; + outtree = c_list(); + musthave('\n', 0); + return(yynerrs!=0); +} + +static struct op * +pipeline(cf) +int cf; +{ + register struct op *t, *p; + register int c; + + t = command(cf); + if (t != NULL) { + while ((c = yylex(0)) == '|') { + if ((p = command(CONTIN)) == NULL) + SYNTAXERR; + if (t->type != TPAREN && t->type != TCOM) { + /* shell statement */ + t = block(TPAREN, t, NOBLOCK, NOWORDS); + } + t = block(TPIPE, t, p, NOWORDS); + } + peeksym = c; + } + return(t); +} + +static struct op * +andor() +{ + register struct op *t, *p; + register int c; + + t = pipeline(0); + if (t != NULL) { + while ((c = yylex(0)) == LOGAND || c == LOGOR) { + if ((p = pipeline(CONTIN)) == NULL) + SYNTAXERR; + t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS); + } + peeksym = c; + } + return(t); +} + +static struct op * +c_list() +{ + register struct op *t, *p; + register int c; + + t = andor(); + if (t != NULL) { + if((peeksym = yylex(0)) == '&') + t = block(TASYNC, t, NOBLOCK, NOWORDS); + while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) { + if ((p = andor()) == NULL) + return(t); + if((peeksym = yylex(0)) == '&') + p = block(TASYNC, p, NOBLOCK, NOWORDS); + t = list(t, p); + } + peeksym = c; + } + return(t); +} + + +static int +synio(cf) +int cf; +{ + register struct ioword *iop; + register int i; + register int c; + + if ((c = yylex(cf)) != '<' && c != '>') { + peeksym = c; + return(0); + } + i = yylval.i; + musthave(WORD, 0); + iop = io(iounit, i, yylval.cp); + iounit = IODEFAULT; + if (i & IOHERE) + markhere(yylval.cp, iop); + return(1); +} + +static void +musthave(c, cf) +int c, cf; +{ + if ((peeksym = yylex(cf)) != c) + SYNTAXERR; + peeksym = 0; +} + +static struct op * +simple() +{ + register struct op *t; + + t = NULL; + for (;;) { + switch (peeksym = yylex(0)) { + case '<': + case '>': + (void) synio(0); + break; + + case WORD: + if (t == NULL) { + t = newtp(); + t->type = TCOM; + } + peeksym = 0; + word(yylval.cp); + break; + + default: + return(t); + } + } +} + +static struct op * +nested(type, mark) +int type, mark; +{ + register struct op *t; + + multiline++; + t = c_list(); + musthave(mark, 0); + multiline--; + return(block(type, t, NOBLOCK, NOWORDS)); +} + +static struct op * +command(cf) +int cf; +{ + register struct op *t; + struct wdblock *iosave; + register int c; + + iosave = iolist; + iolist = NULL; + if (multiline) + cf |= CONTIN; + while (synio(cf)) + cf = 0; + switch (c = yylex(cf)) { + default: + peeksym = c; + if ((t = simple()) == NULL) { + if (iolist == NULL) + return((struct op *)NULL); + t = newtp(); + t->type = TCOM; + } + break; + + case '(': + t = nested(TPAREN, ')'); + break; + + case '{': + t = nested(TBRACE, '}'); + break; + + case FOR: + t = newtp(); + t->type = TFOR; + musthave(WORD, 0); + startl = 1; + t->str = yylval.cp; + multiline++; + t->words = wordlist(); + if ((c = yylex(0)) != '\n' && c != ';') + peeksym = c; + t->left = dogroup(0); + multiline--; + break; + + case WHILE: + case UNTIL: + multiline++; + t = newtp(); + t->type = c == WHILE? TWHILE: TUNTIL; + t->left = c_list(); + t->right = dogroup(1); + t->words = NULL; + multiline--; + break; + + case CASE: + t = newtp(); + t->type = TCASE; + musthave(WORD, 0); + t->str = yylval.cp; + startl++; + multiline++; + musthave(IN, CONTIN); + startl++; + t->left = caselist(); + musthave(ESAC, 0); + multiline--; + break; + + case IF: + multiline++; + t = newtp(); + t->type = TIF; + t->left = c_list(); + t->right = thenpart(); + musthave(FI, 0); + multiline--; + break; + } + while (synio(0)) + ; + t = namelist(t); + iolist = iosave; + return(t); +} + +static struct op * +dogroup(onlydone) +int onlydone; +{ + register int c; + register struct op *list; + + c = yylex(CONTIN); + if (c == DONE && onlydone) + return((struct op *)NULL); + if (c != DO) + SYNTAXERR; + list = c_list(); + musthave(DONE, 0); + return(list); +} + +static struct op * +thenpart() +{ + register int c; + register struct op *t; + + if ((c = yylex(0)) != THEN) { + peeksym = c; + return((struct op *)NULL); + } + t = newtp(); + t->type = 0; + t->left = c_list(); + if (t->left == NULL) + SYNTAXERR; + t->right = elsepart(); + return(t); +} + +static struct op * +elsepart() +{ + register int c; + register struct op *t; + + switch (c = yylex(0)) { + case ELSE: + if ((t = c_list()) == NULL) + SYNTAXERR; + return(t); + + case ELIF: + t = newtp(); + t->type = TELIF; + t->left = c_list(); + t->right = thenpart(); + return(t); + + default: + peeksym = c; + return((struct op *)NULL); + } +} + +static struct op * +caselist() +{ + register struct op *t; + + t = NULL; + while ((peeksym = yylex(CONTIN)) != ESAC) + t = list(t, casepart()); + return(t); +} + +static struct op * +casepart() +{ + register struct op *t; + + t = newtp(); + t->type = TPAT; + t->words = pattern(); + musthave(')', 0); + t->left = c_list(); + if ((peeksym = yylex(CONTIN)) != ESAC) + musthave(BREAK, CONTIN); + return(t); +} + +static char ** +pattern() +{ + register int c, cf; + + cf = CONTIN; + do { + musthave(WORD, cf); + word(yylval.cp); + cf = 0; + } while ((c = yylex(0)) == '|'); + peeksym = c; + word(NOWORD); + return(copyw()); +} + +static char ** +wordlist() +{ + register int c; + + if ((c = yylex(0)) != IN) { + peeksym = c; + return((char **)NULL); + } + startl = 0; + while ((c = yylex(0)) == WORD) + word(yylval.cp); + word(NOWORD); + peeksym = c; + return(copyw()); +} + +/* + * supporting functions + */ +static struct op * +list(t1, t2) +register struct op *t1, *t2; +{ + if (t1 == NULL) + return(t2); + if (t2 == NULL) + return(t1); + return(block(TLIST, t1, t2, NOWORDS)); +} + +static struct op * +block(type, t1, t2, wp) +int type; +struct op *t1, *t2; +char **wp; +{ + register struct op *t; + + t = newtp(); + t->type = type; + t->left = t1; + t->right = t2; + t->words = wp; + return(t); +} + +struct res { + char *r_name; + int r_val; +} restab[] = { + "for", FOR, + "case", CASE, + "esac", ESAC, + "while", WHILE, + "do", DO, + "done", DONE, + "if", IF, + "in", IN, + "then", THEN, + "else", ELSE, + "elif", ELIF, + "until", UNTIL, + "fi", FI, + + ";;", BREAK, + "||", LOGOR, + "&&", LOGAND, + "{", '{', + "}", '}', + + 0, +}; + +int +rlookup(n) +register char *n; +{ + register struct res *rp; + + for (rp = restab; rp->r_name; rp++) + if (strcmp(rp->r_name, n) == 0) + return(rp->r_val); + return(0); +} + +static struct op * +newtp() +{ + register struct op *t; + + t = (struct op *)tree(sizeof(*t)); + t->type = 0; + t->words = NULL; + t->ioact = NULL; + t->left = NULL; + t->right = NULL; + t->str = NULL; + return(t); +} + +static struct op * +namelist(t) +register struct op *t; +{ + if (iolist) { + iolist = addword((char *)NULL, iolist); + t->ioact = copyio(); + } else + t->ioact = NULL; + if (t->type != TCOM) { + if (t->type != TPAREN && t->ioact != NULL) { + t = block(TPAREN, t, NOBLOCK, NOWORDS); + t->ioact = t->left->ioact; + t->left->ioact = NULL; + } + return(t); + } + word(NOWORD); + t->words = copyw(); + return(t); +} + +static char ** +copyw() +{ + register char **wd; + + wd = getwords(wdlist); + wdlist = 0; + return(wd); +} + +static void +word(cp) +char *cp; +{ + wdlist = addword(cp, wdlist); +} + +static struct ioword ** +copyio() +{ + register struct ioword **iop; + + iop = (struct ioword **) getwords(iolist); + iolist = 0; + return(iop); +} + +static struct ioword * +io(u, f, cp) +int u; +int f; +char *cp; +{ + register struct ioword *iop; + + iop = (struct ioword *) tree(sizeof(*iop)); + iop->io_unit = u; + iop->io_flag = f; + iop->io_name = cp; + iolist = addword((char *)iop, iolist); + return(iop); +} + +static void +zzerr() +{ + yyerror("syntax error"); +} + +void +yyerror(s) +char *s; +{ + yynerrs++; + if (talking && e.iop <= iostack) { + multiline = 0; + while (eofc() == 0 && yylex(0) != '\n') + ; + } + err(s); + fail(); +} + +static int +yylex(cf) +int cf; +{ + register int c, c1; + int atstart; + + if ((c = peeksym) > 0) { + peeksym = 0; + if (c == '\n') + startl = 1; + return(c); + } + nlseen = 0; + e.linep = line; + atstart = startl; + startl = 0; + yylval.i = 0; + +loop: + while ((c = getc(0)) == ' ' || c == '\t') + ; + switch (c) { + default: + if (any(c, "0123456789")) { + unget(c1 = getc(0)); + if (c1 == '<' || c1 == '>') { + iounit = c - '0'; + goto loop; + } + *e.linep++ = c; + c = c1; + } + break; + + case '#': + while ((c = getc(0)) != 0 && c != '\n') + ; + unget(c); + goto loop; + + case 0: + return(c); + + case '$': + *e.linep++ = c; + if ((c = getc(0)) == '{') { + if ((c = collect(c, '}')) != '\0') + return(c); + goto pack; + } + break; + + case '`': + case '\'': + case '"': + if ((c = collect(c, c)) != '\0') + return(c); + goto pack; + + case '|': + case '&': + case ';': + if ((c1 = dual(c)) != '\0') { + startl = 1; + return(c1); + } + startl = 1; + return(c); + case '^': + startl = 1; + return('|'); + case '>': + case '<': + diag(c); + return(c); + + case '\n': + nlseen++; + gethere(); + startl = 1; + if (multiline || cf & CONTIN) { + if (talking && e.iop <= iostack) + prs(cprompt->value); + if (cf & CONTIN) + goto loop; + } + return(c); + + case '(': + case ')': + startl = 1; + return(c); + } + + unget(c); + +pack: + while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) + if (e.linep >= elinep) + err("word too long"); + else + *e.linep++ = c; + unget(c); + if(any(c, "\"'`$")) + goto loop; + *e.linep++ = '\0'; + if (atstart && (c = rlookup(line))!=0) { + startl = 1; + return(c); + } + yylval.cp = strsave(line, areanum); + return(WORD); +} + +int +collect(c, c1) +register c, c1; +{ + char s[2]; + + *e.linep++ = c; + while ((c = getc(c1)) != c1) { + if (c == 0) { + unget(c); + s[0] = c1; + s[1] = 0; + prs("no closing "); yyerror(s); + return(YYERRCODE); + } + if (talking && c == '\n' && e.iop <= iostack) + prs(cprompt->value); + *e.linep++ = c; + } + *e.linep++ = c; + return(0); +} + +int +dual(c) +register c; +{ + char s[3]; + register char *cp = s; + + *cp++ = c; + *cp++ = getc(0); + *cp = 0; + if ((c = rlookup(s)) == 0) + unget(*--cp); + return(c); +} + +static void +diag(ec) +register int ec; +{ + register int c; + + c = getc(0); + if (c == '>' || c == '<') { + if (c != ec) + zzerr(); + yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE; + c = getc(0); + } else + yylval.i = ec == '>'? IOWRITE: IOREAD; + if (c != '&' || yylval.i == IOHERE) + unget(c); + else + yylval.i |= IODUP; +} + +static char * +tree(size) +unsigned size; +{ + register char *t; + + if ((t = getcell(size)) == NULL) { + prs("command line too complicated\n"); + fail(); + /* NOTREACHED */ + } + return(t); +} + +/* VARARGS1 */ +/* ARGSUSED */ +void +printf(s) /* yyparse calls it */ +char *s; +{ +} + diff --git a/src/bin/sh/sh3.c b/src/bin/sh/sh3.c new file mode 100644 index 0000000..b67c426 --- /dev/null +++ b/src/bin/sh/sh3.c @@ -0,0 +1,1142 @@ +#define Extern extern +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef NULL +#include "sh.h" + +/* -------- exec.c -------- */ +/* #include "sh.h" */ + +/* + * execute tree + */ + +static char *signame[] = { + "Signal 0", + "Hangup", + (char *)NULL, /* interrupt */ + "Quit", + "Illegal instruction", + "Trace/BPT trap", + "Abort", + "EMT trap", + "Floating exception", + "Killed", + "Bus error", + "Memory fault", + "Bad system call", + (char *)NULL, /* broken pipe */ + "Alarm clock", + "Terminated", +}; +#define NSIGNAL (sizeof(signame)/sizeof(signame[0])) + + +_PROTOTYPE(static int forkexec, (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked )); +_PROTOTYPE(static int parent, (void)); +_PROTOTYPE(int iosetup, (struct ioword *iop, int pipein, int pipeout )); +_PROTOTYPE(static void echo, (char **wp )); +_PROTOTYPE(static struct op **find1case, (struct op *t, char *w )); +_PROTOTYPE(static struct op *findcase, (struct op *t, char *w )); +_PROTOTYPE(static void brkset, (struct brkcon *bc )); +_PROTOTYPE(int dolabel, (void)); +_PROTOTYPE(int dochdir, (struct op *t )); +_PROTOTYPE(int doshift, (struct op *t )); +_PROTOTYPE(int dologin, (struct op *t )); +_PROTOTYPE(int doumask, (struct op *t )); +_PROTOTYPE(int doexec, (struct op *t )); +_PROTOTYPE(int dodot, (struct op *t )); +_PROTOTYPE(int dowait, (struct op *t )); +_PROTOTYPE(int doread, (struct op *t )); +_PROTOTYPE(int doeval, (struct op *t )); +_PROTOTYPE(int dotrap, (struct op *t )); +_PROTOTYPE(int getsig, (char *s )); +_PROTOTYPE(void setsig, (int n, void (*f)())); +_PROTOTYPE(int getn, (char *as )); +_PROTOTYPE(int dobreak, (struct op *t )); +_PROTOTYPE(int docontinue, (struct op *t )); +_PROTOTYPE(static int brkcontin, (char *cp, int val )); +_PROTOTYPE(int doexit, (struct op *t )); +_PROTOTYPE(int doexport, (struct op *t )); +_PROTOTYPE(int doreadonly, (struct op *t )); +_PROTOTYPE(static void rdexp, (char **wp, void (*f)(), int key)); +_PROTOTYPE(static void badid, (char *s )); +_PROTOTYPE(int doset, (struct op *t )); +_PROTOTYPE(void varput, (char *s, int out )); +_PROTOTYPE(int dotimes, (void)); + +int +execute(t, pin, pout, act) +register struct op *t; +int *pin, *pout; +int act; +{ + register struct op *t1; + int i, pv[2], rv, child, a; + char *cp, **wp, **wp2; + struct var *vp; + struct brkcon bc; + + if (t == NULL) + return(0); + rv = 0; + a = areanum++; + wp = (wp2 = t->words) != NULL + ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) + : NULL; + + switch(t->type) { + case TPAREN: + case TCOM: + rv = forkexec(t, pin, pout, act, wp, &child); + if (child) { + exstat = rv; + leave(); + } + break; + + case TPIPE: + if ((rv = openpipe(pv)) < 0) + break; + pv[0] = remap(pv[0]); + pv[1] = remap(pv[1]); + (void) execute(t->left, pin, pv, 0); + rv = execute(t->right, pv, pout, 0); + break; + + case TLIST: + (void) execute(t->left, pin, pout, 0); + rv = execute(t->right, pin, pout, 0); + break; + + case TASYNC: + i = parent(); + if (i != 0) { + if (i != -1) { + setval(lookup("!"), putn(i)); + if (pin != NULL) + closepipe(pin); + if (talking) { + prs(putn(i)); + prs("\n"); + } + } else + rv = -1; + setstatus(rv); + } else { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + if (talking) + signal(SIGTERM, SIG_DFL); + talking = 0; + if (pin == NULL) { + close(0); + open("/dev/null", 0); + } + exit(execute(t->left, pin, pout, FEXEC)); + } + break; + + case TOR: + case TAND: + rv = execute(t->left, pin, pout, 0); + if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND)) + rv = execute(t1, pin, pout, 0); + break; + + case TFOR: + if (wp == NULL) { + wp = dolv+1; + if ((i = dolc) < 0) + i = 0; + } else { + i = -1; + while (*wp++ != NULL) + ; + } + vp = lookup(t->str); + while (setjmp(bc.brkpt)) + if (isbreak) + goto broken; + brkset(&bc); + for (t1 = t->left; i-- && *wp != NULL;) { + setval(vp, *wp++); + rv = execute(t1, pin, pout, 0); + } + brklist = brklist->nextlev; + break; + + case TWHILE: + case TUNTIL: + while (setjmp(bc.brkpt)) + if (isbreak) + goto broken; + brkset(&bc); + t1 = t->left; + while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE)) + rv = execute(t->right, pin, pout, 0); + brklist = brklist->nextlev; + break; + + case TIF: + case TELIF: + if (t->right != NULL) { + rv = !execute(t->left, pin, pout, 0) ? + execute(t->right->left, pin, pout, 0): + execute(t->right->right, pin, pout, 0); + } + break; + + case TCASE: + if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0) + cp = ""; + if ((t1 = findcase(t->left, cp)) != NULL) + rv = execute(t1, pin, pout, 0); + break; + + case TBRACE: +/* + if (iopp = t->ioact) + while (*iopp) + if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) { + rv = -1; + break; + } +*/ + if (rv >= 0 && (t1 = t->left)) + rv = execute(t1, pin, pout, 0); + break; + } + +broken: + t->words = wp2; + isbreak = 0; + freehere(areanum); + freearea(areanum); + areanum = a; + if (talking && intr) { + closeall(); + fail(); + } + if ((i = trapset) != 0) { + trapset = 0; + runtrap(i); + } + return(rv); +} + +static int +forkexec(t, pin, pout, act, wp, pforked) +register struct op *t; +int *pin, *pout; +int act; +char **wp; +int *pforked; +{ + int i, rv, (*shcom)(); + register int f; + char *cp; + struct ioword **iopp; + int resetsig; + char **owp; + + owp = wp; + resetsig = 0; + *pforked = 0; + shcom = NULL; + rv = -1; /* system-detected error */ + if (t->type == TCOM) { + while ((cp = *wp++) != NULL) + ; + cp = *wp; + + /* strip all initial assignments */ + /* not correct wrt PATH=yyy command etc */ + if (flag['x']) + echo (cp ? wp: owp); + if (cp == NULL && t->ioact == NULL) { + while ((cp = *owp++) != NULL && assign(cp, COPYV)) + ; + return(setstatus(0)); + } + else if (cp != NULL) + shcom = inbuilt(cp); + } + t->words = wp; + f = act; + if (shcom == NULL && (f & FEXEC) == 0) { + i = parent(); + if (i != 0) { + if (i == -1) + return(rv); + if (pin != NULL) + closepipe(pin); + return(pout==NULL? setstatus(waitfor(i,0)): 0); + } + if (talking) { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + resetsig = 1; + } + talking = 0; + intr = 0; + (*pforked)++; + brklist = 0; + execflg = 0; + } + if (owp != NULL) + while ((cp = *owp++) != NULL && assign(cp, COPYV)) + if (shcom == NULL) + export(lookup(cp)); +#ifdef COMPIPE + if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { + err("piping to/from shell builtins not yet done"); + return(-1); + } +#endif + if (pin != NULL) { + dup2(pin[0], 0); + closepipe(pin); + } + if (pout != NULL) { + dup2(pout[1], 1); + closepipe(pout); + } + if ((iopp = t->ioact) != NULL) { + if (shcom != NULL && shcom != doexec) { + prs(cp); + err(": cannot redirect shell command"); + return(-1); + } + while (*iopp) + if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) + return(rv); + } + if (shcom) + return(setstatus((*shcom)(t))); + /* should use FIOCEXCL */ + for (i=FDBASE; itype == TPAREN) + exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); + if (wp[0] == NULL) + exit(0); + cp = rexecve(wp[0], wp, makenv()); + prs(wp[0]); prs(": "); warn(cp); + if (!execflg) + trap[0] = NULL; + leave(); + /* NOTREACHED */ +} + +/* + * common actions when creating a new child + */ +static int +parent() +{ + register int i; + + i = fork(); + if (i != 0) { + if (i == -1) + warn("try again"); + } + return(i); +} + +/* + * 0< 1> are ignored as required + * within pipelines. + */ +int +iosetup(iop, pipein, pipeout) +register struct ioword *iop; +int pipein, pipeout; +{ + register u; + char *cp, *msg; + + if (iop->io_unit == IODEFAULT) /* take default */ + iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1; + if (pipein && iop->io_unit == 0) + return(0); + if (pipeout && iop->io_unit == 1) + return(0); + msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create"; + if ((iop->io_flag & IOHERE) == 0) { + cp = iop->io_name; + if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL) + return(1); + } + if (iop->io_flag & IODUP) { + if (cp[1] || (!digit(*cp) && *cp != '-')) { + prs(cp); + err(": illegal >& argument"); + return(1); + } + if (*cp == '-') + iop->io_flag = IOCLOSE; + iop->io_flag &= ~(IOREAD|IOWRITE); + } + switch (iop->io_flag) { + case IOREAD: + u = open(cp, 0); + break; + + case IOHERE: + case IOHERE|IOXHERE: + u = herein(iop->io_name, iop->io_flag&IOXHERE); + cp = "here file"; + break; + + case IOWRITE|IOCAT: + if ((u = open(cp, 1)) >= 0) { + lseek(u, (long)0, 2); + break; + } + case IOWRITE: + u = creat(cp, 0666); + break; + + case IODUP: + u = dup2(*cp-'0', iop->io_unit); + break; + + case IOCLOSE: + close(iop->io_unit); + return(0); + } + if (u < 0) { + prs(cp); + prs(": cannot "); + warn(msg); + return(1); + } else { + if (u != iop->io_unit) { + dup2(u, iop->io_unit); + close(u); + } + } + return(0); +} + +static void +echo(wp) +register char **wp; +{ + register i; + + prs("+"); + for (i=0; wp[i]; i++) { + if (i) + prs(" "); + prs(wp[i]); + } + prs("\n"); +} + +static struct op ** +find1case(t, w) +struct op *t; +char *w; +{ + register struct op *t1; + struct op **tp; + register char **wp, *cp; + + if (t == NULL) + return((struct op **)NULL); + if (t->type == TLIST) { + if ((tp = find1case(t->left, w)) != NULL) + return(tp); + t1 = t->right; /* TPAT */ + } else + t1 = t; + for (wp = t1->words; *wp;) + if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) + return(&t1->left); + return((struct op **)NULL); +} + +static struct op * +findcase(t, w) +struct op *t; +char *w; +{ + register struct op **tp; + + return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL); +} + +/* + * Enter a new loop level (marked for break/continue). + */ +static void +brkset(bc) +struct brkcon *bc; +{ + bc->nextlev = brklist; + brklist = bc; +} + +/* + * Wait for the last process created. + * Print a message for each process found + * that was killed by a signal. + * Ignore interrupt signals while waiting + * unless `canintr' is true. + */ +int +waitfor(lastpid, canintr) +register int lastpid; +int canintr; +{ + register int pid, rv; + int s; + int oheedint = heedint; + + heedint = 0; + rv = 0; + do { + pid = wait(&s); + if (pid == -1) { + if (errno != EINTR || canintr) + break; + } else { + if ((rv = WAITSIG(s)) != 0) { + if (rv < NSIGNAL) { + if (signame[rv] != NULL) { + if (pid != lastpid) { + prn(pid); + prs(": "); + } + prs(signame[rv]); + } + } else { + if (pid != lastpid) { + prn(pid); + prs(": "); + } + prs("Signal "); prn(rv); prs(" "); + } + if (WAITCORE(s)) + prs(" - core dumped"); + if (rv >= NSIGNAL || signame[rv]) + prs("\n"); + rv = -1; + } else + rv = WAITVAL(s); + } + } while (pid != lastpid); + heedint = oheedint; + if (intr) + if (talking) { + if (canintr) + intr = 0; + } else { + if (exstat == 0) exstat = rv; + onintr(0); + } + return(rv); +} + +int +setstatus(s) +register int s; +{ + exstat = s; + setval(lookup("?"), putn(s)); + return(s); +} + +/* + * PATH-searching interface to execve. + * If getenv("PATH") were kept up-to-date, + * execvp might be used. + */ +char * +rexecve(c, v, envp) +char *c, **v, **envp; +{ + register int i; + register char *sp, *tp; + int eacces = 0, asis = 0; + + sp = any('/', c)? "": path->value; + asis = *sp == '\0'; + while (asis || *sp != '\0') { + asis = 0; + tp = e.linep; + for (; *sp != '\0'; tp++) + if ((*tp = *sp++) == ':') { + asis = *sp == '\0'; + break; + } + if (tp != e.linep) + *tp++ = '/'; + for (i = 0; (*tp++ = c[i++]) != '\0';) + ; + execve(e.linep, v, envp); + switch (errno) { + case ENOEXEC: + *v = e.linep; + tp = *--v; + *v = e.linep; + execve("/bin/sh", v, envp); + *v = tp; + return("no Shell"); + + case ENOMEM: + return("program too big"); + + case E2BIG: + return("argument list too long"); + + case EACCES: + eacces++; + break; + } + } + return(errno==ENOENT ? "not found" : "cannot execute"); +} + +/* + * Run the command produced by generator `f' + * applied to stream `arg'. + */ +int +run(argp, f) +struct ioarg *argp; +int (*f)(); +{ + struct op *otree; + struct wdblock *swdlist; + struct wdblock *siolist; + jmp_buf ev, rt; + xint *ofail; + int rv; + + areanum++; + swdlist = wdlist; + siolist = iolist; + otree = outtree; + ofail = failpt; + rv = -1; + if (newenv(setjmp(errpt = ev)) == 0) { + wdlist = 0; + iolist = 0; + pushio(argp, f); + e.iobase = e.iop; + yynerrs = 0; + if (setjmp(failpt = rt) == 0 && yyparse() == 0) + rv = execute(outtree, NOPIPE, NOPIPE, 0); + quitenv(); + } + wdlist = swdlist; + iolist = siolist; + failpt = ofail; + outtree = otree; + freearea(areanum--); + return(rv); +} + +/* -------- do.c -------- */ +/* #include "sh.h" */ + +/* + * built-in commands: doX + */ + +int +dolabel() +{ + return(0); +} + +int +dochdir(t) +register struct op *t; +{ + register char *cp, *er; + + if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL) + er = ": no home directory"; + else if(chdir(cp) < 0) + er = ": bad directory"; + else + return(0); + prs(cp != NULL? cp: "cd"); + err(er); + return(1); +} + +int +doshift(t) +register struct op *t; +{ + register n; + + n = t->words[1]? getn(t->words[1]): 1; + if(dolc < n) { + err("nothing to shift"); + return(1); + } + dolv[n] = dolv[0]; + dolv += n; + dolc -= n; + setval(lookup("#"), putn(dolc)); + return(0); +} + +/* + * execute login and newgrp directly + */ +int +dologin(t) +struct op *t; +{ + register char *cp; + + if (talking) { + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + } + cp = rexecve(t->words[0], t->words, makenv()); + prs(t->words[0]); prs(": "); err(cp); + return(1); +} + +int +doumask(t) +register struct op *t; +{ + register int i, n; + register char *cp; + + if ((cp = t->words[1]) == NULL) { + i = umask(0); + umask(i); + for (n=3*4; (n-=3) >= 0;) + putc('0'+((i>>n)&07)); + putc('\n'); + } else { + for (n=0; *cp>='0' && *cp<='9'; cp++) + n = n*8 + (*cp-'0'); + umask(n); + } + return(0); +} + +int +doexec(t) +register struct op *t; +{ + register i; + jmp_buf ex; + xint *ofail; + + t->ioact = NULL; + for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++) + ; + if (i == 0) + return(1); + execflg = 1; + ofail = failpt; + if (setjmp(failpt = ex) == 0) + execute(t, NOPIPE, NOPIPE, FEXEC); + failpt = ofail; + execflg = 0; + return(1); +} + +int +dodot(t) +struct op *t; +{ + register i; + register char *sp, *tp; + char *cp; + + if ((cp = t->words[1]) == NULL) + return(0); + sp = any('/', cp)? ":": path->value; + while (*sp) { + tp = e.linep; + while (*sp && (*tp = *sp++) != ':') + tp++; + if (tp != e.linep) + *tp++ = '/'; + for (i = 0; (*tp++ = cp[i++]) != '\0';) + ; + if ((i = open(e.linep, 0)) >= 0) { + exstat = 0; + next(remap(i)); + return(exstat); + } + } + prs(cp); + err(": not found"); + return(-1); +} + +int +dowait(t) +struct op *t; +{ + register i; + register char *cp; + + if ((cp = t->words[1]) != NULL) { + i = getn(cp); + if (i == 0) + return(0); + } else + i = -1; + setstatus(waitfor(i, 1)); + return(0); +} + +int +doread(t) +struct op *t; +{ + register char *cp, **wp; + register nb; + register int nl = 0; + + if (t->words[1] == NULL) { + err("Usage: read name ..."); + return(1); + } + for (wp = t->words+1; *wp; wp++) { + for (cp = e.linep; !nl && cp < elinep-1; cp++) + if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) || + (nl = (*cp == '\n')) || + (wp[1] && any(*cp, ifs->value))) + break; + *cp = 0; + if (nb <= 0) + break; + setval(lookup(*wp), e.linep); + } + return(nb <= 0); +} + +int +doeval(t) +register struct op *t; +{ + return(RUN(awordlist, t->words+1, wdchar)); +} + +int +dotrap(t) +register struct op *t; +{ + register int n, i; + register int resetsig; + + if (t->words[1] == NULL) { + for (i=0; i<=_NSIG; i++) + if (trap[i]) { + prn(i); + prs(": "); + prs(trap[i]); + prs("\n"); + } + return(0); + } + resetsig = digit(*t->words[1]); + for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) { + n = getsig(t->words[i]); + xfree(trap[n]); + trap[n] = 0; + if (!resetsig) { + if (*t->words[1] != '\0') { + trap[n] = strsave(t->words[1], 0); + setsig(n, sig); + } else + setsig(n, SIG_IGN); + } else { + if (talking) + if (n == SIGINT) + setsig(n, onintr); + else + setsig(n, n == SIGQUIT ? SIG_IGN + : SIG_DFL); + else + setsig(n, SIG_DFL); + } + } + return(0); +} + +int +getsig(s) +char *s; +{ + register int n; + + if ((n = getn(s)) < 0 || n > _NSIG) { + err("trap: bad signal number"); + n = 0; + } + return(n); +} + +void +setsig(n, f) +register n; +_PROTOTYPE(void (*f), (int)); +{ + if (n == 0) + return; + if (signal(n, SIG_IGN) != SIG_IGN || ourtrap[n]) { + ourtrap[n] = 1; + signal(n, f); + } +} + +int +getn(as) +char *as; +{ + register char *s; + register n, m; + + s = as; + m = 1; + if (*s == '-') { + m = -1; + s++; + } + for (n = 0; digit(*s); s++) + n = (n*10) + (*s-'0'); + if (*s) { + prs(as); + err(": bad number"); + } + return(n*m); +} + +int +dobreak(t) +struct op *t; +{ + return(brkcontin(t->words[1], 1)); +} + +int +docontinue(t) +struct op *t; +{ + return(brkcontin(t->words[1], 0)); +} + +static int +brkcontin(cp, val) +register char *cp; +int val; +{ + register struct brkcon *bc; + register nl; + + nl = cp == NULL? 1: getn(cp); + if (nl <= 0) + nl = 999; + do { + if ((bc = brklist) == NULL) + break; + brklist = bc->nextlev; + } while (--nl); + if (nl) { + err("bad break/continue level"); + return(1); + } + isbreak = val; + longjmp(bc->brkpt, 1); + /* NOTREACHED */ +} + +int +doexit(t) +struct op *t; +{ + register char *cp; + + execflg = 0; + if ((cp = t->words[1]) != NULL) + setstatus(getn(cp)); + leave(); + /* NOTREACHED */ +} + +int +doexport(t) +struct op *t; +{ + rdexp(t->words+1, export, EXPORT); + return(0); +} + +int +doreadonly(t) +struct op *t; +{ + rdexp(t->words+1, ronly, RONLY); + return(0); +} + +static void +rdexp(wp, f, key) +register char **wp; +void (*f)(); +int key; +{ + if (*wp != NULL) { + for (; *wp != NULL; wp++) + if (checkname(*wp)) + (*f)(lookup(*wp)); + else + badid(*wp); + } else + putvlist(key, 1); +} + +static void +badid(s) +register char *s; +{ + prs(s); + err(": bad identifier"); +} + +int +doset(t) +register struct op *t; +{ + register struct var *vp; + register char *cp; + register n; + + if ((cp = t->words[1]) == NULL) { + for (vp = vlist; vp; vp = vp->next) + varput(vp->name, 1); + return(0); + } + if (*cp == '-') { + /* bad: t->words++; */ + for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++) + ; + if (*++cp == 0) + flag['x'] = flag['v'] = 0; + else + for (; *cp; cp++) + switch (*cp) { + case 'e': + if (!talking) + flag['e']++; + break; + + default: + if (*cp>='a' && *cp<='z') + flag[*cp]++; + break; + } + setdash(); + } + if (t->words[1]) { + t->words[0] = dolv[0]; + for (n=1; t->words[n]; n++) + setarea((char *)t->words[n], 0); + dolc = n-1; + dolv = t->words; + setval(lookup("#"), putn(dolc)); + setarea((char *)(dolv-1), 0); + } + return(0); +} + +void +varput(s, out) +register char *s; +int out; +{ + if (letnum(*s)) { + write(out, s, strlen(s)); + write(out, "\n", 1); + } +} + + +#define SECS 60L +#define MINS 3600L + +int +dotimes() +{ + struct tms tbuf; + + times(&tbuf); + + prn((int)(tbuf.tms_cutime / MINS)); + prs("m"); + prn((int)((tbuf.tms_cutime % MINS) / SECS)); + prs("s "); + prn((int)(tbuf.tms_cstime / MINS)); + prs("m"); + prn((int)((tbuf.tms_cstime % MINS) / SECS)); + prs("s\n"); + return(0); +} + +struct builtin { + char *command; + int (*fn)(); +}; +static struct builtin builtin[] = { + ":", dolabel, + "cd", dochdir, + "shift", doshift, + "exec", doexec, + "wait", dowait, + "read", doread, + "eval", doeval, + "trap", dotrap, + "break", dobreak, + "continue", docontinue, + "exit", doexit, + "export", doexport, + "readonly", doreadonly, + "set", doset, + ".", dodot, + "umask", doumask, + "login", dologin, + "newgrp", dologin, + "times", dotimes, + 0, +}; + +int (*inbuilt(s))() +register char *s; +{ + register struct builtin *bp; + + for (bp = builtin; bp->command != NULL; bp++) + if (strcmp(bp->command, s) == 0) + return(bp->fn); + return((int(*)())NULL); +} + diff --git a/src/bin/sh/sh4.c b/src/bin/sh/sh4.c new file mode 100644 index 0000000..7308b41 --- /dev/null +++ b/src/bin/sh/sh4.c @@ -0,0 +1,765 @@ +#define Extern extern +#include +#include +#include +#include +#include +#include +#include +#include "sh.h" + +/* -------- eval.c -------- */ +/* #include "sh.h" */ +/* #include "word.h" */ + +/* + * ${} + * `command` + * blank interpretation + * quoting + * glob + */ + +_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f )); +_PROTOTYPE(static char *blank, (int f )); +_PROTOTYPE(static int dollar, (int quoted )); +_PROTOTYPE(static int grave, (int quoted )); +_PROTOTYPE(void globname, (char *we, char *pp )); +_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end )); +_PROTOTYPE(static int anyspcl, (struct wdblock *wb )); +_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 )); +_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *))); +_PROTOTYPE(void glob1, (char *base, char *lim )); +_PROTOTYPE(void glob2, (char *i, char *j )); +_PROTOTYPE(void glob3, (char *i, char *j, char *k )); +_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb )); + +char ** +eval(ap, f) +register char **ap; +int f; +{ + struct wdblock *wb; + char **wp; + char **wf; + jmp_buf ev; + + wp = NULL; + wb = NULL; + wf = NULL; + if (newenv(setjmp(errpt = ev)) == 0) { + while (*ap && isassign(*ap)) + expand(*ap++, &wb, f & ~DOGLOB); + if (flag['k']) { + for (wf = ap; *wf; wf++) { + if (isassign(*wf)) + expand(*wf, &wb, f & ~DOGLOB); + } + } + for (wb = addword((char *)0, wb); *ap; ap++) { + if (!flag['k'] || !isassign(*ap)) + expand(*ap, &wb, f & ~DOKEY); + } + wb = addword((char *)0, wb); + wp = getwords(wb); + quitenv(); + } else + gflg = 1; + return(gflg? (char **)NULL: wp); +} + +/* + * Make the exported environment from the exported + * names in the dictionary. Keyword assignments + * will already have been done. + */ +char ** +makenv() + +{ + register struct wdblock *wb; + register struct var *vp; + + wb = NULL; + for (vp = vlist; vp; vp = vp->next) + if (vp->status & EXPORT) + wb = addword(vp->name, wb); + wb = addword((char *)0, wb); + return(getwords(wb)); +} + +char * +evalstr(cp, f) +register char *cp; +int f; +{ + struct wdblock *wb; + + wb = NULL; + if (expand(cp, &wb, f)) { + if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL) + cp = ""; + DELETE(wb); + } else + cp = NULL; + return(cp); +} + +static int +expand(cp, wbp, f) +register char *cp; +register struct wdblock **wbp; +int f; +{ + jmp_buf ev; + + gflg = 0; + if (cp == NULL) + return(0); + if (!anys("$`'\"", cp) && + !anys(ifs->value, cp) && + ((f&DOGLOB)==0 || !anys("[*?", cp))) { + cp = strsave(cp, areanum); + if (f & DOTRIM) + unquote(cp); + *wbp = addword(cp, *wbp); + return(1); + } + if (newenv(setjmp(errpt = ev)) == 0) { + PUSHIO(aword, cp, strchar); + e.iobase = e.iop; + while ((cp = blank(f)) && gflg == 0) { + e.linep = cp; + cp = strsave(cp, areanum); + if ((f&DOGLOB) == 0) { + if (f & DOTRIM) + unquote(cp); + *wbp = addword(cp, *wbp); + } else + *wbp = glob(cp, *wbp); + } + quitenv(); + } else + gflg = 1; + return(gflg == 0); +} + +/* + * Blank interpretation and quoting + */ +static char * +blank(f) +int f; +{ + register c, c1; + register char *sp; + int scanequals, foundequals; + + sp = e.linep; + scanequals = f & DOKEY; + foundequals = 0; + +loop: + switch (c = subgetc('"', foundequals)) { + case 0: + if (sp == e.linep) + return(0); + *e.linep++ = 0; + return(sp); + + default: + if (f & DOBLANK && any(c, ifs->value)) + goto loop; + break; + + case '"': + case '\'': + scanequals = 0; + if (INSUB()) + break; + for (c1 = c; (c = subgetc(c1, 1)) != c1;) { + if (c == 0) + break; + if (c == '\'' || !any(c, "$`\"")) + c |= QUOTE; + *e.linep++ = c; + } + c = 0; + } + unget(c); + if (!letter(c)) + scanequals = 0; + for (;;) { + c = subgetc('"', foundequals); + if (c == 0 || + f & (DOBLANK && any(c, ifs->value)) || + (!INSUB() && any(c, "\"'"))) { + scanequals = 0; + unget(c); + if (any(c, "\"'")) + goto loop; + break; + } + if (scanequals) + if (c == '=') { + foundequals = 1; + scanequals = 0; + } + else if (!letnum(c)) + scanequals = 0; + *e.linep++ = c; + } + *e.linep++ = 0; + return(sp); +} + +/* + * Get characters, substituting for ` and $ + */ +int +subgetc(ec, quoted) +register char ec; +int quoted; +{ + register char c; + +again: + c = getc(ec); + if (!INSUB() && ec != '\'') { + if (c == '`') { + if (grave(quoted) == 0) + return(0); + e.iop->task = XGRAVE; + goto again; + } + if (c == '$' && (c = dollar(quoted)) == 0) { + e.iop->task = XDOLL; + goto again; + } + } + return(c); +} + +/* + * Prepare to generate the string returned by ${} substitution. + */ +static int +dollar(quoted) +int quoted; +{ + int otask; + struct io *oiop; + char *dolp; + register char *s, c, *cp; + struct var *vp; + + c = readc(); + s = e.linep; + if (c != '{') { + *e.linep++ = c; + if (letter(c)) { + while ((c = readc())!=0 && letnum(c)) + if (e.linep < elinep) + *e.linep++ = c; + unget(c); + } + c = 0; + } else { + oiop = e.iop; + otask = e.iop->task; + e.iop->task = XOTHER; + while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n') + if (e.linep < elinep) + *e.linep++ = c; + if (oiop == e.iop) + e.iop->task = otask; + if (c != '}') { + err("unclosed ${"); + gflg++; + return(c); + } + } + if (e.linep >= elinep) { + err("string in ${} too long"); + gflg++; + e.linep -= 10; + } + *e.linep = 0; + if (*s) + for (cp = s+1; *cp; cp++) + if (any(*cp, "=-+?")) { + c = *cp; + *cp++ = 0; + break; + } + if (s[1] == 0 && (*s == '*' || *s == '@')) { + if (dolc > 1) { + /* currently this does not distinguish $* and $@ */ + /* should check dollar */ + e.linep = s; + PUSHIO(awordlist, dolv+1, dolchar); + return(0); + } else { /* trap the nasty ${=} */ + s[0] = '1'; + s[1] = 0; + } + } + vp = lookup(s); + if ((dolp = vp->value) == null) { + switch (c) { + case '=': + if (digit(*s)) { + err("cannot use ${...=...} with $n"); + gflg++; + break; + } + setval(vp, cp); + dolp = vp->value; + break; + + case '-': + dolp = strsave(cp, areanum); + break; + + case '?': + if (*cp == 0) { + prs("missing value for "); + err(s); + } else + err(cp); + gflg++; + break; + } + } else if (c == '+') + dolp = strsave(cp, areanum); + if (flag['u'] && dolp == null) { + prs("unset variable: "); + err(s); + gflg++; + } + e.linep = s; + PUSHIO(aword, dolp, quoted ? qstrchar : strchar); + return(0); +} + +/* + * Run the command in `...` and read its output. + */ +static int +grave(quoted) +int quoted; +{ + register char *cp; + register int i; + int pf[2]; + + for (cp = e.iop->argp->aword; *cp != '`'; cp++) + if (*cp == 0) { + err("no closing `"); + return(0); + } + if (openpipe(pf) < 0) + return(0); + if ((i = fork()) == -1) { + closepipe(pf); + err("try again"); + return(0); + } + if (i != 0) { + e.iop->argp->aword = ++cp; + close(pf[1]); + PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar); + return(1); + } + *cp = 0; + /* allow trapped signals */ + for (i=0; i<=_NSIG; i++) + if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN) + signal(i, SIG_DFL); + dup2(pf[1], 1); + closepipe(pf); + flag['e'] = 0; + flag['v'] = 0; + flag['n'] = 0; + cp = strsave(e.iop->argp->aword, 0); + areanum = 1; + freehere(areanum); + freearea(areanum); /* free old space */ + e.oenv = NULL; + e.iop = (e.iobase = iostack) - 1; + unquote(cp); + talking = 0; + PUSHIO(aword, cp, nlchar); + onecommand(); + exit(1); +} + +char * +unquote(as) +register char *as; +{ + register char *s; + + if ((s = as) != NULL) + while (*s) + *s++ &= ~QUOTE; + return(as); +} + +/* -------- glob.c -------- */ +/* #include "sh.h" */ + +/* + * glob + */ + +#define scopy(x) strsave((x), areanum) +#define BLKSIZ 512 +#define NDENT ((BLKSIZ+sizeof(struct direct)-1)/sizeof(struct direct)) + +static struct wdblock *cl, *nl; +static char spcl[] = "[?*"; + +struct wdblock * +glob(cp, wb) +char *cp; +struct wdblock *wb; +{ + register i; + register char *pp; + + if (cp == 0) + return(wb); + i = 0; + for (pp = cp; *pp; pp++) + if (any(*pp, spcl)) + i++; + else if (!any(*pp & ~QUOTE, spcl)) + *pp &= ~QUOTE; + if (i != 0) { + for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) { + nl = newword(cl->w_nword*2); + for(i=0; iw_nword; i++) { /* for each argument */ + for (pp = cl->w_words[i]; *pp; pp++) + if (any(*pp, spcl)) { + globname(cl->w_words[i], pp); + break; + } + if (*pp == '\0') + nl = addword(scopy(cl->w_words[i]), nl); + } + for(i=0; iw_nword; i++) + DELETE(cl->w_words[i]); + DELETE(cl); + } + for(i=0; iw_nword; i++) + unquote(cl->w_words[i]); + glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp); + if (cl->w_nword) { + for (i=0; iw_nword; i++) + wb = addword(cl->w_words[i], wb); + DELETE(cl); + return(wb); + } + } + wb = addword(unquote(cp), wb); + return(wb); +} + +void +globname(we, pp) +char *we; +register char *pp; +{ + register char *np, *cp; + char *name, *gp, *dp; + int dn, j, n, k; + struct direct ent[NDENT]; + char dname[NAME_MAX+1]; + struct stat dbuf; + + for (np = we; np != pp; pp--) + if (pp[-1] == '/') + break; + for (dp = cp = space((int)(pp-np)+3); np < pp;) + *cp++ = *np++; + *cp++ = '.'; + *cp = '\0'; + for (gp = cp = space(strlen(pp)+1); *np && *np != '/';) + *cp++ = *np++; + *cp = '\0'; + dn = open(dp, 0); + if (dn < 0) { + DELETE(dp); + DELETE(gp); + return; + } + dname[NAME_MAX] = '\0'; + while ((n = read(dn, (char *)ent, sizeof(ent))) >= sizeof(*ent)) { + n /= sizeof(*ent); + for (j=0; jw_words; + for (i=0; iw_nword; i++) + if (anys(spcl, *wd++)) + return(1); + return(0); +} + +static int +xstrcmp(p1, p2) +char *p1, *p2; +{ + return(strcmp(*(char **)p1, *(char **)p2)); +} + +/* -------- word.c -------- */ +/* #include "sh.h" */ +/* #include "word.h" */ + +#define NSTART 16 /* default number of words to allow for initially */ + +struct wdblock * +newword(nw) +register int nw; +{ + register struct wdblock *wb; + + wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *)); + wb->w_bsize = nw; + wb->w_nword = 0; + return(wb); +} + +struct wdblock * +addword(wd, wb) +char *wd; +register struct wdblock *wb; +{ + register struct wdblock *wb2; + register nw; + + if (wb == NULL) + wb = newword(NSTART); + if ((nw = wb->w_nword) >= wb->w_bsize) { + wb2 = newword(nw * 2); + memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *)); + wb2->w_nword = nw; + DELETE(wb); + wb = wb2; + } + wb->w_words[wb->w_nword++] = wd; + return(wb); +} + +char ** +getwords(wb) +register struct wdblock *wb; +{ + register char **wd; + register nb; + + if (wb == NULL) + return((char **)NULL); + if (wb->w_nword == 0) { + DELETE(wb); + return((char **)NULL); + } + wd = (char **) space(nb = sizeof(*wd) * wb->w_nword); + memcopy((char *)wd, (char *)wb->w_words, nb); + DELETE(wb); /* perhaps should done by caller */ + return(wd); +} + +_PROTOTYPE(int (*func), (char *, char *)); +int globv; + +void +glob0(a0, a1, a2, a3) +char *a0; +unsigned a1; +int a2; +_PROTOTYPE(int (*a3), (char *, char *)); +{ + func = a3; + globv = a2; + glob1(a0, a0 + a1 * a2); +} + +void +glob1(base, lim) +char *base, *lim; +{ + register char *i, *j; + int v2; + char *lptr, *hptr; + int c; + unsigned n; + + + v2 = globv; + +top: + if ((n=(int)(lim-base)) <= v2) + return; + n = v2 * (n / (2*v2)); + hptr = lptr = base+n; + i = base; + j = lim-v2; + for(;;) { + if (i < lptr) { + if ((c = (*func)(i, lptr)) == 0) { + glob2(i, lptr -= v2); + continue; + } + if (c < 0) { + i += v2; + continue; + } + } + +begin: + if (j > hptr) { + if ((c = (*func)(hptr, j)) == 0) { + glob2(hptr += v2, j); + goto begin; + } + if (c > 0) { + if (i == lptr) { + glob3(i, hptr += v2, j); + i = lptr += v2; + goto begin; + } + glob2(i, j); + j -= v2; + i += v2; + continue; + } + j -= v2; + goto begin; + } + + + if (i == lptr) { + if (lptr-base >= lim-hptr) { + glob1(hptr+v2, lim); + lim = lptr; + } else { + glob1(base, lptr); + base = hptr+v2; + } + goto top; + } + + + glob3(j, lptr -= v2, i); + j = hptr -= v2; + } +} + +void +glob2(i, j) +char *i, *j; +{ + register char *index1, *index2, c; + int m; + + m = globv; + index1 = i; + index2 = j; + do { + c = *index1; + *index1++ = *index2; + *index2++ = c; + } while(--m); +} + +void +glob3(i, j, k) +char *i, *j, *k; +{ + register char *index1, *index2, *index3; + int c; + int m; + + m = globv; + index1 = i; + index2 = j; + index3 = k; + do { + c = *index1; + *index1++ = *index3; + *index3++ = *index2; + *index2++ = c; + } while(--m); +} + +char * +memcopy(ato, from, nb) +register char *ato, *from; +register int nb; +{ + register char *to; + + to = ato; + while (--nb >= 0) + *to++ = *from++; + return(ato); +} diff --git a/src/bin/sh/sh5.c b/src/bin/sh/sh5.c new file mode 100644 index 0000000..9786a6a --- /dev/null +++ b/src/bin/sh/sh5.c @@ -0,0 +1,674 @@ +#define Extern extern +#include +#include +#include +#include +#include "sh.h" + +/* -------- io.c -------- */ +/* #include "sh.h" */ + +/* + * shell IO + */ + +static struct iobuf sharedbuf = {AFID_NOBUF}; +static struct iobuf mainbuf = {AFID_NOBUF}; +static unsigned bufid = AFID_ID; /* buffer id counter */ + +struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0}; + +_PROTOTYPE(static void readhere, (char **name, char *s, int ec )); +_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)())); +_PROTOTYPE(static int xxchar, (struct ioarg *ap )); +_PROTOTYPE(void tempname, (char *tname )); + +int +getc(ec) +register int ec; +{ + register int c; + + if(e.linep > elinep) { + while((c=readc()) != '\n' && c) + ; + err("input line too long"); + gflg++; + return(c); + } + c = readc(); + if (ec != '\'' && e.iop->task != XGRAVE) { + if(c == '\\') { + c = readc(); + if (c == '\n' && ec != '\"') + return(getc(ec)); + c |= QUOTE; + } + } + return(c); +} + +void +unget(c) +int c; +{ + if (e.iop >= e.iobase) + e.iop->peekc = c; +} + +int +eofc() + +{ + return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0); +} + +int +readc() +{ + register c; + + for (; e.iop >= e.iobase; e.iop--) + if ((c = e.iop->peekc) != '\0') { + e.iop->peekc = 0; + return(c); + } + else { + if (e.iop->prev != 0) { + if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') { + if (c == -1) { + e.iop++; + continue; + } + if (e.iop == iostack) + ioecho(c); + return(e.iop->prev = c); + } + else if (e.iop->task == XIO && e.iop->prev != '\n') { + e.iop->prev = 0; + if (e.iop == iostack) + ioecho('\n'); + return '\n'; + } + } + if (e.iop->task == XIO) { + if (multiline) + return e.iop->prev = 0; + if (talking && e.iop == iostack+1) + prs(prompt->value); + } + } + if (e.iop >= iostack) + return(0); + leave(); + /* NOTREACHED */ +} + +void +ioecho(c) +char c; +{ + if (flag['v']) + write(2, &c, sizeof c); +} + +void +pushio(argp, fn) +struct ioarg *argp; +int (*fn)(); +{ + if (++e.iop >= &iostack[NPUSH]) { + e.iop--; + err("Shell input nested too deeply"); + gflg++; + return; + } + e.iop->iofn = fn; + + if (argp->afid != AFID_NOBUF) + e.iop->argp = argp; + else { + e.iop->argp = ioargstack + (e.iop - iostack); + *e.iop->argp = *argp; + e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf; + if (isatty(e.iop->argp->afile) == 0 && + (e.iop == &iostack[0] || + lseek(e.iop->argp->afile, 0L, 1) != -1)) { + if (++bufid == AFID_NOBUF) + bufid = AFID_ID; + e.iop->argp->afid = bufid; + } + } + + e.iop->prev = ~'\n'; + e.iop->peekc = 0; + e.iop->xchar = 0; + e.iop->nlcount = 0; + if (fn == filechar || fn == linechar) + e.iop->task = XIO; + else if (fn == gravechar || fn == qgravechar) + e.iop->task = XGRAVE; + else + e.iop->task = XOTHER; +} + +struct io * +setbase(ip) +struct io *ip; +{ + register struct io *xp; + + xp = e.iobase; + e.iobase = ip; + return(xp); +} + +/* + * Input generating functions + */ + +/* + * Produce the characters of a string, then a newline, then EOF. + */ +int +nlchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL) + return(0); + if ((c = *ap->aword++) == 0) { + ap->aword = NULL; + return('\n'); + } + return(c); +} + +/* + * Given a list of words, produce the characters + * in them, with a space after each word. + */ +int +wdchar(ap) +register struct ioarg *ap; +{ + register char c; + register char **wl; + + if ((wl = ap->awordlist) == NULL) + return(0); + if (*wl != NULL) { + if ((c = *(*wl)++) != 0) + return(c & 0177); + ap->awordlist++; + return(' '); + } + ap->awordlist = NULL; + return('\n'); +} + +/* + * Return the characters of a list of words, + * producing a space between them. + */ +int +dolchar(ap) +register struct ioarg *ap; +{ + register char *wp; + + if ((wp = *ap->awordlist++) != NULL) { + PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar); + return(-1); + } + return(0); +} + +static int +xxchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL) + return(0); + if ((c = *ap->aword++) == '\0') { + ap->aword = NULL; + return(' '); + } + return(c); +} + +/* + * Produce the characters from a single word (string). + */ +int +strchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL || (c = *ap->aword++) == 0) + return(0); + return(c); +} + +/* + * Produce quoted characters from a single word (string). + */ +int +qstrchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL || (c = *ap->aword++) == 0) + return(0); + return(c|QUOTE); +} + +/* + * Return the characters from a file. + */ +int +filechar(ap) +register struct ioarg *ap; +{ + register int i; + char c; + struct iobuf *bp = ap->afbuf; + + if (ap->afid != AFID_NOBUF) { + if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { + if (i) + lseek(ap->afile, ap->afpos, 0); + do { + i = read(ap->afile, bp->buf, sizeof(bp->buf)); + } while (i < 0 && errno == EINTR); + if (i <= 0) { + closef(ap->afile); + return 0; + } + bp->id = ap->afid; + bp->ebufp = (bp->bufp = bp->buf) + i; + } + ap->afpos++; + return *bp->bufp++ & 0177; + } + + do { + i = read(ap->afile, &c, sizeof(c)); + } while (i < 0 && errno == EINTR); + return(i == sizeof(c)? c&0177: (closef(ap->afile), 0)); +} + +/* + * Return the characters from a here temp file. + */ +int +herechar(ap) +register struct ioarg *ap; +{ + char c; + + + if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) { + close(ap->afile); + c = 0; + } + return (c); + +} + +/* + * Return the characters produced by a process (`...`). + * Quote them if required, and remove any trailing newline characters. + */ +int +gravechar(ap, iop) +struct ioarg *ap; +struct io *iop; +{ + register int c; + + if ((c = qgravechar(ap, iop)&~QUOTE) == '\n') + c = ' '; + return(c); +} + +int +qgravechar(ap, iop) +register struct ioarg *ap; +struct io *iop; +{ + register int c; + + if (iop->xchar) { + if (iop->nlcount) { + iop->nlcount--; + return('\n'|QUOTE); + } + c = iop->xchar; + iop->xchar = 0; + } else if ((c = filechar(ap)) == '\n') { + iop->nlcount = 1; + while ((c = filechar(ap)) == '\n') + iop->nlcount++; + iop->xchar = c; + if (c == 0) + return(c); + iop->nlcount--; + c = '\n'; + } + return(c!=0? c|QUOTE: 0); +} + +/* + * Return a single command (usually the first line) from a file. + */ +int +linechar(ap) +register struct ioarg *ap; +{ + register int c; + + if ((c = filechar(ap)) == '\n') { + if (!multiline) { + closef(ap->afile); + ap->afile = -1; /* illegal value */ + } + } + return(c); +} + +void +prs(s) +register char *s; +{ + if (*s) + write(2, s, strlen(s)); +} + +void +putc(c) +char c; +{ + write(2, &c, sizeof c); +} + +void +prn(u) +unsigned u; +{ + prs(itoa(u, 0)); +} + +void +closef(i) +register int i; +{ + if (i > 2) + close(i); +} + +void +closeall() +{ + register u; + + for (u=NUFILE; u= 0 && fd < e.iofd); + for (i=0; ih_tag = evalstr(s, DOSUB); + if (h->h_tag == 0) + return; + h->h_iop = iop; + iop->io_name = 0; + h->h_next = NULL; + if (inhere == 0) + inhere = h; + else + for (lh = inhere; lh!=NULL; lh = lh->h_next) + if (lh->h_next == 0) { + lh->h_next = h; + break; + } + iop->io_flag |= IOHERE|IOXHERE; + for (s = h->h_tag; *s; s++) + if (*s & QUOTE) { + iop->io_flag &= ~ IOXHERE; + *s &= ~ QUOTE; + } + h->h_dosub = iop->io_flag & IOXHERE; +} + +void +gethere() +{ + register struct here *h, *hp; + + /* Scan here files first leaving inhere list in place */ + for (hp = h = inhere; h != NULL; hp = h, h = h->h_next) + readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\''); + + /* Make inhere list active - keep list intact for scraphere */ + if (hp != NULL) { + hp->h_next = acthere; + acthere = inhere; + inhere = NULL; + } +} + +static void +readhere(name, s, ec) +char **name; +register char *s; +int ec; +{ + int tf; + char tname[30]; + register c; + jmp_buf ev; + char line [LINELIM+1]; + char *next; + + tempname(tname); + *name = strsave(tname, areanum); + tf = creat(tname, 0600); + if (tf < 0) + return; + if (newenv(setjmp(errpt = ev)) != 0) + unlink(tname); + else { + pushio(e.iop->argp, e.iop->iofn); + e.iobase = e.iop; + for (;;) { + if (talking && e.iop <= iostack) + prs(cprompt->value); + next = line; + while ((c = getc(ec)) != '\n' && c) { + if (ec == '\'') + c &= ~ QUOTE; + if (next >= &line[LINELIM]) { + c = 0; + break; + } + *next++ = c; + } + *next = 0; + if (strcmp(s, line) == 0 || c == 0) + break; + *next++ = '\n'; + write (tf, line, (int)(next-line)); + } + if (c == 0) { + prs("here document `"); prs(s); err("' unclosed"); + } + quitenv(); + } + close(tf); +} + +/* + * open here temp file. + * if unquoted here, expand here temp file into second temp file. + */ +int +herein(hname, xdoll) +char *hname; +int xdoll; +{ + register hf, tf; + + if (hname == 0) + return(-1); + hf = open(hname, 0); + if (hf < 0) + return (-1); + if (xdoll) { + char c; + char tname[30]; + jmp_buf ev; + + tempname(tname); + if ((tf = creat(tname, 0600)) < 0) + return (-1); + if (newenv(setjmp(errpt = ev)) == 0) { + PUSHIO(afile, hf, herechar); + setbase(e.iop); + while ((c = subgetc(0, 0)) != 0) { + c &= ~ QUOTE; + write(tf, &c, sizeof c); + } + quitenv(); + } else + unlink(tname); + close(tf); + tf = open(tname, 0); + unlink(tname); + return (tf); + } else + return (hf); +} + +void +scraphere() +{ + register struct here *h; + + for (h = inhere; h != NULL; h = h->h_next) { + if (h->h_iop && h->h_iop->io_name) + unlink(h->h_iop->io_name); + } + inhere = NULL; +} + +/* unlink here temp files before a freearea(area) */ +void +freehere(area) +int area; +{ + register struct here *h, *hl; + + hl = NULL; + for (h = acthere; h != NULL; h = h->h_next) + if (getarea((char *) h) >= area) { + if (h->h_iop->io_name != NULL) + unlink(h->h_iop->io_name); + if (hl == NULL) + acthere = h->h_next; + else + hl->h_next = h->h_next; + } else + hl = h; +} + +void +tempname(tname) +char *tname; +{ + static int inc; + register char *cp, *lp; + + for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++) + ; + lp = putn(getpid()*1000 + inc++); + for (; (*cp = *lp++) != '\0'; cp++) + ; +} diff --git a/src/bin/sh/sh6.c b/src/bin/sh/sh6.c new file mode 100644 index 0000000..802be74 --- /dev/null +++ b/src/bin/sh/sh6.c @@ -0,0 +1,8 @@ +#define Extern + +#include +#include +#include +#include +#include "sh.h" + diff --git a/src/bin/shell/Makefile b/src/bin/shell/Makefile new file mode 100644 index 0000000..c7631d1 --- /dev/null +++ b/src/bin/shell/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#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 = ../../lib/libc_old/libc_old.so ../../lib/ubix_api/ubix_api.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/shell/commands.c b/src/bin/shell/commands.c new file mode 100644 index 0000000..9e24fd2 --- /dev/null +++ b/src/bin/shell/commands.c @@ -0,0 +1,166 @@ +/***************************************************************************************** + 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$ + +*****************************************************************************************/ + +#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; + +printf("WEST\n\n"); + + if (data == NULL) return 1; + if (data->args->arg == NULL) 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) { + exec("clock",0x0); + exit(0x1); + } else { + printf("Childs Pid: [%i]\n",cPid); + while (pidStatus(cPid) > 0) + sched_yield(); + } + cPid = fork(); + if (cPid == 0x0) { + exec("ls", 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); + exec("clock",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 if (!strcmp(argv[1],"newexec")) { + printf("Switching To New EXEC\n"); + boo = 0x1; + } + else if (!strcmp(argv[1],"oldexec")) { + printf("Switching To Old EXEC\n"); + boo = 0x0; + } + 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..adf30a6 --- /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$ + +**************************************************************************************/ + +#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..a31d5e5 --- /dev/null +++ b/src/bin/shell/exec.c @@ -0,0 +1,57 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#include +#include +#include +#include +#include +#include "shell.h" + +int boo = 0x0; + +void execProgram(inputBuffer *data) { + char file[1024]; + char **argv = &data->argv; + int cPid = 0x0; + + printf("Executing App\n"); + + cPid = fork(); + + if (!cPid) { + sprintf(file,"%s%s",cwd,argv[1]); + if (boo == 0) + exec(file,&data->argv); + else + execn(file,&data->argv); + printf("%s: Command Not Found.\n",argv[1]); + exit(-1); + } + else { + if (data->bg == 0x0) { + while (pidStatus(cPid) > 0) + sched_yield(); + } + } + } diff --git a/src/bin/shell/input.c b/src/bin/shell/input.c new file mode 100644 index 0000000..cbc7736 --- /dev/null +++ b/src/bin/shell/input.c @@ -0,0 +1,87 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#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"); + + printf("sh[%s:%s]",arg,data); + 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); + + for (i=0x1;i <= buffer->argc;i++) { + argv[i] = tmpArgs->arg; + printf("argv[%i]: %s\n",i,argv[i]); + tmpArgs = tmpArgs->next; + } + argv[0] = buffer->argc; + //argv[buffer->argc+1] = buffer->envp; + } + +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..0be249a --- /dev/null +++ b/src/bin/shell/main.c @@ -0,0 +1,71 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#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("[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); + + if (inBuf->args->arg != 0x0) { + 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..9a28739 --- /dev/null +++ b/src/bin/shell/shell.h @@ -0,0 +1,23 @@ +#include + +extern char *cwd; +extern int boo; + +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/shell2/Makefile b/src/bin/shell2/Makefile new file mode 100644 index 0000000..86ee4de --- /dev/null +++ b/src/bin/shell2/Makefile @@ -0,0 +1,54 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = shell2 + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o error.o commands.o exec.o input.o + +INCLUDES = -I../../include.new + +LIBRARIES = ../../lib/libc/libc.so + +STARTUP = ../../lib/csu/*.o + + + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/shell2/commands.c b/src/bin/shell2/commands.c new file mode 100644 index 0000000..3b8bf86 --- /dev/null +++ b/src/bin/shell2/commands.c @@ -0,0 +1,135 @@ +/***************************************************************************************** + 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$ + +*****************************************************************************************/ + +#include +#include +#include +//#include +//#include +#include +#include +//#include + +#include "shell.h" + +int commands(inputBuffer *data) { + int cPid = 0x0,i = 0x0,x = 0x0; + + //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(); +*/ + exit(1); + } + cPid = fork(); + if (cPid == 0x0) { + execve("ls", 0x0, 0x0); + exit(0x1); + } else { + printf("Childs Pid: [%i]\n",cPid); +/* + while (pidStatus(cPid) > 0) + sched_yield(); +*/ +exit(1); + } + } + } + else if (memcmp(data->args->arg,"echo",4) == 0) { + for (i=1;iargc;i++) { + printf("%s ",data->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 (data->argv[1]) { + chdir(data->argv[1]); + getcwd(cwd,1024); + } + } + else if (memcmp(data->args->arg,"unlink",6) == 0) { + if (data->argv[1]) { + unlink(data->argv[1]); + } + } + else if (memcmp(data->args->arg,"msg",3) == 0x0) { + printf("Posting Message\n"); + //cmdMsg.header = atoi(data->argv[2]); + //sprintf(cmdMsg.data,data->argv[3]); + //mpi_postMessage(data->argv[1],0x1,&cmdMsg); + } + else if (memcmp(data->args->arg,"mkdir",5) == 0x0) { + if (data->argv[1]) { + mkdir(data->argv[1],0xEAA); + } + } + else if (memcmp(data->args->arg,"id",2) == 0x0) { + printf("UID: %i, GID: %i\n",getuid(),getgid()); + } + else if (!strcmp(data->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/shell2/error.c b/src/bin/shell2/error.c new file mode 100644 index 0000000..adf30a6 --- /dev/null +++ b/src/bin/shell2/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$ + +**************************************************************************************/ + +#include +#include + +void error(int errorCode,const char *errorMsg) { + printf("ERROR: #%i Message: %s\n", errorCode, errorMsg); + exit(errorCode); + } diff --git a/src/bin/shell2/exec.c b/src/bin/shell2/exec.c new file mode 100644 index 0000000..4bb30e9 --- /dev/null +++ b/src/bin/shell2/exec.c @@ -0,0 +1,50 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +//#include +//#include +#include +#include +#include +#include "shell.h" + +void execProgram(inputBuffer *data) { + char file[1024]; + int cPid = 0x0; + cPid = fork(); + if (!cPid) { + sprintf(file,"%s%s",cwd,data->argv[1]); + execve(file,data->argc,data->argv+1); + printf("%s: Command Not Found.\n",data->argv[1]); + exit(-1); + } + else { + if (data->bg == 0x0) { +/* + while (pidStatus(cPid) > 0) + sched_yield(); +*/ +exit(1); + } + } + } diff --git a/src/bin/shell2/input.c b/src/bin/shell2/input.c new file mode 100644 index 0000000..66651b2 --- /dev/null +++ b/src/bin/shell2/input.c @@ -0,0 +1,74 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#include +#include +#include +#include "shell.h" + +void parseInput(inputBuffer *buffer,char *data) { + int i = 0x0; + char *arg = 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 (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; + } + } + + buffer->argv = (char **)malloc(4*(buffer->argc * 1)); + buffer->envp = (char **)malloc(sizeof(char)); + buffer->envp[0] = 0x1; + tmpArgs = buffer->args; + for (i=1;i<=buffer->argc;i++) { + buffer->argv[i] = tmpArgs->arg; + tmpArgs = tmpArgs->next; + } + buffer->argv[0] = buffer->argc; + buffer->argv[buffer->argc+1] = buffer->envp; + } + +void freeArgs(inputBuffer *ptr) { + free(ptr->args); + //free(tmpArgs->argv); + } diff --git a/src/bin/shell2/main.c b/src/bin/shell2/main.c new file mode 100644 index 0000000..21a2d2f --- /dev/null +++ b/src/bin/shell2/main.c @@ -0,0 +1,67 @@ +/************************************************************************************** + 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$ + +**************************************************************************************/ + +#include +#include +#include +#include +#include "shell.h" + +char *machine = 0x0; +char *cwd = 0x0; +char *cwc = 0x0; + +int main() { + char *data = 0x0; + 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); +while(1); + + printf("Oh\n"); + + //printf("[0x%X]\n",ubix_test()); + + while (1) { + aGain: + printf("%s@%s> ",machine,cwd); + gets((char *)buffer); + data = (u_int8_t *)buffer; + if (buffer[0] == 0x0) + goto aGain; + parseInput(inBuf,data); + if (inBuf->args->arg != 0x0) { + if (!commands(inBuf)) execProgram(inBuf); + } + freeArgs(inBuf); + inBuf->argc = 0x0; + inBuf->args = 0x0; + inBuf->bg = 0x0; + } + return(0x0); + } diff --git a/src/bin/shell2/shell.h b/src/bin/shell2/shell.h new file mode 100644 index 0000000..9500a23 --- /dev/null +++ b/src/bin/shell2/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; + u_int8_t 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/shell2/shell2 b/src/bin/shell2/shell2 new file mode 100755 index 0000000..303bf31 --- /dev/null +++ b/src/bin/shell2/shell2 Binary files differ diff --git a/src/bin/stat/Makefile b/src/bin/stat/Makefile new file mode 100644 index 0000000..6257e4b --- /dev/null +++ b/src/bin/stat/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = stat + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/stat/main.c b/src/bin/stat/main.c new file mode 100644 index 0000000..4648582 --- /dev/null +++ b/src/bin/stat/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$ + +*****************************************************************************************/ + +#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; + 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..f556214 --- /dev/null +++ b/src/bin/ttyd/Makefile @@ -0,0 +1,45 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = ttyd + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/ttyd/main.c b/src/bin/ttyd/main.c new file mode 100644 index 0000000..d4fbee2 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..5240c62 --- /dev/null +++ b/src/bin/ubistry/Makefile @@ -0,0 +1,48 @@ +# $Id$ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc +include ../Makefile.inc + +#Linker +LD = ld + +#Binary File Name +BINARY = ubistry + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = db.o message.o main.o + +LIBRARIES = ../../lib/libc_old/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o $@ $(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) $(BINARY) diff --git a/src/bin/ubistry/db.c b/src/bin/ubistry/db.c new file mode 100644 index 0000000..0f00868 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..6b23f31 --- /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$ + +*****************************************************************************************/ + +#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$ + 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..264fcc6 --- /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$ + +*****************************************************************************************/ + +#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"); + exec("ubistry@sys",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$ + 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..bdee55b --- /dev/null +++ b/src/bin/views/Makefile @@ -0,0 +1,49 @@ +# $Id$ +# Application Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.inc + +#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 $@ $(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) $(BINARY) diff --git a/src/bin/views/main.c b/src/bin/views/main.c new file mode 100644 index 0000000..e86deaa --- /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$ + +**************************************************************************************/ + +#include +#include + +int main(int argc,char **argv) { + return(0); + } + +/*** + END + ***/ + diff --git a/src/contrib/gdtoa/README b/src/contrib/gdtoa/README new file mode 100644 index 0000000..6bece75 --- /dev/null +++ b/src/contrib/gdtoa/README @@ -0,0 +1,323 @@ +This directory contains source for a library of binary -> decimal +and decimal -> binary conversion routines, for single-, double-, +and extended-precision IEEE binary floating-point arithmetic, and +other IEEE-like binary floating-point, including "double double", +as in + + T. J. Dekker, "A Floating-Point Technique for Extending the + Available Precision", Numer. Math. 18 (1971), pp. 224-242 + +and + + "Inside Macintosh: PowerPC Numerics", Addison-Wesley, 1994 + +The conversion routines use double-precision floating-point arithmetic +and, where necessary, high precision integer arithmetic. The routines +are generalizations of the strtod and dtoa routines described in + + David M. Gay, "Correctly Rounded Binary-Decimal and + Decimal-Binary Conversions", Numerical Analysis Manuscript + No. 90-10, Bell Labs, Murray Hill, 1990; + http://cm.bell-labs.com/cm/cs/what/ampl/REFS/rounding.ps.gz + +(based in part on papers by Clinger and Steele & White: see the +references in the above paper). + +The present conversion routines should be able to use any of IEEE binary, +VAX, or IBM-mainframe double-precision arithmetic internally, but I (dmg) +have so far only had a chance to test them with IEEE double precision +arithmetic. + +The core conversion routines are strtodg for decimal -> binary conversions +and gdtoa for binary -> decimal conversions. These routines operate +on arrays of unsigned 32-bit integers of type ULong, a signed 32-bit +exponent of type Long, and arithmetic characteristics described in +struct FPI; FPI, Long, and ULong are defined in gdtoa.h. File arith.h +is supposed to provide #defines that cause gdtoa.h to define its +types correctly. File arithchk.c is source for a program that +generates a suitable arith.h on all systems where I've been able to +test it. + +The core conversion routines are meant to be called by helper routines +that know details of the particular binary arithmetic of interest and +convert. The present directory provides helper routines for 5 variants +of IEEE binary floating-point arithmetic, each indicated by one or +two letters: + + f IEEE single precision + d IEEE double precision + x IEEE extended precision, as on Intel 80x87 + and software emulations of Motorola 68xxx chips + that do not pad the way the 68xxx does, but + only store 80 bits + xL IEEE extended precision, as on Motorola 68xxx chips + Q quad precision, as on Sun Sparc chips + dd double double, pairs of IEEE double numbers + whose sum is the desired value + +For decimal -> binary conversions, there are three families of +helper routines: one for round-nearest: + + strtof + strtod + strtodd + strtopd + strtopf + strtopx + strtopxL + strtopQ + +one with rounding direction specified: + + strtorf + strtord + strtordd + strtorx + strtorxL + strtorQ + +and one for computing an interval (at most one bit wide) that contains +the decimal number: + + strtoIf + strtoId + strtoIdd + strtoIx + strtoIxL + strtoIQ + +The latter call strtoIg, which makes one call on strtodg and adjusts +the result to provide the desired interval. On systems where native +arithmetic can easily make one-ulp adjustments on values in the +desired floating-point format, it might be more efficient to use the +native arithmetic. Routine strtodI is a variant of strtoId that +illustrates one way to do this for IEEE binary double-precision +arithmetic -- but whether this is more efficient remains to be seen. + +Functions strtod and strtof have "natural" return types, float and +double -- strtod is specified by the C standard, and strtof appears +in the stdlib.h of some systems, such as (at least some) Linux systems. +The other functions write their results to their final argument(s): +to the final two argument for the strtoI... (interval) functions, +and to the final argument for the others (strtop... and strtor...). +Where possible, these arguments have "natural" return types (double* +or float*), to permit at least some type checking. In reality, they +are viewed as arrays of ULong (or, for the "x" functions, UShort) +values. On systems where long double is the appropriate type, one can +pass long double* final argument(s) to these routines. The int value +that these routines return is the return value from the call they make +on strtodg; see the enum of possible return values in gdtoa.h. + +Source files g_ddfmt.c, misc.c, smisc.c, strtod.c, strtodg.c, and ulp.c +should use true IEEE double arithmetic (not, e.g., double extended), +at least for storing (and viewing the bits of) the variables declared +"double" within them. + +One detail indicated in struct FPI is whether the target binary +arithmetic departs from the IEEE standard by flushing denormalized +numbers to 0. On systems that do this, the helper routines for +conversion to double-double format (when compiled with +Sudden_Underflow #defined) penalize the bottom of the exponent +range so that they return a nonzero result only when the least +significant bit of the less significant member of the pair of +double values returned can be expressed as a normalized double +value. An alternative would be to drop to 53-bit precision near +the bottom of the exponent range. To get correct rounding, this +would (in general) require two calls on strtodg (one specifying +126-bit arithmetic, then, if necessary, one specifying 53-bit +arithmetic). + +By default, the core routine strtodg and strtod set errno to ERANGE +if the result overflows to +Infinity or underflows to 0. Compile +these routines with NO_ERRNO #defined to inhibit errno assignments. + +Routine strtod is based on netlib's "dtoa.c from fp", and +(f = strtod(s,se)) is more efficient for some conversions than, say, +strtord(s,se,1,&f). Parts of strtod require true IEEE double +arithmetic with the default rounding mode (round-to-nearest) and, on +systems with IEEE extended-precision registers, double-precision +(53-bit) rounding precision. If the machine uses (the equivalent of) +Intel 80x87 arithmetic, the call + _control87(PC_53, MCW_PC); +does this with many compilers. Whether this or another call is +appropriate depends on the compiler; for this to work, it may be +necessary to #include "float.h" or another system-dependent header +file. + +The values returned for NaNs may be signaling NaNs on some systems, +since the rules for distinguishing signaling from quiet NaNs are +system-dependent. You can easily fix this by suitably modifying the +ULto* routines in strtor*.c. + +C99's hexadecimal floating-point constants are recognized by the +strto* routines (but this feature has not yet been heavily tested). +Compiling with NO_HEX_FP #defined disables this feature. + +The strto* routines do not (yet) recognize C99's NaN(...) syntax; the +strto* routines simply regard '(' as the first unprocessed input +character. + +For binary -> decimal conversions, I've provided just one family +of helper routines: + + g_ffmt + g_dfmt + g_ddfmt + g_xfmt + g_xLfmt + g_Qfmt + +which do a "%g" style conversion either to a specified number of decimal +places (if their ndig argument is positive), or to the shortest +decimal string that rounds to the given binary floating-point value +(if ndig <= 0). They write into a buffer supplied as an argument +and return either a pointer to the end of the string (a null character) +in the buffer, if the buffer was long enough, or 0. Other forms of +conversion are easily done with the help of gdtoa(), such as %e or %f +style and conversions with direction of rounding specified (so that, if +desired, the decimal value is either >= or <= the binary value). + +For an example of more general conversions based on dtoa(), see +netlib's "printf.c from ampl/solvers". + +For double-double -> decimal, g_ddfmt() assumes IEEE-like arithmetic +of precision max(126, #bits(input)) bits, where #bits(input) is the +number of mantissa bits needed to represent the sum of the two double +values in the input. + +The makefile creates a library, gdtoa.a. To use the helper +routines, a program only needs to include gdtoa.h. All the +source files for gdtoa.a include a more extensive gdtoaimp.h; +among other things, gdtoaimp.h has #defines that make "internal" +names end in _D2A. To make a "system" library, one could modify +these #defines to make the names start with __. + +Various comments about possible #defines appear in gdtoaimp.h, +but for most purposes, arith.h should set suitable #defines. + +Systems with preemptive scheduling of multiple threads require some +manual intervention. On such systems, it's necessary to compile +dmisc.c, dtoa.c gdota.c, and misc.c with MULTIPLE_THREADS #defined, +and to provide (or suitably #define) two locks, acquired by +ACQUIRE_DTOA_LOCK(n) and freed by FREE_DTOA_LOCK(n) for n = 0 or 1. +(The second lock, accessed in pow5mult, ensures lazy evaluation of +only one copy of high powers of 5; omitting this lock would introduce +a small probability of wasting memory, but would otherwise be harmless.) +Routines that call dtoa or gdtoa directly must also invoke freedtoa(s) +to free the value s returned by dtoa or gdtoa. It's OK to do so whether +or not MULTIPLE_THREADS is #defined, and the helper g_*fmt routines +listed above all do this indirectly (in gfmt_D2A(), which they all call). + +By default, there is a private pool of memory of length 2000 bytes +for intermediate quantities, and MALLOC (see gdtoaimp.h) is called only +if the private pool does not suffice. 2000 is large enough that MALLOC +is called only under very unusual circumstances (decimal -> binary +conversion of very long strings) for conversions to and from double +precision. For systems with preemptivaly scheduled multiple threads +or for conversions to extended or quad, it may be appropriate to +#define PRIVATE_MEM nnnn, where nnnn is a suitable value > 2000. +For extended and quad precisions, -DPRIVATE_MEM=20000 is probably +plenty even for many digits at the ends of the exponent range. +Use of the private pool avoids some overhead. + +Directory test provides some test routines. See its README. +I've also tested this stuff (except double double conversions) +with Vern Paxson's testbase program: see + + V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal + Conversion", manuscript, May 1991, + ftp://ftp.ee.lbl.gov/testbase-report.ps.Z . + +(The same ftp directory has source for testbase.) + +Some system-dependent additions to CFLAGS in the makefile: + + HU-UX: -Aa -Ae + OSF (DEC Unix): -ieee_with_no_inexact + SunOS 4.1x: -DKR_headers -DBad_float_h + +If you want to put this stuff into a shared library and your +operating system requires export lists for shared libraries, +the following would be an appropriate export list: + + dtoa + freedtoa + g_Qfmt + g_ddfmt + g_dfmt + g_ffmt + g_xLfmt + g_xfmt + gdtoa + strtoIQ + strtoId + strtoIdd + strtoIf + strtoIx + strtoIxL + strtod + strtodI + strtodg + strtof + strtopQ + strtopd + strtopdd + strtopf + strtopx + strtopxL + strtorQ + strtord + strtordd + strtorf + strtorx + strtorxL + +When time permits, I (dmg) hope to write in more detail about the +present conversion routines; for now, this README file must suffice. +Meanwhile, if you wish to write helper functions for other kinds of +IEEE-like arithmetic, some explanation of struct FPI and the bits +array may be helpful. Both gdtoa and strtodg operate on a bits array +described by FPI *fpi. The bits array is of type ULong, a 32-bit +unsigned integer type. Floating-point numbers have fpi->nbits bits, +with the least significant 32 bits in bits[0], the next 32 bits in +bits[1], etc. These numbers are regarded as integers multiplied by +2^e (i.e., 2 to the power of the exponent e), where e is the second +argument (be) to gdtoa and is stored in *exp by strtodg. The minimum +and maximum exponent values fpi->emin and fpi->emax for normalized +floating-point numbers reflect this arrangement. For example, the +P754 standard for binary IEEE arithmetic specifies doubles as having +53 bits, with normalized values of the form 1.xxxxx... times 2^(b-1023), +with 52 bits (the x's) and the biased exponent b represented explicitly; +b is an unsigned integer in the range 1 <= b <= 2046 for normalized +finite doubles, b = 0 for denormals, and b = 2047 for Infinities and NaNs. +To turn an IEEE double into the representation used by strtodg and gdtoa, +we multiply 1.xxxx... by 2^52 (to make it an integer) and reduce the +exponent e = (b-1023) by 52: + + fpi->emin = 1 - 1023 - 52 + fpi->emax = 1046 - 1023 - 52 + +In various wrappers for IEEE double, we actually write -53 + 1 rather +than -52, to emphasize that there are 53 bits including one implicit bit. +Field fpi->rounding indicates the desired rounding direction, with +possible values + FPI_Round_zero = toward 0, + FPI_Round_near = unbiased rounding -- the IEEE default, + FPI_Round_up = toward +Infinity, and + FPI_Round_down = toward -Infinity +given in gdtoa.h. + +Field fpi->sudden_underflow indicates whether strtodg should return +denormals or flush them to zero. Normal floating-point numbers have +bit fpi->nbits in the bits array on. Denormals have it off, with +exponent = fpi->emin. Strtodg provides distinct return values for normals +and denormals; see gdtoa.h. + +Compiling g__fmt.c, strtod.c, and strtodg.c with -DUSE_LOCALE causes +the decimal-point character to be taken from the current locale; otherwise +it is '.'. + +Please send comments to + + David M. Gay + dmg@acm.org diff --git a/src/contrib/gdtoa/arithchk.c b/src/contrib/gdtoa/arithchk.c new file mode 100644 index 0000000..59eaad7 --- /dev/null +++ b/src/contrib/gdtoa/arithchk.c @@ -0,0 +1,182 @@ +/**************************************************************** +Copyright (C) 1997, 1998 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. +****************************************************************/ + +/* Try to deduce arith.h from arithmetic properties. */ + +#include + + static int dalign; + typedef struct +Akind { + char *name; + int kind; + } Akind; + + static Akind +IEEE_8087 = { "IEEE_8087", 1 }, +IEEE_MC68k = { "IEEE_MC68k", 2 }, +IBM = { "IBM", 3 }, +VAX = { "VAX", 4 }, +CRAY = { "CRAY", 5}; + + static Akind * +Lcheck() +{ + union { + double d; + long L[2]; + } u; + struct { + double d; + long L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(long))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + + static Akind * +icheck() +{ + union { + double d; + int L[2]; + } u; + struct { + double d; + int L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(int))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + +char *emptyfmt = ""; /* avoid possible warning message with printf("") */ + + static Akind * +ccheck() +{ + union { + double d; + long L; + } u; + long Cray1; + + /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */ + Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 693716; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 115456; + u.d = 1e13; + if (u.L == Cray1) + return &CRAY; + return 0; + } + + static int +fzcheck() +{ + double a, b; + int i; + + a = 1.; + b = .1; + for(i = 155;; b *= b, i >>= 1) { + if (i & 1) { + a *= b; + if (i == 1) + break; + } + } + b = a * a; + return b == 0.; + } + +main() +{ + Akind *a = 0; + int Ldef = 0; + FILE *f; + +#ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */ + f = fopen("arith.h", "w"); + if (!f) { + printf("Cannot open arith.h\n"); + return 1; + } +#else + f = stdout; +#endif + + if (sizeof(double) == 2*sizeof(long)) + a = Lcheck(); + else if (sizeof(double) == 2*sizeof(int)) { + Ldef = 1; + a = icheck(); + } + else if (sizeof(double) == sizeof(long)) + a = ccheck(); + if (a) { + fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n", + a->name, a->kind); + if (Ldef) + fprintf(f, "#define Long int\n#define Intcast (int)(long)\n"); + if (dalign) + fprintf(f, "#define Double_Align\n"); + if (sizeof(char*) == 8) + fprintf(f, "#define X64_bit_pointers\n"); +#ifndef NO_LONG_LONG + if (sizeof(long long) < 8) +#endif + fprintf(f, "#define NO_LONG_LONG\n"); + if (a->kind <= 2 && fzcheck()) + fprintf(f, "#define Sudden_Underflow\n"); + return 0; + } + fprintf(f, "/* Unknown arithmetic */\n"); + return 1; + } diff --git a/src/contrib/gdtoa/dmisc.c b/src/contrib/gdtoa/dmisc.c new file mode 100644 index 0000000..14b5d7e --- /dev/null +++ b/src/contrib/gdtoa/dmisc.c @@ -0,0 +1,222 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#ifndef MULTIPLE_THREADS + char *dtoa_result; +#endif + + char * +#ifdef KR_headers +rv_alloc(i) int i; +#else +rv_alloc(int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + char * +#ifdef KR_headers +nrv_alloc(s, rve, n) char *s, **rve; int n; +#else +nrv_alloc(char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while((*t = *s++) !=0) + t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +#ifdef KR_headers +freedtoa(s) char *s; +#else +freedtoa(char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + + int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } diff --git a/src/contrib/gdtoa/dtoa.c b/src/contrib/gdtoa/dtoa.c new file mode 100644 index 0000000..20e2405 --- /dev/null +++ b/src/contrib/gdtoa/dtoa.c @@ -0,0 +1,759 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + char * +dtoa +#ifdef KR_headers + (d, mode, ndigits, decpt, sign, rve) + double d; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + double d2, ds, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); +#endif + return nrv_alloc("NaN", rve, 3); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (( j1 = -k )!=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (( j = b5 - m5 )!=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0) + i = 32 - i; +#else + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + ) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + trimzeros: + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } diff --git a/src/contrib/gdtoa/g_Qfmt.c b/src/contrib/gdtoa/g_Qfmt.c new file mode 100644 index 0000000..896b9d4 --- /dev/null +++ b/src/contrib/gdtoa/g_Qfmt.c @@ -0,0 +1,120 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + char* +#ifdef KR_headers +g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[4], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[3] = L[_0] & 0xffff; + bits[2] = L[_1]; + bits[1] = L[_2]; + bits[0] = L[_3]; + b = buf; + if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1] | bits[2] | bits[3]) + b = strcpy(b, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + bits[3] |= 0x10000; + } + else if (bits[0] | bits[1] | bits[2] | bits[3]) { + i = STRTOG_Denormal; + ex = 1; + } + else { +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 112; + mode = 2; + if (ndig <= 0) { + if (bufsize < 48) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/src/contrib/gdtoa/g__fmt.c b/src/contrib/gdtoa/g__fmt.c new file mode 100644 index 0000000..6274681 --- /dev/null +++ b/src/contrib/gdtoa/g__fmt.c @@ -0,0 +1,101 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + dmg@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + char * +#ifdef KR_headers +g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign; +#else +g__fmt(char *b, char *s, char *se, int decpt, ULong sign) +#endif +{ + int i, j, k; + char *s0 = s; +#ifdef USE_LOCALE + char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + if (sign) + *b++ = '-'; + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = decimalpoint; + while((*b = *s++) !=0) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } + else if (decpt <= 0) { + *b++ = decimalpoint; + for(; decpt < 0; decpt++) + *b++ = '0'; + while((*b = *s++) !=0) + b++; + } + else { + while((*b = *s++) !=0) { + b++; + if (--decpt == 0 && *s) + *b++ = decimalpoint; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + freedtoa(s0); + return b; + } diff --git a/src/contrib/gdtoa/g_ddfmt.c b/src/contrib/gdtoa/g_ddfmt.c new file mode 100644 index 0000000..7d214ba --- /dev/null +++ b/src/contrib/gdtoa/g_ddfmt.c @@ -0,0 +1,161 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" +#include + + char * +#ifdef KR_headers +g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize; +#else +g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) +#endif +{ + FPI fpi; + char *b, *s, *se; + ULong *L, bits0[4], *bits, *zx; + int bx, by, decpt, ex, ey, i, j, mode; + Bigint *x, *y, *z; + double ddx[2]; + + if (bufsize < 10 || bufsize < ndig + 8) + return 0; + + L = (ULong*)dd; + if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + nanret: + return strcp(buf, "NaN"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + if (L[2+_0] & 0xfffff || L[2+_1]) + goto nanret; + if ((L[_0] ^ L[2+_0]) & 0x80000000L) + goto nanret; /* Infinity - Infinity */ + } + infret: + b = buf; + if (L[_0] & 0x80000000L) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + L += 2; + if (L[_0] & 0xfffff || L[_1]) + goto nanret; + goto infret; + } + if (dd[0] + dd[1] == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & L[2+_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { + ddx[1] = dd[0]; + ddx[0] = dd[1]; + dd = ddx; + L = (ULong*)dd; + } + z = d2b(dd[0], &ex, &bx); + if (dd[1] == 0.) + goto no_y; + x = z; + y = d2b(dd[1], &ey, &by); + if ( (i = ex - ey) !=0) { + if (i > 0) { + x = lshift(x, i); + ex = ey; + } + else + y = lshift(y, -i); + } + if ((L[_0] ^ L[2+_0]) & 0x80000000L) { + z = diff(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1 - z->sign; + } + else { + z = sum(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1; + } + Bfree(x); + Bfree(y); + no_y: + bits = zx = z->x; + for(i = 0; !*zx; zx++) + i += 32; + i += lo0bits(zx); + if (i) { + rshift(z, i); + ex += i; + } + fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); + if (fpi.nbits < 106) { + fpi.nbits = 106; + if (j < 3) { + for(i = 0; i <= j; i++) + bits0[i] = bits[i]; + while(i < 4) + bits0[i++] = 0; + bits = bits0; + } + } + mode = 2; + if (ndig <= 0) { + if (bufsize < (int)(fpi.nbits * .301029995664) + 10) { + Bfree(z); + return 0; + } + mode = 0; + } + fpi.emin = 1-1023-53+1; + fpi.emax = 2046-1023-106+1; + fpi.rounding = FPI_Round_near; + fpi.sudden_underflow = 0; + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + b = g__fmt(buf, s, se, decpt, z->sign); + Bfree(z); + return b; + } diff --git a/src/contrib/gdtoa/g_dfmt.c b/src/contrib/gdtoa/g_dfmt.c new file mode 100644 index 0000000..1ade834 --- /dev/null +++ b/src/contrib/gdtoa/g_dfmt.c @@ -0,0 +1,95 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + char* +#ifdef KR_headers +g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize; +#else +g_dfmt(char *buf, double *d, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)d; + sign = L[_0] & 0x80000000L; + if ((L[_0] & 0x7ff00000) == 0x7ff00000) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[_1]; + bits[1] = L[_0] & 0xfffff; + if ( (ex = (L[_0] >> 20) & 0x7ff) !=0) + bits[1] |= 0x100000; + else + ex = 1; + ex -= 0x3ff + 52; + mode = 2; + if (ndig <= 0) { + if (bufsize < 25) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/src/contrib/gdtoa/g_ffmt.c b/src/contrib/gdtoa/g_ffmt.c new file mode 100644 index 0000000..851394a --- /dev/null +++ b/src/contrib/gdtoa/g_ffmt.c @@ -0,0 +1,94 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + char* +#ifdef KR_headers +g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize; +#else +g_ffmt(char *buf, float *f, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; + char *b, *s, *se; + ULong bits[1], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)f; + sign = L[0] & 0x80000000L; + if ((L[0] & 0x7f800000) == 0x7f800000) { + /* Infinity or NaN */ + if (L[0] & 0x7fffff) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (*f == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[0] & 0x7fffff; + if ( (ex = (L[0] >> 23) & 0xff) !=0) + bits[0] |= 0x800000; + else + ex = 1; + ex -= 0x7f + 23; + mode = 2; + if (ndig <= 0) { + if (bufsize < 16) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/src/contrib/gdtoa/g_xLfmt.c b/src/contrib/gdtoa/g_xLfmt.c new file mode 100644 index 0000000..fc17643 --- /dev/null +++ b/src/contrib/gdtoa/g_xLfmt.c @@ -0,0 +1,114 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + char* +#ifdef KR_headers +g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[1] = L[_1]; + bits[0] = L[_2]; + if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/src/contrib/gdtoa/g_xfmt.c b/src/contrib/gdtoa/g_xfmt.c new file mode 100644 index 0000000..1e2a381 --- /dev/null +++ b/src/contrib/gdtoa/g_xfmt.c @@ -0,0 +1,119 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + char* +#ifdef KR_headers +g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], sign; + UShort *L; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (UShort *)V; + sign = L[_0] & 0x8000; + bits[1] = (L[_1] << 16) | L[_2]; + bits[0] = (L[_3] << 16) | L[_4]; + if ( (ex = L[_0] & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/src/contrib/gdtoa/gdtoa.c b/src/contrib/gdtoa/gdtoa.c new file mode 100644 index 0000000..706c055 --- /dev/null +++ b/src/contrib/gdtoa/gdtoa.c @@ -0,0 +1,764 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + static Bigint * +#ifdef KR_headers +bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits; +#else +bitstob(ULong *bits, int nbits, int *bbits) +#endif +{ + int i, k; + Bigint *b; + ULong *be, *x, *x0; + + i = ULbits; + k = 0; + while(i < nbits) { + i <<= 1; + k++; + } +#ifndef Pack_32 + if (!k) + k = 1; +#endif + b = Balloc(k); + be = bits + ((nbits - 1) >> kshift); + x = x0 = b->x; + do { + *x++ = *bits & ALL_ON; +#ifdef Pack_16 + *x++ = (*bits >> 16) & ALL_ON; +#endif + } while(++bits <= be); + i = x - x0; + while(!x0[--i]) + if (!i) { + b->wds = 0; + *bbits = 0; + goto ret; + } + b->wds = i + 1; + *bbits = i*ULbits + 32 - hi0bits(b->x[i]); + ret: + return b; + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +gdtoa +#ifdef KR_headers + (fpi, be, bits, kindp, mode, ndigits, decpt, rve) + FPI *fpi; int be; ULong *bits; + int *kindp, mode, ndigits, *decpt; char **rve; +#else + (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) +#endif +{ + /* Arguments ndigits and decpt are similar to the second and third + arguments of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex; + int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits; + int rdir, s2, s5, spec_case, try_quick; + Long L; + Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; + double d, d2, ds, eps; + char *s, *s0; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + inex = 0; + kind = *kindp &= ~STRTOG_Inexact; + switch(kind & STRTOG_Retmask) { + case STRTOG_Zero: + goto ret_zero; + case STRTOG_Normal: + case STRTOG_Denormal: + break; + case STRTOG_Infinite: + *decpt = -32768; + return nrv_alloc("Infinity", rve, 8); + case STRTOG_NaN: + *decpt = -32768; + return nrv_alloc("NaN", rve, 3); + default: + return 0; + } + b = bitstob(bits, nbits = fpi->nbits, &bbits); + be0 = be; + if ( (i = trailz(b)) !=0) { + rshift(b, i); + be += i; + bbits -= i; + } + if (!b->wds) { + Bfree(b); + ret_zero: + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + dval(d) = b2d(b, &i); + i = be + bbits - 1; + word0(d) &= Frac_mask1; + word0(d) |= Exp_11; +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ +#ifdef IBM + i <<= 2; + i += j; +#endif + ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + + /* correct assumption about exponent range */ + if ((j = i) < 0) + j = -j; + if ((j -= 1077) > 0) + ds += j * 7e-17; + + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; +#ifdef IBM + j = be + bbits - 1; + if ( (j1 = j & 3) !=0) + dval(d) *= 1 << j1; + word0(d) += j << Exp_shift - 2 & Exp_mask; +#else + word0(d) += (be + bbits - 1) << Exp_shift; +#endif + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = (int)(nbits * .30103) + 3; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + + if ( (rdir = fpi->rounding - 1) !=0) { + if (rdir < 0) + rdir = 2; + if (kind & STRTOG_Neg) + rdir = 3 - rdir; + } + + /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ + + if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir +#ifndef IMPRECISE_INEXACT + && k == 0 +#endif + ) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = dval(d); +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + } + else { + ds = 1.; + if ( (j1 = -k) !=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)(dval(d)/ds); + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + if (ds - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + if ( (L = (Long)(dval(d)/ds)) !=0) + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (i == ilim) { + ds *= 0.5; + if (dval(d) > ds + dval(eps)) + goto bump_up; + else if (dval(d) < ds - dval(eps)) { + while(*--s == '0'){} + s++; + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = dval(d) / ds; + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (dval(d) == 0.) + break; + if (i == ilim) { + if (rdir) { + if (rdir == 1) + goto bump_up; + inex = STRTOG_Inexlo; + goto ret1; + } + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + else + inex = STRTOG_Inexlo; + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = nbits - bbits; + if (be - i++ < fpi->emin) + /* denormal */ + i = be - fpi->emin + 1; + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ( (j = b5 - m5) !=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2) { + if (bbits == 1 && be0 > fpi->emin + 1) { + /* The special case */ + b2++; + s2++; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0) + i = 32 - i; +#else + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + inex = STRTOG_Inexlo; + goto ret; + } + one_digit: + inex = STRTOG_Inexhi; + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, 1); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { + if (dig == '9') + goto round_9_up; + if (j <= 0) { + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + } + else { + dig++; + inex = STRTOG_Inexhi; + } + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && !mode +#ifndef ROUND_BIASED + && !(bits[0] & 1) +#endif + ) { + if (rdir && (b->wds > 1 || b->x[0])) { + if (rdir == 2) { + inex = STRTOG_Inexlo; + goto accept; + } + while (cmp(S,mhi) > 0) { + *s++ = dig; + mhi1 = multadd(mhi, 10, 0); + if (mlo == mhi) + mlo = mhi1; + mhi = mhi1; + b = multadd(b, 10, 0); + dig = quorem(b,S) + '0'; + } + if (dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + goto accept; + } + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + } + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + accept: + *s++ = dig; + goto ret; + } + if (j1 > 0 && rdir != 2) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + inex = STRTOG_Inexhi; + goto roundoff; + } + inex = STRTOG_Inexhi; + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + if (rdir) { + if (rdir == 2 || b->wds <= 1 && !b->x[0]) + goto chopzeros; + goto roundoff; + } + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + chopzeros: + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + while(*--s == '0'){} + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + *kindp |= inex; + return s0; + } diff --git a/src/contrib/gdtoa/gdtoa.h b/src/contrib/gdtoa/gdtoa.h new file mode 100644 index 0000000..62553f2 --- /dev/null +++ b/src/contrib/gdtoa/gdtoa.h @@ -0,0 +1,159 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#ifndef GDTOA_H_INCLUDED +#define GDTOA_H_INCLUDED + +#include "arith.h" + +#ifndef Long +#define Long long +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif +#ifndef UShort +typedef unsigned short UShort; +#endif + +#ifndef ANSI +#ifdef KR_headers +#define ANSI(x) () +#define Void /*nothing*/ +#else +#define ANSI(x) x +#define Void void +#endif +#endif /* ANSI */ + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif /* CONST */ + + enum { /* return values from strtodg */ + STRTOG_Zero = 0, + STRTOG_Normal = 1, + STRTOG_Denormal = 2, + STRTOG_Infinite = 3, + STRTOG_NaN = 4, + STRTOG_NaNbits = 5, + STRTOG_NoNumber = 6, + STRTOG_Retmask = 7, + + /* The following may be or-ed into one of the above values. */ + + STRTOG_Neg = 0x08, + STRTOG_Inexlo = 0x10, + STRTOG_Inexhi = 0x20, + STRTOG_Inexact = 0x30, + STRTOG_Underflow= 0x40, + STRTOG_Overflow = 0x80 + }; + + typedef struct +FPI { + int nbits; + int emin; + int emax; + int rounding; + int sudden_underflow; + } FPI; + +enum { /* FPI.rounding values: same as FLT_ROUNDS */ + FPI_Round_zero = 0, + FPI_Round_near = 1, + FPI_Round_up = 2, + FPI_Round_down = 3 + }; + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, + int *sign, char **rve)); +extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); +extern void freedtoa ANSI((char*)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); +extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); + +extern char* g_ddfmt ANSI((char*, double*, int, unsigned)); +extern char* g_dfmt ANSI((char*, double*, int, unsigned)); +extern char* g_ffmt ANSI((char*, float*, int, unsigned)); +extern char* g_Qfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xLfmt ANSI((char*, void*, int, unsigned)); + +extern int strtoId ANSI((CONST char*, char**, double*, double*)); +extern int strtoIdd ANSI((CONST char*, char**, double*, double*)); +extern int strtoIf ANSI((CONST char*, char**, float*, float*)); +extern int strtoIQ ANSI((CONST char*, char**, void*, void*)); +extern int strtoIx ANSI((CONST char*, char**, void*, void*)); +extern int strtoIxL ANSI((CONST char*, char**, void*, void*)); +extern int strtord ANSI((CONST char*, char**, int, double*)); +extern int strtordd ANSI((CONST char*, char**, int, double*)); +extern int strtorf ANSI((CONST char*, char**, int, float*)); +extern int strtorQ ANSI((CONST char*, char**, int, void*)); +extern int strtorx ANSI((CONST char*, char**, int, void*)); +extern int strtorxL ANSI((CONST char*, char**, int, void*)); +#if 1 +extern int strtodI ANSI((CONST char*, char**, double*)); +extern int strtopd ANSI((CONST char*, char**, double*)); +extern int strtopdd ANSI((CONST char*, char**, double*)); +extern int strtopf ANSI((CONST char*, char**, float*)); +extern int strtopQ ANSI((CONST char*, char**, void*)); +extern int strtopx ANSI((CONST char*, char**, void*)); +extern int strtopxL ANSI((CONST char*, char**, void*)); +#else +#define strtopd(s,se,x) strtord(s,se,1,x) +#define strtopdd(s,se,x) strtordd(s,se,1,x) +#define strtopf(s,se,x) strtorf(s,se,1,x) +#define strtopQ(s,se,x) strtorQ(s,se,1,x) +#define strtopx(s,se,x) strtorx(s,se,1,x) +#define strtopxL(s,se,x) strtorxL(s,se,1,x) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* GDTOA_H_INCLUDED */ diff --git a/src/contrib/gdtoa/gdtoaimp.h b/src/contrib/gdtoa/gdtoaimp.h new file mode 100644 index 0000000..7f3d70e --- /dev/null +++ b/src/contrib/gdtoa/gdtoaimp.h @@ -0,0 +1,692 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* $FreeBSD: src/contrib/gdtoa/gdtoaimp.h,v 1.7 2005/01/18 18:56:18 das Exp $ */ + +/* This is a variation on dtoa.c that converts arbitary binary + floating-point formats to and from decimal notation. It uses + double-precision arithmetic internally, so there are still + various #ifdefs that adapt the calculations to the native + double-precision arithmetic (any of IEEE, VAX D_floating, + or IBM mainframe arithmetic). + + Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. When converting IEEE double precision values, the + * longest string gdtoa can return is about 751 bytes long. For + * conversions by strtod of strings of 800 digits and all gdtoa + * conversions of IEEE doubles in single-threaded executions with + * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with + * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtodg also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the fraction bits of the resulting NaN; if there are two or + * more strings of hexadecimal digits, each string is assigned + * to the next available sequence of 32-bit words of fractions + * bits (starting with the most significant), right-aligned in + * each sequence. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define IMPRECISE_INEXACT if you do not care about the setting of + * the STRTOG_Inexact bits in the special case of doing IEEE double + * precision conversions (which could also be done by the strtog in + * dtoa.c). + * #define NO_HEX_FP to disable recognition of C9x's hexadecimal + * floating-point constants. + * #define -DNO_ERRNO to suppress setting errno (in strtod.c and + * strtodg.c). + * #define NO_STRING_H to use private versions of memcpy. + * On some K&R systems, it may also be necessary to + * #define DECLARE_SIZE_T in this case. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + */ + +#ifndef GDTOAIMP_H_INCLUDED +#define GDTOAIMP_H_INCLUDED +#include "gdtoa.h" + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "limits.h" +#include "stdlib.h" +#include "string.h" +#include "libc_private.h" + +#include "namespace.h" +#include +#include "un-namespace.h" + +#ifdef KR_headers +#define Char char +#else +#define Char void +#endif + +#ifdef MALLOC +extern Char *MALLOC ANSI((size_t)); +#else +#define MALLOC malloc +#endif + +#define INFNAN_CHECK +#define USE_LOCALE +#define Honor_FLT_ROUNDS + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#include "errno.h" +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#define DBL_MAX 1.7976931348623157e+308 +#endif + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#define n_bigtens 2 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +#endif /* Bad_float_h */ + +#ifdef IEEE_Arith +#define Scale_Bit 0x10 +#define n_bigtens 5 +#endif + +#ifdef IBM +#define n_bigtens 3 +#endif + +#ifdef VAX +#define n_bigtens 2 +#endif + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +#define dval(x) x +#ifdef IEEE_8087 +#define word0(x) ((ULong *)&x)[1] +#define word1(x) ((ULong *)&x)[0] +#else +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[1] +#endif +#else /* !YES_ALIAS */ +#ifdef IEEE_8087 +#define word0(x) ((U*)&x)->L[1] +#define word1(x) ((U*)&x)->L[0] +#else +#define word0(x) ((U*)&x)->L[0] +#define word1(x) ((U*)&x)->L[1] +#endif +#define dval(x) ((U*)&x)->d +#endif /* YES_ALIAS */ + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#else /* ifndef IEEE_Arith */ +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#undef Pack_16 +#ifndef Pack_32 +#define Pack_32 +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +#define Pack_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#define ALL_ON 0xffffffff +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#define ALL_ON 0xffff +#endif + +#define MULTIPLE_THREADS +extern pthread_mutex_t __gdtoa_locks[2]; +#define ACQUIRE_DTOA_LOCK(n) do { \ + if (__isthreaded) \ + _pthread_mutex_lock(&__gdtoa_locks[n]); \ +} while(0) +#define FREE_DTOA_LOCK(n) do { \ + if (__isthreaded) \ + _pthread_mutex_unlock(&__gdtoa_locks[n]); \ +} while(0) + +#define Kmax 15 + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + +#ifdef NO_STRING_H +#ifdef DECLARE_SIZE_T +typedef unsigned int size_t; +#endif +extern void memcpy_D2A ANSI((void*, const void*, size_t)); +#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#else /* !NO_STRING_H */ +#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#endif /* NO_STRING_H */ + +/* + * Paranoia: Protect exported symbols, including ones in files we don't + * compile right now. The standard strtof and strtod survive. + */ +#define dtoa __dtoa +#define gdtoa __gdtoa +#define freedtoa __freedtoa +#define strtodg __strtodg +#define g_ddfmt __g_ddfmt +#define g_dfmt __g_dfmt +#define g_ffmt __g_ffmt +#define g_Qfmt __g_Qfmt +#define g_xfmt __g_xfmt +#define g_xLfmt __g_xLfmt +#define strtoId __strtoId +#define strtoIdd __strtoIdd +#define strtoIf __strtoIf +#define strtoIQ __strtoIQ +#define strtoIx __strtoIx +#define strtoIxL __strtoIxL +#define strtord __strtord +#define strtordd __strtordd +#define strtorf __strtorf +#define strtorQ __strtorQ +#define strtorx __strtorx +#define strtorxL __strtorxL +#define strtodI __strtodI +#define strtopd __strtopd +#define strtopdd __strtopdd +#define strtopf __strtopf +#define strtopQ __strtopQ +#define strtopx __strtopx +#define strtopxL __strtopxL + +/* Protect gdtoa-internal symbols */ +#define Balloc __Balloc_D2A +#define Bfree __Bfree_D2A +#define ULtoQ __ULtoQ_D2A +#define ULtof __ULtof_D2A +#define ULtod __ULtod_D2A +#define ULtodd __ULtodd_D2A +#define ULtox __ULtox_D2A +#define ULtoxL __ULtoxL_D2A +#define any_on __any_on_D2A +#define b2d __b2d_D2A +#define bigtens __bigtens_D2A +#define cmp __cmp_D2A +#define copybits __copybits_D2A +#define d2b __d2b_D2A +#define decrement __decrement_D2A +#define diff __diff_D2A +#define dtoa_result __dtoa_result_D2A +#define g__fmt __g__fmt_D2A +#define gethex __gethex_D2A +#define hexdig __hexdig_D2A +#define hexdig_init_D2A __hexdig_init_D2A +#define hexnan __hexnan_D2A +#define hi0bits __hi0bits_D2A +#define i2b __i2b_D2A +#define increment __increment_D2A +#define lo0bits __lo0bits_D2A +#define lshift __lshift_D2A +#define match __match_D2A +#define mult __mult_D2A +#define multadd __multadd_D2A +#define nrv_alloc __nrv_alloc_D2A +#define pow5mult __pow5mult_D2A +#define quorem __quorem_D2A +#define ratio __ratio_D2A +#define rshift __rshift_D2A +#define rv_alloc __rv_alloc_D2A +#define s2b __s2b_D2A +#define set_ones __set_ones_D2A +#define strcp __strcp_D2A +#define strcp_D2A __strcp_D2A +#define strtoIg __strtoIg_D2A +#define sum __sum_D2A +#define tens __tens_D2A +#define tinytens __tinytens_D2A +#define tinytens __tinytens_D2A +#define trailz __trailz_D2A +#define ulp __ulp_D2A + + extern char *dtoa_result; + extern CONST double bigtens[], tens[], tinytens[]; + extern unsigned char hexdig[]; + + extern Bigint *Balloc ANSI((int)); + extern void Bfree ANSI((Bigint*)); + extern void ULtof ANSI((ULong*, ULong*, Long, int)); + extern void ULtod ANSI((ULong*, ULong*, Long, int)); + extern void ULtodd ANSI((ULong*, ULong*, Long, int)); + extern void ULtoQ ANSI((ULong*, ULong*, Long, int)); + extern void ULtox ANSI((UShort*, ULong*, Long, int)); + extern void ULtoxL ANSI((ULong*, ULong*, Long, int)); + extern ULong any_on ANSI((Bigint*, int)); + extern double b2d ANSI((Bigint*, int*)); + extern int cmp ANSI((Bigint*, Bigint*)); + extern void copybits ANSI((ULong*, int, Bigint*)); + extern Bigint *d2b ANSI((double, int*, int*)); + extern int decrement ANSI((Bigint*)); + extern Bigint *diff ANSI((Bigint*, Bigint*)); + extern char *dtoa ANSI((double d, int mode, int ndigits, + int *decpt, int *sign, char **rve)); + extern void freedtoa ANSI((char*)); + extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); + extern char *g__fmt ANSI((char*, char*, char*, int, ULong)); + extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int)); + extern void hexdig_init_D2A(Void); + extern int hexnan ANSI((CONST char**, FPI*, ULong*)); + extern int hi0bits ANSI((ULong)); + extern Bigint *i2b ANSI((int)); + extern Bigint *increment ANSI((Bigint*)); + extern int lo0bits ANSI((ULong*)); + extern Bigint *lshift ANSI((Bigint*, int)); + extern int match ANSI((CONST char**, char*)); + extern Bigint *mult ANSI((Bigint*, Bigint*)); + extern Bigint *multadd ANSI((Bigint*, int, int)); + extern char *nrv_alloc ANSI((char*, char **, int)); + extern Bigint *pow5mult ANSI((Bigint*, int)); + extern int quorem ANSI((Bigint*, Bigint*)); + extern double ratio ANSI((Bigint*, Bigint*)); + extern void rshift ANSI((Bigint*, int)); + extern char *rv_alloc ANSI((int)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *set_ones ANSI((Bigint*, int)); + extern char *strcp ANSI((char*, const char*)); + extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); + + extern int strtoId ANSI((CONST char *, char **, double *, double *)); + extern int strtoIdd ANSI((CONST char *, char **, double *, double *)); + extern int strtoIf ANSI((CONST char *, char **, float *, float *)); + extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); + extern int strtoIQ ANSI((CONST char *, char **, void *, void *)); + extern int strtoIx ANSI((CONST char *, char **, void *, void *)); + extern int strtoIxL ANSI((CONST char *, char **, void *, void *)); + extern double strtod ANSI((const char *s00, char **se)); + extern int strtopQ ANSI((CONST char *, char **, Void *)); + extern int strtopf ANSI((CONST char *, char **, float *)); + extern int strtopd ANSI((CONST char *, char **, double *)); + extern int strtopdd ANSI((CONST char *, char **, double *)); + extern int strtopx ANSI((CONST char *, char **, Void *)); + extern int strtopxL ANSI((CONST char *, char **, Void *)); + extern int strtord ANSI((CONST char *, char **, int, double *)); + extern int strtordd ANSI((CONST char *, char **, int, double *)); + extern int strtorf ANSI((CONST char *, char **, int, float *)); + extern int strtorQ ANSI((CONST char *, char **, int, void *)); + extern int strtorx ANSI((CONST char *, char **, int, void *)); + extern int strtorxL ANSI((CONST char *, char **, int, void *)); + extern Bigint *sum ANSI((Bigint*, Bigint*)); + extern int trailz ANSI((Bigint*)); + extern double ulp ANSI((double)); + +#ifdef __cplusplus +} +#endif + + +#ifdef IEEE_Arith +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#else +#define _0 1 +#define _1 0 +#endif +#else +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif +#endif /* INFNAN_CHECK */ + +#undef SI +#ifdef Sudden_Underflow +#define SI 1 +#else +#define SI 0 +#endif + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/src/contrib/gdtoa/gethex.c b/src/contrib/gdtoa/gethex.c new file mode 100644 index 0000000..fadb5de --- /dev/null +++ b/src/contrib/gdtoa/gethex.c @@ -0,0 +1,249 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + dmg@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + int +#ifdef KR_headers +gethex(sp, fpi, exp, bp, sign) + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; +#else +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + int esign, havedig, irv, k, n, nbits, up; + ULong L, lostbits, *x; + Long e, e1; +#ifdef USE_LOCALE + unsigned char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + + if (!hexdig['0']) + hexdig_init_D2A(); + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + if (!hexdig[*s]) { + if (*s == decimalpoint) { + decpt = ++s; + if (!hexdig[*s]) + goto ret0; + } + else { + ret0: + *sp = (char*)s; + return havedig ? STRTOG_Zero : STRTOG_NoNumber; + } + while(*s == '0') + s++; + havedig = 1; + if (!hexdig[*s]) + goto ret0; + s0 = s; + } + while(hexdig[*s]) + s++; + if (*s == decimalpoint && !decpt) { + decpt = ++s; + while(hexdig[*s]) + s++; + } + e = 0; + if (decpt) + e = -(((Long)(s-decpt)) << 2); + s1 = s; + switch(*s) { + case 'p': + case 'P': + esign = 0; + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) + e1 = 10*e1 + n - 0x10; + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + n = s1 - s0 - 1; + for(k = 0; n > 7; n >>= 1) + k++; + b = Balloc(k); + x = b->x; + n = 0; + L = 0; + while(s1 > s0) { + if (*--s1 == decimalpoint) + continue; + if (n == 32) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = 32*n - hi0bits(L); + nbits = fpi->nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 1 && any_on(b,k-1)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > fpi->emax) { + ovfl: + Bfree(b); + *bp = 0; + return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; + } + irv = STRTOG_Normal; + if (e < fpi->emin) { + irv = STRTOG_Denormal; + n = fpi->emin - e; + if (n >= nbits) { + switch (fpi->rounding) { + case FPI_Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) + goto one_bit; + break; + case FPI_Round_up: + if (!sign) + goto one_bit; + break; + case FPI_Round_down: + if (sign) { + one_bit: + *exp = fpi->emin; + x[0] = b->wds = 1; + *bp = b; + return STRTOG_Denormal | STRTOG_Inexhi + | STRTOG_Underflow; + } + } + Bfree(b); + *bp = 0; + return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = fpi->emin; + } + if (lostbits) { + up = 0; + switch(fpi->rounding) { + case FPI_Round_zero: + break; + case FPI_Round_near: + if (lostbits & 2 + && (lostbits & 1) | x[0] & 1) + up = 1; + break; + case FPI_Round_up: + up = 1 - sign; + break; + case FPI_Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k + || (n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n) { + rshift(b,1); + if (++e > fpi->emax) + goto ovfl; + } + irv |= STRTOG_Inexhi; + } + else + irv |= STRTOG_Inexlo; + } + *bp = b; + *exp = e; + return irv; + } diff --git a/src/contrib/gdtoa/gmisc.c b/src/contrib/gdtoa/gmisc.c new file mode 100644 index 0000000..1607f4b --- /dev/null +++ b/src/contrib/gdtoa/gmisc.c @@ -0,0 +1,92 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = ULbits - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & ALL_ON; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = x1 - b->x) == 0) + b->x[0] = 0; + } + + int +#ifdef KR_headers +trailz(b) Bigint *b; +#else +trailz(Bigint *b) +#endif +{ + ULong L, *x, *xe; + int n = 0; + + x = b->x; + xe = x + b->wds; + for(n = 0; x < xe && !*x; x++) + n += ULbits; + if (x < xe) { + L = *x; + n += lo0bits(&L); + } + return n; + } diff --git a/src/contrib/gdtoa/hd_init.c b/src/contrib/gdtoa/hd_init.c new file mode 100644 index 0000000..73afca1 --- /dev/null +++ b/src/contrib/gdtoa/hd_init.c @@ -0,0 +1,61 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + unsigned char hexdig[256]; + + static void +#ifdef KR_headers +htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; +#else +htinit(unsigned char *h, unsigned char *s, int inc) +#endif +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + void +hexdig_init_D2A(Void) +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } diff --git a/src/contrib/gdtoa/hexnan.c b/src/contrib/gdtoa/hexnan.c new file mode 100644 index 0000000..7a7e03a --- /dev/null +++ b/src/contrib/gdtoa/hexnan.c @@ -0,0 +1,137 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + static void +#ifdef KR_headers +L_shift(x, x1, i) ULong *x; ULong *x1; int i; +#else +L_shift(ULong *x, ULong *x1, int i) +#endif +{ + int j; + + i = 8 - i; + i <<= 2; + j = ULbits - i; + do { + *x |= x[1] << j; + x[1] >>= i; + } while(++x < x1); + } + + int +#ifdef KR_headers +hexnan(sp, fpi, x0) + CONST char **sp; FPI *fpi; ULong *x0; +#else +hexnan( CONST char **sp, FPI *fpi, ULong *x0) +#endif +{ + ULong c, h, *x, *x1, *xe; + CONST char *s; + int havedig, hd0, i, nbits; + + if (!hexdig['0']) + hexdig_init_D2A(); + nbits = fpi->nbits; + x = x0 + (nbits >> kshift); + if (nbits & kmask) + x++; + *--x = 0; + x1 = xe = x; + havedig = hd0 = i = 0; + s = *sp; + while(c = *(CONST unsigned char*)++s) { + if (!(h = hexdig[c])) { + if (c <= ' ') { + if (hd0 < havedig) { + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x <= x0) { + i = 8; + continue; + } + hd0 = havedig; + *--x = 0; + x1 = x; + i = 0; + } + continue; + } + if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + return STRTOG_NaN; + } + havedig++; + if (++i > 8) { + if (x <= x0) + continue; + i = 1; + *--x = 0; + } + *x = (*x << 4) | h & 0xf; + } + if (!havedig) + return STRTOG_NaN; + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x > x0) { + x1 = x0; + do *x1++ = *x++; + while(x <= xe); + do *x1++ = 0; + while(x1 <= xe); + } + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); + } + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; + if (x1 == x0) { + *x1 = 1; + break; + } + } + return STRTOG_NaNbits; + } diff --git a/src/contrib/gdtoa/makefile b/src/contrib/gdtoa/makefile new file mode 100644 index 0000000..3387a65 --- /dev/null +++ b/src/contrib/gdtoa/makefile @@ -0,0 +1,69 @@ +# /**************************************************************** +# Copyright (C) 1998 by Lucent Technologies +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that the copyright notice and this +# permission notice and warranty disclaimer appear in supporting +# documentation, and that the name of Lucent or any of its entities +# not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +# IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +# SPECIAL, 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. +# +# ****************************************************************/ + +.SUFFIXES: .c .o +CC = cc +CFLAGS = -g -DINFNAN_CHECK + +.c.o: + $(CC) -c $(CFLAGS) $*.c + +all: arith.h gdtoa.a + +arith.h: arithchk.c + $(CC) $(CFLAGS) arithchk.c || $(CC) -DNO_LONG_LONG $(CFLAGS) arithchk.c + ./a.out >arith.h + rm -f a.out arithchk.o + +gdtoa.a: dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c\ + g_xLfmt.c g_xfmt.c gdtoa.c gethex.c gmisc.c hd_init.c hexnan.c\ + misc.c smisc.c strtoIQ.c strtoId.c strtoIdd.c strtoIf.c strtoIg.c\ + strtoIx.c strtoIxL.c strtod.c strtodI.c strtodg.c strtof.c strtopQ.c\ + strtopd.c strtopdd.c strtopf.c strtopx.c strtopxL.c strtorQ.c\ + strtord.c strtordd.c strtorf.c strtorx.c strtorxL.c sum.c ulp.c + $(CC) -c $(CFLAGS) $? + x=`echo $? | sed 's/\.c/.o/g'` && ar ruv gdtoa.a $$x && rm $$x + ranlib gdtoa.a || true + +# If your system lacks ranlib, you do not need it. + +xs0 = README arithchk.c dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c\ + g_ffmt.c g_xLfmt.c g_xfmt.c gdtoa.c gdtoa.h gdtoaimp.h gethex.c\ + gmisc.c hd_init.c hexnan.c makefile misc.c smisc.c strtoIQ.c\ + strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c strtoIxL.c\ + strtod.c strtodI.c strtodg.c strtof.c strtopQ.c strtopd.c strtopdd.c\ + strtopf.c strtopx.c strtopxL.c strtorQ.c strtord.c strtordd.c\ + strtorf.c strtorx.c strtorxL.c sum.c ulp.c + +# "make xsum.out" to check for transmission errors; source for xsum is +# netlib's "xsum.c from f2c", e.g., +# ftp://netlib.bell-labs.com/netlib/f2c/xsum.c.gz + +xsum.out: xsum0.out $(xs0) + xsum $(xs0) >xsum1.out + cmp xsum0.out xsum1.out && mv xsum1.out xsum.out || diff xsum[01].out + +clean: + rm -f arith.h *.[ao] xsum.out xsum1.out diff --git a/src/contrib/gdtoa/misc.c b/src/contrib/gdtoa/misc.c new file mode 100644 index 0000000..5f5cbc2 --- /dev/null +++ b/src/contrib/gdtoa/misc.c @@ -0,0 +1,862 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + static Bigint *freelist[Kmax+1]; +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + + Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + if ( (rv = freelist[k]) !=0) { + freelist[k] = rv->next; + } + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + + int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x & 1) + return 32; + } + *y = x; + return k; + } + + Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + int +hi0bits +#ifdef KR_headers + (x) register ULong x; +#else + (register ULong x) +#endif +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & 0xffffffffUL; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ( (y = *xb & 0xffff) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ( (y = *xb >> 16) !=0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ( (i = k & 3) !=0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if ((p5 = p5s) == 0) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if ((p51 = p5->next) == 0) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> kshift; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= kmask) { +#ifdef Pack_32 + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) !=0) + ++n1; +#else + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; +#endif + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + d1 = y << (32-Ebits) + k | w >> Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> 32 - k; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#endif + return dval(d); + } +#undef d0 +#undef d1 + + Bigint * +d2b +#ifdef KR_headers + (d, e, bits) double d; int *e, *bits; +#else + (double d, int *e, int *bits) +#endif +{ + Bigint *b; + int de, i, k; + ULong *x, y, z; +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ( (de = (int)(d0 >> Exp_shift)) !=0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) { + x[0] = y | z << 32 - k; + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) !=0 ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#else + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 + }; +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#else +bigtens[] = { 1e16, 1e32 }; +CONST double tinytens[] = { 1e-16, 1e-32 }; +#endif +#endif + + CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + char * +#ifdef KR_headers +strcp_D2A(a, b) char *a; char *b; +#else +strcp_D2A(char *a, CONST char *b) +#endif +{ + while(*a = *b++) + a++; + return a; + } + +#ifdef NO_STRING_H + + Char * +#ifdef KR_headers +memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; +#else +memcpy_D2A(void *a1, void *b1, size_t len) +#endif +{ + register char *a = (char*)a1, *ae = a + len; + register char *b = (char*)b1, *a0 = a; + while(a < ae) + *a++ = *b++; + return a0; + } + +#endif /* NO_STRING_H */ diff --git a/src/contrib/gdtoa/smisc.c b/src/contrib/gdtoa/smisc.c new file mode 100644 index 0000000..e20e9da --- /dev/null +++ b/src/contrib/gdtoa/smisc.c @@ -0,0 +1,197 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +#else + (CONST char *s, int nd0, int nd, ULong y9) +#endif +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; + } + + double +ratio +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + double da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); + k = ka - kb + ULbits*(a->wds - b->wds); +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); + } + +#ifdef INFNAN_CHECK + + int +match +#ifdef KR_headers + (sp, t) char **sp, *t; +#else + (CONST char **sp, char *t) +#endif +{ + int c, d; + CONST char *s = *sp; + + while( (d = *t++) !=0) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } +#endif /* INFNAN_CHECK */ + + void +#ifdef KR_headers +copybits(c, n, b) ULong *c; int n; Bigint *b; +#else +copybits(ULong *c, int n, Bigint *b) +#endif +{ + ULong *ce, *x, *xe; +#ifdef Pack_16 + int nw, nw1; +#endif + + ce = c + ((n-1) >> kshift) + 1; + x = b->x; +#ifdef Pack_32 + xe = x + b->wds; + while(x < xe) + *c++ = *x++; +#else + nw = b->wds; + nw1 = nw & 1; + for(xe = x + (nw - nw1); x < xe; x += 2) + Storeinc(c, x[1], x[0]); + if (nw1) + *c++ = *x; +#endif + while(c < ce) + *c++ = 0; + } + + ULong +#ifdef KR_headers +any_on(b, k) Bigint *b; int k; +#else +any_on(Bigint *b, int k) +#endif +{ + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) + n = nwds; + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) + return 1; + } + x0 = x; + x += n; + while(x > x0) + if (*--x) + return 1; + return 0; + } diff --git a/src/contrib/gdtoa/strtoIQ.c b/src/contrib/gdtoa/strtoIQ.c new file mode 100644 index 0000000..0ce0420 --- /dev/null +++ b/src/contrib/gdtoa/strtoIQ.c @@ -0,0 +1,69 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIQ(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoQ(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoQ(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtoId.c b/src/contrib/gdtoa/strtoId.c new file mode 100644 index 0000000..f986e04 --- /dev/null +++ b/src/contrib/gdtoa/strtoId.c @@ -0,0 +1,66 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoId(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtoIdd.c b/src/contrib/gdtoa/strtoIdd.c new file mode 100644 index 0000000..9622c18 --- /dev/null +++ b/src/contrib/gdtoa/strtoIdd.c @@ -0,0 +1,72 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoIdd(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + ((ULong*)f1)[2] = ((ULong*)f0)[2]; + ((ULong*)f1)[3] = ((ULong*)f0)[3]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtoIf.c b/src/contrib/gdtoa/strtoIf.c new file mode 100644 index 0000000..c439ff5 --- /dev/null +++ b/src/contrib/gdtoa/strtoIf.c @@ -0,0 +1,64 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1; +#else +strtoIf(CONST char *s, char **sp, float *f0, float *f1) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(0); + B[0]->wds = 1; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else + *(ULong*)f1 = *(ULong*)f0; + return k; + } diff --git a/src/contrib/gdtoa/strtoIg.c b/src/contrib/gdtoa/strtoIg.c new file mode 100644 index 0000000..a766813 --- /dev/null +++ b/src/contrib/gdtoa/strtoIg.c @@ -0,0 +1,139 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; +#else +strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) +#endif +{ + Bigint *b, *b1; + int i, nb, nw, nw1, rv, rv1, swap; + unsigned int nb1, nb11; + Long e1; + + b = *B; + rv = strtodg(s00, se, fpi, exp, b->x); + if (!(rv & STRTOG_Inexact)) { + B[1] = 0; + return *rvp = rv; + } + e1 = exp[0]; + rv1 = rv ^ STRTOG_Inexact; + b1 = Balloc(b->k); + Bcopy(b1, b); + nb = fpi->nbits; + nb1 = nb & 31; + nb11 = (nb1 - 1) & 31; + nw = b->wds; + nw1 = nw - 1; + if (rv & STRTOG_Inexlo) { + swap = 0; + b1 = increment(b1); + if (fpi->sudden_underflow + && (rv & STRTOG_Retmask) == STRTOG_Zero) { + b1->x[0] = 0; + b1->x[nw1] = 1L << nb11; + rv1 += STRTOG_Normal - STRTOG_Zero; + rv1 &= ~STRTOG_Underflow; + goto swapcheck; + } + if (b1->wds > nw + || nb1 && b1->x[nw1] & 1L << nb1) { + if (++e1 > fpi->emax) + rv1 = STRTOG_Infinite | STRTOG_Inexhi; + rshift(b1, 1); + } + else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + if (b1->x[nw1] & 1L << nb11) { + rv1 += STRTOG_Normal - STRTOG_Denormal; + rv1 &= ~STRTOG_Underflow; + } + } + } + else { + swap = STRTOG_Neg; + if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { + b1 = set_ones(b1, nb); + e1 = fpi->emax; + rv1 = STRTOG_Normal | STRTOG_Inexlo; + goto swapcheck; + } + decrement(b1); + if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + for(i = nw1; !b1->x[i]; --i) + if (!i) { + rv1 = STRTOG_Zero | STRTOG_Inexlo; + break; + } + goto swapcheck; + } + if (!(b1->x[nw1] & 1L << nb11)) { + if (e1 == fpi->emin) { + if (fpi->sudden_underflow) + rv1 += STRTOG_Zero - STRTOG_Normal; + else + rv1 += STRTOG_Denormal - STRTOG_Normal; + rv1 |= STRTOG_Underflow; + } + else { + b1 = lshift(b1, 1); + b1->x[0] |= 1; + --e1; + } + } + } + swapcheck: + if (swap ^ (rv & STRTOG_Neg)) { + rvp[0] = rv1; + rvp[1] = rv; + B[0] = b1; + B[1] = b; + exp[1] = exp[0]; + exp[0] = e1; + } + else { + rvp[0] = rv; + rvp[1] = rv1; + B[1] = b1; + exp[1] = e1; + } + return rv; + } diff --git a/src/contrib/gdtoa/strtoIx.c b/src/contrib/gdtoa/strtoIx.c new file mode 100644 index 0000000..d699f04 --- /dev/null +++ b/src/contrib/gdtoa/strtoIx.c @@ -0,0 +1,70 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIx(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + UShort *L = (UShort *)a, *M = (UShort *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtox(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtox(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + M[4] = L[4]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtoIxL.c b/src/contrib/gdtoa/strtoIxL.c new file mode 100644 index 0000000..c579589 --- /dev/null +++ b/src/contrib/gdtoa/strtoIxL.c @@ -0,0 +1,68 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIxL(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoxL(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoxL(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtod.c b/src/contrib/gdtoa/strtod.c new file mode 100644 index 0000000..4913d50 --- /dev/null +++ b/src/contrib/gdtoa/strtod.c @@ -0,0 +1,966 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + dmg@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef IEEE_Arith +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#undef tinytens +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.e-256 + }; +#endif +#endif + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + double +strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif + + sign = nz0 = nz = 0; + dval(rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + { + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp; + ULong bits[2]; + switch(s[1]) { + case 'x': + case 'X': + switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) { + case STRTOG_NoNumber: + s = s00; + sign = 0; + case STRTOG_Zero: + break; + default: + if (bb) { + copybits(bits, fpi.nbits, bb); + Bfree(bb); + } + ULtod(((U*)&rv)->L, bits, exp, i); + } + goto ret; + } + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + ULong bits[2]; + static FPI fpinan = /* only 52 explicit bits */ + { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { +#ifndef No_Hex_NaN + if (*s == '(' /*)*/ + && hexnan(&s, &fpinan, bits) + == STRTOG_NaNbits) { + word0(rv) = 0x7ff00000 | bits[1]; + word1(rv) = bits[0]; + } + else { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; + } +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << j-32; + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { + undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); + } + diff --git a/src/contrib/gdtoa/strtodI.c b/src/contrib/gdtoa/strtodI.c new file mode 100644 index 0000000..163f363 --- /dev/null +++ b/src/contrib/gdtoa/strtodI.c @@ -0,0 +1,177 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + static double +#ifdef KR_headers +ulpdown(d) double *d; +#else +ulpdown(double *d) +#endif +{ + double u; + ULong *L = (ULong*)d; + + u = ulp(*d); + if (!(L[_1] | L[_0] & 0xfffff) + && (L[_0] & 0x7ff00000) > 0x00100000) + u *= 0.5; + return u; + } + + int +#ifdef KR_headers +strtodI(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtodI(CONST char *s, char **sp, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 1 }; +#else + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 }; +#endif + ULong bits[2], sign; + Long exp; + int j, k; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + k = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + sign = k & STRTOG_Neg ? 0x80000000L : 0; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; +#ifdef Sudden_Underflow + if (k & STRTOG_Inexact) { + if (sign) + u->L[_0] = 0x80100000L; + else + u->L[2+_0] = 0x100000L; + } + break; +#else + goto contain; +#endif + + case STRTOG_Denormal: + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + goto contain; + + case STRTOG_Normal: + u->L[_1] = bits[0]; + u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + contain: + j = k & STRTOG_Inexact; + if (sign) { + u->L[_0] |= sign; + j = STRTOG_Inexact - j; + } + switch(j) { + case STRTOG_Inexlo: +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[2+_0] = u->L[_0] + 0x3500000; + u->L[2+_1] = u->L[_1]; + u->d[1] += ulp(u->d[1]); + u->L[2+_0] -= 0x3500000; + if (!(u->L[2+_0] & 0x7ff00000)) { + u->L[2+_0] = sign; + u->L[2+_1] = 0; + } + } + else +#endif + u->d[1] = u->d[0] + ulp(u->d[0]); + break; + case STRTOG_Inexhi: + u->d[1] = u->d[0]; +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[_0] += 0x3500000; + u->d[0] -= ulpdown(u->d); + u->L[_0] -= 0x3500000; + if (!(u->L[_0] & 0x7ff00000)) { + u->L[_0] = sign; + u->L[_1] = 0; + } + } + else +#endif + u->d[0] -= ulpdown(u->d); + break; + default: + u->d[1] = u->d[0]; + } + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = sign | 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + if (k & STRTOG_Inexact) { + if (sign) { + u->L[2+_0] = 0xffefffffL; + u->L[2+_1] = 0xffffffffL; + } + else { + u->L[_0] = 0x7fefffffL; + u->L[_1] = 0xffffffffL; + } + } + break; + + case STRTOG_NaN: + u->L[_0] = u->L[2+_0] = 0x7fffffff | sign; + u->L[_1] = u->L[2+_1] = (ULong)-1; + break; + + case STRTOG_NaNbits: + u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1]; + u->L[_1] = u->L[2+_1] = bits[0]; + } + return k; + } diff --git a/src/contrib/gdtoa/strtodg.c b/src/contrib/gdtoa/strtodg.c new file mode 100644 index 0000000..bf30e33 --- /dev/null +++ b/src/contrib/gdtoa/strtodg.c @@ -0,0 +1,1001 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + dmg@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + static CONST int +fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, + 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, + 47, 49, 52 +#ifdef VAX + , 54, 56 +#endif + }; + + Bigint * +#ifdef KR_headers +increment(b) Bigint *b; +#else +increment(Bigint *b) +#endif +{ + ULong *x, *xe; + Bigint *b1; +#ifdef Pack_16 + ULong carry = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); +#else + do { + y = *x + carry; + carry = y >> 16; + *x++ = y & 0xffff; + if (!carry) + return b; + } while(x < xe); + if (carry) +#endif + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + + int +#ifdef KR_headers +decrement(b) Bigint *b; +#else +decrement(Bigint *b) +#endif +{ + ULong *x, *xe; +#ifdef Pack_16 + ULong borrow = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x) { + --*x; + break; + } + *x++ = 0xffffffffL; + } + while(x < xe); +#else + do { + y = *x - borrow; + borrow = (y & 0x10000) >> 16; + *x++ = y & 0xffff; + } while(borrow && x < xe); +#endif + return STRTOG_Inexlo; + } + + static int +#ifdef KR_headers +all_on(b, n) Bigint *b; int n; +#else +all_on(Bigint *b, int n) +#endif +{ + ULong *x, *xe; + + x = b->x; + xe = x + (n >> kshift); + while(x < xe) + if ((*x++ & ALL_ON) != ALL_ON) + return 0; + if (n &= kmask) + return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; + return 1; + } + + Bigint * +#ifdef KR_headers +set_ones(b, n) Bigint *b; int n; +#else +set_ones(Bigint *b, int n) +#endif +{ + int k; + ULong *x, *xe; + + k = (n + ((1 << kshift) - 1)) >> kshift; + if (b->k < k) { + Bfree(b); + b = Balloc(k); + } + k = n >> kshift; + if (n &= kmask) + k++; + b->wds = k; + x = b->x; + xe = x + k; + while(x < xe) + *x++ = ALL_ON; + if (n) + x[-1] >>= ULbits - n; + return b; + } + + static int +rvOK +#ifdef KR_headers + (d, fpi, exp, bits, exact, rd, irv) + double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; +#else + (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) +#endif +{ + Bigint *b; + ULong carry, inex, lostbits; + int bdif, e, j, k, k1, nb, rv; + + carry = rv = 0; + b = d2b(d, &e, &bdif); + bdif -= nb = fpi->nbits; + e += bdif; + if (bdif <= 0) { + if (exact) + goto trunc; + goto ret; + } + if (P == nb) { + if ( +#ifndef IMPRECISE_INEXACT + exact && +#endif + fpi->rounding == +#ifdef RND_PRODQUOT + FPI_Round_near +#else + Flt_Rounds +#endif + ) goto trunc; + goto ret; + } + switch(rd) { + case 1: + goto trunc; + case 2: + break; + default: /* round near */ + k = bdif - 1; + if (k < 0) + goto trunc; + if (!k) { + if (!exact) + goto ret; + if (b->x[0] & 2) + break; + goto trunc; + } + if (b->x[k>>kshift] & ((ULong)1 << (k & kmask))) + break; + goto trunc; + } + /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ + carry = 1; + trunc: + inex = lostbits = 0; + if (bdif > 0) { + if ( (lostbits = any_on(b, bdif)) !=0) + inex = STRTOG_Inexlo; + rshift(b, bdif); + if (carry) { + inex = STRTOG_Inexhi; + b = increment(b); + if ( (j = nb & kmask) !=0) + j = 32 - j; + if (hi0bits(b->x[b->wds - 1]) != j) { + if (!lostbits) + lostbits = b->x[0] & 1; + rshift(b, 1); + e++; + } + } + } + else if (bdif < 0) + b = lshift(b, -bdif); + if (e < fpi->emin) { + k = fpi->emin - e; + e = fpi->emin; + if (k > nb || fpi->sudden_underflow) { + b->wds = inex = 0; + *irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + k1 = k - 1; + if (k1 > 0 && !lostbits) + lostbits = any_on(b, k1); + if (!lostbits && !exact) + goto ret; + lostbits |= + carry = b->x[k1>>kshift] & (1 << (k1 & kmask)); + rshift(b, k); + *irv = STRTOG_Denormal; + if (carry) { + b = increment(b); + inex = STRTOG_Inexhi | STRTOG_Underflow; + } + else if (lostbits) + inex = STRTOG_Inexlo | STRTOG_Underflow; + } + } + else if (e > fpi->emax) { + e = fpi->emax + 1; + *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + b->wds = inex = 0; + } + *exp = e; + copybits(bits, nb, b); + *irv |= inex; + rv = 1; + ret: + Bfree(b); + return rv; + } + + static int +#ifdef KR_headers +mantbits(d) double d; +#else +mantbits(double d) +#endif +{ + ULong L; +#ifdef VAX + L = word1(d) << 16 | word1(d) >> 16; + if (L) +#else + if ( (L = word1(d)) !=0) +#endif + return P - lo0bits(&L); +#ifdef VAX + L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11; +#else + L = word0(d) | Exp_msk1; +#endif + return P - 32 - lo0bits(&L); + } + + int +strtodg +#ifdef KR_headers + (s00, se, fpi, exp, bits) + CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; +#else + (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) +#endif +{ + int abe, abits, asub; + int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2; + int c, denorm, dsign, e, e1, e2, emin, esign, finished, i, inex, irv; + int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; + int sudden_underflow; + CONST char *s, *s0, *s1; + double adj, adj0, rv, tol; + Long L; + ULong y, z; + Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; + + irv = STRTOG_Zero; + denorm = sign = nz0 = nz = 0; + dval(rv) = 0.; + rvb = 0; + nbits = fpi->nbits; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + sign = 0; + irv = STRTOG_NoNumber; + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + switch(s[1]) { + case 'x': + case 'X': + irv = gethex(&s, fpi, exp, &rvb, sign); + if (irv == STRTOG_NoNumber) { + s = s00; + sign = 0; + } + goto ret; + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + sudden_underflow = fpi->sudden_underflow; + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + irv = STRTOG_NoNumber; + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + irv = STRTOG_Infinite; + goto infnanexp; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + irv = STRTOG_NaN; + *exp = fpi->emax + 1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + irv = hexnan(&s, fpi, bits); +#endif + goto infnanexp; + } + } +#endif /* INFNAN_CHECK */ + irv = STRTOG_NoNumber; + s = s00; + } + goto ret; + } + + irv = STRTOG_Normal; + e1 = e -= nf; + rd = 0; + switch(fpi->rounding & 3) { + case FPI_Round_up: + rd = 2 - sign; + break; + case FPI_Round_zero: + rd = 1; + break; + case FPI_Round_down: + rd = 1 + sign; + } + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) + dval(rv) = tens[k - 9] * dval(rv) + z; + bd0 = 0; + if (nbits <= P && nd <= DBL_DIG) { + if (!e) { + if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + goto ret; + } + else if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + i = fivesbits[e] + mantbits(dval(rv)) <= P; + /* rv = */ rounded_product(dval(rv), tens[e]); + if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + goto ret; + e1 -= e; + goto rv_notOK; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e2 = e - i; + e1 -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + dval(adj) = dval(rv); + word0(adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(adj), tens[e2]); + if ((word0(adj) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto rv_notOK; + word0(adj) += P*Exp_msk1; + dval(rv) = dval(adj); +#else + /* rv = */ rounded_product(dval(rv), tens[e2]); +#endif + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e2; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e; + } +#endif + } + rv_notOK: + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + e2 = 0; + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + } + } + + rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rve += e2; + if ((j = rvbits - nbits) > 0) { + rshift(rvb, j); + rvbits = nbits; + rve += j; + } + bb0 = 0; /* trailing zero bits in rvb */ + e2 = rve + rvbits - nbits; + if (e2 > fpi->emax) { + rvb->wds = 0; + irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + infnanexp: + *exp = fpi->emax + 1; + goto ret; + } + rve1 = rve + rvbits - nbits; + if (e2 < (emin = fpi->emin)) { + denorm = 1; + j = rve - emin; + if (j > 0) { + rvb = lshift(rvb, j); + rvbits += j; + } + else if (j < 0) { + rvbits += j; + if (rvbits <= 0) { + if (rvbits < -1) { + ufl: + rvb->wds = 0; + rvb->x[0] = 0; + *exp = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + goto ret; + } + rvb->x[0] = rvb->wds = rvbits = 1; + } + else + rshift(rvb, -j); + } + rve = rve1 = emin; + if (sudden_underflow && e2 + 1 < emin) + goto ufl; + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = Balloc(rvb->k); + Bcopy(bb, rvb); + bbbits = rvbits - bb0; + bbe = rve + bb0; + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = nbits + 1 - bbbits; + i = bbe + bbbits - nbits; + if (i < emin) /* denormal */ + j += i - emin; + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + bb2 -= bb0; + if (bb2 > 0) + bb = lshift(bb, bb2); + else if (bb2 < 0) + rshift(bb, -bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + asub = 1; + inex = STRTOG_Inexhi; + delta = diff(bb, bd); + if (delta->wds <= 1 && !delta->x[0]) + break; + dsign = delta->sign; + delta->sign = finished = 0; + L = 0; + i = cmp(delta, bs); + if (rd && i <= 0) { + irv = STRTOG_Normal; + if ( (finished = dsign ^ (rd&1)) !=0) { + if (dsign != 0) { + irv |= STRTOG_Inexhi; + goto adj1; + } + irv |= STRTOG_Inexlo; + if (rve1 == emin) + goto adj1; + for(i = 0, j = nbits; j >= ULbits; + i++, j -= ULbits) { + if (rvb->x[i] & ALL_ON) + goto adj1; + } + if (j > 1 && lo0bits(rvb->x + i) < j - 1) + goto adj1; + rve = rve1 - 1; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; + break; + } + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + irv = dsign + ? STRTOG_Normal | STRTOG_Inexlo + : STRTOG_Normal | STRTOG_Inexhi; + if (dsign || bbbits > 1 || denorm || rve1 == emin) + break; + delta = lshift(delta,1); + if (cmp(delta, bs) > 0) { + irv = STRTOG_Normal | STRTOG_Inexlo; + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if (denorm && all_on(rvb, rvbits)) { + /*boundary case -- increment exponent*/ + rvb->wds = 1; + rvb->x[0] = 1; + rve = emin + nbits - (rvbits = 1); + irv = STRTOG_Normal | STRTOG_Inexhi; + denorm = 0; + break; + } + irv = STRTOG_Normal | STRTOG_Inexlo; + } + else if (bbbits == 1) { + irv = STRTOG_Normal; + drop_down: + /* boundary case -- decrement exponent */ + if (rve1 == emin) { + irv = STRTOG_Normal | STRTOG_Inexhi; + if (rvb->wds == 1 && rvb->x[0] == 1) + sudden_underflow = 1; + break; + } + rve -= nbits; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + else + irv = STRTOG_Normal | STRTOG_Inexhi; + if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + break; + if (dsign) { + rvb = increment(rvb); + if ( (j = rvbits >> kshift) !=0) + j = 32 - j; + if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift]) + != j) + rvbits++; + irv = STRTOG_Normal | STRTOG_Inexhi; + } + else { + if (bbbits == 1) + goto undfl; + decrement(rvb); + irv = STRTOG_Normal | STRTOG_Inexlo; + } + break; + } + if ((dval(adj) = ratio(delta, bs)) <= 2.) { + adj1: + inex = STRTOG_Inexlo; + if (dsign) { + asub = 0; + inex = STRTOG_Inexhi; + } + else if (denorm && bbbits <= 1) { + undfl: + rvb->wds = 0; + rve = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + break; + } + adj0 = dval(adj) = 1.; + } + else { + adj0 = dval(adj) *= 0.5; + if (dsign) { + asub = 0; + inex = STRTOG_Inexlo; + } + if (dval(adj) < 2147483647.) { + L = adj0; + adj0 -= L; + switch(rd) { + case 0: + if (adj0 >= .5) + goto inc_L; + break; + case 1: + if (asub && adj0 > 0.) + goto inc_L; + break; + case 2: + if (!asub && adj0 > 0.) { + inc_L: + L++; + inex = STRTOG_Inexact - inex; + } + } + dval(adj) = L; + } + } + y = rve + rvbits; + + /* adj *= ulp(dval(rv)); */ + /* if (asub) rv -= adj; else rv += adj; */ + + if (!denorm && rvbits < nbits) { + rvb = lshift(rvb, j = nbits - rvbits); + rve -= j; + rvbits = nbits; + } + ab = d2b(dval(adj), &abe, &abits); + if (abe < 0) + rshift(ab, -abe); + else if (abe > 0) + ab = lshift(ab, abe); + rvb0 = rvb; + if (asub) { + /* rv -= adj; */ + j = hi0bits(rvb->x[rvb->wds-1]); + rvb = diff(rvb, ab); + k = rvb0->wds - 1; + if (denorm) + /* do nothing */; + else if (rvb->wds <= k + || hi0bits( rvb->x[k]) > + hi0bits(rvb0->x[k])) { + /* unlikely; can only have lost 1 high bit */ + if (rve1 == emin) { + --rvbits; + denorm = 1; + } + else { + rvb = lshift(rvb, 1); + --rve; + --rve1; + L = finished = 0; + } + } + } + else { + rvb = sum(rvb, ab); + k = rvb->wds - 1; + if (k >= rvb0->wds + || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) { + if (denorm) { + if (++rvbits == nbits) + denorm = 0; + } + else { + rshift(rvb, 1); + rve++; + rve1++; + L = 0; + } + } + } + Bfree(ab); + Bfree(rvb0); + if (finished) + break; + + z = rve + rvbits; + if (y == z && L) { + /* Can we stop now? */ + tol = dval(adj) * 5e-16; /* > max rel error */ + dval(adj) = adj0 - .5; + if (dval(adj) < -tol) { + if (adj0 > tol) { + irv |= inex; + break; + } + } + else if (dval(adj) > tol && adj0 < 1. - tol) { + irv |= inex; + break; + } + } + bb0 = denorm ? 0 : trailz(rvb); + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + if (!denorm && rvbits < nbits) { + j = nbits - rvbits; + rvb = lshift(rvb, j); + rve -= j; + } + *exp = rve; + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (denorm) { + if (sudden_underflow) { + rvb->wds = 0; + irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + irv = (irv & ~STRTOG_Retmask) | + (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); + if (irv & STRTOG_Inexact) + irv |= STRTOG_Underflow; + } + } + if (se) + *se = (char *)s; + if (sign) + irv |= STRTOG_Neg; + if (rvb) { + copybits(bits, nbits, rvb); + Bfree(rvb); + } + return irv; + } diff --git a/src/contrib/gdtoa/strtof.c b/src/contrib/gdtoa/strtof.c new file mode 100644 index 0000000..bb283ae --- /dev/null +++ b/src/contrib/gdtoa/strtof.c @@ -0,0 +1,83 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 1 }; +#else + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; +#endif + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + u.L[0] = bits[0]; + break; + + case STRTOG_Infinite: + u.L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + u.L[0] = 0x7fffffff; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x80000000L; + return u.f; + } diff --git a/src/contrib/gdtoa/strtopQ.c b/src/contrib/gdtoa/strtopQ.c new file mode 100644 index 0000000..4bcc581 --- /dev/null +++ b/src/contrib/gdtoa/strtopQ.c @@ -0,0 +1,109 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + int +#ifdef KR_headers +strtopQ(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopQ(CONST char *s, char **sp, void *V) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 1 }; +#else + static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 }; +#endif + ULong bits[4]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fffffff; + L[_1] = L[_2] = L[_3] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/src/contrib/gdtoa/strtopd.c b/src/contrib/gdtoa/strtopd.c new file mode 100644 index 0000000..54e0838 --- /dev/null +++ b/src/contrib/gdtoa/strtopd.c @@ -0,0 +1,55 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopd(s, sp, d) char *s; char **sp; double *d; +#else +strtopd(CONST char *s, char **sp, double *d) +#endif +{ + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + + k = strtodg(s, sp, &fpi0, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtopdd.c b/src/contrib/gdtoa/strtopdd.c new file mode 100644 index 0000000..f71bced --- /dev/null +++ b/src/contrib/gdtoa/strtopdd.c @@ -0,0 +1,184 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtopdd(CONST char *s, char **sp, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + ULong bits[4]; + Long exp; + int i, j, rv; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + rv = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + switch(rv & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Normal: + u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; + u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & 0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & 0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + u->L[2] = u->L[3] = 0; + break; + } + u->L[2+_1] = bits[0]; + u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + u->L[2] = u->L[3] = 0; + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + } + if (i == 0) { + u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_1] = bits[1]; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0]; + break; + } + j = 32 - i; + u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + break; + + case STRTOG_NaN: + u->L[_0] = u->L[2+_0] = 0x7fffffff; + u->L[_1] = u->L[2+_1] = (ULong)-1; + } + if (rv & STRTOG_Neg) { + u->L[ _0] |= 0x80000000L; + u->L[2+_0] |= 0x80000000L; + } + return rv; + } diff --git a/src/contrib/gdtoa/strtopf.c b/src/contrib/gdtoa/strtopf.c new file mode 100644 index 0000000..c49fc96 --- /dev/null +++ b/src/contrib/gdtoa/strtopf.c @@ -0,0 +1,83 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtopf(s, sp, f) CONST char *s; char **sp; float *f; +#else +strtopf(CONST char *s, char **sp, float *f) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 1 }; +#else + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; +#endif + ULong bits[1], *L; + Long exp; + int k; + + k = strtodg(s, sp, &fpi, &exp, bits); + L = (ULong*)f; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = 0x7fffffff; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + return k; + } diff --git a/src/contrib/gdtoa/strtopx.c b/src/contrib/gdtoa/strtopx.c new file mode 100644 index 0000000..190b80f --- /dev/null +++ b/src/contrib/gdtoa/strtopx.c @@ -0,0 +1,106 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + int +#ifdef KR_headers +strtopx(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopx(CONST char *s, char **sp, void *V) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 1 }; +#else + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; +#endif + ULong bits[2]; + Long exp; + int k; + UShort *L = (UShort*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + L[_0] = exp + 0x3fff + 63; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = (UShort)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + return k; + } diff --git a/src/contrib/gdtoa/strtopxL.c b/src/contrib/gdtoa/strtopxL.c new file mode 100644 index 0000000..95fd3d5 --- /dev/null +++ b/src/contrib/gdtoa/strtopxL.c @@ -0,0 +1,100 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + int +#ifdef KR_headers +strtopxL(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopxL(CONST char *s, char **sp, void *V) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 1 }; +#else + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; +#endif + ULong bits[2]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_2] = bits[0]; + L[_1] = bits[1]; + L[_0] = (exp + 0x3fff + 63) << 16; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/src/contrib/gdtoa/strtorQ.c b/src/contrib/gdtoa/strtorQ.c new file mode 100644 index 0000000..63a7b6a --- /dev/null +++ b/src/contrib/gdtoa/strtorQ.c @@ -0,0 +1,121 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + void +#ifdef KR_headers +ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoQ(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fffffff; + L[_1] = L[_2] = L[_3] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorQ(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoQ((ULong*)L, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtord.c b/src/contrib/gdtoa/strtord.c new file mode 100644 index 0000000..12213f9 --- /dev/null +++ b/src/contrib/gdtoa/strtord.c @@ -0,0 +1,99 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtod(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = 0; + break; + + case STRTOG_Denormal: + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_1] = bits[0]; + L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Infinite: + L[_0] = 0x7ff00000; + L[_1] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fffffff; + L[_1] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d; +#else +strtord(CONST char *s, char **sp, int rounding, double *d) +#endif +{ + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtordd.c b/src/contrib/gdtoa/strtordd.c new file mode 100644 index 0000000..626a4d3 --- /dev/null +++ b/src/contrib/gdtoa/strtordd.c @@ -0,0 +1,205 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtodd(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + int i, j; + + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + L[2] = L[3] = 0; + break; + } + L[2+_1] = bits[0]; + L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + L[2] = L[3] = 0; + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + } + if (i == 0) { + L[_0] = bits[2] & 0xfffff | 33 << 20; + L[_1] = bits[1]; + L[2+_0] = 0; + L[2+_1] = bits[0]; + break; + } + j = 32 - i; + L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & ((ULong)1L << j) - 1; + break; + + case STRTOG_Infinite: + L[_0] = L[2+_0] = 0x7ff00000; + L[_1] = L[2+_1] = 0; + break; + + case STRTOG_NaN: + L[_0] = L[2+_0] = 0x7fffffff; + L[_1] = L[2+_1] = (ULong)-1; + break; + + case STRTOG_NaNbits: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 + | (ULong)0x7ff00000L; + L[2+_1] = bits[0]; + L[2+_0] = bits[1] | (ULong)0x7ff00000L; + } + if (k & STRTOG_Neg) { + L[_0] |= 0x80000000L; + L[2+_0] |= 0x80000000L; + } + } + + int +#ifdef KR_headers +strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd; +#else +strtordd(CONST char *s, char **sp, int rounding, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + FPI *fpi, fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtodd((ULong*)dd, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtorf.c b/src/contrib/gdtoa/strtorf.c new file mode 100644 index 0000000..ecd1c0b --- /dev/null +++ b/src/contrib/gdtoa/strtorf.c @@ -0,0 +1,95 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + void +#ifdef KR_headers +ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtof(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + *L = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = 0x7fffffff; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f; +#else +strtorf(CONST char *s, char **sp, int rounding, float *f) +#endif +{ + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[1]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtof((ULong*)f, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtorx.c b/src/contrib/gdtoa/strtorx.c new file mode 100644 index 0000000..0a81e95 --- /dev/null +++ b/src/contrib/gdtoa/strtorx.c @@ -0,0 +1,118 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + void +#ifdef KR_headers +ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k; +#else +ULtox(UShort *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + L[_0] = exp + 0x3fff + 63; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = (UShort)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + } + + int +#ifdef KR_headers +strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorx(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtox((UShort*)L, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/strtorxL.c b/src/contrib/gdtoa/strtorxL.c new file mode 100644 index 0000000..126cef8 --- /dev/null +++ b/src/contrib/gdtoa/strtorxL.c @@ -0,0 +1,112 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + void +#ifdef KR_headers +ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoxL(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_0] = (exp + 0x3fff + 63) << 16; + L[_1] = bits[1]; + L[_2] = bits[0]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorxL(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoxL((ULong*)L, bits, exp, k); + return k; + } diff --git a/src/contrib/gdtoa/sum.c b/src/contrib/gdtoa/sum.c new file mode 100644 index 0000000..1e1a4de --- /dev/null +++ b/src/contrib/gdtoa/sum.c @@ -0,0 +1,104 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + Bigint * +#ifdef KR_headers +sum(a, b) Bigint *a; Bigint *b; +#else +sum(Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + ULong carry, *xc, *xa, *xb, *xe, y; +#ifdef Pack_32 + ULong z; +#endif + + if (a->wds < b->wds) { + c = b; b = a; a = c; + } + c = Balloc(a->k); + c->wds = a->wds; + carry = 0; + xa = a->x; + xb = b->x; + xc = c->x; + xe = xc + b->wds; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) + (*xb & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + (*xb++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = (*xa & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ + *xb++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = *xa++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif + if (carry) { + if (c->wds == c->maxwds) { + b = Balloc(c->k + 1); + Bcopy(b, c); + Bfree(c); + c = b; + } + c->x[c->wds++] = 1; + } + return c; + } diff --git a/src/contrib/gdtoa/test/Q.ou0 b/src/contrib/gdtoa/test/Q.ou0 new file mode 100644 index 0000000..66c7e9b --- /dev/null +++ b/src/contrib/gdtoa/test/Q.ou0 @@ -0,0 +1,1180 @@ + +Input: 1.23 + +strtoQ consumes 4 bytes and returns 17 +with bits = #3fff3ae1 47ae147a e147ae14 7ae147ae +g_Qfmt(0) gives 4 bytes: "1.23" + +strtoIQ returns 17, consuming 4 bytes. +fI[0] = #3fff3ae1 47ae147a e147ae14 7ae147ae +fI[1] = #3fff3ae1 47ae147a e147ae14 7ae147af +fI[0] == strtod + + +Input: 1.23e+20 + +strtoQ consumes 8 bytes and returns 1 +with bits = #4041aabd f2145b43 0 0 +g_Qfmt(0) gives 8 bytes: "1.23e+20" + +strtoIQ returns 1, consuming 8 bytes. +fI[0] == fI[1] = #4041aabd f2145b43 0 0 + + +Input: 1.23e-20 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3fbcd0ae 4cf76753 9e4cbca ad934841 +g_Qfmt(0) gives 8 bytes: "1.23e-20" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3fbcd0ae 4cf76753 9e4cbca ad934841 +fI[1] = #3fbcd0ae 4cf76753 9e4cbca ad934842 +fI[0] == strtod + + +Input: 1.23456789 + +strtoQ consumes 10 bytes and returns 17 +with bits = #3fff3c0c a4283de1 b7eb6945 1304948f +g_Qfmt(0) gives 10 bytes: "1.23456789" + +strtoIQ returns 17, consuming 10 bytes. +fI[0] = #3fff3c0c a4283de1 b7eb6945 1304948f +fI[1] = #3fff3c0c a4283de1 b7eb6945 13049490 +fI[0] == strtod + + +Input: 1.23456589e+20 + +strtoQ consumes 14 bytes and returns 1 +with bits = #4041ac53 7a660b99 74000000 0 +g_Qfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIQ returns 1, consuming 14 bytes. +fI[0] == fI[1] = #4041ac53 7a660b99 74000000 0 + + +Input: 1.23e+30 + +strtoQ consumes 8 bytes and returns 1 +with bits = #4062f0cb 4e8fb79 4945600 0 +g_Qfmt(0) gives 8 bytes: "1.23e+30" + +strtoIQ returns 1, consuming 8 bytes. +fI[0] == fI[1] = #4062f0cb 4e8fb79 4945600 0 + + +Input: 1.23e-30 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3f9b8f28 66f5010a a9d63f9e d7e8ba14 +g_Qfmt(0) gives 8 bytes: "1.23e-30" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3f9b8f28 66f5010a a9d63f9e d7e8ba14 +fI[1] = #3f9b8f28 66f5010a a9d63f9e d7e8ba15 +fI[0] == strtod + + +Input: 1.23456789e-20 + +strtoQ consumes 14 bytes and returns 33 +with bits = #3fbcd268 1471e7ad a6a4a029 d86c1fa2 +g_Qfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIQ returns 33, consuming 14 bytes. +fI[0] = #3fbcd268 1471e7ad a6a4a029 d86c1fa1 +fI[1] = #3fbcd268 1471e7ad a6a4a029 d86c1fa2 +fI[1] == strtod + + +Input: 1.23456789e-30 + +strtoQ consumes 14 bytes and returns 17 +with bits = #3f9b90a3 e33bbd99 51f85855 5a6b19d4 +g_Qfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIQ returns 17, consuming 14 bytes. +fI[0] = #3f9b90a3 e33bbd99 51f85855 5a6b19d4 +fI[1] = #3f9b90a3 e33bbd99 51f85855 5a6b19d5 +fI[0] == strtod + + +Input: 1.234567890123456789 + +strtoQ consumes 20 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a4194 68dd175b +g_Qfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIQ returns 17, consuming 20 bytes. +fI[0] = #3fff3c0c a428c59f b71a4194 68dd175b +fI[1] = #3fff3c0c a428c59f b71a4194 68dd175c +fI[0] == strtod + + +Input: 1.23456789012345678901234567890123456789 + +strtoQ consumes 40 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a7be1 6b6b6d5b +g_Qfmt(0) gives 36 bytes: "1.2345678901234567890123456789012346" + +strtoIQ returns 17, consuming 40 bytes. +fI[0] = #3fff3c0c a428c59f b71a7be1 6b6b6d5b +fI[1] = #3fff3c0c a428c59f b71a7be1 6b6b6d5c +fI[0] == strtod + + +Input: 1.23e306 + +strtoQ consumes 8 bytes and returns 33 +with bits = #43f7c067 6cd1c61f 4daac5f1 e9fa3b55 +g_Qfmt(0) gives 9 bytes: "1.23e+306" + +strtoIQ returns 33, consuming 8 bytes. +fI[0] = #43f7c067 6cd1c61f 4daac5f1 e9fa3b54 +fI[1] = #43f7c067 6cd1c61f 4daac5f1 e9fa3b55 +fI[1] == strtod + + +Input: 1.23e-306 + +strtoQ consumes 9 bytes and returns 17 +with bits = #3c06ba3b 85da396e 7e496ab7 d233c3dd +g_Qfmt(0) gives 9 bytes: "1.23e-306" + +strtoIQ returns 17, consuming 9 bytes. +fI[0] = #3c06ba3b 85da396e 7e496ab7 d233c3dd +fI[1] = #3c06ba3b 85da396e 7e496ab7 d233c3de +fI[0] == strtod + + +Input: 1.23e-320 + +strtoQ consumes 9 bytes and returns 33 +with bits = #3bd83731 86e30898 7e33b2e8 355f847b +g_Qfmt(0) gives 9 bytes: "1.23e-320" + +strtoIQ returns 33, consuming 9 bytes. +fI[0] = #3bd83731 86e30898 7e33b2e8 355f847a +fI[1] = #3bd83731 86e30898 7e33b2e8 355f847b +fI[1] == strtod + + +Input: 1.23e-20 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3fbcd0ae 4cf76753 9e4cbca ad934841 +g_Qfmt(0) gives 8 bytes: "1.23e-20" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3fbcd0ae 4cf76753 9e4cbca ad934841 +fI[1] = #3fbcd0ae 4cf76753 9e4cbca ad934842 +fI[0] == strtod + + +Input: 1.23456789e307 + +strtoQ consumes 14 bytes and returns 17 +with bits = #43fb194b 14bdaecd bcea468c 902464cf +g_Qfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIQ returns 17, consuming 14 bytes. +fI[0] = #43fb194b 14bdaecd bcea468c 902464cf +fI[1] = #43fb194b 14bdaecd bcea468c 902464d0 +fI[0] == strtod + + +Input: 1.23456589e-307 + +strtoQ consumes 15 bytes and returns 17 +with bits = #3c036319 6bb9845f a6d234e3 39163574 +g_Qfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIQ returns 17, consuming 15 bytes. +fI[0] = #3c036319 6bb9845f a6d234e3 39163574 +fI[1] = #3c036319 6bb9845f a6d234e3 39163575 +fI[0] == strtod + + +Input: 1.234567890123456789 + +strtoQ consumes 20 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a4194 68dd175b +g_Qfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIQ returns 17, consuming 20 bytes. +fI[0] = #3fff3c0c a428c59f b71a4194 68dd175b +fI[1] = #3fff3c0c a428c59f b71a4194 68dd175c +fI[0] == strtod + + +Input: 1.234567890123456789e301 + +strtoQ consumes 24 bytes and returns 33 +with bits = #43e726f5 175f5641 3017ea80 763990ef +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIQ returns 33, consuming 24 bytes. +fI[0] = #43e726f5 175f5641 3017ea80 763990ee +fI[1] = #43e726f5 175f5641 3017ea80 763990ef +fI[1] == strtod + + +Input: 1.234567890123456789e-301 + +strtoQ consumes 25 bytes and returns 17 +with bits = #3c1752a6 4e34ba0d 35b19b04 3222fce5 +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIQ returns 17, consuming 25 bytes. +fI[0] = #3c1752a6 4e34ba0d 35b19b04 3222fce5 +fI[1] = #3c1752a6 4e34ba0d 35b19b04 3222fce6 +fI[0] == strtod + + +Input: 1.234567890123456789e-321 + +strtoQ consumes 25 bytes and returns 17 +with bits = #3bd4f3c2 3699d4db 99d1ea94 2fecd7de +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIQ returns 17, consuming 25 bytes. +fI[0] = #3bd4f3c2 3699d4db 99d1ea94 2fecd7de +fI[1] = #3bd4f3c2 3699d4db 99d1ea94 2fecd7df +fI[0] == strtod + + +Input: 1e23 + +strtoQ consumes 4 bytes and returns 1 +with bits = #404b52d0 2c7e14af 68000000 0 +g_Qfmt(0) gives 5 bytes: "1e+23" + +strtoIQ returns 1, consuming 4 bytes. +fI[0] == fI[1] = #404b52d0 2c7e14af 68000000 0 + + +Input: 1e310 + +strtoQ consumes 5 bytes and returns 33 +with bits = #4404bd03 c8140697 9e9ff00e fefd4cbd +g_Qfmt(0) gives 6 bytes: "1e+310" + +strtoIQ returns 33, consuming 5 bytes. +fI[0] = #4404bd03 c8140697 9e9ff00e fefd4cbc +fI[1] = #4404bd03 c8140697 9e9ff00e fefd4cbd +fI[1] == strtod + + +Input: 9.0259718793241475e-277 + +strtoQ consumes 23 bytes and returns 17 +with bits = #3c69ffff ffffffff f9ed5779 ac118fe1 +g_Qfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIQ returns 17, consuming 23 bytes. +fI[0] = #3c69ffff ffffffff f9ed5779 ac118fe1 +fI[1] = #3c69ffff ffffffff f9ed5779 ac118fe2 +fI[0] == strtod + + +Input: 9.025971879324147880346310405869e-277 + +strtoQ consumes 37 bytes and returns 33 +with bits = #3c6a0000 0 0 9a +g_Qfmt(0) gives 37 bytes: "9.025971879324147880346310405869e-277" + +strtoIQ returns 33, consuming 37 bytes. +fI[0] = #3c6a0000 0 0 99 +fI[1] = #3c6a0000 0 0 9a +fI[1] == strtod + + +Input: 9.025971879324147880346310405868e-277 + +strtoQ consumes 37 bytes and returns 17 +with bits = #3c69ffff ffffffff ffffffff fffffcb5 +g_Qfmt(0) gives 37 bytes: "9.025971879324147880346310405868e-277" + +strtoIQ returns 17, consuming 37 bytes. +fI[0] = #3c69ffff ffffffff ffffffff fffffcb5 +fI[1] = #3c69ffff ffffffff ffffffff fffffcb6 +fI[0] == strtod + + +Input: 2.2250738585072014e-308 + +strtoQ consumes 23 bytes and returns 33 +with bits = #3c010000 0 8c304c cf867de0 +g_Qfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIQ returns 33, consuming 23 bytes. +fI[0] = #3c010000 0 8c304c cf867ddf +fI[1] = #3c010000 0 8c304c cf867de0 +fI[1] == strtod + + +Input: 2.2250738585072013e-308 + +strtoQ consumes 23 bytes and returns 33 +with bits = #3c00ffff ffffffff fa9e4c4f 4c1e8a10 +g_Qfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIQ returns 33, consuming 23 bytes. +fI[0] = #3c00ffff ffffffff fa9e4c4f 4c1e8a0f +fI[1] = #3c00ffff ffffffff fa9e4c4f 4c1e8a10 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff1999 99999999 99999999 99999999 +g_Qfmt(0) gives 36 bytes: "1.0999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 +fI[1] = #3fff1999 99999999 99999999 9999999a +fI[0] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff1999 99999999 99999999 99999999 +g_Qfmt(0) gives 37 bytes: "-1.0999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a +fI[1] = #bfff1999 99999999 99999999 99999999 +fI[1] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 +fI[1] = #3fff3333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 +fI[1] = #bfff3333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff4ccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 36 bytes: "1.2999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd +fI[0] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff4ccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 37 bytes: "-1.2999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc +fI[1] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 +fI[1] = #3fff6666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 +fI[1] = #bfff6666 66666666 66666666 66666666 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff9999 99999999 99999999 99999999 +g_Qfmt(0) gives 36 bytes: "1.5999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 +fI[1] = #3fff9999 99999999 99999999 9999999a +fI[0] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff9999 99999999 99999999 99999999 +g_Qfmt(0) gives 37 bytes: "-1.5999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a +fI[1] = #bfff9999 99999999 99999999 99999999 +fI[1] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 +fI[1] = #3fffb333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 +fI[1] = #bfffb333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffcccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 36 bytes: "1.7999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc +fI[1] = #3fffcccc cccccccc cccccccc cccccccd +fI[0] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffcccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 37 bytes: "-1.7999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd +fI[1] = #bfffcccc cccccccc cccccccc cccccccc +fI[1] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 +fI[1] = #3fffe666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 +fI[1] = #bfffe666 66666666 66666666 66666666 +fI[1] == strtod + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff1999 99999999 99999999 9999999a +g_Qfmt(0) gives 3 bytes: "1.1" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 +fI[1] = #3fff1999 99999999 99999999 9999999a +fI[1] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff1999 99999999 99999999 9999999a +g_Qfmt(0) gives 4 bytes: "-1.1" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a +fI[1] = #bfff1999 99999999 99999999 99999999 +fI[0] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 +fI[1] = #3fff3333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 +fI[1] = #bfff3333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff4ccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 3 bytes: "1.3" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd +fI[1] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff4ccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 4 bytes: "-1.3" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc +fI[0] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 +fI[1] = #3fff6666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 +fI[1] = #bfff6666 66666666 66666666 66666666 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff9999 99999999 99999999 9999999a +g_Qfmt(0) gives 3 bytes: "1.6" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 +fI[1] = #3fff9999 99999999 99999999 9999999a +fI[1] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff9999 99999999 99999999 9999999a +g_Qfmt(0) gives 4 bytes: "-1.6" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a +fI[1] = #bfff9999 99999999 99999999 99999999 +fI[0] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 +fI[1] = #3fffb333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 +fI[1] = #bfffb333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffcccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 3 bytes: "1.8" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc +fI[1] = #3fffcccc cccccccc cccccccc cccccccd +fI[1] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffcccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 4 bytes: "-1.8" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd +fI[1] = #bfffcccc cccccccc cccccccc cccccccc +fI[0] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 +fI[1] = #3fffe666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 +fI[1] = #bfffe666 66666666 66666666 66666666 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff1999 99999999 99999999 9999999a +g_Qfmt(0) gives 3 bytes: "1.1" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 +fI[1] = #3fff1999 99999999 99999999 9999999a +fI[1] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff1999 99999999 99999999 99999999 +g_Qfmt(0) gives 37 bytes: "-1.0999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a +fI[1] = #bfff1999 99999999 99999999 99999999 +fI[1] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff3333 33333333 33333333 33333334 +g_Qfmt(0) gives 36 bytes: "1.2000000000000000000000000000000002" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 +fI[1] = #3fff3333 33333333 33333333 33333334 +fI[1] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 +fI[1] = #bfff3333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff4ccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 3 bytes: "1.3" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd +fI[1] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff4ccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 37 bytes: "-1.2999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc +fI[1] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff6666 66666666 66666666 66666667 +g_Qfmt(0) gives 36 bytes: "1.4000000000000000000000000000000001" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 +fI[1] = #3fff6666 66666666 66666666 66666667 +fI[1] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 +fI[1] = #bfff6666 66666666 66666666 66666666 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff9999 99999999 99999999 9999999a +g_Qfmt(0) gives 3 bytes: "1.6" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 +fI[1] = #3fff9999 99999999 99999999 9999999a +fI[1] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff9999 99999999 99999999 99999999 +g_Qfmt(0) gives 37 bytes: "-1.5999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a +fI[1] = #bfff9999 99999999 99999999 99999999 +fI[1] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffb333 33333333 33333333 33333334 +g_Qfmt(0) gives 36 bytes: "1.7000000000000000000000000000000002" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 +fI[1] = #3fffb333 33333333 33333333 33333334 +fI[1] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 +fI[1] = #bfffb333 33333333 33333333 33333333 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffcccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 3 bytes: "1.8" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc +fI[1] = #3fffcccc cccccccc cccccccc cccccccd +fI[1] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffcccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 37 bytes: "-1.7999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd +fI[1] = #bfffcccc cccccccc cccccccc cccccccc +fI[1] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffe666 66666666 66666666 66666667 +g_Qfmt(0) gives 36 bytes: "1.9000000000000000000000000000000001" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 +fI[1] = #3fffe666 66666666 66666666 66666667 +fI[1] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 +fI[1] = #bfffe666 66666666 66666666 66666666 +fI[1] == strtod + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff1999 99999999 99999999 99999999 +g_Qfmt(0) gives 36 bytes: "1.0999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 +fI[1] = #3fff1999 99999999 99999999 9999999a +fI[0] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff1999 99999999 99999999 9999999a +g_Qfmt(0) gives 4 bytes: "-1.1" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a +fI[1] = #bfff1999 99999999 99999999 99999999 +fI[0] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 +fI[1] = #3fff3333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff3333 33333333 33333333 33333334 +g_Qfmt(0) gives 37 bytes: "-1.2000000000000000000000000000000002" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 +fI[1] = #bfff3333 33333333 33333333 33333333 +fI[0] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff4ccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 36 bytes: "1.2999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd +fI[0] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff4ccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 4 bytes: "-1.3" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc +fI[0] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 +fI[1] = #3fff6666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff6666 66666666 66666666 66666667 +g_Qfmt(0) gives 37 bytes: "-1.4000000000000000000000000000000001" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 +fI[1] = #bfff6666 66666666 66666666 66666666 +fI[0] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff9999 99999999 99999999 99999999 +g_Qfmt(0) gives 36 bytes: "1.5999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 +fI[1] = #3fff9999 99999999 99999999 9999999a +fI[0] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff9999 99999999 99999999 9999999a +g_Qfmt(0) gives 4 bytes: "-1.6" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a +fI[1] = #bfff9999 99999999 99999999 99999999 +fI[0] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 +fI[1] = #3fffb333 33333333 33333333 33333334 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffb333 33333333 33333333 33333334 +g_Qfmt(0) gives 37 bytes: "-1.7000000000000000000000000000000002" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 +fI[1] = #bfffb333 33333333 33333333 33333333 +fI[0] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffcccc cccccccc cccccccc cccccccc +g_Qfmt(0) gives 36 bytes: "1.7999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc +fI[1] = #3fffcccc cccccccc cccccccc cccccccd +fI[0] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffcccc cccccccc cccccccc cccccccd +g_Qfmt(0) gives 4 bytes: "-1.8" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd +fI[1] = #bfffcccc cccccccc cccccccc cccccccc +fI[0] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 +fI[1] = #3fffe666 66666666 66666666 66666667 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffe666 66666666 66666666 66666667 +g_Qfmt(0) gives 37 bytes: "-1.9000000000000000000000000000000001" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 +fI[1] = #bfffe666 66666666 66666666 66666666 +fI[0] == strtod + diff --git a/src/contrib/gdtoa/test/Q.ou1 b/src/contrib/gdtoa/test/Q.ou1 new file mode 100644 index 0000000..cb2a23f --- /dev/null +++ b/src/contrib/gdtoa/test/Q.ou1 @@ -0,0 +1,1468 @@ + +Input: 1.23 + +strtoQ consumes 4 bytes and returns 17 +with bits = #3fff3ae1 47ae147a e147ae14 7ae147ae +printf("%.35Lg") gives 1.23 +g_Qfmt(0) gives 4 bytes: "1.23" + +strtoIQ returns 17, consuming 4 bytes. +fI[0] = #3fff3ae1 47ae147a e147ae14 7ae147ae += 1.23 +fI[1] = #3fff3ae1 47ae147a e147ae14 7ae147af += 1.2300000000000000000000000000000002 +fI[0] == strtod + + +Input: 1.23e+20 + +strtoQ consumes 8 bytes and returns 1 +with bits = #4041aabd f2145b43 0 0 +printf("%.35Lg") gives 123000000000000000000 +g_Qfmt(0) gives 8 bytes: "1.23e+20" + +strtoIQ returns 1, consuming 8 bytes. +fI[0] == fI[1] = #4041aabd f2145b43 0 0 += 123000000000000000000 + + +Input: 1.23e-20 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3fbcd0ae 4cf76753 9e4cbca ad934841 +printf("%.35Lg") gives 1.2299999999999999999999999999999999e-20 +g_Qfmt(0) gives 8 bytes: "1.23e-20" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3fbcd0ae 4cf76753 9e4cbca ad934841 += 1.2299999999999999999999999999999999e-20 +fI[1] = #3fbcd0ae 4cf76753 9e4cbca ad934842 += 1.2300000000000000000000000000000001e-20 +fI[0] == strtod + + +Input: 1.23456789 + +strtoQ consumes 10 bytes and returns 17 +with bits = #3fff3c0c a4283de1 b7eb6945 1304948f +printf("%.35Lg") gives 1.2345678899999999999999999999999999 +g_Qfmt(0) gives 10 bytes: "1.23456789" + +strtoIQ returns 17, consuming 10 bytes. +fI[0] = #3fff3c0c a4283de1 b7eb6945 1304948f += 1.2345678899999999999999999999999999 +fI[1] = #3fff3c0c a4283de1 b7eb6945 13049490 += 1.2345678900000000000000000000000001 +fI[0] == strtod + + +Input: 1.23456589e+20 + +strtoQ consumes 14 bytes and returns 1 +with bits = #4041ac53 7a660b99 74000000 0 +printf("%.35Lg") gives 123456589000000000000 +g_Qfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIQ returns 1, consuming 14 bytes. +fI[0] == fI[1] = #4041ac53 7a660b99 74000000 0 += 123456589000000000000 + + +Input: 1.23e+30 + +strtoQ consumes 8 bytes and returns 1 +with bits = #4062f0cb 4e8fb79 4945600 0 +printf("%.35Lg") gives 1230000000000000000000000000000 +g_Qfmt(0) gives 8 bytes: "1.23e+30" + +strtoIQ returns 1, consuming 8 bytes. +fI[0] == fI[1] = #4062f0cb 4e8fb79 4945600 0 += 1230000000000000000000000000000 + + +Input: 1.23e-30 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3f9b8f28 66f5010a a9d63f9e d7e8ba14 +printf("%.35Lg") gives 1.2299999999999999999999999999999999e-30 +g_Qfmt(0) gives 8 bytes: "1.23e-30" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3f9b8f28 66f5010a a9d63f9e d7e8ba14 += 1.2299999999999999999999999999999999e-30 +fI[1] = #3f9b8f28 66f5010a a9d63f9e d7e8ba15 += 1.2300000000000000000000000000000001e-30 +fI[0] == strtod + + +Input: 1.23456789e-20 + +strtoQ consumes 14 bytes and returns 33 +with bits = #3fbcd268 1471e7ad a6a4a029 d86c1fa2 +printf("%.35Lg") gives 1.2345678900000000000000000000000001e-20 +g_Qfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIQ returns 33, consuming 14 bytes. +fI[0] = #3fbcd268 1471e7ad a6a4a029 d86c1fa1 += 1.2345678899999999999999999999999999e-20 +fI[1] = #3fbcd268 1471e7ad a6a4a029 d86c1fa2 += 1.2345678900000000000000000000000001e-20 +fI[1] == strtod + + +Input: 1.23456789e-30 + +strtoQ consumes 14 bytes and returns 17 +with bits = #3f9b90a3 e33bbd99 51f85855 5a6b19d4 +printf("%.35Lg") gives 1.23456789e-30 +g_Qfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIQ returns 17, consuming 14 bytes. +fI[0] = #3f9b90a3 e33bbd99 51f85855 5a6b19d4 += 1.23456789e-30 +fI[1] = #3f9b90a3 e33bbd99 51f85855 5a6b19d5 += 1.2345678900000000000000000000000001e-30 +fI[0] == strtod + + +Input: 1.234567890123456789 + +strtoQ consumes 20 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a4194 68dd175b +printf("%.35Lg") gives 1.234567890123456789 +g_Qfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIQ returns 17, consuming 20 bytes. +fI[0] = #3fff3c0c a428c59f b71a4194 68dd175b += 1.234567890123456789 +fI[1] = #3fff3c0c a428c59f b71a4194 68dd175c += 1.2345678901234567890000000000000002 +fI[0] == strtod + + +Input: 1.23456789012345678901234567890123456789 + +strtoQ consumes 40 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a7be1 6b6b6d5b +printf("%.35Lg") gives 1.2345678901234567890123456789012346 +g_Qfmt(0) gives 36 bytes: "1.2345678901234567890123456789012346" + +strtoIQ returns 17, consuming 40 bytes. +fI[0] = #3fff3c0c a428c59f b71a7be1 6b6b6d5b += 1.2345678901234567890123456789012346 +fI[1] = #3fff3c0c a428c59f b71a7be1 6b6b6d5c += 1.2345678901234567890123456789012347 +fI[0] == strtod + + +Input: 1.23e306 + +strtoQ consumes 8 bytes and returns 33 +with bits = #43f7c067 6cd1c61f 4daac5f1 e9fa3b55 +printf("%.35Lg") gives 1.23e+306 +g_Qfmt(0) gives 9 bytes: "1.23e+306" + +strtoIQ returns 33, consuming 8 bytes. +fI[0] = #43f7c067 6cd1c61f 4daac5f1 e9fa3b54 += 1.2299999999999999999999999999999999e+306 +fI[1] = #43f7c067 6cd1c61f 4daac5f1 e9fa3b55 += 1.23e+306 +fI[1] == strtod + + +Input: 1.23e-306 + +strtoQ consumes 9 bytes and returns 17 +with bits = #3c06ba3b 85da396e 7e496ab7 d233c3dd +printf("%.35Lg") gives 1.23e-306 +g_Qfmt(0) gives 9 bytes: "1.23e-306" + +strtoIQ returns 17, consuming 9 bytes. +fI[0] = #3c06ba3b 85da396e 7e496ab7 d233c3dd += 1.23e-306 +fI[1] = #3c06ba3b 85da396e 7e496ab7 d233c3de += 1.2300000000000000000000000000000001e-306 +fI[0] == strtod + + +Input: 1.23e-320 + +strtoQ consumes 9 bytes and returns 33 +with bits = #3bd83731 86e30898 7e33b2e8 355f847b +printf("%.35Lg") gives 1.2300000000000000000000000000000001e-320 +g_Qfmt(0) gives 9 bytes: "1.23e-320" + +strtoIQ returns 33, consuming 9 bytes. +fI[0] = #3bd83731 86e30898 7e33b2e8 355f847a += 1.2299999999999999999999999999999999e-320 +fI[1] = #3bd83731 86e30898 7e33b2e8 355f847b += 1.2300000000000000000000000000000001e-320 +fI[1] == strtod + + +Input: 1.23e-20 + +strtoQ consumes 8 bytes and returns 17 +with bits = #3fbcd0ae 4cf76753 9e4cbca ad934841 +printf("%.35Lg") gives 1.2299999999999999999999999999999999e-20 +g_Qfmt(0) gives 8 bytes: "1.23e-20" + +strtoIQ returns 17, consuming 8 bytes. +fI[0] = #3fbcd0ae 4cf76753 9e4cbca ad934841 += 1.2299999999999999999999999999999999e-20 +fI[1] = #3fbcd0ae 4cf76753 9e4cbca ad934842 += 1.2300000000000000000000000000000001e-20 +fI[0] == strtod + + +Input: 1.23456789e307 + +strtoQ consumes 14 bytes and returns 17 +with bits = #43fb194b 14bdaecd bcea468c 902464cf +printf("%.35Lg") gives 1.2345678899999999999999999999999999e+307 +g_Qfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIQ returns 17, consuming 14 bytes. +fI[0] = #43fb194b 14bdaecd bcea468c 902464cf += 1.2345678899999999999999999999999999e+307 +fI[1] = #43fb194b 14bdaecd bcea468c 902464d0 += 1.2345678900000000000000000000000001e+307 +fI[0] == strtod + + +Input: 1.23456589e-307 + +strtoQ consumes 15 bytes and returns 17 +with bits = #3c036319 6bb9845f a6d234e3 39163574 +printf("%.35Lg") gives 1.23456589e-307 +g_Qfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIQ returns 17, consuming 15 bytes. +fI[0] = #3c036319 6bb9845f a6d234e3 39163574 += 1.23456589e-307 +fI[1] = #3c036319 6bb9845f a6d234e3 39163575 += 1.2345658900000000000000000000000002e-307 +fI[0] == strtod + + +Input: 1.234567890123456789 + +strtoQ consumes 20 bytes and returns 17 +with bits = #3fff3c0c a428c59f b71a4194 68dd175b +printf("%.35Lg") gives 1.234567890123456789 +g_Qfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIQ returns 17, consuming 20 bytes. +fI[0] = #3fff3c0c a428c59f b71a4194 68dd175b += 1.234567890123456789 +fI[1] = #3fff3c0c a428c59f b71a4194 68dd175c += 1.2345678901234567890000000000000002 +fI[0] == strtod + + +Input: 1.234567890123456789e301 + +strtoQ consumes 24 bytes and returns 33 +with bits = #43e726f5 175f5641 3017ea80 763990ef +printf("%.35Lg") gives 1.2345678901234567890000000000000001e+301 +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIQ returns 33, consuming 24 bytes. +fI[0] = #43e726f5 175f5641 3017ea80 763990ee += 1.2345678901234567889999999999999999e+301 +fI[1] = #43e726f5 175f5641 3017ea80 763990ef += 1.2345678901234567890000000000000001e+301 +fI[1] == strtod + + +Input: 1.234567890123456789e-301 + +strtoQ consumes 25 bytes and returns 17 +with bits = #3c1752a6 4e34ba0d 35b19b04 3222fce5 +printf("%.35Lg") gives 1.234567890123456789e-301 +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIQ returns 17, consuming 25 bytes. +fI[0] = #3c1752a6 4e34ba0d 35b19b04 3222fce5 += 1.234567890123456789e-301 +fI[1] = #3c1752a6 4e34ba0d 35b19b04 3222fce6 += 1.2345678901234567890000000000000002e-301 +fI[0] == strtod + + +Input: 1.234567890123456789e-321 + +strtoQ consumes 25 bytes and returns 17 +with bits = #3bd4f3c2 3699d4db 99d1ea94 2fecd7de +printf("%.35Lg") gives 1.234567890123456789e-321 +g_Qfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIQ returns 17, consuming 25 bytes. +fI[0] = #3bd4f3c2 3699d4db 99d1ea94 2fecd7de += 1.234567890123456789e-321 +fI[1] = #3bd4f3c2 3699d4db 99d1ea94 2fecd7df += 1.2345678901234567890000000000000001e-321 +fI[0] == strtod + + +Input: 1e23 + +strtoQ consumes 4 bytes and returns 1 +with bits = #404b52d0 2c7e14af 68000000 0 +printf("%.35Lg") gives 100000000000000000000000 +g_Qfmt(0) gives 5 bytes: "1e+23" + +strtoIQ returns 1, consuming 4 bytes. +fI[0] == fI[1] = #404b52d0 2c7e14af 68000000 0 += 100000000000000000000000 + + +Input: 1e310 + +strtoQ consumes 5 bytes and returns 33 +with bits = #4404bd03 c8140697 9e9ff00e fefd4cbd +printf("%.35Lg") gives 1e+310 +g_Qfmt(0) gives 6 bytes: "1e+310" + +strtoIQ returns 33, consuming 5 bytes. +fI[0] = #4404bd03 c8140697 9e9ff00e fefd4cbc += 9.9999999999999999999999999999999992e+309 +fI[1] = #4404bd03 c8140697 9e9ff00e fefd4cbd += 1e+310 +fI[1] == strtod + + +Input: 9.0259718793241475e-277 + +strtoQ consumes 23 bytes and returns 17 +with bits = #3c69ffff ffffffff f9ed5779 ac118fe1 +printf("%.35Lg") gives 9.0259718793241474999999999999999997e-277 +g_Qfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIQ returns 17, consuming 23 bytes. +fI[0] = #3c69ffff ffffffff f9ed5779 ac118fe1 += 9.0259718793241474999999999999999997e-277 +fI[1] = #3c69ffff ffffffff f9ed5779 ac118fe2 += 9.0259718793241475000000000000000006e-277 +fI[0] == strtod + + +Input: 9.025971879324147880346310405869e-277 + +strtoQ consumes 37 bytes and returns 33 +with bits = #3c6a0000 0 0 9a +printf("%.35Lg") gives 9.0259718793241478803463104058690004e-277 +g_Qfmt(0) gives 37 bytes: "9.025971879324147880346310405869e-277" + +strtoIQ returns 33, consuming 37 bytes. +fI[0] = #3c6a0000 0 0 99 += 9.0259718793241478803463104058689987e-277 +fI[1] = #3c6a0000 0 0 9a += 9.0259718793241478803463104058690004e-277 +fI[1] == strtod + + +Input: 9.025971879324147880346310405868e-277 + +strtoQ consumes 37 bytes and returns 17 +with bits = #3c69ffff ffffffff ffffffff fffffcb5 +printf("%.35Lg") gives 9.025971879324147880346310405868e-277 +g_Qfmt(0) gives 37 bytes: "9.025971879324147880346310405868e-277" + +strtoIQ returns 17, consuming 37 bytes. +fI[0] = #3c69ffff ffffffff ffffffff fffffcb5 += 9.025971879324147880346310405868e-277 +fI[1] = #3c69ffff ffffffff ffffffff fffffcb6 += 9.0259718793241478803463104058680009e-277 +fI[0] == strtod + + +Input: 2.2250738585072014e-308 + +strtoQ consumes 23 bytes and returns 33 +with bits = #3c010000 0 8c304c cf867de0 +printf("%.35Lg") gives 2.2250738585072014000000000000000001e-308 +g_Qfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIQ returns 33, consuming 23 bytes. +fI[0] = #3c010000 0 8c304c cf867ddf += 2.2250738585072013999999999999999997e-308 +fI[1] = #3c010000 0 8c304c cf867de0 += 2.2250738585072014000000000000000001e-308 +fI[1] == strtod + + +Input: 2.2250738585072013e-308 + +strtoQ consumes 23 bytes and returns 33 +with bits = #3c00ffff ffffffff fa9e4c4f 4c1e8a10 +printf("%.35Lg") gives 2.2250738585072013e-308 +g_Qfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIQ returns 33, consuming 23 bytes. +fI[0] = #3c00ffff ffffffff fa9e4c4f 4c1e8a0f += 2.2250738585072012999999999999999998e-308 +fI[1] = #3c00ffff ffffffff fa9e4c4f 4c1e8a10 += 2.2250738585072013e-308 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff1999 99999999 99999999 99999999 +printf("%.35Lg") gives 1.0999999999999999999999999999999999 +g_Qfmt(0) gives 36 bytes: "1.0999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 += 1.0999999999999999999999999999999999 +fI[1] = #3fff1999 99999999 99999999 9999999a += 1.1000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff1999 99999999 99999999 99999999 +printf("%.35Lg") gives -1.0999999999999999999999999999999999 +g_Qfmt(0) gives 37 bytes: "-1.0999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a += -1.1000000000000000000000000000000001 +fI[1] = #bfff1999 99999999 99999999 99999999 += -1.0999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.2 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 += 1.2 +fI[1] = #3fff3333 33333333 33333333 33333334 += 1.2000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.2 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 += -1.2000000000000000000000000000000002 +fI[1] = #bfff3333 33333333 33333333 33333333 += -1.2 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff4ccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives 1.2999999999999999999999999999999998 +g_Qfmt(0) gives 36 bytes: "1.2999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc += 1.2999999999999999999999999999999998 +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd += 1.3 +fI[0] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff4ccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives -1.2999999999999999999999999999999998 +g_Qfmt(0) gives 37 bytes: "-1.2999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd += -1.3 +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc += -1.2999999999999999999999999999999998 +fI[1] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.3999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 += 1.3999999999999999999999999999999999 +fI[1] = #3fff6666 66666666 66666666 66666667 += 1.4000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.3999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 += -1.4000000000000000000000000000000001 +fI[1] = #bfff6666 66666666 66666666 66666666 += -1.3999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +printf("%.35Lg") gives 1.5 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 += 1.5 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +printf("%.35Lg") gives -1.5 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 += -1.5 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff9999 99999999 99999999 99999999 +printf("%.35Lg") gives 1.5999999999999999999999999999999999 +g_Qfmt(0) gives 36 bytes: "1.5999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 += 1.5999999999999999999999999999999999 +fI[1] = #3fff9999 99999999 99999999 9999999a += 1.6000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff9999 99999999 99999999 99999999 +printf("%.35Lg") gives -1.5999999999999999999999999999999999 +g_Qfmt(0) gives 37 bytes: "-1.5999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a += -1.6000000000000000000000000000000001 +fI[1] = #bfff9999 99999999 99999999 99999999 += -1.5999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.7 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 += 1.7 +fI[1] = #3fffb333 33333333 33333333 33333334 += 1.7000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.7 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 += -1.7000000000000000000000000000000002 +fI[1] = #bfffb333 33333333 33333333 33333333 += -1.7 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffcccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives 1.7999999999999999999999999999999998 +g_Qfmt(0) gives 36 bytes: "1.7999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc += 1.7999999999999999999999999999999998 +fI[1] = #3fffcccc cccccccc cccccccc cccccccd += 1.8 +fI[0] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffcccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives -1.7999999999999999999999999999999998 +g_Qfmt(0) gives 37 bytes: "-1.7999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd += -1.8 +fI[1] = #bfffcccc cccccccc cccccccc cccccccc += -1.7999999999999999999999999999999998 +fI[1] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.8999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 += 1.8999999999999999999999999999999999 +fI[1] = #3fffe666 66666666 66666666 66666667 += 1.9000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.8999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 += -1.9000000000000000000000000000000001 +fI[1] = #bfffe666 66666666 66666666 66666666 += -1.8999999999999999999999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff1999 99999999 99999999 9999999a +printf("%.35Lg") gives 1.1000000000000000000000000000000001 +g_Qfmt(0) gives 3 bytes: "1.1" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 += 1.0999999999999999999999999999999999 +fI[1] = #3fff1999 99999999 99999999 9999999a += 1.1000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff1999 99999999 99999999 9999999a +printf("%.35Lg") gives -1.1000000000000000000000000000000001 +g_Qfmt(0) gives 4 bytes: "-1.1" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a += -1.1000000000000000000000000000000001 +fI[1] = #bfff1999 99999999 99999999 99999999 += -1.0999999999999999999999999999999999 +fI[0] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.2 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 += 1.2 +fI[1] = #3fff3333 33333333 33333333 33333334 += 1.2000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.2 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 += -1.2000000000000000000000000000000002 +fI[1] = #bfff3333 33333333 33333333 33333333 += -1.2 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff4ccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives 1.3 +g_Qfmt(0) gives 3 bytes: "1.3" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc += 1.2999999999999999999999999999999998 +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd += 1.3 +fI[1] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff4ccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives -1.3 +g_Qfmt(0) gives 4 bytes: "-1.3" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd += -1.3 +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc += -1.2999999999999999999999999999999998 +fI[0] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.3999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 += 1.3999999999999999999999999999999999 +fI[1] = #3fff6666 66666666 66666666 66666667 += 1.4000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.3999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 += -1.4000000000000000000000000000000001 +fI[1] = #bfff6666 66666666 66666666 66666666 += -1.3999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +printf("%.35Lg") gives 1.5 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 += 1.5 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +printf("%.35Lg") gives -1.5 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 += -1.5 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff9999 99999999 99999999 9999999a +printf("%.35Lg") gives 1.6000000000000000000000000000000001 +g_Qfmt(0) gives 3 bytes: "1.6" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 += 1.5999999999999999999999999999999999 +fI[1] = #3fff9999 99999999 99999999 9999999a += 1.6000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff9999 99999999 99999999 9999999a +printf("%.35Lg") gives -1.6000000000000000000000000000000001 +g_Qfmt(0) gives 4 bytes: "-1.6" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a += -1.6000000000000000000000000000000001 +fI[1] = #bfff9999 99999999 99999999 99999999 += -1.5999999999999999999999999999999999 +fI[0] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.7 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 += 1.7 +fI[1] = #3fffb333 33333333 33333333 33333334 += 1.7000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.7 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 += -1.7000000000000000000000000000000002 +fI[1] = #bfffb333 33333333 33333333 33333333 += -1.7 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffcccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives 1.8 +g_Qfmt(0) gives 3 bytes: "1.8" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc += 1.7999999999999999999999999999999998 +fI[1] = #3fffcccc cccccccc cccccccc cccccccd += 1.8 +fI[1] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffcccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives -1.8 +g_Qfmt(0) gives 4 bytes: "-1.8" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd += -1.8 +fI[1] = #bfffcccc cccccccc cccccccc cccccccc += -1.7999999999999999999999999999999998 +fI[0] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.8999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 += 1.8999999999999999999999999999999999 +fI[1] = #3fffe666 66666666 66666666 66666667 += 1.9000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.8999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 += -1.9000000000000000000000000000000001 +fI[1] = #bfffe666 66666666 66666666 66666666 += -1.8999999999999999999999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff1999 99999999 99999999 9999999a +printf("%.35Lg") gives 1.1000000000000000000000000000000001 +g_Qfmt(0) gives 3 bytes: "1.1" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 += 1.0999999999999999999999999999999999 +fI[1] = #3fff1999 99999999 99999999 9999999a += 1.1000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff1999 99999999 99999999 99999999 +printf("%.35Lg") gives -1.0999999999999999999999999999999999 +g_Qfmt(0) gives 37 bytes: "-1.0999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a += -1.1000000000000000000000000000000001 +fI[1] = #bfff1999 99999999 99999999 99999999 += -1.0999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff3333 33333333 33333333 33333334 +printf("%.35Lg") gives 1.2000000000000000000000000000000002 +g_Qfmt(0) gives 36 bytes: "1.2000000000000000000000000000000002" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 += 1.2 +fI[1] = #3fff3333 33333333 33333333 33333334 += 1.2000000000000000000000000000000002 +fI[1] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff3333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.2 +g_Qfmt(0) gives 4 bytes: "-1.2" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 += -1.2000000000000000000000000000000002 +fI[1] = #bfff3333 33333333 33333333 33333333 += -1.2 +fI[1] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff4ccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives 1.3 +g_Qfmt(0) gives 3 bytes: "1.3" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc += 1.2999999999999999999999999999999998 +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd += 1.3 +fI[1] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff4ccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives -1.2999999999999999999999999999999998 +g_Qfmt(0) gives 37 bytes: "-1.2999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd += -1.3 +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc += -1.2999999999999999999999999999999998 +fI[1] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff6666 66666666 66666666 66666667 +printf("%.35Lg") gives 1.4000000000000000000000000000000001 +g_Qfmt(0) gives 36 bytes: "1.4000000000000000000000000000000001" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 += 1.3999999999999999999999999999999999 +fI[1] = #3fff6666 66666666 66666666 66666667 += 1.4000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff6666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.3999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.4" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 += -1.4000000000000000000000000000000001 +fI[1] = #bfff6666 66666666 66666666 66666666 += -1.3999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +printf("%.35Lg") gives 1.5 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 += 1.5 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +printf("%.35Lg") gives -1.5 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 += -1.5 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fff9999 99999999 99999999 9999999a +printf("%.35Lg") gives 1.6000000000000000000000000000000001 +g_Qfmt(0) gives 3 bytes: "1.6" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 += 1.5999999999999999999999999999999999 +fI[1] = #3fff9999 99999999 99999999 9999999a += 1.6000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfff9999 99999999 99999999 99999999 +printf("%.35Lg") gives -1.5999999999999999999999999999999999 +g_Qfmt(0) gives 37 bytes: "-1.5999999999999999999999999999999999" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a += -1.6000000000000000000000000000000001 +fI[1] = #bfff9999 99999999 99999999 99999999 += -1.5999999999999999999999999999999999 +fI[1] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffb333 33333333 33333333 33333334 +printf("%.35Lg") gives 1.7000000000000000000000000000000002 +g_Qfmt(0) gives 36 bytes: "1.7000000000000000000000000000000002" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 += 1.7 +fI[1] = #3fffb333 33333333 33333333 33333334 += 1.7000000000000000000000000000000002 +fI[1] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffb333 33333333 33333333 33333333 +printf("%.35Lg") gives -1.7 +g_Qfmt(0) gives 4 bytes: "-1.7" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 += -1.7000000000000000000000000000000002 +fI[1] = #bfffb333 33333333 33333333 33333333 += -1.7 +fI[1] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffcccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives 1.8 +g_Qfmt(0) gives 3 bytes: "1.8" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc += 1.7999999999999999999999999999999998 +fI[1] = #3fffcccc cccccccc cccccccc cccccccd += 1.8 +fI[1] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffcccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives -1.7999999999999999999999999999999998 +g_Qfmt(0) gives 37 bytes: "-1.7999999999999999999999999999999998" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd += -1.8 +fI[1] = #bfffcccc cccccccc cccccccc cccccccc += -1.7999999999999999999999999999999998 +fI[1] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 33 +with bits = #3fffe666 66666666 66666666 66666667 +printf("%.35Lg") gives 1.9000000000000000000000000000000001 +g_Qfmt(0) gives 36 bytes: "1.9000000000000000000000000000000001" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 += 1.8999999999999999999999999999999999 +fI[1] = #3fffe666 66666666 66666666 66666667 += 1.9000000000000000000000000000000001 +fI[1] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 25 +with bits = #bfffe666 66666666 66666666 66666666 +printf("%.35Lg") gives -1.8999999999999999999999999999999999 +g_Qfmt(0) gives 4 bytes: "-1.9" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 += -1.9000000000000000000000000000000001 +fI[1] = #bfffe666 66666666 66666666 66666666 += -1.8999999999999999999999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff1999 99999999 99999999 99999999 +printf("%.35Lg") gives 1.0999999999999999999999999999999999 +g_Qfmt(0) gives 36 bytes: "1.0999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff1999 99999999 99999999 99999999 += 1.0999999999999999999999999999999999 +fI[1] = #3fff1999 99999999 99999999 9999999a += 1.1000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.1 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff1999 99999999 99999999 9999999a +printf("%.35Lg") gives -1.1000000000000000000000000000000001 +g_Qfmt(0) gives 4 bytes: "-1.1" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff1999 99999999 99999999 9999999a += -1.1000000000000000000000000000000001 +fI[1] = #bfff1999 99999999 99999999 99999999 += -1.0999999999999999999999999999999999 +fI[0] == strtod + + +Input: 1.2 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff3333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.2 +g_Qfmt(0) gives 3 bytes: "1.2" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff3333 33333333 33333333 33333333 += 1.2 +fI[1] = #3fff3333 33333333 33333333 33333334 += 1.2000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.2 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff3333 33333333 33333333 33333334 +printf("%.35Lg") gives -1.2000000000000000000000000000000002 +g_Qfmt(0) gives 37 bytes: "-1.2000000000000000000000000000000002" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff3333 33333333 33333333 33333334 += -1.2000000000000000000000000000000002 +fI[1] = #bfff3333 33333333 33333333 33333333 += -1.2 +fI[0] == strtod + + +Input: 1.3 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff4ccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives 1.2999999999999999999999999999999998 +g_Qfmt(0) gives 36 bytes: "1.2999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff4ccc cccccccc cccccccc cccccccc += 1.2999999999999999999999999999999998 +fI[1] = #3fff4ccc cccccccc cccccccc cccccccd += 1.3 +fI[0] == strtod + + +Input: -1.3 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff4ccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives -1.3 +g_Qfmt(0) gives 4 bytes: "-1.3" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff4ccc cccccccc cccccccc cccccccd += -1.3 +fI[1] = #bfff4ccc cccccccc cccccccc cccccccc += -1.2999999999999999999999999999999998 +fI[0] == strtod + + +Input: 1.4 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff6666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.3999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.4" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fff6666 66666666 66666666 66666666 += 1.3999999999999999999999999999999999 +fI[1] = #3fff6666 66666666 66666666 66666667 += 1.4000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.4 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff6666 66666666 66666666 66666667 +printf("%.35Lg") gives -1.4000000000000000000000000000000001 +g_Qfmt(0) gives 37 bytes: "-1.4000000000000000000000000000000001" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfff6666 66666666 66666666 66666667 += -1.4000000000000000000000000000000001 +fI[1] = #bfff6666 66666666 66666666 66666666 += -1.3999999999999999999999999999999999 +fI[0] == strtod + + +Input: 1.5 + +strtoQ consumes 3 bytes and returns 1 +with bits = #3fff8000 0 0 0 +printf("%.35Lg") gives 1.5 +g_Qfmt(0) gives 3 bytes: "1.5" + +strtoIQ returns 1, consuming 3 bytes. +fI[0] == fI[1] = #3fff8000 0 0 0 += 1.5 + + +Input: -1.5 + +strtoQ consumes 4 bytes and returns 9 +with bits = #bfff8000 0 0 0 +printf("%.35Lg") gives -1.5 +g_Qfmt(0) gives 4 bytes: "-1.5" + +strtoIQ returns 9, consuming 4 bytes. +fI[0] == fI[1] = #bfff8000 0 0 0 += -1.5 + + +Input: 1.6 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fff9999 99999999 99999999 99999999 +printf("%.35Lg") gives 1.5999999999999999999999999999999999 +g_Qfmt(0) gives 36 bytes: "1.5999999999999999999999999999999999" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fff9999 99999999 99999999 99999999 += 1.5999999999999999999999999999999999 +fI[1] = #3fff9999 99999999 99999999 9999999a += 1.6000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.6 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfff9999 99999999 99999999 9999999a +printf("%.35Lg") gives -1.6000000000000000000000000000000001 +g_Qfmt(0) gives 4 bytes: "-1.6" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfff9999 99999999 99999999 9999999a += -1.6000000000000000000000000000000001 +fI[1] = #bfff9999 99999999 99999999 99999999 += -1.5999999999999999999999999999999999 +fI[0] == strtod + + +Input: 1.7 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffb333 33333333 33333333 33333333 +printf("%.35Lg") gives 1.7 +g_Qfmt(0) gives 3 bytes: "1.7" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffb333 33333333 33333333 33333333 += 1.7 +fI[1] = #3fffb333 33333333 33333333 33333334 += 1.7000000000000000000000000000000002 +fI[0] == strtod + + +Input: -1.7 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffb333 33333333 33333333 33333334 +printf("%.35Lg") gives -1.7000000000000000000000000000000002 +g_Qfmt(0) gives 37 bytes: "-1.7000000000000000000000000000000002" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffb333 33333333 33333333 33333334 += -1.7000000000000000000000000000000002 +fI[1] = #bfffb333 33333333 33333333 33333333 += -1.7 +fI[0] == strtod + + +Input: 1.8 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffcccc cccccccc cccccccc cccccccc +printf("%.35Lg") gives 1.7999999999999999999999999999999998 +g_Qfmt(0) gives 36 bytes: "1.7999999999999999999999999999999998" + +strtoIQ returns 33, consuming 3 bytes. +fI[0] = #3fffcccc cccccccc cccccccc cccccccc += 1.7999999999999999999999999999999998 +fI[1] = #3fffcccc cccccccc cccccccc cccccccd += 1.8 +fI[0] == strtod + + +Input: -1.8 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffcccc cccccccc cccccccc cccccccd +printf("%.35Lg") gives -1.8 +g_Qfmt(0) gives 4 bytes: "-1.8" + +strtoIQ returns 41, consuming 4 bytes. +fI[0] = #bfffcccc cccccccc cccccccc cccccccd += -1.8 +fI[1] = #bfffcccc cccccccc cccccccc cccccccc += -1.7999999999999999999999999999999998 +fI[0] == strtod + + +Input: 1.9 + +strtoQ consumes 3 bytes and returns 17 +with bits = #3fffe666 66666666 66666666 66666666 +printf("%.35Lg") gives 1.8999999999999999999999999999999999 +g_Qfmt(0) gives 3 bytes: "1.9" + +strtoIQ returns 17, consuming 3 bytes. +fI[0] = #3fffe666 66666666 66666666 66666666 += 1.8999999999999999999999999999999999 +fI[1] = #3fffe666 66666666 66666666 66666667 += 1.9000000000000000000000000000000001 +fI[0] == strtod + + +Input: -1.9 + +strtoQ consumes 4 bytes and returns 41 +with bits = #bfffe666 66666666 66666666 66666667 +printf("%.35Lg") gives -1.9000000000000000000000000000000001 +g_Qfmt(0) gives 37 bytes: "-1.9000000000000000000000000000000001" + +strtoIQ returns 25, consuming 4 bytes. +fI[0] = #bfffe666 66666666 66666666 66666667 += -1.9000000000000000000000000000000001 +fI[1] = #bfffe666 66666666 66666666 66666666 += -1.8999999999999999999999999999999999 +fI[0] == strtod + diff --git a/src/contrib/gdtoa/test/Qtest.c b/src/contrib/gdtoa/test/Qtest.c new file mode 100644 index 0000000..14e5de7 --- /dev/null +++ b/src/contrib/gdtoa/test/Qtest.c @@ -0,0 +1,170 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_Qfmt, strtoIQ, strtopQ, and strtorQ. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex0 hex1 hex2 hex3 + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex0 is a string of <= 8 Hex digits for the most significant + * word of the number, hex1 is a similar string for the next + * word, etc., and ndig is a parameters to g_Qfmt. + */ + +#include "gdtoa.h" +#include +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[2048]; +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + +#define U (unsigned long) + + int +main(Void) +{ + char *s, *se, *se1; + int i, dItry, ndig = 0, r = 1; + union { long double d; ULong bits[4]; } u, v[2]; + + while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) { + while(*s <= ' ') + if (!*s++) + continue; + dItry = 0; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + sscanf(s+1, "%lx %lx %lx %lx", &u.bits[_0], + &u.bits[_1], &u.bits[_2], &u.bits[_3]); + printf("\nInput: %s", ibuf); + printf(" --> f = #%lx %lx %lx %lx\n", u.bits[_0], + u.bits[_1], u.bits[_2], u.bits[_3]); + goto fmt_test; + } + dItry = 1; + printf("\nInput: %s", ibuf); + i = strtorQ(ibuf, &se, r, u.bits); + if (r == 1 && (strtopQ(ibuf,&se1,v[0].bits) != i + || se != se1 || memcmp(u.bits, v[0].bits, 16))) + printf("***strtoQ and strtorQ disagree!!\n:"); + printf("\nstrtoQ consumes %d bytes and returns %d\n", + (int)(se-ibuf), i); + printf("with bits = #%lx %lx %lx %lx\n", + U u.bits[_0], U u.bits[_1], U u.bits[_2], U u.bits[_3]); + fmt_test: + if (sizeof(long double) == 16) + printf("printf(\"%%.35Lg\") gives %.35Lg\n", u.d); + se = g_Qfmt(obuf, u.bits, ndig, sizeof(obuf)); + printf("g_Qfmt(%d) gives %d bytes: \"%s\"\n\n", ndig, + (int)(se-obuf), se ? obuf : ""); + if (!dItry) + continue; + printf("strtoIQ returns %d,", + strtoIQ(ibuf, &se, v[0].bits, v[1].bits)); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (!memcmp(v[0].bits, v[1].bits, 16)) { + if (!memcpy(u.bits, v[0].bits, 16)) + printf("fI[0] == fI[1] == strtoQ\n"); + else { + printf("fI[0] == fI[1] = #%lx %lx %lx %lx\n", + U v[0].bits[_0], U v[0].bits[_1], + U v[0].bits[_2], U v[0].bits[_3]); + if (sizeof(long double) == 16) + printf("= %.35Lg\n", v[0].d); + } + } + else { + printf("fI[0] = #%lx %lx %lx %lx\n", + U v[0].bits[_0], U v[0].bits[_1], + U v[0].bits[_2], U v[0].bits[_3]); + if (sizeof(long double) == 16) + printf("= %.35Lg\n", v[0].d); + printf("fI[1] = #%lx %lx %lx %lx\n", + U v[1].bits[_0], U v[1].bits[_1], + U v[1].bits[_2], U v[1].bits[_3]); + if (sizeof(long double) == 16) + printf("= %.35Lg\n", v[1].d); + if (!memcmp(v[0].bits, u.bits, 16)) + printf("fI[0] == strtod\n"); + else if (!memcmp(v[1].bits, u.bits, 16)) + printf("fI[1] == strtod\n"); + else + printf("**** Both differ from strtod ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/README b/src/contrib/gdtoa/test/README new file mode 100644 index 0000000..79b1c91 --- /dev/null +++ b/src/contrib/gdtoa/test/README @@ -0,0 +1,61 @@ +This directory contains source for several test programs: + +dt is for conversion to/from double; it permits input of pairs of +32-bit hex integers as #hhhhhhhh hhhhhhhh (i.e., the initial '#' +indicates hex input). No initial # ==> decimal input. +After the input number is an optional : mode ndigits +(colon, and decimal integers for parameters "mode" and "ndigits" +to gdtoa). + +Qtest, ddtest, dtest, ftest, xLtest and xtest are for conversion to/from + + f IEEE single precision + d IEEE double precision + xL IEEE extended precision, as on Motorola 680x0 chips + x IEEE extended precision, as on Intel 80x87 chips or + software emulation of Motorola 680x0 chips + Q quad precision, as on Sun Sparc chips + dd double double, pairs of IEEE double numbers + whose sum is the desired value + +They're all similar, except for the precision. They test both +directed roundings and interval input (the strtoI* routines). +Lines that begin with "r" specify or interrogate the desired rounding +direction: + + 0 = toward 0 + 1 = nearest (default) + 2 = toward +Infinity + 3 = toward -Infinity + +These are the FPI_Round_* values in gdota.h. The "r" value is sticky: +it stays in effect til changed. To change the value, give a line that +starts with r followed by 0, 1, 2, or 3. To check the value, give "r" +by itself. + +Lines that begin with n followed by a number specify the ndig +argument for subsequent calls to the relevant g_*fmt routine. + +Lines that start with # followed by the appropriate number of +hexadecimal strings (see the comments) give the big-endian +internal representation of the desired number. + +When routines Qtest, xLtest, and xtest are used on machines whose +long double is of type "quad" (for Qtest) or "extended" (for x*test), +they try to print with %Lg as another way to show binary values. + +Program ddtest also accepts (white-space separated) pairs of decimal +input numbers; it converts both with strtod and feeds the result +to g_ddfmt. + +Program dItest exercises strtodI and strtoId. + +Programs dItestsi and ddtestsi are for testing the sudden-underflow +logic (on double and double-double conversions). + +Program strtodt tests strtod on some hard cases (in file testnos3) +posted by Fred Tydeman to comp.arch.arithmetic on 26 Feb. 1996. + +These are simple test programs, not meant for exhaustive testing, +but for manually testing "interesting" cases. Paxson's testbase +is good for more exhaustive testing, in part with random inputs. diff --git a/src/contrib/gdtoa/test/d.out b/src/contrib/gdtoa/test/d.out new file mode 100644 index 0000000..a0ac991 --- /dev/null +++ b/src/contrib/gdtoa/test/d.out @@ -0,0 +1,986 @@ + +Input: 1.23 +strtod consumes 4 bytes and returns 17 with f = 1.23 = #3ff3ae14 7ae147ae +g_dfmt(0) gives 4 bytes: "1.23" + +strtoId returns 17, consuming 4 bytes. +fI[0] = #3ff3ae14 7ae147ae = 1.23 +fI[1] = #3ff3ae14 7ae147af = 1.2300000000000002 +fI[0] == strtod + + +Input: 1.23e+20 +strtod consumes 8 bytes and returns 1 with f = 1.23e+20 = #441aabdf 2145b430 +g_dfmt(0) gives 8 bytes: "1.23e+20" + +strtoId returns 1, consuming 8 bytes. +fI[0] == fI[1] == strtod + + +Input: 1.23e-20 +strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-20 = #3bcd0ae4 cf767531 +g_dfmt(0) gives 8 bytes: "1.23e-20" + +strtoId returns 33, consuming 8 bytes. +fI[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +fI[1] = #3bcd0ae4 cf767531 = 1.2300000000000001e-20 +fI[1] == strtod + + +Input: 1.23456789 +strtod consumes 10 bytes and returns 17 with f = 1.2345678899999999 = #3ff3c0ca 4283de1b +g_dfmt(0) gives 10 bytes: "1.23456789" + +strtoId returns 17, consuming 10 bytes. +fI[0] = #3ff3c0ca 4283de1b = 1.2345678899999999 +fI[1] = #3ff3c0ca 4283de1c = 1.2345678900000001 +fI[0] == strtod + + +Input: 1.23456589e+20 +strtod consumes 14 bytes and returns 17 with f = 1.23456589e+20 = #441ac537 a660b997 +g_dfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoId returns 17, consuming 14 bytes. +fI[0] = #441ac537 a660b997 = 1.23456589e+20 +fI[1] = #441ac537 a660b998 = 1.2345658900000001e+20 +fI[0] == strtod + + +Input: 1.23e+30 +strtod consumes 8 bytes and returns 17 with f = 1.23e+30 = #462f0cb0 4e8fb790 +g_dfmt(0) gives 8 bytes: "1.23e+30" + +strtoId returns 17, consuming 8 bytes. +fI[0] = #462f0cb0 4e8fb790 = 1.23e+30 +fI[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30 +fI[0] == strtod + + +Input: 1.23e-30 +strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-30 = #39b8f286 6f5010ab +g_dfmt(0) gives 8 bytes: "1.23e-30" + +strtoId returns 33, consuming 8 bytes. +fI[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30 +fI[1] = #39b8f286 6f5010ab = 1.2300000000000001e-30 +fI[1] == strtod + + +Input: 1.23456789e-20 +strtod consumes 14 bytes and returns 17 with f = 1.2345678899999999e-20 = #3bcd2681 471e7ada +g_dfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoId returns 17, consuming 14 bytes. +fI[0] = #3bcd2681 471e7ada = 1.2345678899999999e-20 +fI[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20 +fI[0] == strtod + + +Input: 1.23456789e-30 +strtod consumes 14 bytes and returns 17 with f = 1.23456789e-30 = #39b90a3e 33bbd995 +g_dfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoId returns 17, consuming 14 bytes. +fI[0] = #39b90a3e 33bbd995 = 1.23456789e-30 +fI[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30 +fI[0] == strtod + + +Input: 1.234567890123456789 +strtod consumes 20 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb +g_dfmt(0) gives 18 bytes: "1.2345678901234567" + +strtoId returns 17, consuming 20 bytes. +fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569 +fI[0] == strtod + + +Input: 1.23456789012345678901234567890123456789 +strtod consumes 40 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb +g_dfmt(0) gives 18 bytes: "1.2345678901234567" + +strtoId returns 17, consuming 40 bytes. +fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569 +fI[0] == strtod + + +Input: 1.23e306 +strtod consumes 8 bytes and returns 33 with f = 1.23e+306 = #7f7c0676 cd1c61f5 +g_dfmt(0) gives 9 bytes: "1.23e+306" + +strtoId returns 33, consuming 8 bytes. +fI[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306 +fI[1] = #7f7c0676 cd1c61f5 = 1.23e+306 +fI[1] == strtod + + +Input: 1.23e-306 +strtod consumes 9 bytes and returns 33 with f = 1.23e-306 = #6ba3b8 5da396e8 +g_dfmt(0) gives 9 bytes: "1.23e-306" + +strtoId returns 33, consuming 9 bytes. +fI[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306 +fI[1] = #6ba3b8 5da396e8 = 1.23e-306 +fI[1] == strtod + + +Input: 1.23e-320 +strtod consumes 9 bytes and returns 98 with f = 1.2302234581447039e-320 = #0 9ba +g_dfmt(0) gives 9 bytes: "1.23e-320" + +strtoId returns 98, consuming 9 bytes. +fI[0] = #0 9b9 = 1.2297293924988626e-320 +fI[1] = #0 9ba = 1.2302234581447039e-320 +fI[1] == strtod + + +Input: 1.23e-20 +strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-20 = #3bcd0ae4 cf767531 +g_dfmt(0) gives 8 bytes: "1.23e-20" + +strtoId returns 33, consuming 8 bytes. +fI[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +fI[1] = #3bcd0ae4 cf767531 = 1.2300000000000001e-20 +fI[1] == strtod + + +Input: 1.23456789e307 +strtod consumes 14 bytes and returns 33 with f = 1.23456789e+307 = #7fb194b1 4bdaecdc +g_dfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoId returns 33, consuming 14 bytes. +fI[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307 +fI[1] = #7fb194b1 4bdaecdc = 1.23456789e+307 +fI[1] == strtod + + +Input: 1.23456589e-307 +strtod consumes 15 bytes and returns 17 with f = 1.2345658899999999e-307 = #363196 bb9845fa +g_dfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoId returns 17, consuming 15 bytes. +fI[0] = #363196 bb9845fa = 1.2345658899999999e-307 +fI[1] = #363196 bb9845fb = 1.2345658900000001e-307 +fI[0] == strtod + + +Input: 1.234567890123456789 +strtod consumes 20 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb +g_dfmt(0) gives 18 bytes: "1.2345678901234567" + +strtoId returns 17, consuming 20 bytes. +fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569 +fI[0] == strtod + + +Input: 1.234567890123456789e301 +strtod consumes 24 bytes and returns 17 with f = 1.2345678901234568e+301 = #7e726f51 75f56413 +g_dfmt(0) gives 23 bytes: "1.2345678901234568e+301" + +strtoId returns 17, consuming 24 bytes. +fI[0] = #7e726f51 75f56413 = 1.2345678901234568e+301 +fI[1] = #7e726f51 75f56414 = 1.234567890123457e+301 +fI[0] == strtod + + +Input: 1.234567890123456789e-301 +strtod consumes 25 bytes and returns 17 with f = 1.2345678901234567e-301 = #1752a64 e34ba0d3 +g_dfmt(0) gives 23 bytes: "1.2345678901234567e-301" + +strtoId returns 17, consuming 25 bytes. +fI[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301 +fI[1] = #1752a64 e34ba0d4 = 1.2345678901234569e-301 +fI[0] == strtod + + +Input: 1.234567890123456789e-321 +strtod consumes 25 bytes and returns 98 with f = 1.2351641146031164e-321 = #0 fa +g_dfmt(0) gives 10 bytes: "1.235e-321" + +strtoId returns 98, consuming 25 bytes. +fI[0] = #0 f9 = 1.2302234581447039e-321 +fI[1] = #0 fa = 1.2351641146031164e-321 +fI[1] == strtod + + +Input: 1e23 +strtod consumes 4 bytes and returns 17 with f = 9.9999999999999992e+22 = #44b52d02 c7e14af6 +g_dfmt(0) gives 5 bytes: "1e+23" + +strtoId returns 17, consuming 4 bytes. +fI[0] = #44b52d02 c7e14af6 = 9.9999999999999992e+22 +fI[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23 +fI[0] == strtod + + +Input: 1e310 +strtod consumes 5 bytes and returns 163 with f = Infinity = #7ff00000 0 +g_dfmt(0) gives 8 bytes: "Infinity" + +strtoId returns 163, consuming 5 bytes. +fI[0] = #7fefffff ffffffff = 1.7976931348623157e+308 +fI[1] = #7ff00000 0 = Infinity +fI[1] == strtod + + +Input: 9.0259718793241475e-277 +strtod consumes 23 bytes and returns 33 with f = 9.0259718793241479e-277 = #6a00000 0 +g_dfmt(0) gives 22 bytes: "9.025971879324148e-277" + +strtoId returns 33, consuming 23 bytes. +fI[0] = #69fffff ffffffff = 9.0259718793241469e-277 +fI[1] = #6a00000 0 = 9.0259718793241479e-277 +fI[1] == strtod + + +Input: 9.025971879324147880346310405869e-277 +strtod consumes 37 bytes and returns 17 with f = 9.0259718793241479e-277 = #6a00000 0 +g_dfmt(0) gives 22 bytes: "9.025971879324148e-277" + +strtoId returns 17, consuming 37 bytes. +fI[0] = #6a00000 0 = 9.0259718793241479e-277 +fI[1] = #6a00000 1 = 9.0259718793241499e-277 +fI[0] == strtod + + +Input: 9.025971879324147880346310405868e-277 +strtod consumes 37 bytes and returns 33 with f = 9.0259718793241479e-277 = #6a00000 0 +g_dfmt(0) gives 22 bytes: "9.025971879324148e-277" + +strtoId returns 33, consuming 37 bytes. +fI[0] = #69fffff ffffffff = 9.0259718793241469e-277 +fI[1] = #6a00000 0 = 9.0259718793241479e-277 +fI[1] == strtod + + +Input: 2.2250738585072014e-308 +strtod consumes 23 bytes and returns 17 with f = 2.2250738585072014e-308 = #100000 0 +g_dfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoId returns 17, consuming 23 bytes. +fI[0] = #100000 0 = 2.2250738585072014e-308 +fI[1] = #100000 1 = 2.2250738585072019e-308 +fI[0] == strtod + + +Input: 2.2250738585072013e-308 +strtod consumes 23 bytes and returns 33 with f = 2.2250738585072014e-308 = #100000 0 +g_dfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoId returns 33, consuming 23 bytes. +fI[0] = #fffff ffffffff = 2.2250738585072009e-308 +fI[1] = #100000 0 = 2.2250738585072014e-308 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 +strtod consumes 3 bytes and returns 17 with f = 1.0999999999999999 = #3ff19999 99999999 +g_dfmt(0) gives 18 bytes: "1.0999999999999999" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff19999 99999999 = 1.0999999999999999 +fI[1] = #3ff19999 9999999a = 1.1000000000000001 +fI[0] == strtod + + +Input: -1.1 +strtod consumes 4 bytes and returns 25 with f = -1.0999999999999999 = #bff19999 99999999 +g_dfmt(0) gives 19 bytes: "-1.0999999999999999" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff19999 9999999a = -1.1000000000000001 +fI[1] = #bff19999 99999999 = -1.0999999999999999 +fI[1] == strtod + + +Input: 1.2 +strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333 +g_dfmt(0) gives 3 bytes: "1.2" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff33333 33333333 = 1.2 +fI[1] = #3ff33333 33333334 = 1.2000000000000002 +fI[0] == strtod + + +Input: -1.2 +strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333 +g_dfmt(0) gives 4 bytes: "-1.2" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff33333 33333334 = -1.2000000000000002 +fI[1] = #bff33333 33333333 = -1.2 +fI[1] == strtod + + +Input: 1.3 +strtod consumes 3 bytes and returns 17 with f = 1.2999999999999998 = #3ff4cccc cccccccc +g_dfmt(0) gives 18 bytes: "1.2999999999999998" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff4cccc cccccccc = 1.2999999999999998 +fI[1] = #3ff4cccc cccccccd = 1.3 +fI[0] == strtod + + +Input: -1.3 +strtod consumes 4 bytes and returns 25 with f = -1.2999999999999998 = #bff4cccc cccccccc +g_dfmt(0) gives 19 bytes: "-1.2999999999999998" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff4cccc cccccccd = -1.3 +fI[1] = #bff4cccc cccccccc = -1.2999999999999998 +fI[1] == strtod + + +Input: 1.4 +strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666 +g_dfmt(0) gives 3 bytes: "1.4" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff66666 66666666 = 1.3999999999999999 +fI[1] = #3ff66666 66666667 = 1.4000000000000001 +fI[0] == strtod + + +Input: -1.4 +strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666 +g_dfmt(0) gives 4 bytes: "-1.4" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff66666 66666667 = -1.4000000000000001 +fI[1] = #bff66666 66666666 = -1.3999999999999999 +fI[1] == strtod + + +Input: 1.5 +strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0 +g_dfmt(0) gives 3 bytes: "1.5" + +strtoId returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtod + + +Input: -1.5 +strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0 +g_dfmt(0) gives 4 bytes: "-1.5" + +strtoId returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtod + + +Input: 1.6 +strtod consumes 3 bytes and returns 17 with f = 1.5999999999999999 = #3ff99999 99999999 +g_dfmt(0) gives 18 bytes: "1.5999999999999999" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff99999 99999999 = 1.5999999999999999 +fI[1] = #3ff99999 9999999a = 1.6000000000000001 +fI[0] == strtod + + +Input: -1.6 +strtod consumes 4 bytes and returns 25 with f = -1.5999999999999999 = #bff99999 99999999 +g_dfmt(0) gives 19 bytes: "-1.5999999999999999" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff99999 9999999a = -1.6000000000000001 +fI[1] = #bff99999 99999999 = -1.5999999999999999 +fI[1] == strtod + + +Input: 1.7 +strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333 +g_dfmt(0) gives 3 bytes: "1.7" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffb3333 33333333 = 1.7 +fI[1] = #3ffb3333 33333334 = 1.7000000000000002 +fI[0] == strtod + + +Input: -1.7 +strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333 +g_dfmt(0) gives 4 bytes: "-1.7" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffb3333 33333334 = -1.7000000000000002 +fI[1] = #bffb3333 33333333 = -1.7 +fI[1] == strtod + + +Input: 1.8 +strtod consumes 3 bytes and returns 17 with f = 1.7999999999999998 = #3ffccccc cccccccc +g_dfmt(0) gives 18 bytes: "1.7999999999999998" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ffccccc cccccccc = 1.7999999999999998 +fI[1] = #3ffccccc cccccccd = 1.8 +fI[0] == strtod + + +Input: -1.8 +strtod consumes 4 bytes and returns 25 with f = -1.7999999999999998 = #bffccccc cccccccc +g_dfmt(0) gives 19 bytes: "-1.7999999999999998" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bffccccc cccccccd = -1.8 +fI[1] = #bffccccc cccccccc = -1.7999999999999998 +fI[1] == strtod + + +Input: 1.9 +strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666 +g_dfmt(0) gives 3 bytes: "1.9" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffe6666 66666666 = 1.8999999999999999 +fI[1] = #3ffe6666 66666667 = 1.9000000000000001 +fI[0] == strtod + + +Input: -1.9 +strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666 +g_dfmt(0) gives 4 bytes: "-1.9" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffe6666 66666667 = -1.9000000000000001 +fI[1] = #bffe6666 66666666 = -1.8999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 +strtod consumes 3 bytes and returns 33 with f = 1.1000000000000001 = #3ff19999 9999999a +g_dfmt(0) gives 3 bytes: "1.1" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff19999 99999999 = 1.0999999999999999 +fI[1] = #3ff19999 9999999a = 1.1000000000000001 +fI[1] == strtod + + +Input: -1.1 +strtod consumes 4 bytes and returns 41 with f = -1.1000000000000001 = #bff19999 9999999a +g_dfmt(0) gives 4 bytes: "-1.1" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff19999 9999999a = -1.1000000000000001 +fI[1] = #bff19999 99999999 = -1.0999999999999999 +fI[0] == strtod + + +Input: 1.2 +strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333 +g_dfmt(0) gives 3 bytes: "1.2" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff33333 33333333 = 1.2 +fI[1] = #3ff33333 33333334 = 1.2000000000000002 +fI[0] == strtod + + +Input: -1.2 +strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333 +g_dfmt(0) gives 4 bytes: "-1.2" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff33333 33333334 = -1.2000000000000002 +fI[1] = #bff33333 33333333 = -1.2 +fI[1] == strtod + + +Input: 1.3 +strtod consumes 3 bytes and returns 33 with f = 1.3 = #3ff4cccc cccccccd +g_dfmt(0) gives 3 bytes: "1.3" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff4cccc cccccccc = 1.2999999999999998 +fI[1] = #3ff4cccc cccccccd = 1.3 +fI[1] == strtod + + +Input: -1.3 +strtod consumes 4 bytes and returns 41 with f = -1.3 = #bff4cccc cccccccd +g_dfmt(0) gives 4 bytes: "-1.3" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff4cccc cccccccd = -1.3 +fI[1] = #bff4cccc cccccccc = -1.2999999999999998 +fI[0] == strtod + + +Input: 1.4 +strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666 +g_dfmt(0) gives 3 bytes: "1.4" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff66666 66666666 = 1.3999999999999999 +fI[1] = #3ff66666 66666667 = 1.4000000000000001 +fI[0] == strtod + + +Input: -1.4 +strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666 +g_dfmt(0) gives 4 bytes: "-1.4" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff66666 66666667 = -1.4000000000000001 +fI[1] = #bff66666 66666666 = -1.3999999999999999 +fI[1] == strtod + + +Input: 1.5 +strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0 +g_dfmt(0) gives 3 bytes: "1.5" + +strtoId returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtod + + +Input: -1.5 +strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0 +g_dfmt(0) gives 4 bytes: "-1.5" + +strtoId returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtod + + +Input: 1.6 +strtod consumes 3 bytes and returns 33 with f = 1.6000000000000001 = #3ff99999 9999999a +g_dfmt(0) gives 3 bytes: "1.6" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff99999 99999999 = 1.5999999999999999 +fI[1] = #3ff99999 9999999a = 1.6000000000000001 +fI[1] == strtod + + +Input: -1.6 +strtod consumes 4 bytes and returns 41 with f = -1.6000000000000001 = #bff99999 9999999a +g_dfmt(0) gives 4 bytes: "-1.6" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff99999 9999999a = -1.6000000000000001 +fI[1] = #bff99999 99999999 = -1.5999999999999999 +fI[0] == strtod + + +Input: 1.7 +strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333 +g_dfmt(0) gives 3 bytes: "1.7" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffb3333 33333333 = 1.7 +fI[1] = #3ffb3333 33333334 = 1.7000000000000002 +fI[0] == strtod + + +Input: -1.7 +strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333 +g_dfmt(0) gives 4 bytes: "-1.7" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffb3333 33333334 = -1.7000000000000002 +fI[1] = #bffb3333 33333333 = -1.7 +fI[1] == strtod + + +Input: 1.8 +strtod consumes 3 bytes and returns 33 with f = 1.8 = #3ffccccc cccccccd +g_dfmt(0) gives 3 bytes: "1.8" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ffccccc cccccccc = 1.7999999999999998 +fI[1] = #3ffccccc cccccccd = 1.8 +fI[1] == strtod + + +Input: -1.8 +strtod consumes 4 bytes and returns 41 with f = -1.8 = #bffccccc cccccccd +g_dfmt(0) gives 4 bytes: "-1.8" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bffccccc cccccccd = -1.8 +fI[1] = #bffccccc cccccccc = -1.7999999999999998 +fI[0] == strtod + + +Input: 1.9 +strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666 +g_dfmt(0) gives 3 bytes: "1.9" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffe6666 66666666 = 1.8999999999999999 +fI[1] = #3ffe6666 66666667 = 1.9000000000000001 +fI[0] == strtod + + +Input: -1.9 +strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666 +g_dfmt(0) gives 4 bytes: "-1.9" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffe6666 66666667 = -1.9000000000000001 +fI[1] = #bffe6666 66666666 = -1.8999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 +strtod consumes 3 bytes and returns 33 with f = 1.1000000000000001 = #3ff19999 9999999a +g_dfmt(0) gives 3 bytes: "1.1" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff19999 99999999 = 1.0999999999999999 +fI[1] = #3ff19999 9999999a = 1.1000000000000001 +fI[1] == strtod + + +Input: -1.1 +strtod consumes 4 bytes and returns 25 with f = -1.0999999999999999 = #bff19999 99999999 +g_dfmt(0) gives 19 bytes: "-1.0999999999999999" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff19999 9999999a = -1.1000000000000001 +fI[1] = #bff19999 99999999 = -1.0999999999999999 +fI[1] == strtod + + +Input: 1.2 +strtod consumes 3 bytes and returns 33 with f = 1.2000000000000002 = #3ff33333 33333334 +g_dfmt(0) gives 18 bytes: "1.2000000000000002" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff33333 33333333 = 1.2 +fI[1] = #3ff33333 33333334 = 1.2000000000000002 +fI[1] == strtod + + +Input: -1.2 +strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333 +g_dfmt(0) gives 4 bytes: "-1.2" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff33333 33333334 = -1.2000000000000002 +fI[1] = #bff33333 33333333 = -1.2 +fI[1] == strtod + + +Input: 1.3 +strtod consumes 3 bytes and returns 33 with f = 1.3 = #3ff4cccc cccccccd +g_dfmt(0) gives 3 bytes: "1.3" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff4cccc cccccccc = 1.2999999999999998 +fI[1] = #3ff4cccc cccccccd = 1.3 +fI[1] == strtod + + +Input: -1.3 +strtod consumes 4 bytes and returns 25 with f = -1.2999999999999998 = #bff4cccc cccccccc +g_dfmt(0) gives 19 bytes: "-1.2999999999999998" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff4cccc cccccccd = -1.3 +fI[1] = #bff4cccc cccccccc = -1.2999999999999998 +fI[1] == strtod + + +Input: 1.4 +strtod consumes 3 bytes and returns 33 with f = 1.4000000000000001 = #3ff66666 66666667 +g_dfmt(0) gives 18 bytes: "1.4000000000000001" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff66666 66666666 = 1.3999999999999999 +fI[1] = #3ff66666 66666667 = 1.4000000000000001 +fI[1] == strtod + + +Input: -1.4 +strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666 +g_dfmt(0) gives 4 bytes: "-1.4" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff66666 66666667 = -1.4000000000000001 +fI[1] = #bff66666 66666666 = -1.3999999999999999 +fI[1] == strtod + + +Input: 1.5 +strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0 +g_dfmt(0) gives 3 bytes: "1.5" + +strtoId returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtod + + +Input: -1.5 +strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0 +g_dfmt(0) gives 4 bytes: "-1.5" + +strtoId returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtod + + +Input: 1.6 +strtod consumes 3 bytes and returns 33 with f = 1.6000000000000001 = #3ff99999 9999999a +g_dfmt(0) gives 3 bytes: "1.6" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff99999 99999999 = 1.5999999999999999 +fI[1] = #3ff99999 9999999a = 1.6000000000000001 +fI[1] == strtod + + +Input: -1.6 +strtod consumes 4 bytes and returns 25 with f = -1.5999999999999999 = #bff99999 99999999 +g_dfmt(0) gives 19 bytes: "-1.5999999999999999" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff99999 9999999a = -1.6000000000000001 +fI[1] = #bff99999 99999999 = -1.5999999999999999 +fI[1] == strtod + + +Input: 1.7 +strtod consumes 3 bytes and returns 33 with f = 1.7000000000000002 = #3ffb3333 33333334 +g_dfmt(0) gives 18 bytes: "1.7000000000000002" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffb3333 33333333 = 1.7 +fI[1] = #3ffb3333 33333334 = 1.7000000000000002 +fI[1] == strtod + + +Input: -1.7 +strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333 +g_dfmt(0) gives 4 bytes: "-1.7" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffb3333 33333334 = -1.7000000000000002 +fI[1] = #bffb3333 33333333 = -1.7 +fI[1] == strtod + + +Input: 1.8 +strtod consumes 3 bytes and returns 33 with f = 1.8 = #3ffccccc cccccccd +g_dfmt(0) gives 3 bytes: "1.8" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ffccccc cccccccc = 1.7999999999999998 +fI[1] = #3ffccccc cccccccd = 1.8 +fI[1] == strtod + + +Input: -1.8 +strtod consumes 4 bytes and returns 25 with f = -1.7999999999999998 = #bffccccc cccccccc +g_dfmt(0) gives 19 bytes: "-1.7999999999999998" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bffccccc cccccccd = -1.8 +fI[1] = #bffccccc cccccccc = -1.7999999999999998 +fI[1] == strtod + + +Input: 1.9 +strtod consumes 3 bytes and returns 33 with f = 1.9000000000000001 = #3ffe6666 66666667 +g_dfmt(0) gives 18 bytes: "1.9000000000000001" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffe6666 66666666 = 1.8999999999999999 +fI[1] = #3ffe6666 66666667 = 1.9000000000000001 +fI[1] == strtod + + +Input: -1.9 +strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666 +g_dfmt(0) gives 4 bytes: "-1.9" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffe6666 66666667 = -1.9000000000000001 +fI[1] = #bffe6666 66666666 = -1.8999999999999999 +fI[1] == strtod + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 +strtod consumes 3 bytes and returns 17 with f = 1.0999999999999999 = #3ff19999 99999999 +g_dfmt(0) gives 18 bytes: "1.0999999999999999" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff19999 99999999 = 1.0999999999999999 +fI[1] = #3ff19999 9999999a = 1.1000000000000001 +fI[0] == strtod + + +Input: -1.1 +strtod consumes 4 bytes and returns 41 with f = -1.1000000000000001 = #bff19999 9999999a +g_dfmt(0) gives 4 bytes: "-1.1" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff19999 9999999a = -1.1000000000000001 +fI[1] = #bff19999 99999999 = -1.0999999999999999 +fI[0] == strtod + + +Input: 1.2 +strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333 +g_dfmt(0) gives 3 bytes: "1.2" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff33333 33333333 = 1.2 +fI[1] = #3ff33333 33333334 = 1.2000000000000002 +fI[0] == strtod + + +Input: -1.2 +strtod consumes 4 bytes and returns 41 with f = -1.2000000000000002 = #bff33333 33333334 +g_dfmt(0) gives 19 bytes: "-1.2000000000000002" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff33333 33333334 = -1.2000000000000002 +fI[1] = #bff33333 33333333 = -1.2 +fI[0] == strtod + + +Input: 1.3 +strtod consumes 3 bytes and returns 17 with f = 1.2999999999999998 = #3ff4cccc cccccccc +g_dfmt(0) gives 18 bytes: "1.2999999999999998" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff4cccc cccccccc = 1.2999999999999998 +fI[1] = #3ff4cccc cccccccd = 1.3 +fI[0] == strtod + + +Input: -1.3 +strtod consumes 4 bytes and returns 41 with f = -1.3 = #bff4cccc cccccccd +g_dfmt(0) gives 4 bytes: "-1.3" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff4cccc cccccccd = -1.3 +fI[1] = #bff4cccc cccccccc = -1.2999999999999998 +fI[0] == strtod + + +Input: 1.4 +strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666 +g_dfmt(0) gives 3 bytes: "1.4" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ff66666 66666666 = 1.3999999999999999 +fI[1] = #3ff66666 66666667 = 1.4000000000000001 +fI[0] == strtod + + +Input: -1.4 +strtod consumes 4 bytes and returns 41 with f = -1.4000000000000001 = #bff66666 66666667 +g_dfmt(0) gives 19 bytes: "-1.4000000000000001" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bff66666 66666667 = -1.4000000000000001 +fI[1] = #bff66666 66666666 = -1.3999999999999999 +fI[0] == strtod + + +Input: 1.5 +strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0 +g_dfmt(0) gives 3 bytes: "1.5" + +strtoId returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtod + + +Input: -1.5 +strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0 +g_dfmt(0) gives 4 bytes: "-1.5" + +strtoId returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtod + + +Input: 1.6 +strtod consumes 3 bytes and returns 17 with f = 1.5999999999999999 = #3ff99999 99999999 +g_dfmt(0) gives 18 bytes: "1.5999999999999999" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ff99999 99999999 = 1.5999999999999999 +fI[1] = #3ff99999 9999999a = 1.6000000000000001 +fI[0] == strtod + + +Input: -1.6 +strtod consumes 4 bytes and returns 41 with f = -1.6000000000000001 = #bff99999 9999999a +g_dfmt(0) gives 4 bytes: "-1.6" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bff99999 9999999a = -1.6000000000000001 +fI[1] = #bff99999 99999999 = -1.5999999999999999 +fI[0] == strtod + + +Input: 1.7 +strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333 +g_dfmt(0) gives 3 bytes: "1.7" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffb3333 33333333 = 1.7 +fI[1] = #3ffb3333 33333334 = 1.7000000000000002 +fI[0] == strtod + + +Input: -1.7 +strtod consumes 4 bytes and returns 41 with f = -1.7000000000000002 = #bffb3333 33333334 +g_dfmt(0) gives 19 bytes: "-1.7000000000000002" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffb3333 33333334 = -1.7000000000000002 +fI[1] = #bffb3333 33333333 = -1.7 +fI[0] == strtod + + +Input: 1.8 +strtod consumes 3 bytes and returns 17 with f = 1.7999999999999998 = #3ffccccc cccccccc +g_dfmt(0) gives 18 bytes: "1.7999999999999998" + +strtoId returns 33, consuming 3 bytes. +fI[0] = #3ffccccc cccccccc = 1.7999999999999998 +fI[1] = #3ffccccc cccccccd = 1.8 +fI[0] == strtod + + +Input: -1.8 +strtod consumes 4 bytes and returns 41 with f = -1.8 = #bffccccc cccccccd +g_dfmt(0) gives 4 bytes: "-1.8" + +strtoId returns 41, consuming 4 bytes. +fI[0] = #bffccccc cccccccd = -1.8 +fI[1] = #bffccccc cccccccc = -1.7999999999999998 +fI[0] == strtod + + +Input: 1.9 +strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666 +g_dfmt(0) gives 3 bytes: "1.9" + +strtoId returns 17, consuming 3 bytes. +fI[0] = #3ffe6666 66666666 = 1.8999999999999999 +fI[1] = #3ffe6666 66666667 = 1.9000000000000001 +fI[0] == strtod + + +Input: -1.9 +strtod consumes 4 bytes and returns 41 with f = -1.9000000000000001 = #bffe6666 66666667 +g_dfmt(0) gives 19 bytes: "-1.9000000000000001" + +strtoId returns 25, consuming 4 bytes. +fI[0] = #bffe6666 66666667 = -1.9000000000000001 +fI[1] = #bffe6666 66666666 = -1.8999999999999999 +fI[0] == strtod + diff --git a/src/contrib/gdtoa/test/dI.out b/src/contrib/gdtoa/test/dI.out new file mode 100644 index 0000000..b4070de --- /dev/null +++ b/src/contrib/gdtoa/test/dI.out @@ -0,0 +1,168 @@ + +Input: 1.23 +strtodI consumes 4 bytes and returns 17 +dd[0] = #3ff3ae14 7ae147ae = 1.23 +dd[1] = #3ff3ae14 7ae147af = 1.2300000000000002 + + +Input: 1.23e+20 +strtodI consumes 8 bytes and returns 1 +dd[0] = #441aabdf 2145b430 = 1.23e+20 +dd[1] = #441aabdf 2145b430 = 1.23e+20 + + +Input: 1.23e-20 +strtodI consumes 8 bytes and returns 33 +dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +dd[1] = #3bcd0ae4 cf767531 = 1.23e-20 + + +Input: 1.23456789 +strtodI consumes 10 bytes and returns 17 +dd[0] = #3ff3c0ca 4283de1b = 1.23456789 +dd[1] = #3ff3c0ca 4283de1c = 1.2345678900000001 + + +Input: 1.23456589e+20 +strtodI consumes 14 bytes and returns 17 +dd[0] = #441ac537 a660b997 = 1.23456589e+20 +dd[1] = #441ac537 a660b998 = 123456589000000010000 + + +Input: 1.23e+30 +strtodI consumes 8 bytes and returns 17 +dd[0] = #462f0cb0 4e8fb790 = 1.23e+30 +dd[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30 + + +Input: 1.23e-30 +strtodI consumes 8 bytes and returns 33 +dd[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30 +dd[1] = #39b8f286 6f5010ab = 1.23e-30 + + +Input: 1.23456789e-20 +strtodI consumes 14 bytes and returns 17 +dd[0] = #3bcd2681 471e7ada = 1.23456789e-20 +dd[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20 + + +Input: 1.23456789e-30 +strtodI consumes 14 bytes and returns 17 +dd[0] = #39b90a3e 33bbd995 = 1.23456789e-30 +dd[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30 + + +Input: 1.234567890123456789 +strtodI consumes 20 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.23456789012345678901234567890123456789 +strtodI consumes 40 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.23e306 +strtodI consumes 8 bytes and returns 33 +dd[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306 +dd[1] = #7f7c0676 cd1c61f5 = 1.23e+306 + + +Input: 1.23e-306 +strtodI consumes 9 bytes and returns 33 +dd[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306 +dd[1] = #6ba3b8 5da396e8 = 1.23e-306 + + +Input: 1.23e-320 +strtodI consumes 9 bytes and returns 98 +dd[0] = #0 9b9 = 1.2297e-320 +dd[1] = #0 9ba = 1.23e-320 + + +Input: 1.23e-20 +strtodI consumes 8 bytes and returns 33 +dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +dd[1] = #3bcd0ae4 cf767531 = 1.23e-20 + + +Input: 1.23456789e307 +strtodI consumes 14 bytes and returns 33 +dd[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307 +dd[1] = #7fb194b1 4bdaecdc = 1.23456789e+307 + + +Input: 1.23456589e-307 +strtodI consumes 15 bytes and returns 17 +dd[0] = #363196 bb9845fa = 1.23456589e-307 +dd[1] = #363196 bb9845fb = 1.2345658900000001e-307 + + +Input: 1.234567890123456789 +strtodI consumes 20 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.234567890123456789e301 +strtodI consumes 24 bytes and returns 17 +dd[0] = #7e726f51 75f56413 = 1.2345678901234568e+301 +dd[1] = #7e726f51 75f56414 = 1.234567890123457e+301 + + +Input: 1.234567890123456789e-301 +strtodI consumes 25 bytes and returns 17 +dd[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301 +dd[1] = #1752a64 e34ba0d4 = 1.234567890123457e-301 + + +Input: 1.234567890123456789e-321 +strtodI consumes 25 bytes and returns 98 +dd[0] = #0 f9 = 1.23e-321 +dd[1] = #0 fa = 1.235e-321 + + +Input: 1e23 +strtodI consumes 4 bytes and returns 17 +dd[0] = #44b52d02 c7e14af6 = 1e+23 +dd[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23 + + +Input: 1e310 +strtodI consumes 5 bytes and returns 163 +dd[0] = #7fefffff ffffffff = 1.7976931348623157e+308 +dd[1] = #7ff00000 0 = Infinity + + +Input: 9.0259718793241475e-277 +strtodI consumes 23 bytes and returns 33 +dd[0] = #69fffff ffffffff = 9.025971879324147e-277 +dd[1] = #6a00000 0 = 9.025971879324148e-277 + + +Input: 9.025971879324147880346310405869e-277 +strtodI consumes 37 bytes and returns 17 +dd[0] = #6a00000 0 = 9.025971879324148e-277 +dd[1] = #6a00000 1 = 9.02597187932415e-277 + + +Input: 9.025971879324147880346310405868e-277 +strtodI consumes 37 bytes and returns 33 +dd[0] = #69fffff ffffffff = 9.025971879324147e-277 +dd[1] = #6a00000 0 = 9.025971879324148e-277 + + +Input: 2.2250738585072014e-308 +strtodI consumes 23 bytes and returns 17 +dd[0] = #100000 0 = 2.2250738585072014e-308 +dd[1] = #100000 1 = 2.225073858507202e-308 + + +Input: 2.2250738585072013e-308 +strtodI consumes 23 bytes and returns 33 +dd[0] = #fffff ffffffff = 2.225073858507201e-308 +dd[1] = #100000 0 = 2.2250738585072014e-308 + diff --git a/src/contrib/gdtoa/test/dIsi.out b/src/contrib/gdtoa/test/dIsi.out new file mode 100644 index 0000000..3388a1a --- /dev/null +++ b/src/contrib/gdtoa/test/dIsi.out @@ -0,0 +1,168 @@ + +Input: 1.23 +strtodI consumes 4 bytes and returns 17 +dd[0] = #3ff3ae14 7ae147ae = 1.23 +dd[1] = #3ff3ae14 7ae147af = 1.2300000000000002 + + +Input: 1.23e+20 +strtodI consumes 8 bytes and returns 1 +dd[0] = #441aabdf 2145b430 = 1.23e+20 +dd[1] = #441aabdf 2145b430 = 1.23e+20 + + +Input: 1.23e-20 +strtodI consumes 8 bytes and returns 33 +dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +dd[1] = #3bcd0ae4 cf767531 = 1.23e-20 + + +Input: 1.23456789 +strtodI consumes 10 bytes and returns 17 +dd[0] = #3ff3c0ca 4283de1b = 1.23456789 +dd[1] = #3ff3c0ca 4283de1c = 1.2345678900000001 + + +Input: 1.23456589e+20 +strtodI consumes 14 bytes and returns 17 +dd[0] = #441ac537 a660b997 = 1.23456589e+20 +dd[1] = #441ac537 a660b998 = 123456589000000010000 + + +Input: 1.23e+30 +strtodI consumes 8 bytes and returns 17 +dd[0] = #462f0cb0 4e8fb790 = 1.23e+30 +dd[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30 + + +Input: 1.23e-30 +strtodI consumes 8 bytes and returns 33 +dd[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30 +dd[1] = #39b8f286 6f5010ab = 1.23e-30 + + +Input: 1.23456789e-20 +strtodI consumes 14 bytes and returns 17 +dd[0] = #3bcd2681 471e7ada = 1.23456789e-20 +dd[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20 + + +Input: 1.23456789e-30 +strtodI consumes 14 bytes and returns 17 +dd[0] = #39b90a3e 33bbd995 = 1.23456789e-30 +dd[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30 + + +Input: 1.234567890123456789 +strtodI consumes 20 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.23456789012345678901234567890123456789 +strtodI consumes 40 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.23e306 +strtodI consumes 8 bytes and returns 33 +dd[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306 +dd[1] = #7f7c0676 cd1c61f5 = 1.23e+306 + + +Input: 1.23e-306 +strtodI consumes 9 bytes and returns 33 +dd[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306 +dd[1] = #6ba3b8 5da396e8 = 1.23e-306 + + +Input: 1.23e-320 +strtodI consumes 9 bytes and returns 80 +dd[0] = #0 0 = 0 +dd[1] = #100000 0 = 2.2250738585072014e-308 + + +Input: 1.23e-20 +strtodI consumes 8 bytes and returns 33 +dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20 +dd[1] = #3bcd0ae4 cf767531 = 1.23e-20 + + +Input: 1.23456789e307 +strtodI consumes 14 bytes and returns 33 +dd[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307 +dd[1] = #7fb194b1 4bdaecdc = 1.23456789e+307 + + +Input: 1.23456589e-307 +strtodI consumes 15 bytes and returns 17 +dd[0] = #363196 bb9845fa = 1.23456589e-307 +dd[1] = #363196 bb9845fb = 1.2345658900000001e-307 + + +Input: 1.234567890123456789 +strtodI consumes 20 bytes and returns 17 +dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567 +dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457 + + +Input: 1.234567890123456789e301 +strtodI consumes 24 bytes and returns 17 +dd[0] = #7e726f51 75f56413 = 1.2345678901234568e+301 +dd[1] = #7e726f51 75f56414 = 1.234567890123457e+301 + + +Input: 1.234567890123456789e-301 +strtodI consumes 25 bytes and returns 17 +dd[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301 +dd[1] = #1752a64 e34ba0d4 = 1.234567890123457e-301 + + +Input: 1.234567890123456789e-321 +strtodI consumes 25 bytes and returns 80 +dd[0] = #0 0 = 0 +dd[1] = #100000 0 = 2.2250738585072014e-308 + + +Input: 1e23 +strtodI consumes 4 bytes and returns 17 +dd[0] = #44b52d02 c7e14af6 = 1e+23 +dd[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23 + + +Input: 1e310 +strtodI consumes 5 bytes and returns 163 +dd[0] = #7fefffff ffffffff = 1.7976931348623157e+308 +dd[1] = #7ff00000 0 = Infinity + + +Input: 9.0259718793241475e-277 +strtodI consumes 23 bytes and returns 33 +dd[0] = #69fffff ffffffff = 9.025971879324147e-277 +dd[1] = #6a00000 0 = 9.025971879324148e-277 + + +Input: 9.025971879324147880346310405869e-277 +strtodI consumes 37 bytes and returns 17 +dd[0] = #6a00000 0 = 9.025971879324148e-277 +dd[1] = #6a00000 1 = 9.02597187932415e-277 + + +Input: 9.025971879324147880346310405868e-277 +strtodI consumes 37 bytes and returns 33 +dd[0] = #69fffff ffffffff = 9.025971879324147e-277 +dd[1] = #6a00000 0 = 9.025971879324148e-277 + + +Input: 2.2250738585072014e-308 +strtodI consumes 23 bytes and returns 17 +dd[0] = #100000 0 = 2.2250738585072014e-308 +dd[1] = #100000 1 = 2.225073858507202e-308 + + +Input: 2.2250738585072013e-308 +strtodI consumes 23 bytes and returns 33 +dd[0] = #0 0 = 0 +dd[1] = #100000 0 = 2.2250738585072014e-308 + diff --git a/src/contrib/gdtoa/test/dItest.c b/src/contrib/gdtoa/test/dItest.c new file mode 100644 index 0000000..d9b56d5 --- /dev/null +++ b/src/contrib/gdtoa/test/dItest.c @@ -0,0 +1,88 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" +#include +#include + + static char ibuf[2048]; + +#define U (unsigned long) + + static void +#ifdef KR_headers +dshow(what, d) char *what; double d; +#else +dshow(char *what, double d) +#endif +{ + char buf[32]; + g_dfmt(buf, &d, 0, sizeof(buf)); + printf("%s = #%lx %lx = %s\n", what, + U ((ULong*)&d)[_0], U ((ULong*)&d)[_1], buf); + } + + int +main(Void) +{ + /* Input: one number per line */ + + char *s, *se, *se1; + int i, j; + double dd[2], dd1, dd2; + static char cfmt[] = "%s consumes %d bytes and returns %d\n"; + + while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) { + while(*s <= ' ') + if (!*s++) + continue; + printf("\nInput: %s", ibuf); + i = strtodI(ibuf, &se, dd); + printf(cfmt, "strtodI", (int)(se-ibuf), i); + dshow("dd[0]", dd[0]); + dshow("dd[1]", dd[1]); + printf("\n"); + j = strtoId(ibuf, &se1, &dd1, &dd2); + if (j != i || se != se1 + || dd[0] != dd1 || dd[1] != dd2) { + printf(cfmt, "**** strtoId", (int)(se-ibuf), j); + dshow("dd1", dd1); + dshow("dd2", dd2); + } + } + return 0; + } diff --git a/src/contrib/gdtoa/test/dd.out b/src/contrib/gdtoa/test/dd.out new file mode 100644 index 0000000..b1d2744 --- /dev/null +++ b/src/contrib/gdtoa/test/dd.out @@ -0,0 +1,1356 @@ + +Input: 1.23 +strtopdd consumes 4 bytes and returns 17 +dd[0] = 1.23 = #3ff3ae14 7ae147ae +dd[1] = 1.7763568394002496e-17 = #3c747ae1 47ae1478 +g_ddfmt(0) gives 4 bytes: "1.23" + +strtoIdd returns 17, consuming 4 bytes. +ddI[0] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1478 += 1.23 + 1.7763568394002496e-17 +ddI[1] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1480 += 1.23 + 1.776356839400252e-17 +ddI[0] == strtod + + +Input: 1.23e+20 +strtopdd consumes 8 bytes and returns 1 +dd[0] = 1.23e+20 = #441aabdf 2145b430 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 8 bytes: "1.23e+20" + +strtoIdd returns 1, consuming 8 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e-20 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530 +dd[1] = 9.304023318521521e-37 = #3873c997 955b2691 +g_ddfmt(0) gives 8 bytes: "1.23e-20" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690 += 1.2299999999999999e-20 + 9.3040233185215194e-37 +ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691 += 1.2299999999999999e-20 + 9.3040233185215211e-37 +ddI[1] == strtod + + +Input: 1.23456789 +strtopdd consumes 10 bytes and returns 17 +dd[0] = 1.23456789 = #3ff3c0ca 4283de1b +dd[1] = 1.0990618193318369e-16 = #3c9fada5 144c1252 +g_ddfmt(0) gives 10 bytes: "1.23456789" + +strtoIdd returns 17, consuming 10 bytes. +ddI[0] = #3ff3c0ca 4283de1b + 3c9fada5 144c1252 += 1.2345678899999999 + 1.0990618193318369e-16 +ddI[1] = #3ff3c0ca 4283de1b + 3c9fada5 144c1254 += 1.2345678899999999 + 1.0990618193318371e-16 +ddI[0] == strtod + + +Input: 1.23456589e+20 +strtopdd consumes 14 bytes and returns 1 +dd[0] = 1.23456589e+20 = #441ac537 a660b997 +dd[1] = 4096 = #40b00000 0 +g_ddfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIdd returns 1, consuming 14 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e+30 +strtopdd consumes 8 bytes and returns 1 +dd[0] = 1.23e+30 = #462f0cb0 4e8fb790 +dd[1] = 40281156091904 = #42c25158 0 +g_ddfmt(0) gives 8 bytes: "1.23e+30" + +strtoIdd returns 1, consuming 8 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e-30 +strtopdd consumes 8 bytes and returns 17 +dd[0] = 1.2299999999999999e-30 = #39b8f286 6f5010aa +dd[1] = 1.076909723013918e-46 = #3663ac7f 3dafd174 +g_ddfmt(0) gives 8 bytes: "1.23e-30" + +strtoIdd returns 17, consuming 8 bytes. +ddI[0] = #39b8f286 6f5010aa + 3663ac7f 3dafd174 += 1.2299999999999999e-30 + 1.076909723013918e-46 +ddI[1] = #39b8f286 6f5010aa + 3663ac7f 3dafd175 += 1.2299999999999999e-30 + 1.0769097230139181e-46 +ddI[0] == strtod + + +Input: 1.23456789e-20 +strtopdd consumes 14 bytes and returns 17 +dd[0] = 1.23456789e-20 = #3bcd2681 471e7ada +dd[1] = 6.247111971663133e-37 = #386a9280 a761b07e +g_ddfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIdd returns 17, consuming 14 bytes. +ddI[0] = #3bcd2681 471e7ada + 386a9280 a761b07e += 1.2345678899999999e-20 + 6.2471119716631328e-37 +ddI[1] = #3bcd2681 471e7ada + 386a9280 a761b080 += 1.2345678899999999e-20 + 6.2471119716631345e-37 +ddI[0] == strtod + + +Input: 1.23456789e-30 +strtopdd consumes 14 bytes and returns 33 +dd[0] = 1.23456789e-30 = #39b90a3e 33bbd995 +dd[1] = 2.1567930523648577e-47 = #363f8585 55a6b1a0 +g_ddfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIdd returns 33, consuming 14 bytes. +ddI[0] = #39b90a3e 33bbd995 + 363f8585 55a6b198 += 1.23456789e-30 + 2.1567930523648558e-47 +ddI[1] = #39b90a3e 33bbd995 + 363f8585 55a6b1a0 += 1.23456789e-30 + 2.1567930523648577e-47 +ddI[1] == strtod + + +Input: 1.234567890123456789 +strtopdd consumes 20 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e +g_ddfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIdd returns 33, consuming 20 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c += 1.2345678901234567 + 9.8567864525888563e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e += 1.2345678901234567 + 9.8567864525888588e-17 +ddI[1] == strtod + + +Input: 1.23456789012345678901234567890123456789 +strtopdd consumes 40 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.858021020478982e-17 = #3c9c69ef 85adadb6 +g_ddfmt(0) gives 34 bytes: "1.23456789012345678901234567890124" + +strtoIdd returns 33, consuming 40 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb4 += 1.2345678901234567 + 9.8580210204789798e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb6 += 1.2345678901234567 + 9.8580210204789823e-17 +ddI[1] == strtod + + +Input: 1.23e306 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e+306 = #7f7c0676 cd1c61f4 +dd[1] = 1.3319001448659015e+290 = #7c2b558b e3d3f477 +g_ddfmt(0) gives 9 bytes: "1.23e+306" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f476 += 1.2299999999999999e+306 + 1.3319001448659013e+290 +ddI[1] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f477 += 1.2299999999999999e+306 + 1.3319001448659015e+290 +ddI[1] == strtod + + +Input: 1.23e-306 +strtopdd consumes 9 bytes and returns 98 +dd[0] = 1.2299999999999999e-306 = #6ba3b8 5da396e7 +dd[1] = 1.43e-322 = #0 1d +g_ddfmt(0) gives 9 bytes: "1.23e-306" + +strtoIdd returns 98, consuming 9 bytes. +ddI[0] = #6ba3b8 5da396e7 + 0 1c += 1.2299999999999999e-306 + 1.3833838083554903e-322 +ddI[1] = #6ba3b8 5da396e7 + 0 1d += 1.2299999999999999e-306 + 1.432790372939615e-322 +ddI[1] == strtod + + +Input: 1.23e-320 +strtopdd consumes 9 bytes and returns 98 +dd[0] = 1.23e-320 = #0 9ba +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 9 bytes: "1.23e-320" + +strtoIdd returns 98, consuming 9 bytes. +ddI[0] = #0 9b9 + 0 0 += 1.2297293924988626e-320 + 0 +ddI[1] = #0 9ba + 0 0 += 1.2302234581447039e-320 + 0 +ddI[1] == strtod + + +Input: 1.23e-20 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530 +dd[1] = 9.304023318521521e-37 = #3873c997 955b2691 +g_ddfmt(0) gives 8 bytes: "1.23e-20" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690 += 1.2299999999999999e-20 + 9.3040233185215194e-37 +ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691 += 1.2299999999999999e-20 + 9.3040233185215211e-37 +ddI[1] == strtod + + +Input: 1.23456789e307 +strtopdd consumes 14 bytes and returns 33 +dd[0] = 1.2345678899999998e+307 = #7fb194b1 4bdaecdb +dd[1] = 2.0137933598720243e+291 = #7c69d48d 192048ca +g_ddfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIdd returns 33, consuming 14 bytes. +ddI[0] = #7fb194b1 4bdaecdb + 7c69d48d 192048c9 += 1.2345678899999998e+307 + 2.013793359872024e+291 +ddI[1] = #7fb194b1 4bdaecdb + 7c69d48d 192048ca += 1.2345678899999998e+307 + 2.0137933598720243e+291 +ddI[1] == strtod + + +Input: 1.23456589e-307 +strtopdd consumes 15 bytes and returns 98 +dd[0] = 1.23456589e-307 = #363196 bb9845fa +dd[1] = 1e-323 = #0 2 +g_ddfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIdd returns 98, consuming 15 bytes. +ddI[0] = #363196 bb9845fa + 0 1 += 1.2345658899999999e-307 + 4.9406564584124654e-324 +ddI[1] = #363196 bb9845fa + 0 2 += 1.2345658899999999e-307 + 9.8813129168249309e-324 +ddI[1] == strtod + + +Input: 1.234567890123456789 +strtopdd consumes 20 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e +g_ddfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIdd returns 33, consuming 20 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c += 1.2345678901234567 + 9.8567864525888563e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e += 1.2345678901234567 + 9.8567864525888588e-17 +ddI[1] == strtod + + +Input: 1.234567890123456789e301 +strtopdd consumes 24 bytes and returns 33 +dd[0] = 1.2345678901234568e+301 = #7e726f51 75f56413 +dd[1] = 1.3892003943918827e+283 = #7ab7ea80 76399100 +g_ddfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIdd returns 33, consuming 24 bytes. +ddI[0] = #7e726f51 75f56413 + 7ab7ea80 76399080 += 1.2345678901234568e+301 + 1.3892003943918563e+283 +ddI[1] = #7e726f51 75f56413 + 7ab7ea80 76399100 += 1.2345678901234568e+301 + 1.3892003943918827e+283 +ddI[1] == strtod + + +Input: 1.234567890123456789e-301 +strtopdd consumes 25 bytes and returns 82 +dd[0] = 1.2345678901234567e-301 = #1752a64 e34ba0d3 +dd[1] = 7.374365e-318 = #0 16c66c +g_ddfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIdd returns 82, consuming 25 bytes. +ddI[0] = #1752a64 e34ba0d3 + 0 16c66c += 1.2345678901234567e-301 + 7.374364541948945e-318 +ddI[1] = #1752a64 e34ba0d3 + 0 16c66d += 1.2345678901234567e-301 + 7.3743694826054034e-318 +ddI[0] == strtod + + +Input: 1.234567890123456789e-321 +strtopdd consumes 25 bytes and returns 98 +dd[0] = 1.235e-321 = #0 fa +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 10 bytes: "1.235e-321" + +strtoIdd returns 98, consuming 25 bytes. +ddI[0] = #0 f9 + 0 0 += 1.2302234581447039e-321 + 0 +ddI[1] = #0 fa + 0 0 += 1.2351641146031164e-321 + 0 +ddI[1] == strtod + + +Input: 1e23 +strtopdd consumes 4 bytes and returns 1 +dd[0] = 1e+23 = #44b52d02 c7e14af6 +dd[1] = 8388608 = #41600000 0 +g_ddfmt(0) gives 5 bytes: "1e+23" + +strtoIdd returns 1, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1e310 +strtopdd consumes 5 bytes and returns 163 +dd[0] = Infinity = #7ff00000 0 +dd[1] = Infinity = #7ff00000 0 +g_ddfmt(0) gives 8 bytes: "Infinity" + +strtoIdd returns 163, consuming 5 bytes. +ddI[0] = #7fefffff ffffffff + 7c9fffff ffffffff += 1.7976931348623157e+308 + 1.9958403095347196e+292 +ddI[1] = #7ff00000 0 + 7ff00000 0 += Infinity + Infinity +ddI[1] == strtod + + +Input: 9.0259718793241475e-277 +strtopdd consumes 23 bytes and returns 33 +dd[0] = 9.025971879324147e-277 = #69fffff ffffffff +dd[1] = 6.217378695986177e-293 = #343daae f3582320 +g_ddfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIdd returns 33, consuming 23 bytes. +ddI[0] = #69fffff ffffffff + 343daae f358231f += 9.0259718793241469e-277 + 6.2173786959861757e-293 +ddI[1] = #69fffff ffffffff + 343daae f3582320 += 9.0259718793241469e-277 + 6.2173786959861768e-293 +ddI[1] == strtod + + +Input: 9.025971879324147880346310405869e-277 +strtopdd consumes 37 bytes and returns 17 +dd[0] = 9.025971879324148e-277 = #6a00000 0 +dd[1] = 2.2250738585072014e-308 = #100000 0 +g_ddfmt(0) gives 37 bytes: "9.025971879324147880346310405869e-277" + +strtoIdd returns 17, consuming 37 bytes. +ddI[0] = #6a00000 0 + 100000 0 += 9.0259718793241479e-277 + 2.2250738585072014e-308 +ddI[1] = #6a00000 0 + 200000 0 += 9.0259718793241479e-277 + 4.4501477170144028e-308 +ddI[0] == strtod + + +Input: 9.025971879324147880346310405868e-277 +strtopdd consumes 37 bytes and returns 17 +dd[0] = 9.025971879324147e-277 = #69fffff ffffffff +dd[1] = 1.0020841800044856e-292 = #34fffff fffffff9 +g_ddfmt(0) gives 37 bytes: "9.025971879324147880346310405868e-277" + +strtoIdd returns 17, consuming 37 bytes. +ddI[0] = #69fffff ffffffff + 34fffff fffffff9 += 9.0259718793241469e-277 + 1.0020841800044856e-292 +ddI[1] = #69fffff ffffffff + 34fffff fffffffa += 9.0259718793241469e-277 + 1.0020841800044857e-292 +ddI[0] == strtod + + +Input: 2.2250738585072014e-308 +strtopdd consumes 23 bytes and returns 82 +dd[0] = 2.2250738585072014e-308 = #100000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIdd returns 82, consuming 23 bytes. +ddI[0] = #100000 0 + 0 0 += 2.2250738585072014e-308 + 0 +ddI[1] = #100000 1 + 0 0 += 2.2250738585072019e-308 + 0 +ddI[0] == strtod + + +Input: 2.2250738585072013e-308 +strtopdd consumes 23 bytes and returns 98 +dd[0] = 2.2250738585072014e-308 = #100000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIdd returns 98, consuming 23 bytes. +ddI[0] = #fffff ffffffff + 0 0 += 2.2250738585072009e-308 + 0 +ddI[1] = #100000 0 + 0 0 += 2.2250738585072014e-308 + 0 +ddI[1] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.0999999999999999 = #3ff19999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.1" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff19999 99999999 + 3ca33333 33333333 += 1.0999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff19999 99999999 + 3ca33333 33333334 += 1.0999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.1 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.0999999999999999 = #bff19999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.1" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff19999 99999999 + bca33333 33333334 += -1.0999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff19999 99999999 + bca33333 33333333 += -1.0999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.2 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.2 = #3ff33333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.2" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff33333 33333333 + 3c899999 99999998 += 1.2 + 4.4408920985006252e-17 +ddI[1] = #3ff33333 33333333 + 3c899999 9999999c += 1.2 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.2 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.2 = #bff33333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.2" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff33333 33333333 + bc899999 9999999c += -1.2 + -4.4408920985006276e-17 +ddI[1] = #bff33333 33333333 + bc899999 99999998 += -1.2 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.3 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.2999999999999998 = #3ff4cccc cccccccc +dd[1] = 1.7763568394002503e-16 = #3ca99999 99999999 +g_ddfmt(0) gives 34 bytes: "1.29999999999999999999999999999999" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff4cccc cccccccc + 3ca99999 99999999 += 1.2999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ff4cccc cccccccc + 3ca99999 9999999a += 1.2999999999999998 + 1.7763568394002506e-16 +ddI[0] == strtod + + +Input: -1.3 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.2999999999999998 = #bff4cccc cccccccc +dd[1] = -1.7763568394002503e-16 = #bca99999 99999999 +g_ddfmt(0) gives 35 bytes: "-1.29999999999999999999999999999999" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff4cccc cccccccc + bca99999 9999999a += -1.2999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bff4cccc cccccccc + bca99999 99999999 += -1.2999999999999998 + -1.7763568394002503e-16 +ddI[1] == strtod + + +Input: 1.4 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.4 = #3ff66666 66666666 +dd[1] = 8.88178419700125e-17 = #3c999999 99999998 +g_ddfmt(0) gives 34 bytes: "1.39999999999999999999999999999998" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff66666 66666666 + 3c999999 99999998 += 1.3999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ff66666 66666666 + 3c999999 9999999a += 1.3999999999999999 + 8.8817841970012528e-17 +ddI[0] == strtod + + +Input: -1.4 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.4 = #bff66666 66666666 +dd[1] = -8.88178419700125e-17 = #bc999999 99999998 +g_ddfmt(0) gives 35 bytes: "-1.39999999999999999999999999999998" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff66666 66666666 + bc999999 9999999a += -1.3999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bff66666 66666666 + bc999999 99999998 += -1.3999999999999999 + -8.8817841970012504e-17 +ddI[1] == strtod + + +Input: 1.5 +strtopdd consumes 3 bytes and returns 1 +dd[0] = 1.5 = #3ff80000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 1, consuming 3 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: -1.5 +strtopdd consumes 4 bytes and returns 9 +dd[0] = -1.5 = #bff80000 0 +dd[1] = -0 = #80000000 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 9, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.6 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.5999999999999999 = #3ff99999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.6" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff99999 99999999 + 3ca33333 33333333 += 1.5999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff99999 99999999 + 3ca33333 33333334 += 1.5999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.6 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.5999999999999999 = #bff99999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.6" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff99999 99999999 + bca33333 33333334 += -1.5999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff99999 99999999 + bca33333 33333333 += -1.5999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.7 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.7 = #3ffb3333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.7" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ffb3333 33333333 + 3c899999 99999998 += 1.7 + 4.4408920985006252e-17 +ddI[1] = #3ffb3333 33333333 + 3c899999 9999999c += 1.7 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.7 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.7 = #bffb3333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.7" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bffb3333 33333333 + bc899999 9999999c += -1.7 + -4.4408920985006276e-17 +ddI[1] = #bffb3333 33333333 + bc899999 99999998 += -1.7 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.8 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.7999999999999998 = #3ffccccc cccccccc +dd[1] = 1.7763568394002503e-16 = #3ca99999 99999999 +g_ddfmt(0) gives 34 bytes: "1.79999999999999999999999999999999" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffccccc cccccccc + 3ca99999 99999999 += 1.7999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ffccccc cccccccc + 3ca99999 9999999a += 1.7999999999999998 + 1.7763568394002506e-16 +ddI[0] == strtod + + +Input: -1.8 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.7999999999999998 = #bffccccc cccccccc +dd[1] = -1.7763568394002503e-16 = #bca99999 99999999 +g_ddfmt(0) gives 35 bytes: "-1.79999999999999999999999999999999" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffccccc cccccccc + bca99999 9999999a += -1.7999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bffccccc cccccccc + bca99999 99999999 += -1.7999999999999998 + -1.7763568394002503e-16 +ddI[1] == strtod + + +Input: 1.9 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.9 = #3ffe6666 66666666 +dd[1] = 8.88178419700125e-17 = #3c999999 99999998 +g_ddfmt(0) gives 34 bytes: "1.89999999999999999999999999999998" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffe6666 66666666 + 3c999999 99999998 += 1.8999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ffe6666 66666666 + 3c999999 9999999a += 1.8999999999999999 + 8.8817841970012528e-17 +ddI[0] == strtod + + +Input: -1.9 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.9 = #bffe6666 66666666 +dd[1] = -8.88178419700125e-17 = #bc999999 99999998 +g_ddfmt(0) gives 35 bytes: "-1.89999999999999999999999999999998" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffe6666 66666666 + bc999999 9999999a += -1.8999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bffe6666 66666666 + bc999999 99999998 += -1.8999999999999999 + -8.8817841970012504e-17 +ddI[1] == strtod + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.0999999999999999 = #3ff19999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.1" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff19999 99999999 + 3ca33333 33333333 += 1.0999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff19999 99999999 + 3ca33333 33333334 += 1.0999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.1 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.0999999999999999 = #bff19999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.1" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff19999 99999999 + bca33333 33333334 += -1.0999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff19999 99999999 + bca33333 33333333 += -1.0999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.2 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.2 = #3ff33333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.2" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff33333 33333333 + 3c899999 99999998 += 1.2 + 4.4408920985006252e-17 +ddI[1] = #3ff33333 33333333 + 3c899999 9999999c += 1.2 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.2 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.2 = #bff33333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.2" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff33333 33333333 + bc899999 9999999c += -1.2 + -4.4408920985006276e-17 +ddI[1] = #bff33333 33333333 + bc899999 99999998 += -1.2 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.3 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.2999999999999998 = #3ff4cccc cccccccc +dd[1] = 1.7763568394002506e-16 = #3ca99999 9999999a +g_ddfmt(0) gives 3 bytes: "1.3" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff4cccc cccccccc + 3ca99999 99999999 += 1.2999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ff4cccc cccccccc + 3ca99999 9999999a += 1.2999999999999998 + 1.7763568394002506e-16 +ddI[1] == strtod + + +Input: -1.3 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.2999999999999998 = #bff4cccc cccccccc +dd[1] = -1.7763568394002506e-16 = #bca99999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.3" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff4cccc cccccccc + bca99999 9999999a += -1.2999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bff4cccc cccccccc + bca99999 99999999 += -1.2999999999999998 + -1.7763568394002503e-16 +ddI[0] == strtod + + +Input: 1.4 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.4 = #3ff66666 66666666 +dd[1] = 8.881784197001253e-17 = #3c999999 9999999a +g_ddfmt(0) gives 3 bytes: "1.4" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff66666 66666666 + 3c999999 99999998 += 1.3999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ff66666 66666666 + 3c999999 9999999a += 1.3999999999999999 + 8.8817841970012528e-17 +ddI[1] == strtod + + +Input: -1.4 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.4 = #bff66666 66666666 +dd[1] = -8.881784197001253e-17 = #bc999999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.4" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff66666 66666666 + bc999999 9999999a += -1.3999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bff66666 66666666 + bc999999 99999998 += -1.3999999999999999 + -8.8817841970012504e-17 +ddI[0] == strtod + + +Input: 1.5 +strtopdd consumes 3 bytes and returns 1 +dd[0] = 1.5 = #3ff80000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 1, consuming 3 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: -1.5 +strtopdd consumes 4 bytes and returns 9 +dd[0] = -1.5 = #bff80000 0 +dd[1] = -0 = #80000000 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 9, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.6 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.5999999999999999 = #3ff99999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.6" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff99999 99999999 + 3ca33333 33333333 += 1.5999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff99999 99999999 + 3ca33333 33333334 += 1.5999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.6 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.5999999999999999 = #bff99999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.6" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff99999 99999999 + bca33333 33333334 += -1.5999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff99999 99999999 + bca33333 33333333 += -1.5999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.7 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.7 = #3ffb3333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.7" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ffb3333 33333333 + 3c899999 99999998 += 1.7 + 4.4408920985006252e-17 +ddI[1] = #3ffb3333 33333333 + 3c899999 9999999c += 1.7 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.7 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.7 = #bffb3333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.7" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bffb3333 33333333 + bc899999 9999999c += -1.7 + -4.4408920985006276e-17 +ddI[1] = #bffb3333 33333333 + bc899999 99999998 += -1.7 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.8 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.7999999999999998 = #3ffccccc cccccccc +dd[1] = 1.7763568394002506e-16 = #3ca99999 9999999a +g_ddfmt(0) gives 3 bytes: "1.8" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffccccc cccccccc + 3ca99999 99999999 += 1.7999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ffccccc cccccccc + 3ca99999 9999999a += 1.7999999999999998 + 1.7763568394002506e-16 +ddI[1] == strtod + + +Input: -1.8 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.7999999999999998 = #bffccccc cccccccc +dd[1] = -1.7763568394002506e-16 = #bca99999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.8" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffccccc cccccccc + bca99999 9999999a += -1.7999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bffccccc cccccccc + bca99999 99999999 += -1.7999999999999998 + -1.7763568394002503e-16 +ddI[0] == strtod + + +Input: 1.9 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.9 = #3ffe6666 66666666 +dd[1] = 8.881784197001253e-17 = #3c999999 9999999a +g_ddfmt(0) gives 3 bytes: "1.9" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffe6666 66666666 + 3c999999 99999998 += 1.8999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ffe6666 66666666 + 3c999999 9999999a += 1.8999999999999999 + 8.8817841970012528e-17 +ddI[1] == strtod + + +Input: -1.9 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.9 = #bffe6666 66666666 +dd[1] = -8.881784197001253e-17 = #bc999999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.9" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffe6666 66666666 + bc999999 9999999a += -1.8999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bffe6666 66666666 + bc999999 99999998 += -1.8999999999999999 + -8.8817841970012504e-17 +ddI[0] == strtod + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.0999999999999999 = #3ff19999 99999999 +dd[1] = 1.332267629550188e-16 = #3ca33333 33333334 +g_ddfmt(0) gives 34 bytes: "1.10000000000000000000000000000002" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff19999 99999999 + 3ca33333 33333333 += 1.0999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff19999 99999999 + 3ca33333 33333334 += 1.0999999999999999 + 1.332267629550188e-16 +ddI[1] == strtod + + +Input: -1.1 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.0999999999999999 = #bff19999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.1" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff19999 99999999 + bca33333 33333334 += -1.0999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff19999 99999999 + bca33333 33333333 += -1.0999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.2 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.2 = #3ff33333 33333333 +dd[1] = 4.4408920985006276e-17 = #3c899999 9999999c +g_ddfmt(0) gives 34 bytes: "1.20000000000000000000000000000001" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff33333 33333333 + 3c899999 99999998 += 1.2 + 4.4408920985006252e-17 +ddI[1] = #3ff33333 33333333 + 3c899999 9999999c += 1.2 + 4.4408920985006276e-17 +ddI[1] == strtod + + +Input: -1.2 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.2 = #bff33333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.2" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff33333 33333333 + bc899999 9999999c += -1.2 + -4.4408920985006276e-17 +ddI[1] = #bff33333 33333333 + bc899999 99999998 += -1.2 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.3 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.2999999999999998 = #3ff4cccc cccccccc +dd[1] = 1.7763568394002506e-16 = #3ca99999 9999999a +g_ddfmt(0) gives 3 bytes: "1.3" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff4cccc cccccccc + 3ca99999 99999999 += 1.2999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ff4cccc cccccccc + 3ca99999 9999999a += 1.2999999999999998 + 1.7763568394002506e-16 +ddI[1] == strtod + + +Input: -1.3 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.2999999999999998 = #bff4cccc cccccccc +dd[1] = -1.7763568394002503e-16 = #bca99999 99999999 +g_ddfmt(0) gives 35 bytes: "-1.29999999999999999999999999999999" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff4cccc cccccccc + bca99999 9999999a += -1.2999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bff4cccc cccccccc + bca99999 99999999 += -1.2999999999999998 + -1.7763568394002503e-16 +ddI[1] == strtod + + +Input: 1.4 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.4 = #3ff66666 66666666 +dd[1] = 8.881784197001253e-17 = #3c999999 9999999a +g_ddfmt(0) gives 3 bytes: "1.4" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff66666 66666666 + 3c999999 99999998 += 1.3999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ff66666 66666666 + 3c999999 9999999a += 1.3999999999999999 + 8.8817841970012528e-17 +ddI[1] == strtod + + +Input: -1.4 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.4 = #bff66666 66666666 +dd[1] = -8.88178419700125e-17 = #bc999999 99999998 +g_ddfmt(0) gives 35 bytes: "-1.39999999999999999999999999999998" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff66666 66666666 + bc999999 9999999a += -1.3999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bff66666 66666666 + bc999999 99999998 += -1.3999999999999999 + -8.8817841970012504e-17 +ddI[1] == strtod + + +Input: 1.5 +strtopdd consumes 3 bytes and returns 1 +dd[0] = 1.5 = #3ff80000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 1, consuming 3 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: -1.5 +strtopdd consumes 4 bytes and returns 9 +dd[0] = -1.5 = #bff80000 0 +dd[1] = -0 = #80000000 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 9, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.6 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.5999999999999999 = #3ff99999 99999999 +dd[1] = 1.332267629550188e-16 = #3ca33333 33333334 +g_ddfmt(0) gives 34 bytes: "1.60000000000000000000000000000002" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff99999 99999999 + 3ca33333 33333333 += 1.5999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff99999 99999999 + 3ca33333 33333334 += 1.5999999999999999 + 1.332267629550188e-16 +ddI[1] == strtod + + +Input: -1.6 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.5999999999999999 = #bff99999 99999999 +dd[1] = -1.3322676295501878e-16 = #bca33333 33333333 +g_ddfmt(0) gives 4 bytes: "-1.6" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff99999 99999999 + bca33333 33333334 += -1.5999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff99999 99999999 + bca33333 33333333 += -1.5999999999999999 + -1.3322676295501878e-16 +ddI[1] == strtod + + +Input: 1.7 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.7 = #3ffb3333 33333333 +dd[1] = 4.4408920985006276e-17 = #3c899999 9999999c +g_ddfmt(0) gives 34 bytes: "1.70000000000000000000000000000001" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ffb3333 33333333 + 3c899999 99999998 += 1.7 + 4.4408920985006252e-17 +ddI[1] = #3ffb3333 33333333 + 3c899999 9999999c += 1.7 + 4.4408920985006276e-17 +ddI[1] == strtod + + +Input: -1.7 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.7 = #bffb3333 33333333 +dd[1] = -4.440892098500625e-17 = #bc899999 99999998 +g_ddfmt(0) gives 4 bytes: "-1.7" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bffb3333 33333333 + bc899999 9999999c += -1.7 + -4.4408920985006276e-17 +ddI[1] = #bffb3333 33333333 + bc899999 99999998 += -1.7 + -4.4408920985006252e-17 +ddI[1] == strtod + + +Input: 1.8 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.7999999999999998 = #3ffccccc cccccccc +dd[1] = 1.7763568394002506e-16 = #3ca99999 9999999a +g_ddfmt(0) gives 3 bytes: "1.8" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffccccc cccccccc + 3ca99999 99999999 += 1.7999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ffccccc cccccccc + 3ca99999 9999999a += 1.7999999999999998 + 1.7763568394002506e-16 +ddI[1] == strtod + + +Input: -1.8 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.7999999999999998 = #bffccccc cccccccc +dd[1] = -1.7763568394002503e-16 = #bca99999 99999999 +g_ddfmt(0) gives 35 bytes: "-1.79999999999999999999999999999999" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffccccc cccccccc + bca99999 9999999a += -1.7999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bffccccc cccccccc + bca99999 99999999 += -1.7999999999999998 + -1.7763568394002503e-16 +ddI[1] == strtod + + +Input: 1.9 +strtopdd consumes 3 bytes and returns 33 +dd[0] = 1.9 = #3ffe6666 66666666 +dd[1] = 8.881784197001253e-17 = #3c999999 9999999a +g_ddfmt(0) gives 3 bytes: "1.9" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffe6666 66666666 + 3c999999 99999998 += 1.8999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ffe6666 66666666 + 3c999999 9999999a += 1.8999999999999999 + 8.8817841970012528e-17 +ddI[1] == strtod + + +Input: -1.9 +strtopdd consumes 4 bytes and returns 25 +dd[0] = -1.9 = #bffe6666 66666666 +dd[1] = -8.88178419700125e-17 = #bc999999 99999998 +g_ddfmt(0) gives 35 bytes: "-1.89999999999999999999999999999998" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffe6666 66666666 + bc999999 9999999a += -1.8999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bffe6666 66666666 + bc999999 99999998 += -1.8999999999999999 + -8.8817841970012504e-17 +ddI[1] == strtod + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.0999999999999999 = #3ff19999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.1" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff19999 99999999 + 3ca33333 33333333 += 1.0999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff19999 99999999 + 3ca33333 33333334 += 1.0999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.1 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.0999999999999999 = #bff19999 99999999 +dd[1] = -1.332267629550188e-16 = #bca33333 33333334 +g_ddfmt(0) gives 35 bytes: "-1.10000000000000000000000000000002" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff19999 99999999 + bca33333 33333334 += -1.0999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff19999 99999999 + bca33333 33333333 += -1.0999999999999999 + -1.3322676295501878e-16 +ddI[0] == strtod + + +Input: 1.2 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.2 = #3ff33333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.2" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff33333 33333333 + 3c899999 99999998 += 1.2 + 4.4408920985006252e-17 +ddI[1] = #3ff33333 33333333 + 3c899999 9999999c += 1.2 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.2 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.2 = #bff33333 33333333 +dd[1] = -4.4408920985006276e-17 = #bc899999 9999999c +g_ddfmt(0) gives 35 bytes: "-1.20000000000000000000000000000001" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff33333 33333333 + bc899999 9999999c += -1.2 + -4.4408920985006276e-17 +ddI[1] = #bff33333 33333333 + bc899999 99999998 += -1.2 + -4.4408920985006252e-17 +ddI[0] == strtod + + +Input: 1.3 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.2999999999999998 = #3ff4cccc cccccccc +dd[1] = 1.7763568394002503e-16 = #3ca99999 99999999 +g_ddfmt(0) gives 34 bytes: "1.29999999999999999999999999999999" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff4cccc cccccccc + 3ca99999 99999999 += 1.2999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ff4cccc cccccccc + 3ca99999 9999999a += 1.2999999999999998 + 1.7763568394002506e-16 +ddI[0] == strtod + + +Input: -1.3 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.2999999999999998 = #bff4cccc cccccccc +dd[1] = -1.7763568394002506e-16 = #bca99999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.3" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff4cccc cccccccc + bca99999 9999999a += -1.2999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bff4cccc cccccccc + bca99999 99999999 += -1.2999999999999998 + -1.7763568394002503e-16 +ddI[0] == strtod + + +Input: 1.4 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.4 = #3ff66666 66666666 +dd[1] = 8.88178419700125e-17 = #3c999999 99999998 +g_ddfmt(0) gives 34 bytes: "1.39999999999999999999999999999998" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ff66666 66666666 + 3c999999 99999998 += 1.3999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ff66666 66666666 + 3c999999 9999999a += 1.3999999999999999 + 8.8817841970012528e-17 +ddI[0] == strtod + + +Input: -1.4 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.4 = #bff66666 66666666 +dd[1] = -8.881784197001253e-17 = #bc999999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.4" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bff66666 66666666 + bc999999 9999999a += -1.3999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bff66666 66666666 + bc999999 99999998 += -1.3999999999999999 + -8.8817841970012504e-17 +ddI[0] == strtod + + +Input: 1.5 +strtopdd consumes 3 bytes and returns 1 +dd[0] = 1.5 = #3ff80000 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 1, consuming 3 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: -1.5 +strtopdd consumes 4 bytes and returns 9 +dd[0] = -1.5 = #bff80000 0 +dd[1] = -0 = #80000000 0 +g_ddfmt(0) gives 3 bytes: "1.5" + +strtoIdd returns 9, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.6 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.5999999999999999 = #3ff99999 99999999 +dd[1] = 1.3322676295501878e-16 = #3ca33333 33333333 +g_ddfmt(0) gives 3 bytes: "1.6" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ff99999 99999999 + 3ca33333 33333333 += 1.5999999999999999 + 1.3322676295501878e-16 +ddI[1] = #3ff99999 99999999 + 3ca33333 33333334 += 1.5999999999999999 + 1.332267629550188e-16 +ddI[0] == strtod + + +Input: -1.6 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.5999999999999999 = #bff99999 99999999 +dd[1] = -1.332267629550188e-16 = #bca33333 33333334 +g_ddfmt(0) gives 35 bytes: "-1.60000000000000000000000000000002" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bff99999 99999999 + bca33333 33333334 += -1.5999999999999999 + -1.332267629550188e-16 +ddI[1] = #bff99999 99999999 + bca33333 33333333 += -1.5999999999999999 + -1.3322676295501878e-16 +ddI[0] == strtod + + +Input: 1.7 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.7 = #3ffb3333 33333333 +dd[1] = 4.440892098500625e-17 = #3c899999 99999998 +g_ddfmt(0) gives 3 bytes: "1.7" + +strtoIdd returns 17, consuming 3 bytes. +ddI[0] = #3ffb3333 33333333 + 3c899999 99999998 += 1.7 + 4.4408920985006252e-17 +ddI[1] = #3ffb3333 33333333 + 3c899999 9999999c += 1.7 + 4.4408920985006276e-17 +ddI[0] == strtod + + +Input: -1.7 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.7 = #bffb3333 33333333 +dd[1] = -4.4408920985006276e-17 = #bc899999 9999999c +g_ddfmt(0) gives 35 bytes: "-1.70000000000000000000000000000001" + +strtoIdd returns 25, consuming 4 bytes. +ddI[0] = #bffb3333 33333333 + bc899999 9999999c += -1.7 + -4.4408920985006276e-17 +ddI[1] = #bffb3333 33333333 + bc899999 99999998 += -1.7 + -4.4408920985006252e-17 +ddI[0] == strtod + + +Input: 1.8 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.7999999999999998 = #3ffccccc cccccccc +dd[1] = 1.7763568394002503e-16 = #3ca99999 99999999 +g_ddfmt(0) gives 34 bytes: "1.79999999999999999999999999999999" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffccccc cccccccc + 3ca99999 99999999 += 1.7999999999999998 + 1.7763568394002503e-16 +ddI[1] = #3ffccccc cccccccc + 3ca99999 9999999a += 1.7999999999999998 + 1.7763568394002506e-16 +ddI[0] == strtod + + +Input: -1.8 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.7999999999999998 = #bffccccc cccccccc +dd[1] = -1.7763568394002506e-16 = #bca99999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.8" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffccccc cccccccc + bca99999 9999999a += -1.7999999999999998 + -1.7763568394002506e-16 +ddI[1] = #bffccccc cccccccc + bca99999 99999999 += -1.7999999999999998 + -1.7763568394002503e-16 +ddI[0] == strtod + + +Input: 1.9 +strtopdd consumes 3 bytes and returns 17 +dd[0] = 1.9 = #3ffe6666 66666666 +dd[1] = 8.88178419700125e-17 = #3c999999 99999998 +g_ddfmt(0) gives 34 bytes: "1.89999999999999999999999999999998" + +strtoIdd returns 33, consuming 3 bytes. +ddI[0] = #3ffe6666 66666666 + 3c999999 99999998 += 1.8999999999999999 + 8.8817841970012504e-17 +ddI[1] = #3ffe6666 66666666 + 3c999999 9999999a += 1.8999999999999999 + 8.8817841970012528e-17 +ddI[0] == strtod + + +Input: -1.9 +strtopdd consumes 4 bytes and returns 41 +dd[0] = -1.9 = #bffe6666 66666666 +dd[1] = -8.881784197001253e-17 = #bc999999 9999999a +g_ddfmt(0) gives 4 bytes: "-1.9" + +strtoIdd returns 41, consuming 4 bytes. +ddI[0] = #bffe6666 66666666 + bc999999 9999999a += -1.8999999999999999 + -8.8817841970012528e-17 +ddI[1] = #bffe6666 66666666 + bc999999 99999998 += -1.8999999999999999 + -8.8817841970012504e-17 +ddI[0] == strtod + diff --git a/src/contrib/gdtoa/test/ddsi.out b/src/contrib/gdtoa/test/ddsi.out new file mode 100644 index 0000000..1677707 --- /dev/null +++ b/src/contrib/gdtoa/test/ddsi.out @@ -0,0 +1,376 @@ + +Input: 1.23 +strtopdd consumes 4 bytes and returns 17 +dd[0] = 1.23 = #3ff3ae14 7ae147ae +dd[1] = 1.7763568394002496e-17 = #3c747ae1 47ae1478 +g_ddfmt(0) gives 4 bytes: "1.23" + +strtoIdd returns 17, consuming 4 bytes. +ddI[0] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1478 += 1.23 + 1.7763568394002496e-17 +ddI[1] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1480 += 1.23 + 1.776356839400252e-17 +ddI[0] == strtod + + +Input: 1.23e+20 +strtopdd consumes 8 bytes and returns 1 +dd[0] = 1.23e+20 = #441aabdf 2145b430 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 8 bytes: "1.23e+20" + +strtoIdd returns 1, consuming 8 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e-20 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530 +dd[1] = 9.304023318521521e-37 = #3873c997 955b2691 +g_ddfmt(0) gives 8 bytes: "1.23e-20" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690 += 1.2299999999999999e-20 + 9.3040233185215194e-37 +ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691 += 1.2299999999999999e-20 + 9.3040233185215211e-37 +ddI[1] == strtod + + +Input: 1.23456789 +strtopdd consumes 10 bytes and returns 17 +dd[0] = 1.23456789 = #3ff3c0ca 4283de1b +dd[1] = 1.0990618193318369e-16 = #3c9fada5 144c1252 +g_ddfmt(0) gives 10 bytes: "1.23456789" + +strtoIdd returns 17, consuming 10 bytes. +ddI[0] = #3ff3c0ca 4283de1b + 3c9fada5 144c1252 += 1.2345678899999999 + 1.0990618193318369e-16 +ddI[1] = #3ff3c0ca 4283de1b + 3c9fada5 144c1254 += 1.2345678899999999 + 1.0990618193318371e-16 +ddI[0] == strtod + + +Input: 1.23456589e+20 +strtopdd consumes 14 bytes and returns 1 +dd[0] = 1.23456589e+20 = #441ac537 a660b997 +dd[1] = 4096 = #40b00000 0 +g_ddfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIdd returns 1, consuming 14 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e+30 +strtopdd consumes 8 bytes and returns 1 +dd[0] = 1.23e+30 = #462f0cb0 4e8fb790 +dd[1] = 40281156091904 = #42c25158 0 +g_ddfmt(0) gives 8 bytes: "1.23e+30" + +strtoIdd returns 1, consuming 8 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1.23e-30 +strtopdd consumes 8 bytes and returns 17 +dd[0] = 1.2299999999999999e-30 = #39b8f286 6f5010aa +dd[1] = 1.076909723013918e-46 = #3663ac7f 3dafd174 +g_ddfmt(0) gives 8 bytes: "1.23e-30" + +strtoIdd returns 17, consuming 8 bytes. +ddI[0] = #39b8f286 6f5010aa + 3663ac7f 3dafd174 += 1.2299999999999999e-30 + 1.076909723013918e-46 +ddI[1] = #39b8f286 6f5010aa + 3663ac7f 3dafd175 += 1.2299999999999999e-30 + 1.0769097230139181e-46 +ddI[0] == strtod + + +Input: 1.23456789e-20 +strtopdd consumes 14 bytes and returns 17 +dd[0] = 1.23456789e-20 = #3bcd2681 471e7ada +dd[1] = 6.247111971663133e-37 = #386a9280 a761b07e +g_ddfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIdd returns 17, consuming 14 bytes. +ddI[0] = #3bcd2681 471e7ada + 386a9280 a761b07e += 1.2345678899999999e-20 + 6.2471119716631328e-37 +ddI[1] = #3bcd2681 471e7ada + 386a9280 a761b080 += 1.2345678899999999e-20 + 6.2471119716631345e-37 +ddI[0] == strtod + + +Input: 1.23456789e-30 +strtopdd consumes 14 bytes and returns 33 +dd[0] = 1.23456789e-30 = #39b90a3e 33bbd995 +dd[1] = 2.1567930523648577e-47 = #363f8585 55a6b1a0 +g_ddfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIdd returns 33, consuming 14 bytes. +ddI[0] = #39b90a3e 33bbd995 + 363f8585 55a6b198 += 1.23456789e-30 + 2.1567930523648558e-47 +ddI[1] = #39b90a3e 33bbd995 + 363f8585 55a6b1a0 += 1.23456789e-30 + 2.1567930523648577e-47 +ddI[1] == strtod + + +Input: 1.234567890123456789 +strtopdd consumes 20 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e +g_ddfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIdd returns 33, consuming 20 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c += 1.2345678901234567 + 9.8567864525888563e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e += 1.2345678901234567 + 9.8567864525888588e-17 +ddI[1] == strtod + + +Input: 1.23456789012345678901234567890123456789 +strtopdd consumes 40 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.858021020478982e-17 = #3c9c69ef 85adadb6 +g_ddfmt(0) gives 34 bytes: "1.23456789012345678901234567890124" + +strtoIdd returns 33, consuming 40 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb4 += 1.2345678901234567 + 9.8580210204789798e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb6 += 1.2345678901234567 + 9.8580210204789823e-17 +ddI[1] == strtod + + +Input: 1.23e306 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e+306 = #7f7c0676 cd1c61f4 +dd[1] = 1.3319001448659015e+290 = #7c2b558b e3d3f477 +g_ddfmt(0) gives 9 bytes: "1.23e+306" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f476 += 1.2299999999999999e+306 + 1.3319001448659013e+290 +ddI[1] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f477 += 1.2299999999999999e+306 + 1.3319001448659015e+290 +ddI[1] == strtod + + +Input: 1.23e-306 +strtopdd consumes 9 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 9 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 1.23e-320 +strtopdd consumes 9 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 9 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 1.23e-20 +strtopdd consumes 8 bytes and returns 33 +dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530 +dd[1] = 9.304023318521521e-37 = #3873c997 955b2691 +g_ddfmt(0) gives 8 bytes: "1.23e-20" + +strtoIdd returns 33, consuming 8 bytes. +ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690 += 1.2299999999999999e-20 + 9.3040233185215194e-37 +ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691 += 1.2299999999999999e-20 + 9.3040233185215211e-37 +ddI[1] == strtod + + +Input: 1.23456789e307 +strtopdd consumes 14 bytes and returns 33 +dd[0] = 1.2345678899999998e+307 = #7fb194b1 4bdaecdb +dd[1] = 2.0137933598720243e+291 = #7c69d48d 192048ca +g_ddfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIdd returns 33, consuming 14 bytes. +ddI[0] = #7fb194b1 4bdaecdb + 7c69d48d 192048c9 += 1.2345678899999998e+307 + 2.013793359872024e+291 +ddI[1] = #7fb194b1 4bdaecdb + 7c69d48d 192048ca += 1.2345678899999998e+307 + 2.0137933598720243e+291 +ddI[1] == strtod + + +Input: 1.23456589e-307 +strtopdd consumes 15 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 15 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 1.234567890123456789 +strtopdd consumes 20 bytes and returns 33 +dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb +dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e +g_ddfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIdd returns 33, consuming 20 bytes. +ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c += 1.2345678901234567 + 9.8567864525888563e-17 +ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e += 1.2345678901234567 + 9.8567864525888588e-17 +ddI[1] == strtod + + +Input: 1.234567890123456789e301 +strtopdd consumes 24 bytes and returns 33 +dd[0] = 1.2345678901234568e+301 = #7e726f51 75f56413 +dd[1] = 1.3892003943918827e+283 = #7ab7ea80 76399100 +g_ddfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIdd returns 33, consuming 24 bytes. +ddI[0] = #7e726f51 75f56413 + 7ab7ea80 76399080 += 1.2345678901234568e+301 + 1.3892003943918563e+283 +ddI[1] = #7e726f51 75f56413 + 7ab7ea80 76399100 += 1.2345678901234568e+301 + 1.3892003943918827e+283 +ddI[1] == strtod + + +Input: 1.234567890123456789e-301 +strtopdd consumes 25 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 25 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 1.234567890123456789e-321 +strtopdd consumes 25 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 25 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 1e23 +strtopdd consumes 4 bytes and returns 1 +dd[0] = 1e+23 = #44b52d02 c7e14af6 +dd[1] = 8388608 = #41600000 0 +g_ddfmt(0) gives 5 bytes: "1e+23" + +strtoIdd returns 1, consuming 4 bytes. +ddI[0] == ddI[1] == strtopdd + + +Input: 1e310 +strtopdd consumes 5 bytes and returns 163 +dd[0] = Infinity = #7ff00000 0 +dd[1] = Infinity = #7ff00000 0 +g_ddfmt(0) gives 8 bytes: "Infinity" + +strtoIdd returns 163, consuming 5 bytes. +ddI[0] = #7fefffff ffffffff + 7c9fffff ffffffff += 1.7976931348623157e+308 + 1.9958403095347196e+292 +ddI[1] = #7ff00000 0 + 7ff00000 0 += Infinity + Infinity +ddI[1] == strtod + + +Input: 9.0259718793241475e-277 +strtopdd consumes 23 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 23 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 9.025971879324147880346310405869e-277 +strtopdd consumes 37 bytes and returns 17 +dd[0] = 9.025971879324148e-277 = #6a00000 0 +dd[1] = 2.2250738585072014e-308 = #100000 0 +g_ddfmt(0) gives 37 bytes: "9.025971879324147880346310405869e-277" + +strtoIdd returns 17, consuming 37 bytes. +ddI[0] = #6a00000 0 + 100000 0 += 9.0259718793241479e-277 + 2.2250738585072014e-308 +ddI[1] = #6a00000 0 + 200000 0 += 9.0259718793241479e-277 + 4.4501477170144028e-308 +ddI[0] == strtod + + +Input: 9.025971879324147880346310405868e-277 +strtopdd consumes 37 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 37 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 2.2250738585072014e-308 +strtopdd consumes 23 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 23 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + + +Input: 2.2250738585072013e-308 +strtopdd consumes 23 bytes and returns 80 +dd[0] = 0 = #0 0 +dd[1] = 0 = #0 0 +g_ddfmt(0) gives 1 bytes: "0" + +strtoIdd returns 80, consuming 23 bytes. +ddI[0] = #0 0 + 0 0 += 0 + 0 +ddI[1] = #6a00000 0 + 0 0 += 9.0259718793241479e-277 + 0 +ddI[0] == strtod + diff --git a/src/contrib/gdtoa/test/ddtest.c b/src/contrib/gdtoa/test/ddtest.c new file mode 100644 index 0000000..aa32e92 --- /dev/null +++ b/src/contrib/gdtoa/test/ddtest.c @@ -0,0 +1,183 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_ddfmt, strtoIdd, strtopdd, and strtordd. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex0 hex1 hex2 hex3 + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex0 is a string of <= 8 Hex digits for the most significant + * word of the number, hex1 is a similar string for the next + * word, etc., and ndig is a parameters to g_ddfmt. + */ + +#include "gdtoaimp.h" +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[1024]; + +#define U (unsigned long) + + static void +#ifdef KR_headers +dprint(what, d) char *what; double d; +#else +dprint(char *what, double d) +#endif +{ + char buf[32]; + ULong *L = (ULong*)&d; + + g_dfmt(buf,&d,0,sizeof(buf)); + printf("%s = %s = #%lx %lx\n", what, buf, U L[_0], U L[_1]); + } + + int +main(Void) +{ + ULong *L; + char *s, *s1, *se, *se1; + int dItry, i, j, r = 1, ndig = 0; + double dd[2], ddI[4]; + long LL[4]; + + L = (ULong*)&dd[0]; + while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) { + while(*s <= ' ') + if (!*s++) + continue; + dItry = 0; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + LL[0] = L[_0]; + LL[1] = L[_1]; + LL[2] = L[2+_0]; + LL[3] = L[2+_1]; + sscanf(s+1, "%lx %lx %lx %lx", &LL[0], &LL[1], + &LL[2], &LL[3]); + L[_0] = LL[0]; + L[_1] = LL[1]; + L[2+_0] = LL[2]; + L[2+_1] = LL[3]; + printf("\nInput: %s", ibuf); + printf(" --> f = #%lx %lx %lx %lx\n", + LL[0],LL[1],LL[2],LL[3]); + goto fmt_test; + } + printf("\nInput: %s", ibuf); + for(s1 = s; *s1 > ' '; s1++){}; + while(*s1 <= ' ' && *s1) s1++; + if (!*s1) { + dItry = 1; + i = strtordd(ibuf, &se, r, dd); + if (r == 1) { + j = strtopdd(ibuf, &se1, ddI); + if (i != j || dd[0] != ddI[0] + || dd[1] != ddI[1] || se != se1) + printf("***strtopdd and strtordd disagree!!\n:"); + } + printf("strtopdd consumes %d bytes and returns %d\n", + (int)(se-ibuf), i); + } + else { + dd[0] = strtod(s, &se); + dd[1] = strtod(se, &se); + } + fmt_test: + dprint("dd[0]", dd[0]); + dprint("dd[1]", dd[1]); + se = g_ddfmt(obuf, dd, ndig, sizeof(obuf)); + printf("g_ddfmt(%d) gives %d bytes: \"%s\"\n\n", + ndig, (int)(se-obuf), se ? obuf : ""); + if (!dItry) + continue; + printf("strtoIdd returns %d,", strtoIdd(ibuf, &se, ddI,&ddI[2])); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (ddI[0] == ddI[2] && ddI[1] == ddI[3]) { + if (ddI[0] == dd[0] && ddI[1] == dd[1]) + printf("ddI[0] == ddI[1] == strtopdd\n"); + else + printf("ddI[0] == ddI[1] = #%lx %lx + %lx %lx\n= %.17g + %17.g\n", + U ((ULong*)ddI)[_0], + U ((ULong*)ddI)[_1], + U ((ULong*)ddI)[2+_0], + U ((ULong*)ddI)[2+_1], + ddI[0], ddI[1]); + } + else { + printf("ddI[0] = #%lx %lx + %lx %lx\n= %.17g + %.17g\n", + U ((ULong*)ddI)[_0], U ((ULong*)ddI)[_1], + U ((ULong*)ddI)[2+_0], U ((ULong*)ddI)[2+_1], + ddI[0], ddI[1]); + printf("ddI[1] = #%lx %lx + %lx %lx\n= %.17g + %.17g\n", + U ((ULong*)ddI)[4+_0], U ((ULong*)ddI)[4+_1], + U ((ULong*)ddI)[6+_0], U ((ULong*)ddI)[6+_1], + ddI[2], ddI[3]); + if (ddI[0] == dd[0] && ddI[1] == dd[1]) + printf("ddI[0] == strtod\n"); + else if (ddI[2] == dd[0] && ddI[3] == dd[1]) + printf("ddI[1] == strtod\n"); + else + printf("**** Both differ from strtopdd ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/dt.c b/src/contrib/gdtoa/test/dt.c new file mode 100644 index 0000000..1a86ba3 --- /dev/null +++ b/src/contrib/gdtoa/test/dt.c @@ -0,0 +1,275 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for strtod and dtoa. + * + * Inputs (on stdin): + * number[: mode [ndigits]] + * or + * #hex0 hex1[: mode [ndigits]] + * where number is a decimal floating-point number, + * hex0 is a string of Hex digits for the most significant + * word of the number, hex1 is a similar string for the other + * (least significant) word, and mode and ndigits are + * parameters to dtoa. + */ + +#include +#include "gdtoa.h" +#ifdef KR_headers +#define Void /*void*/ +#else +#define Void void +#endif + +#ifdef __STDC__ +#include +#else +#ifdef __cplusplus +extern "C" double atof(const char*); +#else +extern double atof ANSI((char*)); +#endif +#endif +#ifdef IEEE_8087 +#define word0(x) ((ULong *)&x)[1] +#define word1(x) ((ULong *)&x)[0] +#else +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[1] +#endif +#include "errno.h" + +#ifdef __cplusplus +extern "C" char *dtoa(double, int, int, int*, int*, char **); +#else +extern char *dtoa ANSI((double, int, int, int*, int*, char **)); +#endif + + static void +#ifdef KR_headers +g_fmt(b, x) char *b; double x; +#else +g_fmt(char *b, double x) +#endif +{ + char *s, *se; + int decpt, i, j, k, sign; + + if (!x) { + *b++ = '0'; + *b = 0; + return; + } + s = dtoa(x, 0, 0, &decpt, &sign, &se); + if (sign) + *b++ = '-'; + if (decpt == 9999) /* Infinity or Nan */ { + while(*b++ = *s++); + return; + } + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = '.'; + while(*b = *s++) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}; + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } + else if (decpt <= 0) { + *b++ = '.'; + for(; decpt < 0; decpt++) + *b++ = '0'; + while(*b++ = *s++); + } + else { + while(*b = *s++) { + b++; + if (--decpt == 0 && *s) + *b++ = '.'; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + } + + static void +baderrno(Void) +{ + fflush(stdout); + perror("\nerrno strtod"); + fflush(stderr); + } + +#define U (unsigned long) + + static void +#ifdef KR_headers +check(d) double d; +#else +check(double d) +#endif +{ + char buf[64]; + int decpt, sign; + char *s, *se; + double d1; + + s = dtoa(d, 0, 0, &decpt, &sign, &se); + sprintf(buf, "%s.%se%d", sign ? "-" : "", s, decpt); + errno = 0; + d1 = strtod(buf, (char **)0); + if (errno) + baderrno(); + if (d != d1) { + printf("sent d = %.17g = 0x%lx %lx, buf = %s\n", + d, U word0(d), U word1(d), buf); + printf("got d1 = %.17g = 0x%lx %lx\n", + d1, U word0(d1), U word1(d1)); + } + } + +main(Void){ + char buf[2048], buf1[32]; + char *fmt, *s, *se; + double d, d1; + int decpt, sign; + int mode = 0, ndigits = 17; + ULong x, y; +#ifdef VAX + ULong z; +#endif + + while(fgets(buf, sizeof(buf), stdin)) { + if (*buf == '*') { + printf("%s", buf); + continue; + } + printf("Input: %s", buf); + if (*buf == '#') { + x = word0(d); + y = word1(d); + sscanf(buf+1, "%lx %lx:%d %d", &x, &y, &mode, &ndigits); + word0(d) = x; + word1(d) = y; + fmt = "Output: d =\n%.17g = 0x%lx %lx\n"; + } + else { + errno = 0; + d = strtod(buf,&se); + if (*se == ':') + sscanf(se+1,"%d %d", &mode, &ndigits); + d1 = atof(buf); + fmt = "Output: d =\n%.17g = 0x%lx %lx, se = %s"; + if (errno) + baderrno(); + } + printf(fmt, d, U word0(d), U word1(d), se); + g_fmt(buf1, d); + printf("\tg_fmt gives \"%s\"\n", buf1); + if (*buf != '#' && d != d1) + printf("atof gives\n\ + d1 = %.17g = 0x%lx %lx\nversus\n\ + d = %.17g = 0x%lx %lx\n", d1, U word0(d1), U word1(d1), + d, U word0(d), U word1(d)); + check(d); + s = dtoa(d, mode, ndigits, &decpt, &sign, &se); + printf("\tdtoa(mode = %d, ndigits = %d):\n", mode, ndigits); + printf("\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n", + sign, decpt, se-s, s); + x = word1(d); + if (x != 0xffffffff + && (word0(d) & 0x7ff00000) != 0x7ff00000) { +#ifdef VAX + z = x << 16 | x >> 16; + z++; + z = z << 16 | z >> 16; + word1(d) = z; +#else + word1(d) = x + 1; +#endif + printf("\tnextafter(d,+Inf) = %.17g = 0x%lx %lx:\n", + d, U word0(d), U word1(d)); + g_fmt(buf1, d); + printf("\tg_fmt gives \"%s\"\n", buf1); + s = dtoa(d, mode, ndigits, &decpt, &sign, &se); + printf( + "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n", + sign, decpt, se-s, s); + check(d); + } + if (x) { +#ifdef VAX + z = x << 16 | x >> 16; + z--; + z = z << 16 | z >> 16; + word1(d) = z; +#else + word1(d) = x - 1; +#endif + printf("\tnextafter(d,-Inf) = %.17g = 0x%lx %lx:\n", + d, U word0(d), U word1(d)); + g_fmt(buf1, d); + printf("\tg_fmt gives \"%s\"\n", buf1); + s = dtoa(d, mode, ndigits, &decpt, &sign, &se); + printf( + "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n", + sign, decpt, se-s, s); + check(d); + } + } + return 0; + } diff --git a/src/contrib/gdtoa/test/dtest.c b/src/contrib/gdtoa/test/dtest.c new file mode 100644 index 0000000..e07b1a8 --- /dev/null +++ b/src/contrib/gdtoa/test/dtest.c @@ -0,0 +1,146 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_dfmt, strtoId, strtod, strtopd, and strtord. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex0 hex1 + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex0 is a string of Hex <= 8 digits for the most significant + * word of the number, hex1 is a similar string for the other + * (least significant) word, and ndig is a parameters to g_dfmt. + */ + +#include "gdtoaimp.h" +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[1024]; + +#define U (unsigned long) + + int +main(Void) +{ + ULong *L; + char *s, *se, *se1; + double f, f1, fI[2]; + int i, i1, ndig = 0, r = 1; + long LL[2]; + + L = (ULong*)&f; + while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) { + while(*s <= ' ') + if (!*s++) + continue; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + LL[0] = L[_0]; + LL[1] = L[_1]; + sscanf(s+1, "%lx %lx", &LL[0], &LL[1]); + L[_0] = LL[0]; + L[_1] = LL[1]; + printf("\nInput: %s", ibuf); + printf("--> f = #%lx %lx\n", (long)L[_0], (long)L[_1]); + goto fmt_test; + } + printf("\nInput: %s", ibuf); + i = strtord(ibuf, &se, r, &f); + if (r == 1) { + if ((f != strtod(ibuf, &se1) || se1 != se)) + printf("***strtod and strtord disagree!!\n"); + i1 = strtopd(ibuf, &se, &f1); + if (i != i1 || f != f1 || se != se1) + printf("***strtord and strtopd disagree!!\n"); + } + printf("strtod consumes %d bytes and returns %d with f = %.17g = #%lx %lx\n", + (int)(se-ibuf), i, f, U L[_0], U L[_1]); + fmt_test: + se = g_dfmt(obuf, &f, ndig, sizeof(obuf)); + printf("g_dfmt(%d) gives %d bytes: \"%s\"\n\n", + ndig, (int)(se-obuf), se ? obuf : ""); + if (*s == '#') + continue; + printf("strtoId returns %d,", strtoId(ibuf, &se, fI, &fI[1])); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (fI[0] == fI[1]) { + if (fI[0] == f) + printf("fI[0] == fI[1] == strtod\n"); + else + printf("fI[0] == fI[1] = #%lx %lx = %.17g\n", + U ((ULong*)fI)[_0], U ((ULong*)fI)[_1], + fI[0]); + } + else { + printf("fI[0] = #%lx %lx = %.17g\n", + U ((ULong*)fI)[_0], U ((ULong*)fI)[_1], fI[0]); + printf("fI[1] = #%lx %lx = %.17g\n", + U ((ULong*)&fI[1])[_0], U ((ULong*)&fI[1])[_1], + fI[1]); + if (fI[0] == f) + printf("fI[0] == strtod\n"); + else if (fI[1] == f) + printf("fI[1] == strtod\n"); + else + printf("**** Both differ from strtod ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/dtst.out b/src/contrib/gdtoa/test/dtst.out new file mode 100644 index 0000000..1ec70ab --- /dev/null +++ b/src/contrib/gdtoa/test/dtst.out @@ -0,0 +1,686 @@ +Input: 1.23 +Output: d = +1.23 = 0x3ff3ae14 7ae147ae, se = + g_fmt gives "1.23" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 1, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af: + g_fmt gives "1.2300000000000002" + dtoa returns sign = 0, decpt = 1, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad: + g_fmt gives "1.2299999999999998" + dtoa returns sign = 0, decpt = 1, 17 digits: +12299999999999998 +Input: 1.23e+20 +Output: d = +1.23e+20 = 0x441aabdf 2145b430, se = + g_fmt gives "1.23e+20" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 21, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431: + g_fmt gives "123000000000000020000" + dtoa returns sign = 0, decpt = 21, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f: + g_fmt gives "122999999999999980000" + dtoa returns sign = 0, decpt = 21, 17 digits: +12299999999999998 +Input: 1.23e-20 +Output: d = +1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = + g_fmt gives "1.23e-20" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532: + g_fmt gives "1.2300000000000002e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530: + g_fmt gives "1.2299999999999999e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12299999999999999 +Input: 1.23456789 +Output: d = +1.2345678899999999 = 0x3ff3c0ca 4283de1b, se = + g_fmt gives "1.23456789" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 1, 9 digits: +123456789 + nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c: + g_fmt gives "1.2345678900000001" + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678900000001 + nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a: + g_fmt gives "1.2345678899999997" + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678899999997 +Input: 1.23456589e+20 +Output: d = +1.23456589e+20 = 0x441ac537 a660b997, se = + g_fmt gives "1.23456589e+20" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 21, 9 digits: +123456589 + nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998: + g_fmt gives "123456589000000010000" + dtoa returns sign = 0, decpt = 21, 17 digits: +12345658900000001 + nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996: + g_fmt gives "123456588999999980000" + dtoa returns sign = 0, decpt = 21, 17 digits: +12345658899999998 +Input: 1.23e+30 +Output: d = +1.23e+30 = 0x462f0cb0 4e8fb790, se = + g_fmt gives "1.23e+30" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 31, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000001e+30 = 0x462f0cb0 4e8fb791: + g_fmt gives "1.2300000000000001e+30" + dtoa returns sign = 0, decpt = 31, 17 digits: +12300000000000001 + nextafter(d,-Inf) = 1.2299999999999998e+30 = 0x462f0cb0 4e8fb78f: + g_fmt gives "1.2299999999999998e+30" + dtoa returns sign = 0, decpt = 31, 17 digits: +12299999999999998 +Input: 1.23e-30 +Output: d = +1.2300000000000001e-30 = 0x39b8f286 6f5010ab, se = + g_fmt gives "1.23e-30" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -29, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-30 = 0x39b8f286 6f5010ac: + g_fmt gives "1.2300000000000002e-30" + dtoa returns sign = 0, decpt = -29, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999999e-30 = 0x39b8f286 6f5010aa: + g_fmt gives "1.2299999999999999e-30" + dtoa returns sign = 0, decpt = -29, 17 digits: +12299999999999999 +Input: 1.23456789e-20 +Output: d = +1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se = + g_fmt gives "1.23456789e-20" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -19, 9 digits: +123456789 + nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb: + g_fmt gives "1.2345678900000001e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12345678900000001 + nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9: + g_fmt gives "1.2345678899999998e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12345678899999998 +Input: 1.23456789e-30 +Output: d = +1.23456789e-30 = 0x39b90a3e 33bbd995, se = + g_fmt gives "1.23456789e-30" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -29, 9 digits: +123456789 + nextafter(d,+Inf) = 1.2345678900000002e-30 = 0x39b90a3e 33bbd996: + g_fmt gives "1.2345678900000002e-30" + dtoa returns sign = 0, decpt = -29, 17 digits: +12345678900000002 + nextafter(d,-Inf) = 1.2345678899999998e-30 = 0x39b90a3e 33bbd994: + g_fmt gives "1.2345678899999998e-30" + dtoa returns sign = 0, decpt = -29, 17 digits: +12345678899999998 +Input: 1.234567890123456789 +Output: d = +1.2345678901234567 = 0x3ff3c0ca 428c59fb, se = + g_fmt gives "1.2345678901234567" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234567 + nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc: + g_fmt gives "1.234567890123457" + dtoa returns sign = 0, decpt = 1, 16 digits: +1234567890123457 + nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa: + g_fmt gives "1.2345678901234565" + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234565 +Input: 1.23456789012345678901234567890123456789 +Output: d = +1.2345678901234567 = 0x3ff3c0ca 428c59fb, se = + g_fmt gives "1.2345678901234567" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234567 + nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc: + g_fmt gives "1.234567890123457" + dtoa returns sign = 0, decpt = 1, 16 digits: +1234567890123457 + nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa: + g_fmt gives "1.2345678901234565" + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234565 +Input: 1.23e306 +Output: d = +1.23e+306 = 0x7f7c0676 cd1c61f5, se = + g_fmt gives "1.23e+306" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 307, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e+306 = 0x7f7c0676 cd1c61f6: + g_fmt gives "1.2300000000000002e+306" + dtoa returns sign = 0, decpt = 307, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999999e+306 = 0x7f7c0676 cd1c61f4: + g_fmt gives "1.2299999999999999e+306" + dtoa returns sign = 0, decpt = 307, 17 digits: +12299999999999999 +Input: 1.23e-306 +Output: d = +1.23e-306 = 0x6ba3b8 5da396e8, se = + g_fmt gives "1.23e-306" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -305, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-306 = 0x6ba3b8 5da396e9: + g_fmt gives "1.2300000000000002e-306" + dtoa returns sign = 0, decpt = -305, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999999e-306 = 0x6ba3b8 5da396e7: + g_fmt gives "1.2299999999999999e-306" + dtoa returns sign = 0, decpt = -305, 17 digits: +12299999999999999 +Input: 1.23e-320 +Output: d = +1.2302234581447039e-320 = 0x0 9ba, se = + g_fmt gives "1.23e-320" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -319, 3 digits: +123 + nextafter(d,+Inf) = 1.2307175237905451e-320 = 0x0 9bb: + g_fmt gives "1.2307e-320" + dtoa returns sign = 0, decpt = -319, 5 digits: +12307 + nextafter(d,-Inf) = 1.2297293924988626e-320 = 0x0 9b9: + g_fmt gives "1.2297e-320" + dtoa returns sign = 0, decpt = -319, 5 digits: +12297 +Input: 1.23e-20 +Output: d = +1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = + g_fmt gives "1.23e-20" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532: + g_fmt gives "1.2300000000000002e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12300000000000002 + nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530: + g_fmt gives "1.2299999999999999e-20" + dtoa returns sign = 0, decpt = -19, 17 digits: +12299999999999999 +Input: 1.23456789e307 +Output: d = +1.23456789e+307 = 0x7fb194b1 4bdaecdc, se = + g_fmt gives "1.23456789e+307" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 308, 9 digits: +123456789 + nextafter(d,+Inf) = 1.2345678900000003e+307 = 0x7fb194b1 4bdaecdd: + g_fmt gives "1.2345678900000003e+307" + dtoa returns sign = 0, decpt = 308, 17 digits: +12345678900000003 + nextafter(d,-Inf) = 1.2345678899999998e+307 = 0x7fb194b1 4bdaecdb: + g_fmt gives "1.2345678899999998e+307" + dtoa returns sign = 0, decpt = 308, 17 digits: +12345678899999998 +Input: 1.23456589e-307 +Output: d = +1.2345658899999999e-307 = 0x363196 bb9845fa, se = + g_fmt gives "1.23456589e-307" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -306, 9 digits: +123456589 + nextafter(d,+Inf) = 1.2345658900000001e-307 = 0x363196 bb9845fb: + g_fmt gives "1.2345658900000001e-307" + dtoa returns sign = 0, decpt = -306, 17 digits: +12345658900000001 + nextafter(d,-Inf) = 1.2345658899999997e-307 = 0x363196 bb9845f9: + g_fmt gives "1.2345658899999997e-307" + dtoa returns sign = 0, decpt = -306, 17 digits: +12345658899999997 +Input: 1.234567890123456789 +Output: d = +1.2345678901234567 = 0x3ff3c0ca 428c59fb, se = + g_fmt gives "1.2345678901234567" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234567 + nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc: + g_fmt gives "1.234567890123457" + dtoa returns sign = 0, decpt = 1, 16 digits: +1234567890123457 + nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa: + g_fmt gives "1.2345678901234565" + dtoa returns sign = 0, decpt = 1, 17 digits: +12345678901234565 +Input: 1.234567890123456789e301 +Output: d = +1.2345678901234568e+301 = 0x7e726f51 75f56413, se = + g_fmt gives "1.2345678901234568e+301" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 302, 17 digits: +12345678901234568 + nextafter(d,+Inf) = 1.234567890123457e+301 = 0x7e726f51 75f56414: + g_fmt gives "1.234567890123457e+301" + dtoa returns sign = 0, decpt = 302, 16 digits: +1234567890123457 + nextafter(d,-Inf) = 1.2345678901234565e+301 = 0x7e726f51 75f56412: + g_fmt gives "1.2345678901234565e+301" + dtoa returns sign = 0, decpt = 302, 17 digits: +12345678901234565 +Input: 1.234567890123456789e-301 +Output: d = +1.2345678901234567e-301 = 0x1752a64 e34ba0d3, se = + g_fmt gives "1.2345678901234567e-301" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -300, 17 digits: +12345678901234567 + nextafter(d,+Inf) = 1.2345678901234569e-301 = 0x1752a64 e34ba0d4: + g_fmt gives "1.234567890123457e-301" + dtoa returns sign = 0, decpt = -300, 16 digits: +1234567890123457 + nextafter(d,-Inf) = 1.2345678901234565e-301 = 0x1752a64 e34ba0d2: + g_fmt gives "1.2345678901234565e-301" + dtoa returns sign = 0, decpt = -300, 17 digits: +12345678901234565 +Input: 1.234567890123456789e-321 +Output: d = +1.2351641146031164e-321 = 0x0 fa, se = + g_fmt gives "1.235e-321" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -320, 4 digits: +1235 + nextafter(d,+Inf) = 1.2401047710615288e-321 = 0x0 fb: + g_fmt gives "1.24e-321" + dtoa returns sign = 0, decpt = -320, 3 digits: +124 + nextafter(d,-Inf) = 1.2302234581447039e-321 = 0x0 f9: + g_fmt gives "1.23e-321" + dtoa returns sign = 0, decpt = -320, 3 digits: +123 +Input: 1e23 +Output: d = +9.9999999999999992e+22 = 0x44b52d02 c7e14af6, se = + g_fmt gives "1e+23" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 24, 1 digits: +1 + nextafter(d,+Inf) = 1.0000000000000001e+23 = 0x44b52d02 c7e14af7: + g_fmt gives "1.0000000000000001e+23" + dtoa returns sign = 0, decpt = 24, 17 digits: +10000000000000001 + nextafter(d,-Inf) = 9.9999999999999975e+22 = 0x44b52d02 c7e14af5: + g_fmt gives "9.999999999999997e+22" + dtoa returns sign = 0, decpt = 23, 16 digits: +9999999999999997 +Input: 1e310 + +errno strtod: Result too large +Output: d = +Infinity = 0x7ff00000 0, se = + g_fmt gives "Infinity" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = 9999, 8 digits: +Infinity +Input: 9.0259718793241475e-277 +Output: d = +9.0259718793241479e-277 = 0x6a00000 0, se = + g_fmt gives "9.025971879324148e-277" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -276, 16 digits: +9025971879324148 + nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1: + g_fmt gives "9.02597187932415e-277" + dtoa returns sign = 0, decpt = -276, 15 digits: +902597187932415 +Input: 9.025971879324147880346310405869e-277 +Output: d = +9.0259718793241479e-277 = 0x6a00000 0, se = + g_fmt gives "9.025971879324148e-277" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -276, 16 digits: +9025971879324148 + nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1: + g_fmt gives "9.02597187932415e-277" + dtoa returns sign = 0, decpt = -276, 15 digits: +902597187932415 +Input: 9.025971879324147880346310405868e-277 +Output: d = +9.0259718793241479e-277 = 0x6a00000 0, se = + g_fmt gives "9.025971879324148e-277" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -276, 16 digits: +9025971879324148 + nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1: + g_fmt gives "9.02597187932415e-277" + dtoa returns sign = 0, decpt = -276, 15 digits: +902597187932415 +Input: 2.2250738585072014e-308 +Output: d = +2.2250738585072014e-308 = 0x100000 0, se = + g_fmt gives "2.2250738585072014e-308" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -307, 17 digits: +22250738585072014 + nextafter(d,+Inf) = 2.2250738585072019e-308 = 0x100000 1: + g_fmt gives "2.225073858507202e-308" + dtoa returns sign = 0, decpt = -307, 16 digits: +2225073858507202 +Input: 2.2250738585072013e-308 +Output: d = +2.2250738585072014e-308 = 0x100000 0, se = + g_fmt gives "2.2250738585072014e-308" + dtoa(mode = 0, ndigits = 17): + dtoa returns sign = 0, decpt = -307, 17 digits: +22250738585072014 + nextafter(d,+Inf) = 2.2250738585072019e-308 = 0x100000 1: + g_fmt gives "2.225073858507202e-308" + dtoa returns sign = 0, decpt = -307, 16 digits: +2225073858507202 +Input: 1.23:2 6 +Output: d = +1.23 = 0x3ff3ae14 7ae147ae, se = :2 6 + g_fmt gives "1.23" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af: + g_fmt gives "1.2300000000000002" + dtoa returns sign = 0, decpt = 1, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad: + g_fmt gives "1.2299999999999998" + dtoa returns sign = 0, decpt = 1, 3 digits: +123 +Input: 1.23:4 6 +Output: d = +1.23 = 0x3ff3ae14 7ae147ae, se = :4 6 + g_fmt gives "1.23" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af: + g_fmt gives "1.2300000000000002" + dtoa returns sign = 0, decpt = 1, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad: + g_fmt gives "1.2299999999999998" + dtoa returns sign = 0, decpt = 1, 3 digits: +123 +Input: 1.23e+20:2 6 +Output: d = +1.23e+20 = 0x441aabdf 2145b430, se = :2 6 + g_fmt gives "1.23e+20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431: + g_fmt gives "123000000000000020000" + dtoa returns sign = 0, decpt = 21, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f: + g_fmt gives "122999999999999980000" + dtoa returns sign = 0, decpt = 21, 3 digits: +123 +Input: 1.23e+20:4 6 +Output: d = +1.23e+20 = 0x441aabdf 2145b430, se = :4 6 + g_fmt gives "1.23e+20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431: + g_fmt gives "123000000000000020000" + dtoa returns sign = 0, decpt = 21, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f: + g_fmt gives "122999999999999980000" + dtoa returns sign = 0, decpt = 21, 3 digits: +123 +Input: 1.23e-20:2 6 +Output: d = +1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = :2 6 + g_fmt gives "1.23e-20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532: + g_fmt gives "1.2300000000000002e-20" + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530: + g_fmt gives "1.2299999999999999e-20" + dtoa returns sign = 0, decpt = -19, 3 digits: +123 +Input: 1.23e-20:4 6 +Output: d = +1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = :4 6 + g_fmt gives "1.23e-20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532: + g_fmt gives "1.2300000000000002e-20" + dtoa returns sign = 0, decpt = -19, 3 digits: +123 + nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530: + g_fmt gives "1.2299999999999999e-20" + dtoa returns sign = 0, decpt = -19, 3 digits: +123 +Input: 1.23456789:2 6 +Output: d = +1.2345678899999999 = 0x3ff3c0ca 4283de1b, se = :2 6 + g_fmt gives "1.23456789" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c: + g_fmt gives "1.2345678900000001" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a: + g_fmt gives "1.2345678899999997" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 +Input: 1.23456789:4 6 +Output: d = +1.2345678899999999 = 0x3ff3c0ca 4283de1b, se = :4 6 + g_fmt gives "1.23456789" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c: + g_fmt gives "1.2345678900000001" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a: + g_fmt gives "1.2345678899999997" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 +Input: 1.23456589e+20:2 6 +Output: d = +1.23456589e+20 = 0x441ac537 a660b997, se = :2 6 + g_fmt gives "1.23456589e+20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998: + g_fmt gives "123456589000000010000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996: + g_fmt gives "123456588999999980000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 +Input: 1.23456589e+20:4 6 +Output: d = +1.23456589e+20 = 0x441ac537 a660b997, se = :4 6 + g_fmt gives "1.23456589e+20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998: + g_fmt gives "123456589000000010000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996: + g_fmt gives "123456588999999980000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 +Input: 1.23456789e-20:2 6 +Output: d = +1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se = :2 6 + g_fmt gives "1.23456789e-20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb: + g_fmt gives "1.2345678900000001e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9: + g_fmt gives "1.2345678899999998e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 +Input: 1.23456789e-20:4 6 +Output: d = +1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se = :4 6 + g_fmt gives "1.23456789e-20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb: + g_fmt gives "1.2345678900000001e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9: + g_fmt gives "1.2345678899999998e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 +Input: 1234565:2 6 +Output: d = +1234565 = 0x4132d685 0, se = :2 6 + g_fmt gives "1234565" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 7, 6 digits: +123456 + nextafter(d,+Inf) = 1234565.0000000002 = 0x4132d685 1: + g_fmt gives "1234565.0000000002" + dtoa returns sign = 0, decpt = 7, 6 digits: +123457 +Input: 1234565:4 6 +Output: d = +1234565 = 0x4132d685 0, se = :4 6 + g_fmt gives "1234565" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 7, 6 digits: +123456 + nextafter(d,+Inf) = 1234565.0000000002 = 0x4132d685 1: + g_fmt gives "1234565.0000000002" + dtoa returns sign = 0, decpt = 7, 6 digits: +123457 +Input: 1.234565:2 6 +Output: d = +1.2345649999999999 = 0x3ff3c0c7 3abc9470, se = :2 6 + g_fmt gives "1.234565" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000001 = 0x3ff3c0c7 3abc9471: + g_fmt gives "1.2345650000000001" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999997 = 0x3ff3c0c7 3abc946f: + g_fmt gives "1.2345649999999997" + dtoa returns sign = 0, decpt = 1, 6 digits: +123456 +Input: 1.234565:4 6 +Output: d = +1.2345649999999999 = 0x3ff3c0c7 3abc9470, se = :4 6 + g_fmt gives "1.234565" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 1, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000001 = 0x3ff3c0c7 3abc9471: + g_fmt gives "1.2345650000000001" + dtoa returns sign = 0, decpt = 1, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999997 = 0x3ff3c0c7 3abc946f: + g_fmt gives "1.2345649999999997" + dtoa returns sign = 0, decpt = 1, 6 digits: +123456 +Input: 1.234565e+20:2 6 +Output: d = +1.234565e+20 = 0x441ac536 6299040d, se = :2 6 + g_fmt gives "1.234565e+20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000002e+20 = 0x441ac536 6299040e: + g_fmt gives "123456500000000020000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999998e+20 = 0x441ac536 6299040c: + g_fmt gives "123456499999999980000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123456 +Input: 1.234565e+20:4 6 +Output: d = +1.234565e+20 = 0x441ac536 6299040d, se = :4 6 + g_fmt gives "1.234565e+20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = 21, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000002e+20 = 0x441ac536 6299040e: + g_fmt gives "123456500000000020000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999998e+20 = 0x441ac536 6299040c: + g_fmt gives "123456499999999980000" + dtoa returns sign = 0, decpt = 21, 6 digits: +123456 +Input: 1.234565e-20:2 6 +Output: d = +1.234565e-20 = 0x3bcd267c ce45a93f, se = :2 6 + g_fmt gives "1.234565e-20" + dtoa(mode = 2, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000001e-20 = 0x3bcd267c ce45a940: + g_fmt gives "1.2345650000000001e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999998e-20 = 0x3bcd267c ce45a93e: + g_fmt gives "1.2345649999999998e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123456 +Input: 1.234565e-20:4 6 +Output: d = +1.234565e-20 = 0x3bcd267c ce45a93f, se = :4 6 + g_fmt gives "1.234565e-20" + dtoa(mode = 4, ndigits = 6): + dtoa returns sign = 0, decpt = -19, 6 digits: +123456 + nextafter(d,+Inf) = 1.2345650000000001e-20 = 0x3bcd267c ce45a940: + g_fmt gives "1.2345650000000001e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123457 + nextafter(d,-Inf) = 1.2345649999999998e-20 = 0x3bcd267c ce45a93e: + g_fmt gives "1.2345649999999998e-20" + dtoa returns sign = 0, decpt = -19, 6 digits: +123456 diff --git a/src/contrib/gdtoa/test/f.out b/src/contrib/gdtoa/test/f.out new file mode 100644 index 0000000..ca8d6eb --- /dev/null +++ b/src/contrib/gdtoa/test/f.out @@ -0,0 +1,968 @@ + +Input: 1.23 +strtof consumes 4 bytes and returns 1.23 = #3f9d70a4 +g_ffmt(0) gives 4 bytes: "1.23" + +strtoIf returns 33, consuming 4 bytes. +fI[0] = #3f9d70a3 = 1.2299999 +fI[1] = #3f9d70a4 = 1.23 +fI[1] == strtof + + +Input: 1.23e+20 +strtof consumes 8 bytes and returns 1.23e+20 = #60d55ef9 +g_ffmt(0) gives 8 bytes: "1.23e+20" + +strtoIf returns 17, consuming 8 bytes. +fI[0] = #60d55ef9 = 1.23e+20 +fI[1] = #60d55efa = 1.2300001e+20 +fI[0] == strtof + + +Input: 1.23e-20 +strtof consumes 8 bytes and returns 1.23e-20 = #1e685726 +g_ffmt(0) gives 8 bytes: "1.23e-20" + +strtoIf returns 17, consuming 8 bytes. +fI[0] = #1e685726 = 1.23e-20 +fI[1] = #1e685727 = 1.23e-20 +fI[0] == strtof + + +Input: 1.23456789 +strtof consumes 10 bytes and returns 1.2345679 = #3f9e0652 +g_ffmt(0) gives 9 bytes: "1.2345679" + +strtoIf returns 17, consuming 10 bytes. +fI[0] = #3f9e0652 = 1.2345679 +fI[1] = #3f9e0653 = 1.234568 +fI[0] == strtof + + +Input: 1.23456589e+20 +strtof consumes 14 bytes and returns 1.2345659e+20 = #60d629bd +g_ffmt(0) gives 13 bytes: "1.2345659e+20" + +strtoIf returns 17, consuming 14 bytes. +fI[0] = #60d629bd = 1.2345659e+20 +fI[1] = #60d629be = 1.234566e+20 +fI[0] == strtof + + +Input: 1.23e+30 +strtof consumes 8 bytes and returns 1.23e+30 = #71786582 +g_ffmt(0) gives 8 bytes: "1.23e+30" + +strtoIf returns 17, consuming 8 bytes. +fI[0] = #71786582 = 1.23e+30 +fI[1] = #71786583 = 1.23e+30 +fI[0] == strtof + + +Input: 1.23e-30 +strtof consumes 8 bytes and returns 1.23e-30 = #dc79433 +g_ffmt(0) gives 8 bytes: "1.23e-30" + +strtoIf returns 17, consuming 8 bytes. +fI[0] = #dc79433 = 1.23e-30 +fI[1] = #dc79434 = 1.23e-30 +fI[0] == strtof + + +Input: 1.23456789e-20 +strtof consumes 14 bytes and returns 1.2345679e-20 = #1e69340a +g_ffmt(0) gives 13 bytes: "1.2345679e-20" + +strtoIf returns 17, consuming 14 bytes. +fI[0] = #1e69340a = 1.2345679e-20 +fI[1] = #1e69340b = 1.234568e-20 +fI[0] == strtof + + +Input: 1.23456789e-30 +strtof consumes 14 bytes and returns 1.2345679e-30 = #dc851f2 +g_ffmt(0) gives 13 bytes: "1.2345679e-30" + +strtoIf returns 33, consuming 14 bytes. +fI[0] = #dc851f1 = 1.2345678e-30 +fI[1] = #dc851f2 = 1.2345679e-30 +fI[1] == strtof + + +Input: 1.234567890123456789 +strtof consumes 20 bytes and returns 1.2345679 = #3f9e0652 +g_ffmt(0) gives 9 bytes: "1.2345679" + +strtoIf returns 17, consuming 20 bytes. +fI[0] = #3f9e0652 = 1.2345679 +fI[1] = #3f9e0653 = 1.234568 +fI[0] == strtof + + +Input: 1.23456789012345678901234567890123456789 +strtof consumes 40 bytes and returns 1.2345679 = #3f9e0652 +g_ffmt(0) gives 9 bytes: "1.2345679" + +strtoIf returns 17, consuming 40 bytes. +fI[0] = #3f9e0652 = 1.2345679 +fI[1] = #3f9e0653 = 1.234568 +fI[0] == strtof + + +Input: 1.23e306 +strtof consumes 8 bytes and returns Infinity = #7f800000 +g_ffmt(0) gives 8 bytes: "Infinity" + +strtoIf returns 163, consuming 8 bytes. +fI[0] = #7f7fffff = 3.4028235e+38 +fI[1] = #7f800000 = Infinity +fI[1] == strtof + + +Input: 1.23e-306 +strtof consumes 9 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 9 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.23e-320 +strtof consumes 9 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 9 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.23e-20 +strtof consumes 8 bytes and returns 1.23e-20 = #1e685726 +g_ffmt(0) gives 8 bytes: "1.23e-20" + +strtoIf returns 17, consuming 8 bytes. +fI[0] = #1e685726 = 1.23e-20 +fI[1] = #1e685727 = 1.23e-20 +fI[0] == strtof + + +Input: 1.23456789e307 +strtof consumes 14 bytes and returns Infinity = #7f800000 +g_ffmt(0) gives 8 bytes: "Infinity" + +strtoIf returns 163, consuming 14 bytes. +fI[0] = #7f7fffff = 3.4028235e+38 +fI[1] = #7f800000 = Infinity +fI[1] == strtof + + +Input: 1.23456589e-307 +strtof consumes 15 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 15 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.234567890123456789 +strtof consumes 20 bytes and returns 1.2345679 = #3f9e0652 +g_ffmt(0) gives 9 bytes: "1.2345679" + +strtoIf returns 17, consuming 20 bytes. +fI[0] = #3f9e0652 = 1.2345679 +fI[1] = #3f9e0653 = 1.234568 +fI[0] == strtof + + +Input: 1.234567890123456789e301 +strtof consumes 24 bytes and returns Infinity = #7f800000 +g_ffmt(0) gives 8 bytes: "Infinity" + +strtoIf returns 163, consuming 24 bytes. +fI[0] = #7f7fffff = 3.4028235e+38 +fI[1] = #7f800000 = Infinity +fI[1] == strtof + + +Input: 1.234567890123456789e-301 +strtof consumes 25 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 25 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.234567890123456789e-321 +strtof consumes 25 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 25 bytes. +fI[0] == fI[1] == strtof + + +Input: 1e23 +strtof consumes 4 bytes and returns 9.9999998e+22 = #65a96816 +g_ffmt(0) gives 5 bytes: "1e+23" + +strtoIf returns 17, consuming 4 bytes. +fI[0] = #65a96816 = 9.9999998e+22 +fI[1] = #65a96817 = 1.0000001e+23 +fI[0] == strtof + + +Input: 1e310 +strtof consumes 5 bytes and returns Infinity = #7f800000 +g_ffmt(0) gives 8 bytes: "Infinity" + +strtoIf returns 163, consuming 5 bytes. +fI[0] = #7f7fffff = 3.4028235e+38 +fI[1] = #7f800000 = Infinity +fI[1] == strtof + + +Input: 9.0259718793241475e-277 +strtof consumes 23 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 23 bytes. +fI[0] == fI[1] == strtof + + +Input: 9.025971879324147880346310405869e-277 +strtof consumes 37 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 37 bytes. +fI[0] == fI[1] == strtof + + +Input: 9.025971879324147880346310405868e-277 +strtof consumes 37 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 37 bytes. +fI[0] == fI[1] == strtof + + +Input: 2.2250738585072014e-308 +strtof consumes 23 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 23 bytes. +fI[0] == fI[1] == strtof + + +Input: 2.2250738585072013e-308 +strtof consumes 23 bytes and returns 0 = #0 +g_ffmt(0) gives 1 bytes: "0" + +strtoIf returns 80, consuming 23 bytes. +fI[0] == fI[1] == strtof + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 +strtof consumes 3 bytes and returns 1.0999999 = #3f8ccccc +g_ffmt(0) gives 9 bytes: "1.0999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f8ccccc = 1.0999999 +fI[1] = #3f8ccccd = 1.1 +fI[0] == strtof + + +Input: -1.1 +strtof consumes 4 bytes and returns -1.0999999 = #bf8ccccc +g_ffmt(0) gives 10 bytes: "-1.0999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf8ccccd = -1.1 +fI[1] = #bf8ccccc = -1.0999999 +fI[1] == strtof + + +Input: 1.2 +strtof consumes 3 bytes and returns 1.1999999 = #3f999999 +g_ffmt(0) gives 9 bytes: "1.1999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f999999 = 1.1999999 +fI[1] = #3f99999a = 1.2 +fI[0] == strtof + + +Input: -1.2 +strtof consumes 4 bytes and returns -1.1999999 = #bf999999 +g_ffmt(0) gives 10 bytes: "-1.1999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf99999a = -1.2 +fI[1] = #bf999999 = -1.1999999 +fI[1] == strtof + + +Input: 1.3 +strtof consumes 3 bytes and returns 1.3 = #3fa66666 +g_ffmt(0) gives 3 bytes: "1.3" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fa66666 = 1.3 +fI[1] = #3fa66667 = 1.3000001 +fI[0] == strtof + + +Input: -1.3 +strtof consumes 4 bytes and returns -1.3 = #bfa66666 +g_ffmt(0) gives 4 bytes: "-1.3" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfa66667 = -1.3000001 +fI[1] = #bfa66666 = -1.3 +fI[1] == strtof + + +Input: 1.4 +strtof consumes 3 bytes and returns 1.4 = #3fb33333 +g_ffmt(0) gives 3 bytes: "1.4" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fb33333 = 1.4 +fI[1] = #3fb33334 = 1.4000001 +fI[0] == strtof + + +Input: -1.4 +strtof consumes 4 bytes and returns -1.4 = #bfb33333 +g_ffmt(0) gives 4 bytes: "-1.4" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfb33334 = -1.4000001 +fI[1] = #bfb33333 = -1.4 +fI[1] == strtof + + +Input: 1.5 +strtof consumes 3 bytes and returns 1.5 = #3fc00000 +g_ffmt(0) gives 3 bytes: "1.5" + +strtoIf returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtof + + +Input: -1.5 +strtof consumes 4 bytes and returns -1.5 = #bfc00000 +g_ffmt(0) gives 4 bytes: "-1.5" + +strtoIf returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.6 +strtof consumes 3 bytes and returns 1.5999999 = #3fcccccc +g_ffmt(0) gives 9 bytes: "1.5999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fcccccc = 1.5999999 +fI[1] = #3fcccccd = 1.6 +fI[0] == strtof + + +Input: -1.6 +strtof consumes 4 bytes and returns -1.5999999 = #bfcccccc +g_ffmt(0) gives 10 bytes: "-1.5999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfcccccd = -1.6 +fI[1] = #bfcccccc = -1.5999999 +fI[1] == strtof + + +Input: 1.7 +strtof consumes 3 bytes and returns 1.6999999 = #3fd99999 +g_ffmt(0) gives 9 bytes: "1.6999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fd99999 = 1.6999999 +fI[1] = #3fd9999a = 1.7 +fI[0] == strtof + + +Input: -1.7 +strtof consumes 4 bytes and returns -1.6999999 = #bfd99999 +g_ffmt(0) gives 10 bytes: "-1.6999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfd9999a = -1.7 +fI[1] = #bfd99999 = -1.6999999 +fI[1] == strtof + + +Input: 1.8 +strtof consumes 3 bytes and returns 1.8 = #3fe66666 +g_ffmt(0) gives 3 bytes: "1.8" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fe66666 = 1.8 +fI[1] = #3fe66667 = 1.8000001 +fI[0] == strtof + + +Input: -1.8 +strtof consumes 4 bytes and returns -1.8 = #bfe66666 +g_ffmt(0) gives 4 bytes: "-1.8" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfe66667 = -1.8000001 +fI[1] = #bfe66666 = -1.8 +fI[1] == strtof + + +Input: 1.9 +strtof consumes 3 bytes and returns 1.9 = #3ff33333 +g_ffmt(0) gives 3 bytes: "1.9" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3ff33333 = 1.9 +fI[1] = #3ff33334 = 1.9000001 +fI[0] == strtof + + +Input: -1.9 +strtof consumes 4 bytes and returns -1.9 = #bff33333 +g_ffmt(0) gives 4 bytes: "-1.9" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bff33334 = -1.9000001 +fI[1] = #bff33333 = -1.9 +fI[1] == strtof + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 +strtof consumes 3 bytes and returns 1.1 = #3f8ccccd +g_ffmt(0) gives 3 bytes: "1.1" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f8ccccc = 1.0999999 +fI[1] = #3f8ccccd = 1.1 +fI[1] == strtof + + +Input: -1.1 +strtof consumes 4 bytes and returns -1.1 = #bf8ccccd +g_ffmt(0) gives 4 bytes: "-1.1" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf8ccccd = -1.1 +fI[1] = #bf8ccccc = -1.0999999 +fI[0] == strtof + + +Input: 1.2 +strtof consumes 3 bytes and returns 1.2 = #3f99999a +g_ffmt(0) gives 3 bytes: "1.2" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f999999 = 1.1999999 +fI[1] = #3f99999a = 1.2 +fI[1] == strtof + + +Input: -1.2 +strtof consumes 4 bytes and returns -1.2 = #bf99999a +g_ffmt(0) gives 4 bytes: "-1.2" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf99999a = -1.2 +fI[1] = #bf999999 = -1.1999999 +fI[0] == strtof + + +Input: 1.3 +strtof consumes 3 bytes and returns 1.3 = #3fa66666 +g_ffmt(0) gives 3 bytes: "1.3" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fa66666 = 1.3 +fI[1] = #3fa66667 = 1.3000001 +fI[0] == strtof + + +Input: -1.3 +strtof consumes 4 bytes and returns -1.3 = #bfa66666 +g_ffmt(0) gives 4 bytes: "-1.3" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfa66667 = -1.3000001 +fI[1] = #bfa66666 = -1.3 +fI[1] == strtof + + +Input: 1.4 +strtof consumes 3 bytes and returns 1.4 = #3fb33333 +g_ffmt(0) gives 3 bytes: "1.4" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fb33333 = 1.4 +fI[1] = #3fb33334 = 1.4000001 +fI[0] == strtof + + +Input: -1.4 +strtof consumes 4 bytes and returns -1.4 = #bfb33333 +g_ffmt(0) gives 4 bytes: "-1.4" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfb33334 = -1.4000001 +fI[1] = #bfb33333 = -1.4 +fI[1] == strtof + + +Input: 1.5 +strtof consumes 3 bytes and returns 1.5 = #3fc00000 +g_ffmt(0) gives 3 bytes: "1.5" + +strtoIf returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtof + + +Input: -1.5 +strtof consumes 4 bytes and returns -1.5 = #bfc00000 +g_ffmt(0) gives 4 bytes: "-1.5" + +strtoIf returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.6 +strtof consumes 3 bytes and returns 1.6 = #3fcccccd +g_ffmt(0) gives 3 bytes: "1.6" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fcccccc = 1.5999999 +fI[1] = #3fcccccd = 1.6 +fI[1] == strtof + + +Input: -1.6 +strtof consumes 4 bytes and returns -1.6 = #bfcccccd +g_ffmt(0) gives 4 bytes: "-1.6" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfcccccd = -1.6 +fI[1] = #bfcccccc = -1.5999999 +fI[0] == strtof + + +Input: 1.7 +strtof consumes 3 bytes and returns 1.7 = #3fd9999a +g_ffmt(0) gives 3 bytes: "1.7" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fd99999 = 1.6999999 +fI[1] = #3fd9999a = 1.7 +fI[1] == strtof + + +Input: -1.7 +strtof consumes 4 bytes and returns -1.7 = #bfd9999a +g_ffmt(0) gives 4 bytes: "-1.7" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfd9999a = -1.7 +fI[1] = #bfd99999 = -1.6999999 +fI[0] == strtof + + +Input: 1.8 +strtof consumes 3 bytes and returns 1.8 = #3fe66666 +g_ffmt(0) gives 3 bytes: "1.8" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fe66666 = 1.8 +fI[1] = #3fe66667 = 1.8000001 +fI[0] == strtof + + +Input: -1.8 +strtof consumes 4 bytes and returns -1.8 = #bfe66666 +g_ffmt(0) gives 4 bytes: "-1.8" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfe66667 = -1.8000001 +fI[1] = #bfe66666 = -1.8 +fI[1] == strtof + + +Input: 1.9 +strtof consumes 3 bytes and returns 1.9 = #3ff33333 +g_ffmt(0) gives 3 bytes: "1.9" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3ff33333 = 1.9 +fI[1] = #3ff33334 = 1.9000001 +fI[0] == strtof + + +Input: -1.9 +strtof consumes 4 bytes and returns -1.9 = #bff33333 +g_ffmt(0) gives 4 bytes: "-1.9" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bff33334 = -1.9000001 +fI[1] = #bff33333 = -1.9 +fI[1] == strtof + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 +strtof consumes 3 bytes and returns 1.1 = #3f8ccccd +g_ffmt(0) gives 3 bytes: "1.1" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f8ccccc = 1.0999999 +fI[1] = #3f8ccccd = 1.1 +fI[1] == strtof + + +Input: -1.1 +strtof consumes 4 bytes and returns -1.0999999 = #bf8ccccc +g_ffmt(0) gives 10 bytes: "-1.0999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf8ccccd = -1.1 +fI[1] = #bf8ccccc = -1.0999999 +fI[1] == strtof + + +Input: 1.2 +strtof consumes 3 bytes and returns 1.2 = #3f99999a +g_ffmt(0) gives 3 bytes: "1.2" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f999999 = 1.1999999 +fI[1] = #3f99999a = 1.2 +fI[1] == strtof + + +Input: -1.2 +strtof consumes 4 bytes and returns -1.1999999 = #bf999999 +g_ffmt(0) gives 10 bytes: "-1.1999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf99999a = -1.2 +fI[1] = #bf999999 = -1.1999999 +fI[1] == strtof + + +Input: 1.3 +strtof consumes 3 bytes and returns 1.3000001 = #3fa66667 +g_ffmt(0) gives 9 bytes: "1.3000001" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fa66666 = 1.3 +fI[1] = #3fa66667 = 1.3000001 +fI[1] == strtof + + +Input: -1.3 +strtof consumes 4 bytes and returns -1.3 = #bfa66666 +g_ffmt(0) gives 4 bytes: "-1.3" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfa66667 = -1.3000001 +fI[1] = #bfa66666 = -1.3 +fI[1] == strtof + + +Input: 1.4 +strtof consumes 3 bytes and returns 1.4000001 = #3fb33334 +g_ffmt(0) gives 9 bytes: "1.4000001" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fb33333 = 1.4 +fI[1] = #3fb33334 = 1.4000001 +fI[1] == strtof + + +Input: -1.4 +strtof consumes 4 bytes and returns -1.4 = #bfb33333 +g_ffmt(0) gives 4 bytes: "-1.4" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfb33334 = -1.4000001 +fI[1] = #bfb33333 = -1.4 +fI[1] == strtof + + +Input: 1.5 +strtof consumes 3 bytes and returns 1.5 = #3fc00000 +g_ffmt(0) gives 3 bytes: "1.5" + +strtoIf returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtof + + +Input: -1.5 +strtof consumes 4 bytes and returns -1.5 = #bfc00000 +g_ffmt(0) gives 4 bytes: "-1.5" + +strtoIf returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.6 +strtof consumes 3 bytes and returns 1.6 = #3fcccccd +g_ffmt(0) gives 3 bytes: "1.6" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fcccccc = 1.5999999 +fI[1] = #3fcccccd = 1.6 +fI[1] == strtof + + +Input: -1.6 +strtof consumes 4 bytes and returns -1.5999999 = #bfcccccc +g_ffmt(0) gives 10 bytes: "-1.5999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfcccccd = -1.6 +fI[1] = #bfcccccc = -1.5999999 +fI[1] == strtof + + +Input: 1.7 +strtof consumes 3 bytes and returns 1.7 = #3fd9999a +g_ffmt(0) gives 3 bytes: "1.7" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fd99999 = 1.6999999 +fI[1] = #3fd9999a = 1.7 +fI[1] == strtof + + +Input: -1.7 +strtof consumes 4 bytes and returns -1.6999999 = #bfd99999 +g_ffmt(0) gives 10 bytes: "-1.6999999" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfd9999a = -1.7 +fI[1] = #bfd99999 = -1.6999999 +fI[1] == strtof + + +Input: 1.8 +strtof consumes 3 bytes and returns 1.8000001 = #3fe66667 +g_ffmt(0) gives 9 bytes: "1.8000001" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fe66666 = 1.8 +fI[1] = #3fe66667 = 1.8000001 +fI[1] == strtof + + +Input: -1.8 +strtof consumes 4 bytes and returns -1.8 = #bfe66666 +g_ffmt(0) gives 4 bytes: "-1.8" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfe66667 = -1.8000001 +fI[1] = #bfe66666 = -1.8 +fI[1] == strtof + + +Input: 1.9 +strtof consumes 3 bytes and returns 1.9000001 = #3ff33334 +g_ffmt(0) gives 9 bytes: "1.9000001" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3ff33333 = 1.9 +fI[1] = #3ff33334 = 1.9000001 +fI[1] == strtof + + +Input: -1.9 +strtof consumes 4 bytes and returns -1.9 = #bff33333 +g_ffmt(0) gives 4 bytes: "-1.9" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bff33334 = -1.9000001 +fI[1] = #bff33333 = -1.9 +fI[1] == strtof + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 +strtof consumes 3 bytes and returns 1.0999999 = #3f8ccccc +g_ffmt(0) gives 9 bytes: "1.0999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f8ccccc = 1.0999999 +fI[1] = #3f8ccccd = 1.1 +fI[0] == strtof + + +Input: -1.1 +strtof consumes 4 bytes and returns -1.1 = #bf8ccccd +g_ffmt(0) gives 4 bytes: "-1.1" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf8ccccd = -1.1 +fI[1] = #bf8ccccc = -1.0999999 +fI[0] == strtof + + +Input: 1.2 +strtof consumes 3 bytes and returns 1.1999999 = #3f999999 +g_ffmt(0) gives 9 bytes: "1.1999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3f999999 = 1.1999999 +fI[1] = #3f99999a = 1.2 +fI[0] == strtof + + +Input: -1.2 +strtof consumes 4 bytes and returns -1.2 = #bf99999a +g_ffmt(0) gives 4 bytes: "-1.2" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bf99999a = -1.2 +fI[1] = #bf999999 = -1.1999999 +fI[0] == strtof + + +Input: 1.3 +strtof consumes 3 bytes and returns 1.3 = #3fa66666 +g_ffmt(0) gives 3 bytes: "1.3" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fa66666 = 1.3 +fI[1] = #3fa66667 = 1.3000001 +fI[0] == strtof + + +Input: -1.3 +strtof consumes 4 bytes and returns -1.3000001 = #bfa66667 +g_ffmt(0) gives 10 bytes: "-1.3000001" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfa66667 = -1.3000001 +fI[1] = #bfa66666 = -1.3 +fI[0] == strtof + + +Input: 1.4 +strtof consumes 3 bytes and returns 1.4 = #3fb33333 +g_ffmt(0) gives 3 bytes: "1.4" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fb33333 = 1.4 +fI[1] = #3fb33334 = 1.4000001 +fI[0] == strtof + + +Input: -1.4 +strtof consumes 4 bytes and returns -1.4000001 = #bfb33334 +g_ffmt(0) gives 10 bytes: "-1.4000001" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfb33334 = -1.4000001 +fI[1] = #bfb33333 = -1.4 +fI[0] == strtof + + +Input: 1.5 +strtof consumes 3 bytes and returns 1.5 = #3fc00000 +g_ffmt(0) gives 3 bytes: "1.5" + +strtoIf returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtof + + +Input: -1.5 +strtof consumes 4 bytes and returns -1.5 = #bfc00000 +g_ffmt(0) gives 4 bytes: "-1.5" + +strtoIf returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtof + + +Input: 1.6 +strtof consumes 3 bytes and returns 1.5999999 = #3fcccccc +g_ffmt(0) gives 9 bytes: "1.5999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fcccccc = 1.5999999 +fI[1] = #3fcccccd = 1.6 +fI[0] == strtof + + +Input: -1.6 +strtof consumes 4 bytes and returns -1.6 = #bfcccccd +g_ffmt(0) gives 4 bytes: "-1.6" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfcccccd = -1.6 +fI[1] = #bfcccccc = -1.5999999 +fI[0] == strtof + + +Input: 1.7 +strtof consumes 3 bytes and returns 1.6999999 = #3fd99999 +g_ffmt(0) gives 9 bytes: "1.6999999" + +strtoIf returns 33, consuming 3 bytes. +fI[0] = #3fd99999 = 1.6999999 +fI[1] = #3fd9999a = 1.7 +fI[0] == strtof + + +Input: -1.7 +strtof consumes 4 bytes and returns -1.7 = #bfd9999a +g_ffmt(0) gives 4 bytes: "-1.7" + +strtoIf returns 41, consuming 4 bytes. +fI[0] = #bfd9999a = -1.7 +fI[1] = #bfd99999 = -1.6999999 +fI[0] == strtof + + +Input: 1.8 +strtof consumes 3 bytes and returns 1.8 = #3fe66666 +g_ffmt(0) gives 3 bytes: "1.8" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3fe66666 = 1.8 +fI[1] = #3fe66667 = 1.8000001 +fI[0] == strtof + + +Input: -1.8 +strtof consumes 4 bytes and returns -1.8000001 = #bfe66667 +g_ffmt(0) gives 10 bytes: "-1.8000001" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bfe66667 = -1.8000001 +fI[1] = #bfe66666 = -1.8 +fI[0] == strtof + + +Input: 1.9 +strtof consumes 3 bytes and returns 1.9 = #3ff33333 +g_ffmt(0) gives 3 bytes: "1.9" + +strtoIf returns 17, consuming 3 bytes. +fI[0] = #3ff33333 = 1.9 +fI[1] = #3ff33334 = 1.9000001 +fI[0] == strtof + + +Input: -1.9 +strtof consumes 4 bytes and returns -1.9000001 = #bff33334 +g_ffmt(0) gives 10 bytes: "-1.9000001" + +strtoIf returns 25, consuming 4 bytes. +fI[0] = #bff33334 = -1.9000001 +fI[1] = #bff33333 = -1.9 +fI[0] == strtof + diff --git a/src/contrib/gdtoa/test/ftest.c b/src/contrib/gdtoa/test/ftest.c new file mode 100644 index 0000000..afafe85 --- /dev/null +++ b/src/contrib/gdtoa/test/ftest.c @@ -0,0 +1,146 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_ffmt, strtof, strtoIf, strtopf, and strtorf. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex is a string of <= 8 Hex digits for the internal representation + * of the number, and ndig is a parameters to g_ffmt. + */ + +#include "gdtoa.h" +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[1024]; + +#define U (unsigned long) + + int +main(Void) +{ + ULong *L; + char *s, *se, *se1; + int dItry, i, i1, ndig = 0, r = 1; + float f, f1, fI[2]; + + L = (ULong*)&f; + while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) { + while(*s <= ' ') + if (!*s++) + continue; + dItry = 0; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + sscanf(s+1, "%lx", &L[0]); + printf("\nInput: %s", ibuf); + printf(" --> f = #%lx\n", L[0]); + goto fmt_test; + } + dItry = 1; + printf("\nInput: %s", ibuf); + i = strtorf(ibuf, &se, r, &f); + if (r == 1) { + if (f != (i1 = strtopf(ibuf, &se1, &f1), f1) + || se != se1 || i != i1) { + printf("***strtopf and strtorf disagree!!\n"); + if (f != f1) + printf("\tf1 = %g\n", (double)f1); + if (i != i1) + printf("\ti = %d but i1 = %d\n", i, i1); + if (se != se1) + printf("se - se1 = %d\n", (int)(se-se1)); + } + if (f != strtof(ibuf, &se1) || se != se1) + printf("***strtof and strtorf disagree!\n"); + } + printf("strtof consumes %d bytes and returns %.8g = #%lx\n", + (int)(se-ibuf), f, U *(ULong*)&f); + fmt_test: + se = g_ffmt(obuf, &f, ndig, sizeof(obuf)); + printf("g_ffmt(%d) gives %d bytes: \"%s\"\n\n", + ndig, (int)(se-obuf), se ? obuf : ""); + if (!dItry) + continue; + printf("strtoIf returns %d,", strtoIf(ibuf, &se, fI, &fI[1])); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (fI[0] == fI[1]) { + if (fI[0] == f) + printf("fI[0] == fI[1] == strtof\n"); + else + printf("fI[0] == fI[1] = #%lx = %.8g\n", + U *(ULong*)fI, fI[0]); + } + else { + printf("fI[0] = #%lx = %.8g\nfI[1] = #%lx = %.8g\n", + U *(ULong*)fI, fI[0], + U *(ULong*)&fI[1], fI[1]); + if (fI[0] == f) + printf("fI[0] == strtof\n"); + else if (fI[1] == f) + printf("fI[1] == strtof\n"); + else + printf("**** Both differ from strtof ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/getround.c b/src/contrib/gdtoa/test/getround.c new file mode 100644 index 0000000..ec1ca11 --- /dev/null +++ b/src/contrib/gdtoa/test/getround.c @@ -0,0 +1,68 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include +#include + +static char *dir[4] = { "toward zero", "nearest", "toward +Infinity", + "toward -Infinity" }; + + int +#ifdef KR_headers +getround(r, s) int r; char *s; +#else +getround(int r, char *s) +#endif +{ + int i; + + i = atoi(s+1); + if (i >= 0 && i < 4) { + printf("Rounding mode for strtor... "); + if (i == r) + printf("was and is %d (%s)\n", i, dir[i]); + else + printf("changed from %d (%s) to %d (%s)\n", + r, dir[r], i, dir[i]); + return i; + } + printf("Bad rounding direction %d: choose among\n", i); + for(i = 0; i < 4; i++) + printf("\t%d (%s)\n", i, dir[i]); + printf("Leaving rounding mode for strtor... at %d (%s)\n", r, dir[r]); + return r; + } diff --git a/src/contrib/gdtoa/test/makefile b/src/contrib/gdtoa/test/makefile new file mode 100644 index 0000000..7e48915 --- /dev/null +++ b/src/contrib/gdtoa/test/makefile @@ -0,0 +1,135 @@ +# /**************************************************************** +# Copyright (C) 1998, 2000 by Lucent Technologies +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that the copyright notice and this +# permission notice and warranty disclaimer appear in supporting +# documentation, and that the name of Lucent or any of its entities +# not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +# IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +# SPECIAL, 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. +# +# ****************************************************************/ + +.SUFFIXES: .c .o +CC = cc +CFLAGS = -g -I.. +A = ../gdtoa.a + +.c.o: + $(CC) -c $(CFLAGS) $*.c + +all: dt dItest ddtest dtest ftest Qtest xLtest xtest ddtestsi dItestsi tests + +dt = dt.o $A +dt: $(dt) + $(CC) -o dt $(dt) + +dItest = dItest.o getround.o $A +dItest: $(dItest) + $(CC) -o dItest $(dItest) + +ddtest = ddtest.o getround.o $A +ddtest: $(ddtest) + $(CC) -o ddtest $(ddtest) + +dtest = dtest.o getround.o $A +dtest: $(dtest) + $(CC) -o dtest $(dtest) + +ftest = ftest.o getround.o $A +ftest: $(ftest) + $(CC) -o ftest $(ftest) + +Qtest = Qtest.o getround.o $A +Qtest: $(Qtest) + $(CC) -o Qtest $(Qtest) + +xtest = xtest.o getround.o $A +xtest: $(xtest) + $(CC) -o xtest $(xtest) + +xLtest = xLtest.o getround.o $A +xLtest: $(xLtest) + $(CC) -o xLtest $(xLtest) + +strtopddSI.o: strtopddSI.c ../strtopdd.c + +strtorddSI.o: strtorddSI.c ../strtordd.c + +strtodISI.o: strtodISI.c ../strtodI.c + +strtoIddSI.o: strtoIddSI.c ../strtoIdd.c + +strtoIdSI.o: strtoIdSI.c ../strtoId.c + +ddtestsi = ddtest.o strtopddSI.o strtorddSI.o strtoIddSI.o getround.o $A +ddtestsi: $(ddtestsi) + $(CC) -o ddtestsi $(ddtestsi) + +dItestsi = dItest.o strtodISI.o strtoIdSI.o getround.o $A +dItestsi: $(dItestsi) + $(CC) -o dItestsi $(dItestsi) + +strtodt = strtodt.o $A +strtodt: $(strtodt) + $(CC) -o strtodt $(strtodt) + +# xQtest generates cp commands that depend on sizeof(long double). +# See the source for details. If you know better, create Q.out, +# x.out and xL.out by copying the relevant *.ou0 or *.ou1 files +# to the corresponding .out files. In short, the *.ou0 files are +# for long double == double; x.ou1 and xL.ou1 are for +# long double == extended (a la 80x87 and MC680x0), and Q.ou1 is +# for long double == quad. + +Q.out x.out xL.out: + $(CC) -o xQtest xQtest.c + ./xQtest | sh + rm -f xQtest xQtest.o + +## The rmdir below will fail if any test results differ. + +tests: Q.out x.out xL.out dt dItest ddtest dtest ftest Qtest xLtest xtest ddtestsi dItestsi strtodt + mkdir bad + cat testnos testnos1 | ./dt >zap 2>&1 + cmp dtst.out zap || mv zap bad/dtst.out + ./dItest zap 2>&1 + cmp dI.out zap || mv zap bad/dI.out + ./dItestsi zap 2>&1 + cmp dIsi.out zap || mv zap bad/dIsi.out + ./ddtestsi zap 2>&1 + cmp ddsi.out zap || mv zap bad/ddsi.out + for i in dd d f x xL Q; do cat testnos rtestnos | \ + ./"$$i"test >zap 2>&1;\ + cmp $$i.out zap || mv zap bad/$$i.out; done + ./strtodt testnos3 >bad/strtodt.out && rm bad/strtodt.out || \ + cat bad/strtodt.out + rmdir bad + touch tests + +xs0 = README Qtest.c dItest.c ddtest.c dtest.c dt.c ftest.c getround.c \ + strtoIdSI.c strtoIddSI.c strtodISI.c strtodt.c strtopddSI.c \ + strtorddSI.c xLtest.c xQtest.c xtest.c rtestnos testnos testnos1 \ + testnos3 dI.out dIsi.out ddsi.out dd.out dtst.out d.out f.out \ + x.ou0 xL.ou0 x.ou1 xL.ou1 Q.ou0 Q.ou1 makefile + +xsum.out: xsum0.out $(xs0) + xsum $(xs0) >xsum1.out + cmp xsum0.out xsum1.out && mv xsum1.out xsum.out || diff xsum[01].out + +clean: + rm -f *.[ao] dt *test *testsi strtodt xsum.out xsum1.out tests zap x.out xL.out Q.out + rm -rf bad diff --git a/src/contrib/gdtoa/test/rtestnos b/src/contrib/gdtoa/test/rtestnos new file mode 100644 index 0000000..cde95b7 --- /dev/null +++ b/src/contrib/gdtoa/test/rtestnos @@ -0,0 +1,76 @@ +r0 +1.1 +-1.1 +1.2 +-1.2 +1.3 +-1.3 +1.4 +-1.4 +1.5 +-1.5 +1.6 +-1.6 +1.7 +-1.7 +1.8 +-1.8 +1.9 +-1.9 +r1 +1.1 +-1.1 +1.2 +-1.2 +1.3 +-1.3 +1.4 +-1.4 +1.5 +-1.5 +1.6 +-1.6 +1.7 +-1.7 +1.8 +-1.8 +1.9 +-1.9 +r2 +1.1 +-1.1 +1.2 +-1.2 +1.3 +-1.3 +1.4 +-1.4 +1.5 +-1.5 +1.6 +-1.6 +1.7 +-1.7 +1.8 +-1.8 +1.9 +-1.9 +r3 +1.1 +-1.1 +1.2 +-1.2 +1.3 +-1.3 +1.4 +-1.4 +1.5 +-1.5 +1.6 +-1.6 +1.7 +-1.7 +1.8 +-1.8 +1.9 +-1.9 diff --git a/src/contrib/gdtoa/test/strtoIdSI.c b/src/contrib/gdtoa/test/strtoIdSI.c new file mode 100644 index 0000000..c5342ed --- /dev/null +++ b/src/contrib/gdtoa/test/strtoIdSI.c @@ -0,0 +1,2 @@ +#define Sudden_Underflow +#include "../strtoId.c" diff --git a/src/contrib/gdtoa/test/strtoIddSI.c b/src/contrib/gdtoa/test/strtoIddSI.c new file mode 100644 index 0000000..2966259 --- /dev/null +++ b/src/contrib/gdtoa/test/strtoIddSI.c @@ -0,0 +1,2 @@ +#define Sudden_Underflow +#include "../strtoIdd.c" diff --git a/src/contrib/gdtoa/test/strtodISI.c b/src/contrib/gdtoa/test/strtodISI.c new file mode 100644 index 0000000..66d2add --- /dev/null +++ b/src/contrib/gdtoa/test/strtodISI.c @@ -0,0 +1,2 @@ +#define Sudden_Underflow +#include "../strtodI.c" diff --git a/src/contrib/gdtoa/test/strtodt.c b/src/contrib/gdtoa/test/strtodt.c new file mode 100644 index 0000000..da74660 --- /dev/null +++ b/src/contrib/gdtoa/test/strtodt.c @@ -0,0 +1,140 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test strtod. */ + +/* On stdin, read triples: d x y: + * d = decimal string + * x = high-order Hex value expected from strtod + * y = low-order Hex value + * Complain about errors. + */ + +#include +#include +#include + + static int W0, W1; + typedef union { + double d; + long L[2]; + } U; + + static int +process(char *fname, FILE *f) +{ + U a, b; + char buf[2048]; + double d; + char *s; + int line, n; + + line = n = 0; + + top: + while(fgets(s = buf, sizeof(buf), f)) { + line++; + while(*s <= ' ') + if (!*s++) + goto top; /* break 2 */ + if (*s == '#') + continue; + while(*s > ' ') + s++; + if (sscanf(s,"\t%lx\t%lx", &a.L[0], &a.L[1]) != 2) { + printf("Badly formatted line %d of %s\n", + line, fname); + n++; + continue; + } + b.d = strtod(buf,0); + if (b.L[W0] != a.L[0] || b.L[W1] != a.L[1]) { + n++; + printf("Line %d of %s: got %lx %lx; expected %lx %lx\n", + line, fname, b.L[W0], b.L[W1], a.L[0], a.L[1]); + } + } + return n; + } + + int +main(int argc, char **argv) +{ + FILE *f; + char *prog, *s; + int n, rc; + U u; + + prog = argv[0]; + if (argc == 2 && !strcmp(argv[1],"-?")) { + fprintf(stderr, "Usage: %s [file [file...]]\n" + "\tto read data file(s) of tab-separated triples d x y with\n" + "\t\td decimal string\n" + "\t\tx = high-order Hex value expected from strtod\n" + "\t\ty = low-order Hex value\n" + "\tComplain about errors by strtod.\n" + "\tIf no files, read triples from stdin.\n", + prog); + return 0; + } + + /* determine endian-ness */ + + u.d = 1.; + W0 = u.L[0] == 0; + W1 = 1 - W0; + + /* test */ + + n = rc = 0; + if (argc <= 1) + n = process("", stdin); + else + while(s = *++argv) + if (f = fopen(s,"r")) { + n += process(s, f); + fclose(f); + } + else { + rc = 2; + fprintf(stderr, "Cannot open %s\n", s); + } + printf("%d bad conversions\n", n); + if (n) + rc |= 1; + return rc; + } diff --git a/src/contrib/gdtoa/test/strtopddSI.c b/src/contrib/gdtoa/test/strtopddSI.c new file mode 100644 index 0000000..d2004e5 --- /dev/null +++ b/src/contrib/gdtoa/test/strtopddSI.c @@ -0,0 +1,2 @@ +#define Sudden_Underflow +#include "../strtopdd.c" diff --git a/src/contrib/gdtoa/test/strtorddSI.c b/src/contrib/gdtoa/test/strtorddSI.c new file mode 100644 index 0000000..dd6a381 --- /dev/null +++ b/src/contrib/gdtoa/test/strtorddSI.c @@ -0,0 +1,2 @@ +#define Sudden_Underflow +#include "../strtordd.c" diff --git a/src/contrib/gdtoa/test/testnos b/src/contrib/gdtoa/test/testnos new file mode 100644 index 0000000..a36a986 --- /dev/null +++ b/src/contrib/gdtoa/test/testnos @@ -0,0 +1,28 @@ +1.23 +1.23e+20 +1.23e-20 +1.23456789 +1.23456589e+20 +1.23e+30 +1.23e-30 +1.23456789e-20 +1.23456789e-30 +1.234567890123456789 +1.23456789012345678901234567890123456789 +1.23e306 +1.23e-306 +1.23e-320 +1.23e-20 +1.23456789e307 +1.23456589e-307 +1.234567890123456789 +1.234567890123456789e301 +1.234567890123456789e-301 +1.234567890123456789e-321 +1e23 +1e310 +9.0259718793241475e-277 +9.025971879324147880346310405869e-277 +9.025971879324147880346310405868e-277 +2.2250738585072014e-308 +2.2250738585072013e-308 diff --git a/src/contrib/gdtoa/test/testnos1 b/src/contrib/gdtoa/test/testnos1 new file mode 100644 index 0000000..d734b35 --- /dev/null +++ b/src/contrib/gdtoa/test/testnos1 @@ -0,0 +1,20 @@ +1.23:2 6 +1.23:4 6 +1.23e+20:2 6 +1.23e+20:4 6 +1.23e-20:2 6 +1.23e-20:4 6 +1.23456789:2 6 +1.23456789:4 6 +1.23456589e+20:2 6 +1.23456589e+20:4 6 +1.23456789e-20:2 6 +1.23456789e-20:4 6 +1234565:2 6 +1234565:4 6 +1.234565:2 6 +1.234565:4 6 +1.234565e+20:2 6 +1.234565e+20:4 6 +1.234565e-20:2 6 +1.234565e-20:4 6 diff --git a/src/contrib/gdtoa/test/testnos3 b/src/contrib/gdtoa/test/testnos3 new file mode 100644 index 0000000..be48902 --- /dev/null +++ b/src/contrib/gdtoa/test/testnos3 @@ -0,0 +1,328 @@ +# Test triples for strtodt, derived from Fred Tydeman's posting +# of 26 February 1996 to comp.arch.arithmetic. + +9e0306 7fa9a202 8368022e +4e-079 2fa7b6d7 1d20b96c +7e-261 9eb8d7e 32be6396 +6e-025 3ae7361c b863de62 +7e-161 1eaf7e0d b3799aa3 +7e0289 7c1cbb54 7777a285 +5e0079 507afcef 51f0fb5f +1e0080 508afcef 51f0fb5f +7e-303 1333391 31c46f8b +5e0152 5fa317e5 ef3ab327 +5e0125 5a07a2ec c414a03f +2e0126 5a27a2ec c414a03f +7e-141 22d5570f 59bd178c +4e-192 18323ff0 6eea847a +9e0043 49102498 ea6df0c4 +1e0303 7ed754e3 1cd072da +95e-089 2dde3cbc 9907fdc8 +85e0194 689d1c26 db7d0dae +69e0267 77c0b7cb 60c994da +97e-019 3c665dde 8e688ba6 +37e0046 49d033d7 eca0adef +74e0046 49e033d7 eca0adef +61e-099 2bc0ad83 6f269a17 +53e-208 151b39ae 1909c31b +93e-234 fc27b2e 4f210075 +79e-095 2c9a5db8 12948281 +87e-274 772d36c f48e7abd +83e0025 4585747a b143e353 +17e-036 38b698cc dc60015a +53e0033 47246a34 18629ef6 +51e-074 30ecd5be e57763e6 +63e-022 3bbdc03b 8fd7016a +839e0143 5e3ae03f 245703e2 +749e-182 1abf1472 7744c63e +999e-026 3b282782 afe1869e +345e0266 77b0b7cb 60c994da +914e-102 2b5ffc81 bc29f02b +829e0102 55b7221a 79cdd1d9 +307e0090 5322d6b1 83fe4b55 +859e0182 6654374d 8b87ac63 +283e0085 5216c309 24bab4b +589e0187 675526be 9c22eb17 +302e0176 64fdcf7d f8f573b7 +604e0176 650dcf7d f8f573b7 +761e-244 de03cea 3586452e +647e0230 7044d64d 4079150c +755e0174 64a7d931 93f78fc6 +255e-075 30dcd5be e57763e6 +3391e0055 4c159bd3 ad46e346 +4147e-015 3d923d1b 5eb1d778 +3996e-026 3b482782 afe1869e +1998e-026 3b382782 afe1869e +3338e-296 335519a c5142aab +1669e-296 325519a c5142aab +8699e-276 772d2df 246ecd2d +5311e0243 73284e91 f4aa0fdb +7903e-096 2cd07c2d 27a5b989 +7611e-226 11d19b87 44033457 +3257e0058 4cb444b3 4a6fb3eb +6514e0058 4cc444b3 4a6fb3eb +3571e0263 77462644 c61d41aa +7142e0263 77562644 c61d41aa +5311e0242 72f3720e 5d54d97c +1617e-063 3384c98f ce16152e +51881e0037 4897d295 dc76da4 +31441e-118 285ef890 f5de4c86 +30179e0079 5143e272 a77478e8 +60358e0079 5153e272 a77478e8 +63876e-020 3cc70385 6844bdbf +31938e-020 3cb70385 6844bdbf +46073e-032 3a42405b 773fbdf3 +32941e0051 4b757eb8 ad52a5c9 +82081e0041 49770105 df3d47cb +38701e-215 1440492a 4a8a37fd +62745e0047 4ab0c52f e6dc6a1b +12549e0048 4ac0c52f e6dc6a1b +64009e-183 1af099b3 93b84832 +89275e0261 77262644 c61d41aa +75859e0025 46232645 e1ba93f0 +57533e0287 7c8272ed 2307f56a +584169e0229 70ad6570 59dc79aa +940189e-112 29eb99d6 240c1a28 +416121e0197 6a00fd07 ed297f80 +832242e0197 6a10fd07 ed297f80 +584738e0076 50e8a85e b277e645 +933587e-140 241b2487 28b9c117 +252601e0121 5a2dda59 2e398dd7 +358423e0274 79f9463b 59b8f2bd +892771e-213 14f25818 c7294f27 +410405e0040 49670105 df3d47cb +928609e-261 afbe2dd 66200bef +302276e-254 c55a462 d91c6ab3 +920657e-023 3c653a99 85dbde6c +609019e-025 3bf1f99e 11ea0a24 +252601e0120 59f7e1e0 f1c7a4ac +654839e-060 34b00e7d b3b3f242 +8823691e0130 5c5e597c b94b7ae +2920845e0228 709d6570 59dc79aa +9210917e0080 51fda232 347e6032 +5800419e-303 26e58ff a48f4fce +6119898e-243 ee3ecf2 2ea07863 +3059949e-243 ed3ecf2 2ea07863 +2572231e0223 6f90f73b e1dff9ad +5444097e-021 3cf8849d d33c95af +5783893e-127 26f7e590 2ce0e151 +3865421e-225 1295d4fe 53afec65 +4590831e0156 61b4689b 4a5fa201 +9181662e0156 61c4689b 4a5fa201 +5906361e-027 3bbbe45a 312d08a0 +7315057e0235 7225f0d4 8362a72 +9088115e0106 5762e51a 84a3c6a0 +1817623e0107 5772e51a 84a3c6a0 +44118455e0129 5c4e597c b94b7ae +35282041e0293 7e5512d5 273e62e8 +31279898e-291 5129b01 b6885d36 +15639949e-291 5029b01 b6885d36 +27966061e0145 5f955bcf 72fd10f9 +55932122e0145 5fa55bcf 72fd10f9 +70176353e-053 36900683 a21de855 +40277543e-032 3adf29ca ff893b1 +50609263e0157 622193af f1f1c8e3 +66094077e0077 518b37c4 b7928317 +84863171e0114 59406e98 f5ec8f37 +89396333e0264 786526f0 61ca9053 +87575437e-309 16e0732 602056c +78693511e-044 3870bc7b 7603a2ca +90285923e-206 16d14700 83f89d48 +30155207e-030 3b423a4a d20748a2 +245540327e0121 5acc569e 968e0944 +263125459e0287 7d44997a 298b2f2e +566446538e-257 c64472b a9550e86 +283223269e-257 c54472b a9550e86 +245540327e0122 5b01b623 1e18c5cb +491080654e0122 5b11b623 1e18c5cb +971212611e-126 27a397d3 c9745d2f +229058583e0052 4c76ce94 febdc7a5 +325270231e0039 49cc7ccf 90c9f8ab +989648089e-035 3a8880a3 d515e849 +653777767e0273 7a720223 f2b3a881 +923091487e0209 6d30bc60 e6896717 +526250918e0288 7d89bfd8 b3edfafa +350301748e-309 18e0732 602056c +741111169e-203 17a14fe7 daf8f3ae +667284113e-240 ff09355 f8050c02 +1227701635e0120 5abc569e 968e0944 +9981396317e-182 1c38afe1 a2a66aa +5232604057e-298 41465b8 96c24520 +5572170023e-088 2fb08478 22f765b2 +1964322616e0122 5b31b623 1e18c5cb +3928645232e0122 5b41b623 1e18c5cb +8715380633e-058 35f4614c 3219891f +4856063055e-127 279397d3 c9745d2f +8336960483e-153 223a06a1 24b95e1 +1007046393e-155 21a01891 fc4717fd +5378822089e-176 1d695fd4 c88d4b1b +5981342308e-190 1a83db11 ac608107 +7214782613e-086 3020b552 d2edcdea +5458466829e0142 5f70acde 6a98eb4c +9078555839e-109 2b5fc575 867314ee +6418488827e0079 526021f1 4ed7b3fa +65325840981e0069 5081a151 ddbd3c4a +49573485983e0089 54a221bd 871d2cf4 +46275205733e0074 51830e6c 7d4e3480 +92550411466e0074 51930e6c 7d4e3480 +41129842097e-202 1832c3e7 2d179607 +93227267727e-049 380960fe 8d5847f +41297294357e0185 688c4943 7fccfadb +41534892987e-067 343a1266 6477886d +42333842451e0201 6be0189a 26df575f +78564021519e-227 13115551 5fd37265 +53587107423e-061 35800a19 a3ffd981 +53827010643e-200 18a32fa6 9a69bd6d +83356057653e0193 6a4544e6 daee2a18 +45256834646e-118 29a541ec dfd48694 +45392779195e-110 2b4fc575 867314ee +23934638219e0291 7e81deaf 40ead9a0 +995779191233e0113 59e2d44e dcc51304 +997422852243e-265 b676688 faee99bc +653532977297e-123 28d925a0 aabcdc68 +938885684947e0147 60f11894 b202e9f4 +619534293513e0124 5c210c20 303fe0f1 +539879452414e-042 39a5e66d c3d6bdb5 +742522891517e0259 782c1c35 2fc3c309 +254901016865e-022 3dbc06d3 66394441 +685763015669e0280 7c85fd7a a44d9477 +384865004907e-285 72aa65b 58639e69 +286556458711e0081 5321958b 36c5102b +573112917422e0081 5331958b 36c5102b +769525178383e-150 234253ec e161420 +416780288265e0192 6a3544e6 daee2a18 +226963895975e-111 2b3fc575 867314ee +665592809339e0063 4f778b65 16c2b478 +3891901811465e0217 6f99ab82 61990292 +4764593340755e0069 50e4177a 9915fbf8 +6336156586177e0269 7a7173f7 6c63b792 +8233559360849e0095 56566fee 5649a7a +3662265515198e-107 2c538e6e dd48f2a3 +1831132757599e-107 2c438e6e dd48f2a3 +7812878489261e-179 1d726dae 7bbeda75 +6363857920591e0145 60b28a61 cf9483b7 +8811915538555e0082 53a51f50 8b287ae7 +9997878507563e-195 1a253db2 fea1ea31 +9224786422069e-291 634ee5d 56b32957 +6284426329974e-294 58d3409 dfbca26f +9199302046091e-062 35c13597 2630774c +6070482281213e-122 29423fa9 e6fcf47e +2780161250963e-301 405acc2 53064c2 +8233559360849e0094 5621f324 d11d4862 +72027097041701e0206 6d946778 12d3a606 +97297545286625e0215 6f79ab82 61990292 +99021992302453e-025 3da5c671 4def374c +54104687080198e-022 3e373cdf 8db7a7bc +33519685743233e0089 5537f203 339c9629 +67039371486466e0089 5547f203 339c9629 +39064392446305e-180 1d626dae 7bbeda75 +17796979903653e0261 78e072f3 819c1321 +28921916763211e0038 4a9eebab e0957af3 +87605699161665e0155 6302920f 96e7f9ef +41921560615349e-067 34d9b2a5 c4041e4b +80527976643809e0061 4f7c7c5a ea080a49 +72335858886654e-159 21cce77c 2b3328fc +52656615219377e0102 57f561de f4a9ee32 +15400733123779e-072 33b8bf7e 7fa6f02a +77003665618895e-073 33a8bf7e 7fa6f02a +475603213226859e-042 3a42d730 88f4050a +972708181182949e0116 5b218a7f 36172332 +246411729980464e-071 342eef5e 1f90ac34 +123205864990232e-071 341eef5e 1f90ac34 +609610927149051e-255 e104273 b18918b1 +475603213226859e-041 3a778cfc ab31064d +672574798934795e0065 508226c6 84c87261 +134514959786959e0066 509226c6 84c87261 +294897574603217e-151 2395f2df 5e675a0f +723047919080275e0036 4a7eebab e0957af3 +660191429952702e-088 30bddc7e 975c5045 +330095714976351e-088 30addc7e 975c5045 +578686871093232e-159 21fce77c 2b3328fc +144671717773308e-159 21dce77c 2b3328fc +385018328094475e-074 3398bf7e 7fa6f02a +330095714976351e-089 3077e398 7916a69e +2215901545757777e-212 171a80a6 e566428c +1702061899637397e-276 9cacc46 749dccfe +1864950924021923e0213 6f53ae60 753af6ca +3729901848043846e0213 6f63ae60 753af6ca +7487252720986826e-165 20f8823a 57adbef9 +3743626360493413e-165 20e8823a 57adbef9 +4988915232824583e0119 5be5f6de 9d5d6b5b +3771476185376383e0277 7cae3c14 d6916ce9 +6182410494241627e-119 2a81b964 58445d07 +2572981889477453e0142 609dfc11 fbf46087 +7793560217139653e0051 4dd28046 1b856ec5 +9163942927285259e-202 194fe601 457dce4d +6353227084707473e0155 63650aff 653ffe8a +4431803091515554e-211 17609068 4f5fe998 +9324754620109615e0211 6f0f7d67 21f7f144 +8870461176410409e0263 79d90529 a37b7e22 +90372559027740405e0143 612491da ad0ba280 +18074511805548081e0146 61a011f2 d73116f4 +54897030182071313e0029 496ec556 66d8f9ec +76232626624829156e-032 3ccb7738 11e75fe +59898021767894608e-165 2128823a 57adbef9 +29949010883947304e-165 2118823a 57adbef9 +26153245263757307e0049 4d83de00 5bd620df +27176258005319167e-261 d27c074 7bd76fa1 +18074511805548081e0147 61d4166f 8cfd5cb1 +24691002732654881e-115 2b759a27 83ce70ab +58483921078398283e0057 4f408ce4 99519ce3 +64409240769861689e-159 22692238 f7987779 +94080055902682397e-242 11364981 e39e66ca +31766135423537365e0154 63550aff 653ffe8a +68985865317742005e0164 657a999d dec72aca +13797173063548401e0165 658a999d dec72aca +902042358290366539e-281 9522dc0 1ca1cb8c +238296178309629163e0272 7c038fd9 3f1f5342 +783308178698887621e0226 72925ae6 2cb346d8 +439176241456570504e0029 499ec556 66d8f9ec +899810892172646163e0283 7e6adf51 fa055e03 +926145344610700019e-225 14f307a6 7f1f69ff +653831131593932675e0047 4d63de00 5bd620df +130766226318786535e0048 4d73de00 5bd620df +557035730189854663e-294 693bfac 6bc4767b +902042358290366539e-280 986b930 23ca3e6f +272104041512242479e0200 6d13bbb4 bf05f087 +544208083024484958e0200 6d23bbb4 bf05f087 +680429695511221511e0192 6b808ebc 116f8a20 +308975121073410857e0236 7490db75 cc001072 +792644927852378159e0078 53d7bff3 36d8ff06 +783308178698887621e0223 71f2cbac 35f71140 +8396094300569779681e-252 f8ab223 efcee35a +3507665085003296281e-074 346b85c0 26a264e4 +7322325862592278999e0074 5336775b 6caa5ae0 +6014546754280072926e0209 6f396397 b06732a4 +7120190517612959703e0120 5cc3220d cd5899fd +3507665085003296281e-073 34a13398 18257f0f +4345544743100783551e-218 168a9c42 e5b6d89f +9778613303868468131e-090 313146fe 1075e1ef +7539204280836061195e-082 32d3d969 e3dbe723 +7862637540082247119e-202 19eaba32 62ee707b +2176832332097939832e0200 6d43bbb4 bf05f087 +8643988913946659879e0115 5bbe71ec 1ed0a4f9 +5529436763613147623e0138 6079c677 be6f236e +6764958008109694533e-173 1fed0669 2e6f5ef6 +6802601037806061975e0197 6cbf92ba cb3cb40c +1360520207561212395e0198 6ccf92ba cb3cb40c +62259110684423957791e0047 4dcd8f2c fc20d6e8 +88800290202542652011e-226 1526cec5 1a43f41a +41010852717673354694e-221 16201295 4b6aabba +20505426358836677347e-221 16101295 4b6aabba +66102447903809911604e0055 4f776206 8a24fd55 +35600952588064798515e0119 5cb3220d cd5899fd +14371240869903838702e0205 6e78d92d 2bcc7a81 +57500690832492901689e0043 4cf65d3e 2acd616b +23432630639573022093e-107 2dbdd54c 40a2f25f +62259110684423957791e0048 4e02797c 1d948651 +35620497849450218807e-306 475b220 82529425 +69658634627134074624e0200 6d93bbb4 bf05f087 +99440755792436956989e-062 37362d10 462a26f4 +55277197169490210673e0081 54d945bf a911e32a +36992084760177624177e-318 1f8c5f9 551c2f9a +30888265282878466443e-111 2cf01b8e f28251fc + +# examples of bugs introduced 20001113, fixed 20010207 +# first is 2^-1075 (half the smallest denormal) +2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125e-324 0 0 +2.47032822920623272e-324 0 0 diff --git a/src/contrib/gdtoa/test/x.ou0 b/src/contrib/gdtoa/test/x.ou0 new file mode 100644 index 0000000..83daa47 --- /dev/null +++ b/src/contrib/gdtoa/test/x.ou0 @@ -0,0 +1,1182 @@ + +Input: 1.23 + +strtox consumes 4 bytes and returns 33 +with bits = #3fff 9d70 a3d7 a3d 70a4 +g_xfmt(0) gives 4 bytes: "1.23" + +strtoIx returns 33, consuming 4 bytes. +fI[0] = #3fff 9d70 a3d7 a3d 70a3 +fI[1] = #3fff 9d70 a3d7 a3d 70a3 +fI[1] == strtox + + +Input: 1.23e+20 + +strtox consumes 8 bytes and returns 1 +with bits = #4041 d55e f90a 2da1 8000 +g_xfmt(0) gives 8 bytes: "1.23e+20" + +strtoIx returns 1, consuming 8 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.23e-20 + +strtox consumes 8 bytes and returns 17 +with bits = #3fbc e857 267b b3a9 84f2 +g_xfmt(0) gives 8 bytes: "1.23e-20" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3fbc e857 267b b3a9 84f2 +fI[1] = #3fbc e857 267b b3a9 84f2 +fI[0] == strtox + + +Input: 1.23456789 + +strtox consumes 10 bytes and returns 33 +with bits = #3fff 9e06 5214 1ef0 dbf6 +g_xfmt(0) gives 10 bytes: "1.23456789" + +strtoIx returns 33, consuming 10 bytes. +fI[0] = #3fff 9e06 5214 1ef0 dbf5 +fI[1] = #3fff 9e06 5214 1ef0 dbf5 +fI[1] == strtox + + +Input: 1.23456589e+20 + +strtox consumes 14 bytes and returns 1 +with bits = #4041 d629 bd33 5cc ba00 +g_xfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIx returns 1, consuming 14 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.23e+30 + +strtox consumes 8 bytes and returns 17 +with bits = #4062 f865 8274 7dbc 824a +g_xfmt(0) gives 8 bytes: "1.23e+30" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #4062 f865 8274 7dbc 824a +fI[1] = #4062 f865 8274 7dbc 824a +fI[0] == strtox + + +Input: 1.23e-30 + +strtox consumes 8 bytes and returns 17 +with bits = #3f9b c794 337a 8085 54eb +g_xfmt(0) gives 8 bytes: "1.23e-30" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3f9b c794 337a 8085 54eb +fI[1] = #3f9b c794 337a 8085 54eb +fI[0] == strtox + + +Input: 1.23456789e-20 + +strtox consumes 14 bytes and returns 17 +with bits = #3fbc e934 a38 f3d6 d352 +g_xfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #3fbc e934 a38 f3d6 d352 +fI[1] = #3fbc e934 a38 f3d6 d352 +fI[0] == strtox + + +Input: 1.23456789e-30 + +strtox consumes 14 bytes and returns 17 +with bits = #3f9b c851 f19d decc a8fc +g_xfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #3f9b c851 f19d decc a8fc +fI[1] = #3f9b c851 f19d decc a8fc +fI[0] == strtox + + +Input: 1.234567890123456789 + +strtox consumes 20 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 20 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d +fI[1] = #3fff 9e06 5214 62cf db8d +fI[0] == strtox + + +Input: 1.23456789012345678901234567890123456789 + +strtox consumes 40 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 40 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d +fI[1] = #3fff 9e06 5214 62cf db8d +fI[0] == strtox + + +Input: 1.23e306 + +strtox consumes 8 bytes and returns 17 +with bits = #43f7 e033 b668 e30f a6d5 +g_xfmt(0) gives 9 bytes: "1.23e+306" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #43f7 e033 b668 e30f a6d5 +fI[1] = #43f7 e033 b668 e30f a6d5 +fI[0] == strtox + + +Input: 1.23e-306 + +strtox consumes 9 bytes and returns 33 +with bits = #3c06 dd1d c2ed 1cb7 3f25 +g_xfmt(0) gives 9 bytes: "1.23e-306" + +strtoIx returns 33, consuming 9 bytes. +fI[0] = #3c06 dd1d c2ed 1cb7 3f24 +fI[1] = #3c06 dd1d c2ed 1cb7 3f24 +fI[1] == strtox + + +Input: 1.23e-320 + +strtox consumes 9 bytes and returns 33 +with bits = #3bd8 9b98 c371 844c 3f1a +g_xfmt(0) gives 9 bytes: "1.23e-320" + +strtoIx returns 33, consuming 9 bytes. +fI[0] = #3bd8 9b98 c371 844c 3f19 +fI[1] = #3bd8 9b98 c371 844c 3f19 +fI[1] == strtox + + +Input: 1.23e-20 + +strtox consumes 8 bytes and returns 17 +with bits = #3fbc e857 267b b3a9 84f2 +g_xfmt(0) gives 8 bytes: "1.23e-20" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3fbc e857 267b b3a9 84f2 +fI[1] = #3fbc e857 267b b3a9 84f2 +fI[0] == strtox + + +Input: 1.23456789e307 + +strtox consumes 14 bytes and returns 17 +with bits = #43fb 8ca5 8a5e d766 de75 +g_xfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #43fb 8ca5 8a5e d766 de75 +fI[1] = #43fb 8ca5 8a5e d766 de75 +fI[0] == strtox + + +Input: 1.23456589e-307 + +strtox consumes 15 bytes and returns 17 +with bits = #3c03 b18c b5dc c22f d369 +g_xfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIx returns 17, consuming 15 bytes. +fI[0] = #3c03 b18c b5dc c22f d369 +fI[1] = #3c03 b18c b5dc c22f d369 +fI[0] == strtox + + +Input: 1.234567890123456789 + +strtox consumes 20 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 20 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d +fI[1] = #3fff 9e06 5214 62cf db8d +fI[0] == strtox + + +Input: 1.234567890123456789e301 + +strtox consumes 24 bytes and returns 33 +with bits = #43e7 937a 8baf ab20 980c +g_xfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIx returns 33, consuming 24 bytes. +fI[0] = #43e7 937a 8baf ab20 980b +fI[1] = #43e7 937a 8baf ab20 980b +fI[1] == strtox + + +Input: 1.234567890123456789e-301 + +strtox consumes 25 bytes and returns 33 +with bits = #3c17 a953 271a 5d06 9ad9 +g_xfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIx returns 33, consuming 25 bytes. +fI[0] = #3c17 a953 271a 5d06 9ad8 +fI[1] = #3c17 a953 271a 5d06 9ad8 +fI[1] == strtox + + +Input: 1.234567890123456789e-321 + +strtox consumes 25 bytes and returns 33 +with bits = #3bd4 f9e1 1b4c ea6d cce9 +g_xfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIx returns 33, consuming 25 bytes. +fI[0] = #3bd4 f9e1 1b4c ea6d cce8 +fI[1] = #3bd4 f9e1 1b4c ea6d cce8 +fI[1] == strtox + + +Input: 1e23 + +strtox consumes 4 bytes and returns 1 +with bits = #404b a968 163f a57 b400 +g_xfmt(0) gives 5 bytes: "1e+23" + +strtoIx returns 1, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1e310 + +strtox consumes 5 bytes and returns 33 +with bits = #4404 de81 e40a 34b cf50 +g_xfmt(0) gives 6 bytes: "1e+310" + +strtoIx returns 33, consuming 5 bytes. +fI[0] = #4404 de81 e40a 34b cf4f +fI[1] = #4404 de81 e40a 34b cf4f +fI[1] == strtox + + +Input: 9.0259718793241475e-277 + +strtox consumes 23 bytes and returns 33 +with bits = #3c69 ffff ffff ffff fcf7 +g_xfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIx returns 33, consuming 23 bytes. +fI[0] = #3c69 ffff ffff ffff fcf6 +fI[1] = #3c69 ffff ffff ffff fcf6 +fI[1] == strtox + + +Input: 9.025971879324147880346310405869e-277 + +strtox consumes 37 bytes and returns 17 +with bits = #3c6a 8000 0 0 0 +g_xfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIx returns 17, consuming 37 bytes. +fI[0] = #3c6a 8000 0 0 0 +fI[1] = #3c6a 8000 0 0 0 +fI[0] == strtox + + +Input: 9.025971879324147880346310405868e-277 + +strtox consumes 37 bytes and returns 33 +with bits = #3c6a 8000 0 0 0 +g_xfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIx returns 33, consuming 37 bytes. +fI[0] = #3c69 ffff ffff ffff ffff +fI[1] = #3c6a 8000 0 ffff ffff +fI[1] == strtox + + +Input: 2.2250738585072014e-308 + +strtox consumes 23 bytes and returns 17 +with bits = #3c01 8000 0 0 46 +g_xfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIx returns 17, consuming 23 bytes. +fI[0] = #3c01 8000 0 0 46 +fI[1] = #3c01 8000 0 0 46 +fI[0] == strtox + + +Input: 2.2250738585072013e-308 + +strtox consumes 23 bytes and returns 17 +with bits = #3c00 ffff ffff ffff fd4f +g_xfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIx returns 17, consuming 23 bytes. +fI[0] = #3c00 ffff ffff ffff fd4f +fI[1] = #3c00 ffff ffff ffff fd4f +fI[0] == strtox + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 8ccc cccc cccc cccc +g_xfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc +fI[1] = #3fff 8ccc cccc cccc cccc +fI[0] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 8ccc cccc cccc cccc +g_xfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd +fI[1] = #bfff 8ccc cccc cccc cccd +fI[1] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 9999 9999 9999 9999 +g_xfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 +fI[1] = #3fff 9999 9999 9999 9999 +fI[0] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 9999 9999 9999 9999 +g_xfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a +fI[1] = #bfff 9999 9999 9999 999a +fI[1] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 +fI[1] = #3fff a666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 +fI[1] = #bfff a666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 +fI[1] = #3fff b333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 +fI[1] = #bfff b333 3333 3333 3334 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff cccc cccc cccc cccc +g_xfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc +fI[1] = #3fff cccc cccc cccc cccc +fI[0] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff cccc cccc cccc cccc +g_xfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd +fI[1] = #bfff cccc cccc cccc cccd +fI[1] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff d999 9999 9999 9999 +g_xfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 +fI[1] = #3fff d999 9999 9999 9999 +fI[0] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff d999 9999 9999 9999 +g_xfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a +fI[1] = #bfff d999 9999 9999 999a +fI[1] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 +fI[1] = #3fff e666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 +fI[1] = #bfff e666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 +fI[1] = #3fff f333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 +fI[1] = #bfff f333 3333 3333 3334 +fI[1] == strtox + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 8ccc cccc cccc cccd +g_xfmt(0) gives 3 bytes: "1.1" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc +fI[1] = #3fff 8ccc cccc cccc cccc +fI[1] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 8ccc cccc cccc cccd +g_xfmt(0) gives 4 bytes: "-1.1" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd +fI[1] = #bfff 8ccc cccc cccc cccd +fI[0] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 9999 9999 9999 999a +g_xfmt(0) gives 3 bytes: "1.2" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 +fI[1] = #3fff 9999 9999 9999 9999 +fI[1] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 9999 9999 9999 999a +g_xfmt(0) gives 4 bytes: "-1.2" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a +fI[1] = #bfff 9999 9999 9999 999a +fI[0] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 +fI[1] = #3fff a666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 +fI[1] = #bfff a666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 +fI[1] = #3fff b333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 +fI[1] = #bfff b333 3333 3333 3334 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff cccc cccc cccc cccd +g_xfmt(0) gives 3 bytes: "1.6" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc +fI[1] = #3fff cccc cccc cccc cccc +fI[1] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff cccc cccc cccc cccd +g_xfmt(0) gives 4 bytes: "-1.6" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd +fI[1] = #bfff cccc cccc cccc cccd +fI[0] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff d999 9999 9999 999a +g_xfmt(0) gives 3 bytes: "1.7" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 +fI[1] = #3fff d999 9999 9999 9999 +fI[1] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff d999 9999 9999 999a +g_xfmt(0) gives 4 bytes: "-1.7" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a +fI[1] = #bfff d999 9999 9999 999a +fI[0] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 +fI[1] = #3fff e666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 +fI[1] = #bfff e666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 +fI[1] = #3fff f333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 +fI[1] = #bfff f333 3333 3333 3334 +fI[1] == strtox + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 8ccc cccc cccc cccd +g_xfmt(0) gives 3 bytes: "1.1" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc +fI[1] = #3fff 8ccc cccc cccc cccc +fI[1] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 8ccc cccc cccc cccc +g_xfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd +fI[1] = #bfff 8ccc cccc cccc cccd +fI[1] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 9999 9999 9999 999a +g_xfmt(0) gives 3 bytes: "1.2" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 +fI[1] = #3fff 9999 9999 9999 9999 +fI[1] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 9999 9999 9999 9999 +g_xfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a +fI[1] = #bfff 9999 9999 9999 999a +fI[1] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff a666 6666 6666 6667 +g_xfmt(0) gives 21 bytes: "1.3000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 +fI[1] = #3fff a666 6666 6666 6666 +fI[1] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 +fI[1] = #bfff a666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff b333 3333 3333 3334 +g_xfmt(0) gives 21 bytes: "1.4000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 +fI[1] = #3fff b333 3333 3333 3333 +fI[1] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 +fI[1] = #bfff b333 3333 3333 3334 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff cccc cccc cccc cccd +g_xfmt(0) gives 3 bytes: "1.6" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc +fI[1] = #3fff cccc cccc cccc cccc +fI[1] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff cccc cccc cccc cccc +g_xfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd +fI[1] = #bfff cccc cccc cccc cccd +fI[1] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff d999 9999 9999 999a +g_xfmt(0) gives 3 bytes: "1.7" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 +fI[1] = #3fff d999 9999 9999 9999 +fI[1] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff d999 9999 9999 9999 +g_xfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a +fI[1] = #bfff d999 9999 9999 999a +fI[1] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff e666 6666 6666 6667 +g_xfmt(0) gives 21 bytes: "1.8000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 +fI[1] = #3fff e666 6666 6666 6666 +fI[1] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 +fI[1] = #bfff e666 6666 6666 6667 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff f333 3333 3333 3334 +g_xfmt(0) gives 21 bytes: "1.9000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 +fI[1] = #3fff f333 3333 3333 3333 +fI[1] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 +fI[1] = #bfff f333 3333 3333 3334 +fI[1] == strtox + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 8ccc cccc cccc cccc +g_xfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc +fI[1] = #3fff 8ccc cccc cccc cccc +fI[0] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 8ccc cccc cccc cccd +g_xfmt(0) gives 4 bytes: "-1.1" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd +fI[1] = #bfff 8ccc cccc cccc cccd +fI[0] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 9999 9999 9999 9999 +g_xfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 +fI[1] = #3fff 9999 9999 9999 9999 +fI[0] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 9999 9999 9999 999a +g_xfmt(0) gives 4 bytes: "-1.2" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a +fI[1] = #bfff 9999 9999 9999 999a +fI[0] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 +fI[1] = #3fff a666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff a666 6666 6666 6667 +g_xfmt(0) gives 22 bytes: "-1.3000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 +fI[1] = #bfff a666 6666 6666 6667 +fI[0] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 +fI[1] = #3fff b333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff b333 3333 3333 3334 +g_xfmt(0) gives 22 bytes: "-1.4000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 +fI[1] = #bfff b333 3333 3333 3334 +fI[0] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff cccc cccc cccc cccc +g_xfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc +fI[1] = #3fff cccc cccc cccc cccc +fI[0] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff cccc cccc cccc cccd +g_xfmt(0) gives 4 bytes: "-1.6" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd +fI[1] = #bfff cccc cccc cccc cccd +fI[0] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff d999 9999 9999 9999 +g_xfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 +fI[1] = #3fff d999 9999 9999 9999 +fI[0] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff d999 9999 9999 999a +g_xfmt(0) gives 4 bytes: "-1.7" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a +fI[1] = #bfff d999 9999 9999 999a +fI[0] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 +fI[1] = #3fff e666 6666 6666 6666 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff e666 6666 6666 6667 +g_xfmt(0) gives 22 bytes: "-1.8000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 +fI[1] = #bfff e666 6666 6666 6667 +fI[0] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 +fI[1] = #3fff f333 3333 3333 3333 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff f333 3333 3333 3334 +g_xfmt(0) gives 22 bytes: "-1.9000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 +fI[1] = #bfff f333 3333 3333 3334 +fI[0] == strtox + diff --git a/src/contrib/gdtoa/test/x.ou1 b/src/contrib/gdtoa/test/x.ou1 new file mode 100644 index 0000000..3ebe74a --- /dev/null +++ b/src/contrib/gdtoa/test/x.ou1 @@ -0,0 +1,1460 @@ + +Input: 1.23 + +strtox consumes 4 bytes and returns 33 +with bits = #3fff 9d70 a3d7 a3d 70a4 +printf("%.21Lg") gives 1.23000000000000000002 +g_xfmt(0) gives 4 bytes: "1.23" + +strtoIx returns 33, consuming 4 bytes. +fI[0] = #3fff 9d70 a3d7 a3d 70a3 += 1.22999999999999999991 +fI[1] = #3fff 9d70 a3d7 a3d 70a3 += 1.23000000000000000002 +fI[1] == strtox + + +Input: 1.23e+20 + +strtox consumes 8 bytes and returns 1 +with bits = #4041 d55e f90a 2da1 8000 +printf("%.21Lg") gives 123000000000000000000 +g_xfmt(0) gives 8 bytes: "1.23e+20" + +strtoIx returns 1, consuming 8 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.23e-20 + +strtox consumes 8 bytes and returns 17 +with bits = #3fbc e857 267b b3a9 84f2 +printf("%.21Lg") gives 1.22999999999999999997e-20 +g_xfmt(0) gives 8 bytes: "1.23e-20" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3fbc e857 267b b3a9 84f2 += 1.22999999999999999997e-20 +fI[1] = #3fbc e857 267b b3a9 84f2 += 1.23000000000000000004e-20 +fI[0] == strtox + + +Input: 1.23456789 + +strtox consumes 10 bytes and returns 33 +with bits = #3fff 9e06 5214 1ef0 dbf6 +printf("%.21Lg") gives 1.23456789000000000003 +g_xfmt(0) gives 10 bytes: "1.23456789" + +strtoIx returns 33, consuming 10 bytes. +fI[0] = #3fff 9e06 5214 1ef0 dbf5 += 1.23456788999999999992 +fI[1] = #3fff 9e06 5214 1ef0 dbf5 += 1.23456789000000000003 +fI[1] == strtox + + +Input: 1.23456589e+20 + +strtox consumes 14 bytes and returns 1 +with bits = #4041 d629 bd33 5cc ba00 +printf("%.21Lg") gives 123456589000000000000 +g_xfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIx returns 1, consuming 14 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.23e+30 + +strtox consumes 8 bytes and returns 17 +with bits = #4062 f865 8274 7dbc 824a +printf("%.21Lg") gives 1.22999999999999999999e+30 +g_xfmt(0) gives 8 bytes: "1.23e+30" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #4062 f865 8274 7dbc 824a += 1.22999999999999999999e+30 +fI[1] = #4062 f865 8274 7dbc 824a += 1.23000000000000000006e+30 +fI[0] == strtox + + +Input: 1.23e-30 + +strtox consumes 8 bytes and returns 17 +with bits = #3f9b c794 337a 8085 54eb +printf("%.21Lg") gives 1.22999999999999999999e-30 +g_xfmt(0) gives 8 bytes: "1.23e-30" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3f9b c794 337a 8085 54eb += 1.22999999999999999999e-30 +fI[1] = #3f9b c794 337a 8085 54eb += 1.23000000000000000007e-30 +fI[0] == strtox + + +Input: 1.23456789e-20 + +strtox consumes 14 bytes and returns 17 +with bits = #3fbc e934 a38 f3d6 d352 +printf("%.21Lg") gives 1.23456788999999999998e-20 +g_xfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #3fbc e934 a38 f3d6 d352 += 1.23456788999999999998e-20 +fI[1] = #3fbc e934 a38 f3d6 d352 += 1.23456789000000000005e-20 +fI[0] == strtox + + +Input: 1.23456789e-30 + +strtox consumes 14 bytes and returns 17 +with bits = #3f9b c851 f19d decc a8fc +printf("%.21Lg") gives 1.23456788999999999999e-30 +g_xfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #3f9b c851 f19d decc a8fc += 1.23456788999999999999e-30 +fI[1] = #3f9b c851 f19d decc a8fc += 1.23456789000000000007e-30 +fI[0] == strtox + + +Input: 1.234567890123456789 + +strtox consumes 20 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +printf("%.21Lg") gives 1.23456789012345678899 +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 20 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678899 +fI[1] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678909 +fI[0] == strtox + + +Input: 1.23456789012345678901234567890123456789 + +strtox consumes 40 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +printf("%.21Lg") gives 1.23456789012345678899 +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 40 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678899 +fI[1] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678909 +fI[0] == strtox + + +Input: 1.23e306 + +strtox consumes 8 bytes and returns 17 +with bits = #43f7 e033 b668 e30f a6d5 +printf("%.21Lg") gives 1.22999999999999999997e+306 +g_xfmt(0) gives 9 bytes: "1.23e+306" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #43f7 e033 b668 e30f a6d5 += 1.22999999999999999997e+306 +fI[1] = #43f7 e033 b668 e30f a6d5 += 1.23000000000000000005e+306 +fI[0] == strtox + + +Input: 1.23e-306 + +strtox consumes 9 bytes and returns 33 +with bits = #3c06 dd1d c2ed 1cb7 3f25 +printf("%.21Lg") gives 1.23000000000000000002e-306 +g_xfmt(0) gives 9 bytes: "1.23e-306" + +strtoIx returns 33, consuming 9 bytes. +fI[0] = #3c06 dd1d c2ed 1cb7 3f24 += 1.22999999999999999995e-306 +fI[1] = #3c06 dd1d c2ed 1cb7 3f24 += 1.23000000000000000002e-306 +fI[1] == strtox + + +Input: 1.23e-320 + +strtox consumes 9 bytes and returns 33 +with bits = #3bd8 9b98 c371 844c 3f1a +printf("%.21Lg") gives 1.23000000000000000002e-320 +g_xfmt(0) gives 9 bytes: "1.23e-320" + +strtoIx returns 33, consuming 9 bytes. +fI[0] = #3bd8 9b98 c371 844c 3f19 += 1.22999999999999999991e-320 +fI[1] = #3bd8 9b98 c371 844c 3f19 += 1.23000000000000000002e-320 +fI[1] == strtox + + +Input: 1.23e-20 + +strtox consumes 8 bytes and returns 17 +with bits = #3fbc e857 267b b3a9 84f2 +printf("%.21Lg") gives 1.22999999999999999997e-20 +g_xfmt(0) gives 8 bytes: "1.23e-20" + +strtoIx returns 17, consuming 8 bytes. +fI[0] = #3fbc e857 267b b3a9 84f2 += 1.22999999999999999997e-20 +fI[1] = #3fbc e857 267b b3a9 84f2 += 1.23000000000000000004e-20 +fI[0] == strtox + + +Input: 1.23456789e307 + +strtox consumes 14 bytes and returns 17 +with bits = #43fb 8ca5 8a5e d766 de75 +printf("%.21Lg") gives 1.23456788999999999998e+307 +g_xfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIx returns 17, consuming 14 bytes. +fI[0] = #43fb 8ca5 8a5e d766 de75 += 1.23456788999999999998e+307 +fI[1] = #43fb 8ca5 8a5e d766 de75 += 1.23456789000000000011e+307 +fI[0] == strtox + + +Input: 1.23456589e-307 + +strtox consumes 15 bytes and returns 17 +with bits = #3c03 b18c b5dc c22f d369 +printf("%.21Lg") gives 1.23456588999999999999e-307 +g_xfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIx returns 17, consuming 15 bytes. +fI[0] = #3c03 b18c b5dc c22f d369 += 1.23456588999999999999e-307 +fI[1] = #3c03 b18c b5dc c22f d369 += 1.23456589000000000009e-307 +fI[0] == strtox + + +Input: 1.234567890123456789 + +strtox consumes 20 bytes and returns 17 +with bits = #3fff 9e06 5214 62cf db8d +printf("%.21Lg") gives 1.23456789012345678899 +g_xfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIx returns 17, consuming 20 bytes. +fI[0] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678899 +fI[1] = #3fff 9e06 5214 62cf db8d += 1.23456789012345678909 +fI[0] == strtox + + +Input: 1.234567890123456789e301 + +strtox consumes 24 bytes and returns 33 +with bits = #43e7 937a 8baf ab20 980c +printf("%.21Lg") gives 1.234567890123456789e+301 +g_xfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIx returns 33, consuming 24 bytes. +fI[0] = #43e7 937a 8baf ab20 980b += 1.23456789012345678889e+301 +fI[1] = #43e7 937a 8baf ab20 980b += 1.234567890123456789e+301 +fI[1] == strtox + + +Input: 1.234567890123456789e-301 + +strtox consumes 25 bytes and returns 33 +with bits = #3c17 a953 271a 5d06 9ad9 +printf("%.21Lg") gives 1.23456789012345678902e-301 +g_xfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIx returns 33, consuming 25 bytes. +fI[0] = #3c17 a953 271a 5d06 9ad8 += 1.23456789012345678892e-301 +fI[1] = #3c17 a953 271a 5d06 9ad8 += 1.23456789012345678902e-301 +fI[1] == strtox + + +Input: 1.234567890123456789e-321 + +strtox consumes 25 bytes and returns 33 +with bits = #3bd4 f9e1 1b4c ea6d cce9 +printf("%.21Lg") gives 1.234567890123456789e-321 +g_xfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIx returns 33, consuming 25 bytes. +fI[0] = #3bd4 f9e1 1b4c ea6d cce8 += 1.23456789012345678893e-321 +fI[1] = #3bd4 f9e1 1b4c ea6d cce8 += 1.234567890123456789e-321 +fI[1] == strtox + + +Input: 1e23 + +strtox consumes 4 bytes and returns 1 +with bits = #404b a968 163f a57 b400 +printf("%.21Lg") gives 1e+23 +g_xfmt(0) gives 5 bytes: "1e+23" + +strtoIx returns 1, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1e310 + +strtox consumes 5 bytes and returns 33 +with bits = #4404 de81 e40a 34b cf50 +printf("%.21Lg") gives 1e+310 +g_xfmt(0) gives 6 bytes: "1e+310" + +strtoIx returns 33, consuming 5 bytes. +fI[0] = #4404 de81 e40a 34b cf4f += 9.9999999999999999994e+309 +fI[1] = #4404 de81 e40a 34b cf4f += 1e+310 +fI[1] == strtox + + +Input: 9.0259718793241475e-277 + +strtox consumes 23 bytes and returns 33 +with bits = #3c69 ffff ffff ffff fcf7 +printf("%.21Lg") gives 9.02597187932414750016e-277 +g_xfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIx returns 33, consuming 23 bytes. +fI[0] = #3c69 ffff ffff ffff fcf6 += 9.02597187932414749967e-277 +fI[1] = #3c69 ffff ffff ffff fcf6 += 9.02597187932414750016e-277 +fI[1] == strtox + + +Input: 9.025971879324147880346310405869e-277 + +strtox consumes 37 bytes and returns 17 +with bits = #3c6a 8000 0 0 0 +printf("%.21Lg") gives 9.02597187932414788035e-277 +g_xfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIx returns 17, consuming 37 bytes. +fI[0] = #3c6a 8000 0 0 0 += 9.02597187932414788035e-277 +fI[1] = #3c6a 8000 0 0 0 += 9.02597187932414788132e-277 +fI[0] == strtox + + +Input: 9.025971879324147880346310405868e-277 + +strtox consumes 37 bytes and returns 33 +with bits = #3c6a 8000 0 0 0 +printf("%.21Lg") gives 9.02597187932414788035e-277 +g_xfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIx returns 33, consuming 37 bytes. +fI[0] = #3c69 ffff ffff ffff ffff += 9.02597187932414787986e-277 +fI[1] = #3c6a 8000 0 ffff ffff += 9.02597187932414788035e-277 +fI[1] == strtox + + +Input: 2.2250738585072014e-308 + +strtox consumes 23 bytes and returns 17 +with bits = #3c01 8000 0 0 46 +printf("%.21Lg") gives 2.22507385850720139998e-308 +g_xfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIx returns 17, consuming 23 bytes. +fI[0] = #3c01 8000 0 0 46 += 2.22507385850720139998e-308 +fI[1] = #3c01 8000 0 0 46 += 2.22507385850720140022e-308 +fI[0] == strtox + + +Input: 2.2250738585072013e-308 + +strtox consumes 23 bytes and returns 17 +with bits = #3c00 ffff ffff ffff fd4f +printf("%.21Lg") gives 2.22507385850720129998e-308 +g_xfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIx returns 17, consuming 23 bytes. +fI[0] = #3c00 ffff ffff ffff fd4f += 2.22507385850720129998e-308 +fI[1] = #3c00 ffff ffff ffff fd4f += 2.2250738585072013001e-308 +fI[0] == strtox + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 8ccc cccc cccc cccc +printf("%.21Lg") gives 1.09999999999999999991 +g_xfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc += 1.09999999999999999991 +fI[1] = #3fff 8ccc cccc cccc cccc += 1.10000000000000000002 +fI[0] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 8ccc cccc cccc cccc +printf("%.21Lg") gives -1.09999999999999999991 +g_xfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd += -1.10000000000000000002 +fI[1] = #bfff 8ccc cccc cccc cccd += -1.09999999999999999991 +fI[1] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 9999 9999 9999 9999 +printf("%.21Lg") gives 1.19999999999999999993 +g_xfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 += 1.19999999999999999993 +fI[1] = #3fff 9999 9999 9999 9999 += 1.20000000000000000004 +fI[0] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 9999 9999 9999 9999 +printf("%.21Lg") gives -1.19999999999999999993 +g_xfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a += -1.20000000000000000004 +fI[1] = #bfff 9999 9999 9999 999a += -1.19999999999999999993 +fI[1] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +printf("%.21Lg") gives 1.29999999999999999996 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 += 1.29999999999999999996 +fI[1] = #3fff a666 6666 6666 6666 += 1.30000000000000000007 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +printf("%.21Lg") gives -1.29999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 += -1.30000000000000000007 +fI[1] = #bfff a666 6666 6666 6667 += -1.29999999999999999996 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +printf("%.21Lg") gives 1.39999999999999999998 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 += 1.39999999999999999998 +fI[1] = #3fff b333 3333 3333 3333 += 1.40000000000000000009 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +printf("%.21Lg") gives -1.39999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 += -1.40000000000000000009 +fI[1] = #bfff b333 3333 3333 3334 += -1.39999999999999999998 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +printf("%.21Lg") gives 1.5 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +printf("%.21Lg") gives -1.5 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff cccc cccc cccc cccc +printf("%.21Lg") gives 1.59999999999999999991 +g_xfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc += 1.59999999999999999991 +fI[1] = #3fff cccc cccc cccc cccc += 1.60000000000000000002 +fI[0] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff cccc cccc cccc cccc +printf("%.21Lg") gives -1.59999999999999999991 +g_xfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd += -1.60000000000000000002 +fI[1] = #bfff cccc cccc cccc cccd += -1.59999999999999999991 +fI[1] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff d999 9999 9999 9999 +printf("%.21Lg") gives 1.69999999999999999993 +g_xfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 += 1.69999999999999999993 +fI[1] = #3fff d999 9999 9999 9999 += 1.70000000000000000004 +fI[0] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff d999 9999 9999 9999 +printf("%.21Lg") gives -1.69999999999999999993 +g_xfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a += -1.70000000000000000004 +fI[1] = #bfff d999 9999 9999 999a += -1.69999999999999999993 +fI[1] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +printf("%.21Lg") gives 1.79999999999999999996 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 += 1.79999999999999999996 +fI[1] = #3fff e666 6666 6666 6666 += 1.80000000000000000007 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +printf("%.21Lg") gives -1.79999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 += -1.80000000000000000007 +fI[1] = #bfff e666 6666 6666 6667 += -1.79999999999999999996 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +printf("%.21Lg") gives 1.89999999999999999998 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 += 1.89999999999999999998 +fI[1] = #3fff f333 3333 3333 3333 += 1.90000000000000000009 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +printf("%.21Lg") gives -1.89999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 += -1.90000000000000000009 +fI[1] = #bfff f333 3333 3333 3334 += -1.89999999999999999998 +fI[1] == strtox + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 8ccc cccc cccc cccd +printf("%.21Lg") gives 1.10000000000000000002 +g_xfmt(0) gives 3 bytes: "1.1" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc += 1.09999999999999999991 +fI[1] = #3fff 8ccc cccc cccc cccc += 1.10000000000000000002 +fI[1] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 8ccc cccc cccc cccd +printf("%.21Lg") gives -1.10000000000000000002 +g_xfmt(0) gives 4 bytes: "-1.1" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd += -1.10000000000000000002 +fI[1] = #bfff 8ccc cccc cccc cccd += -1.09999999999999999991 +fI[0] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 9999 9999 9999 999a +printf("%.21Lg") gives 1.20000000000000000004 +g_xfmt(0) gives 3 bytes: "1.2" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 += 1.19999999999999999993 +fI[1] = #3fff 9999 9999 9999 9999 += 1.20000000000000000004 +fI[1] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 9999 9999 9999 999a +printf("%.21Lg") gives -1.20000000000000000004 +g_xfmt(0) gives 4 bytes: "-1.2" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a += -1.20000000000000000004 +fI[1] = #bfff 9999 9999 9999 999a += -1.19999999999999999993 +fI[0] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +printf("%.21Lg") gives 1.29999999999999999996 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 += 1.29999999999999999996 +fI[1] = #3fff a666 6666 6666 6666 += 1.30000000000000000007 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +printf("%.21Lg") gives -1.29999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 += -1.30000000000000000007 +fI[1] = #bfff a666 6666 6666 6667 += -1.29999999999999999996 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +printf("%.21Lg") gives 1.39999999999999999998 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 += 1.39999999999999999998 +fI[1] = #3fff b333 3333 3333 3333 += 1.40000000000000000009 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +printf("%.21Lg") gives -1.39999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 += -1.40000000000000000009 +fI[1] = #bfff b333 3333 3333 3334 += -1.39999999999999999998 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +printf("%.21Lg") gives 1.5 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +printf("%.21Lg") gives -1.5 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff cccc cccc cccc cccd +printf("%.21Lg") gives 1.60000000000000000002 +g_xfmt(0) gives 3 bytes: "1.6" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc += 1.59999999999999999991 +fI[1] = #3fff cccc cccc cccc cccc += 1.60000000000000000002 +fI[1] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff cccc cccc cccc cccd +printf("%.21Lg") gives -1.60000000000000000002 +g_xfmt(0) gives 4 bytes: "-1.6" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd += -1.60000000000000000002 +fI[1] = #bfff cccc cccc cccc cccd += -1.59999999999999999991 +fI[0] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff d999 9999 9999 999a +printf("%.21Lg") gives 1.70000000000000000004 +g_xfmt(0) gives 3 bytes: "1.7" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 += 1.69999999999999999993 +fI[1] = #3fff d999 9999 9999 9999 += 1.70000000000000000004 +fI[1] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff d999 9999 9999 999a +printf("%.21Lg") gives -1.70000000000000000004 +g_xfmt(0) gives 4 bytes: "-1.7" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a += -1.70000000000000000004 +fI[1] = #bfff d999 9999 9999 999a += -1.69999999999999999993 +fI[0] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +printf("%.21Lg") gives 1.79999999999999999996 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 += 1.79999999999999999996 +fI[1] = #3fff e666 6666 6666 6666 += 1.80000000000000000007 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +printf("%.21Lg") gives -1.79999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 += -1.80000000000000000007 +fI[1] = #bfff e666 6666 6666 6667 += -1.79999999999999999996 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +printf("%.21Lg") gives 1.89999999999999999998 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 += 1.89999999999999999998 +fI[1] = #3fff f333 3333 3333 3333 += 1.90000000000000000009 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +printf("%.21Lg") gives -1.89999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 += -1.90000000000000000009 +fI[1] = #bfff f333 3333 3333 3334 += -1.89999999999999999998 +fI[1] == strtox + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 8ccc cccc cccc cccd +printf("%.21Lg") gives 1.10000000000000000002 +g_xfmt(0) gives 3 bytes: "1.1" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc += 1.09999999999999999991 +fI[1] = #3fff 8ccc cccc cccc cccc += 1.10000000000000000002 +fI[1] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 8ccc cccc cccc cccc +printf("%.21Lg") gives -1.09999999999999999991 +g_xfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd += -1.10000000000000000002 +fI[1] = #bfff 8ccc cccc cccc cccd += -1.09999999999999999991 +fI[1] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff 9999 9999 9999 999a +printf("%.21Lg") gives 1.20000000000000000004 +g_xfmt(0) gives 3 bytes: "1.2" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 += 1.19999999999999999993 +fI[1] = #3fff 9999 9999 9999 9999 += 1.20000000000000000004 +fI[1] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff 9999 9999 9999 9999 +printf("%.21Lg") gives -1.19999999999999999993 +g_xfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a += -1.20000000000000000004 +fI[1] = #bfff 9999 9999 9999 999a += -1.19999999999999999993 +fI[1] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff a666 6666 6666 6667 +printf("%.21Lg") gives 1.30000000000000000007 +g_xfmt(0) gives 21 bytes: "1.3000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 += 1.29999999999999999996 +fI[1] = #3fff a666 6666 6666 6666 += 1.30000000000000000007 +fI[1] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff a666 6666 6666 6666 +printf("%.21Lg") gives -1.29999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.3" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 += -1.30000000000000000007 +fI[1] = #bfff a666 6666 6666 6667 += -1.29999999999999999996 +fI[1] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff b333 3333 3333 3334 +printf("%.21Lg") gives 1.40000000000000000009 +g_xfmt(0) gives 21 bytes: "1.4000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 += 1.39999999999999999998 +fI[1] = #3fff b333 3333 3333 3333 += 1.40000000000000000009 +fI[1] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff b333 3333 3333 3333 +printf("%.21Lg") gives -1.39999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.4" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 += -1.40000000000000000009 +fI[1] = #bfff b333 3333 3333 3334 += -1.39999999999999999998 +fI[1] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +printf("%.21Lg") gives 1.5 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +printf("%.21Lg") gives -1.5 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff cccc cccc cccc cccd +printf("%.21Lg") gives 1.60000000000000000002 +g_xfmt(0) gives 3 bytes: "1.6" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc += 1.59999999999999999991 +fI[1] = #3fff cccc cccc cccc cccc += 1.60000000000000000002 +fI[1] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff cccc cccc cccc cccc +printf("%.21Lg") gives -1.59999999999999999991 +g_xfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd += -1.60000000000000000002 +fI[1] = #bfff cccc cccc cccc cccd += -1.59999999999999999991 +fI[1] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff d999 9999 9999 999a +printf("%.21Lg") gives 1.70000000000000000004 +g_xfmt(0) gives 3 bytes: "1.7" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 += 1.69999999999999999993 +fI[1] = #3fff d999 9999 9999 9999 += 1.70000000000000000004 +fI[1] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff d999 9999 9999 9999 +printf("%.21Lg") gives -1.69999999999999999993 +g_xfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a += -1.70000000000000000004 +fI[1] = #bfff d999 9999 9999 999a += -1.69999999999999999993 +fI[1] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff e666 6666 6666 6667 +printf("%.21Lg") gives 1.80000000000000000007 +g_xfmt(0) gives 21 bytes: "1.8000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 += 1.79999999999999999996 +fI[1] = #3fff e666 6666 6666 6666 += 1.80000000000000000007 +fI[1] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff e666 6666 6666 6666 +printf("%.21Lg") gives -1.79999999999999999996 +g_xfmt(0) gives 4 bytes: "-1.8" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 += -1.80000000000000000007 +fI[1] = #bfff e666 6666 6666 6667 += -1.79999999999999999996 +fI[1] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 33 +with bits = #3fff f333 3333 3333 3334 +printf("%.21Lg") gives 1.90000000000000000009 +g_xfmt(0) gives 21 bytes: "1.9000000000000000001" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 += 1.89999999999999999998 +fI[1] = #3fff f333 3333 3333 3333 += 1.90000000000000000009 +fI[1] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 25 +with bits = #bfff f333 3333 3333 3333 +printf("%.21Lg") gives -1.89999999999999999998 +g_xfmt(0) gives 4 bytes: "-1.9" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 += -1.90000000000000000009 +fI[1] = #bfff f333 3333 3333 3334 += -1.89999999999999999998 +fI[1] == strtox + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 8ccc cccc cccc cccc +printf("%.21Lg") gives 1.09999999999999999991 +g_xfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 8ccc cccc cccc cccc += 1.09999999999999999991 +fI[1] = #3fff 8ccc cccc cccc cccc += 1.10000000000000000002 +fI[0] == strtox + + +Input: -1.1 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 8ccc cccc cccc cccd +printf("%.21Lg") gives -1.10000000000000000002 +g_xfmt(0) gives 4 bytes: "-1.1" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 8ccc cccc cccc cccd += -1.10000000000000000002 +fI[1] = #bfff 8ccc cccc cccc cccd += -1.09999999999999999991 +fI[0] == strtox + + +Input: 1.2 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff 9999 9999 9999 9999 +printf("%.21Lg") gives 1.19999999999999999993 +g_xfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff 9999 9999 9999 9999 += 1.19999999999999999993 +fI[1] = #3fff 9999 9999 9999 9999 += 1.20000000000000000004 +fI[0] == strtox + + +Input: -1.2 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff 9999 9999 9999 999a +printf("%.21Lg") gives -1.20000000000000000004 +g_xfmt(0) gives 4 bytes: "-1.2" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff 9999 9999 9999 999a += -1.20000000000000000004 +fI[1] = #bfff 9999 9999 9999 999a += -1.19999999999999999993 +fI[0] == strtox + + +Input: 1.3 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff a666 6666 6666 6666 +printf("%.21Lg") gives 1.29999999999999999996 +g_xfmt(0) gives 3 bytes: "1.3" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff a666 6666 6666 6666 += 1.29999999999999999996 +fI[1] = #3fff a666 6666 6666 6666 += 1.30000000000000000007 +fI[0] == strtox + + +Input: -1.3 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff a666 6666 6666 6667 +printf("%.21Lg") gives -1.30000000000000000007 +g_xfmt(0) gives 22 bytes: "-1.3000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff a666 6666 6666 6667 += -1.30000000000000000007 +fI[1] = #bfff a666 6666 6666 6667 += -1.29999999999999999996 +fI[0] == strtox + + +Input: 1.4 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff b333 3333 3333 3333 +printf("%.21Lg") gives 1.39999999999999999998 +g_xfmt(0) gives 3 bytes: "1.4" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff b333 3333 3333 3333 += 1.39999999999999999998 +fI[1] = #3fff b333 3333 3333 3333 += 1.40000000000000000009 +fI[0] == strtox + + +Input: -1.4 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff b333 3333 3333 3334 +printf("%.21Lg") gives -1.40000000000000000009 +g_xfmt(0) gives 22 bytes: "-1.4000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff b333 3333 3333 3334 += -1.40000000000000000009 +fI[1] = #bfff b333 3333 3333 3334 += -1.39999999999999999998 +fI[0] == strtox + + +Input: 1.5 + +strtox consumes 3 bytes and returns 1 +with bits = #3fff c000 0 0 0 +printf("%.21Lg") gives 1.5 +g_xfmt(0) gives 3 bytes: "1.5" + +strtoIx returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtox + + +Input: -1.5 + +strtox consumes 4 bytes and returns 9 +with bits = #bfff c000 0 0 0 +printf("%.21Lg") gives -1.5 +g_xfmt(0) gives 4 bytes: "-1.5" + +strtoIx returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtox + + +Input: 1.6 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff cccc cccc cccc cccc +printf("%.21Lg") gives 1.59999999999999999991 +g_xfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff cccc cccc cccc cccc += 1.59999999999999999991 +fI[1] = #3fff cccc cccc cccc cccc += 1.60000000000000000002 +fI[0] == strtox + + +Input: -1.6 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff cccc cccc cccc cccd +printf("%.21Lg") gives -1.60000000000000000002 +g_xfmt(0) gives 4 bytes: "-1.6" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff cccc cccc cccc cccd += -1.60000000000000000002 +fI[1] = #bfff cccc cccc cccc cccd += -1.59999999999999999991 +fI[0] == strtox + + +Input: 1.7 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff d999 9999 9999 9999 +printf("%.21Lg") gives 1.69999999999999999993 +g_xfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIx returns 33, consuming 3 bytes. +fI[0] = #3fff d999 9999 9999 9999 += 1.69999999999999999993 +fI[1] = #3fff d999 9999 9999 9999 += 1.70000000000000000004 +fI[0] == strtox + + +Input: -1.7 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff d999 9999 9999 999a +printf("%.21Lg") gives -1.70000000000000000004 +g_xfmt(0) gives 4 bytes: "-1.7" + +strtoIx returns 41, consuming 4 bytes. +fI[0] = #bfff d999 9999 9999 999a += -1.70000000000000000004 +fI[1] = #bfff d999 9999 9999 999a += -1.69999999999999999993 +fI[0] == strtox + + +Input: 1.8 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff e666 6666 6666 6666 +printf("%.21Lg") gives 1.79999999999999999996 +g_xfmt(0) gives 3 bytes: "1.8" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff e666 6666 6666 6666 += 1.79999999999999999996 +fI[1] = #3fff e666 6666 6666 6666 += 1.80000000000000000007 +fI[0] == strtox + + +Input: -1.8 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff e666 6666 6666 6667 +printf("%.21Lg") gives -1.80000000000000000007 +g_xfmt(0) gives 22 bytes: "-1.8000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff e666 6666 6666 6667 += -1.80000000000000000007 +fI[1] = #bfff e666 6666 6666 6667 += -1.79999999999999999996 +fI[0] == strtox + + +Input: 1.9 + +strtox consumes 3 bytes and returns 17 +with bits = #3fff f333 3333 3333 3333 +printf("%.21Lg") gives 1.89999999999999999998 +g_xfmt(0) gives 3 bytes: "1.9" + +strtoIx returns 17, consuming 3 bytes. +fI[0] = #3fff f333 3333 3333 3333 += 1.89999999999999999998 +fI[1] = #3fff f333 3333 3333 3333 += 1.90000000000000000009 +fI[0] == strtox + + +Input: -1.9 + +strtox consumes 4 bytes and returns 41 +with bits = #bfff f333 3333 3333 3334 +printf("%.21Lg") gives -1.90000000000000000009 +g_xfmt(0) gives 22 bytes: "-1.9000000000000000001" + +strtoIx returns 25, consuming 4 bytes. +fI[0] = #bfff f333 3333 3333 3334 += -1.90000000000000000009 +fI[1] = #bfff f333 3333 3333 3334 += -1.89999999999999999998 +fI[0] == strtox + diff --git a/src/contrib/gdtoa/test/xL.ou0 b/src/contrib/gdtoa/test/xL.ou0 new file mode 100644 index 0000000..dc75f91 --- /dev/null +++ b/src/contrib/gdtoa/test/xL.ou0 @@ -0,0 +1,1182 @@ + +Input: 1.23 + +strtoxL consumes 4 bytes and returns 33 +with bits = #3fff0000 9d70a3d7 a3d70a4 +g_xLfmt(0) gives 4 bytes: "1.23" + +strtoIxL returns 33, consuming 4 bytes. +fI[0] = #3fff0000 9d70a3d7 a3d70a3 +fI[1] = #3fff0000 9d70a3d7 a3d70a4 +fI[1] == strtoxL + + +Input: 1.23e+20 + +strtoxL consumes 8 bytes and returns 1 +with bits = #40410000 d55ef90a 2da18000 +g_xLfmt(0) gives 8 bytes: "1.23e+20" + +strtoIxL returns 1, consuming 8 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.23e-20 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3fbc0000 e857267b b3a984f2 +g_xLfmt(0) gives 8 bytes: "1.23e-20" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3fbc0000 e857267b b3a984f2 +fI[1] = #3fbc0000 e857267b b3a984f3 +fI[0] == strtoxL + + +Input: 1.23456789 + +strtoxL consumes 10 bytes and returns 33 +with bits = #3fff0000 9e065214 1ef0dbf6 +g_xLfmt(0) gives 10 bytes: "1.23456789" + +strtoIxL returns 33, consuming 10 bytes. +fI[0] = #3fff0000 9e065214 1ef0dbf5 +fI[1] = #3fff0000 9e065214 1ef0dbf6 +fI[1] == strtoxL + + +Input: 1.23456589e+20 + +strtoxL consumes 14 bytes and returns 1 +with bits = #40410000 d629bd33 5ccba00 +g_xLfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIxL returns 1, consuming 14 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.23e+30 + +strtoxL consumes 8 bytes and returns 17 +with bits = #40620000 f8658274 7dbc824a +g_xLfmt(0) gives 8 bytes: "1.23e+30" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #40620000 f8658274 7dbc824a +fI[1] = #40620000 f8658274 7dbc824b +fI[0] == strtoxL + + +Input: 1.23e-30 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3f9b0000 c794337a 808554eb +g_xLfmt(0) gives 8 bytes: "1.23e-30" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3f9b0000 c794337a 808554eb +fI[1] = #3f9b0000 c794337a 808554ec +fI[0] == strtoxL + + +Input: 1.23456789e-20 + +strtoxL consumes 14 bytes and returns 17 +with bits = #3fbc0000 e9340a38 f3d6d352 +g_xLfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #3fbc0000 e9340a38 f3d6d352 +fI[1] = #3fbc0000 e9340a38 f3d6d353 +fI[0] == strtoxL + + +Input: 1.23456789e-30 + +strtoxL consumes 14 bytes and returns 17 +with bits = #3f9b0000 c851f19d decca8fc +g_xLfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #3f9b0000 c851f19d decca8fc +fI[1] = #3f9b0000 c851f19d decca8fd +fI[0] == strtoxL + + +Input: 1.234567890123456789 + +strtoxL consumes 20 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 20 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.23456789012345678901234567890123456789 + +strtoxL consumes 40 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 40 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.23e306 + +strtoxL consumes 8 bytes and returns 17 +with bits = #43f70000 e033b668 e30fa6d5 +g_xLfmt(0) gives 9 bytes: "1.23e+306" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #43f70000 e033b668 e30fa6d5 +fI[1] = #43f70000 e033b668 e30fa6d6 +fI[0] == strtoxL + + +Input: 1.23e-306 + +strtoxL consumes 9 bytes and returns 33 +with bits = #3c060000 dd1dc2ed 1cb73f25 +g_xLfmt(0) gives 9 bytes: "1.23e-306" + +strtoIxL returns 33, consuming 9 bytes. +fI[0] = #3c060000 dd1dc2ed 1cb73f24 +fI[1] = #3c060000 dd1dc2ed 1cb73f25 +fI[1] == strtoxL + + +Input: 1.23e-320 + +strtoxL consumes 9 bytes and returns 33 +with bits = #3bd80000 9b98c371 844c3f1a +g_xLfmt(0) gives 9 bytes: "1.23e-320" + +strtoIxL returns 33, consuming 9 bytes. +fI[0] = #3bd80000 9b98c371 844c3f19 +fI[1] = #3bd80000 9b98c371 844c3f1a +fI[1] == strtoxL + + +Input: 1.23e-20 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3fbc0000 e857267b b3a984f2 +g_xLfmt(0) gives 8 bytes: "1.23e-20" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3fbc0000 e857267b b3a984f2 +fI[1] = #3fbc0000 e857267b b3a984f3 +fI[0] == strtoxL + + +Input: 1.23456789e307 + +strtoxL consumes 14 bytes and returns 17 +with bits = #43fb0000 8ca58a5e d766de75 +g_xLfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #43fb0000 8ca58a5e d766de75 +fI[1] = #43fb0000 8ca58a5e d766de76 +fI[0] == strtoxL + + +Input: 1.23456589e-307 + +strtoxL consumes 15 bytes and returns 17 +with bits = #3c030000 b18cb5dc c22fd369 +g_xLfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIxL returns 17, consuming 15 bytes. +fI[0] = #3c030000 b18cb5dc c22fd369 +fI[1] = #3c030000 b18cb5dc c22fd36a +fI[0] == strtoxL + + +Input: 1.234567890123456789 + +strtoxL consumes 20 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 20 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.234567890123456789e301 + +strtoxL consumes 24 bytes and returns 33 +with bits = #43e70000 937a8baf ab20980c +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIxL returns 33, consuming 24 bytes. +fI[0] = #43e70000 937a8baf ab20980b +fI[1] = #43e70000 937a8baf ab20980c +fI[1] == strtoxL + + +Input: 1.234567890123456789e-301 + +strtoxL consumes 25 bytes and returns 33 +with bits = #3c170000 a953271a 5d069ad9 +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIxL returns 33, consuming 25 bytes. +fI[0] = #3c170000 a953271a 5d069ad8 +fI[1] = #3c170000 a953271a 5d069ad9 +fI[1] == strtoxL + + +Input: 1.234567890123456789e-321 + +strtoxL consumes 25 bytes and returns 33 +with bits = #3bd40000 f9e11b4c ea6dcce9 +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIxL returns 33, consuming 25 bytes. +fI[0] = #3bd40000 f9e11b4c ea6dcce8 +fI[1] = #3bd40000 f9e11b4c ea6dcce9 +fI[1] == strtoxL + + +Input: 1e23 + +strtoxL consumes 4 bytes and returns 1 +with bits = #404b0000 a968163f a57b400 +g_xLfmt(0) gives 5 bytes: "1e+23" + +strtoIxL returns 1, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1e310 + +strtoxL consumes 5 bytes and returns 33 +with bits = #44040000 de81e40a 34bcf50 +g_xLfmt(0) gives 6 bytes: "1e+310" + +strtoIxL returns 33, consuming 5 bytes. +fI[0] = #44040000 de81e40a 34bcf4f +fI[1] = #44040000 de81e40a 34bcf50 +fI[1] == strtoxL + + +Input: 9.0259718793241475e-277 + +strtoxL consumes 23 bytes and returns 33 +with bits = #3c690000 ffffffff fffffcf7 +g_xLfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIxL returns 33, consuming 23 bytes. +fI[0] = #3c690000 ffffffff fffffcf6 +fI[1] = #3c690000 ffffffff fffffcf7 +fI[1] == strtoxL + + +Input: 9.025971879324147880346310405869e-277 + +strtoxL consumes 37 bytes and returns 17 +with bits = #3c6a0000 80000000 0 +g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIxL returns 17, consuming 37 bytes. +fI[0] = #3c6a0000 80000000 0 +fI[1] = #3c6a0000 80000000 1 +fI[0] == strtoxL + + +Input: 9.025971879324147880346310405868e-277 + +strtoxL consumes 37 bytes and returns 33 +with bits = #3c6a0000 80000000 0 +g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIxL returns 33, consuming 37 bytes. +fI[0] = #3c690000 ffffffff ffffffff +fI[1] = #3c6a0000 80000000 0 +fI[1] == strtoxL + + +Input: 2.2250738585072014e-308 + +strtoxL consumes 23 bytes and returns 17 +with bits = #3c010000 80000000 46 +g_xLfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIxL returns 17, consuming 23 bytes. +fI[0] = #3c010000 80000000 46 +fI[1] = #3c010000 80000000 47 +fI[0] == strtoxL + + +Input: 2.2250738585072013e-308 + +strtoxL consumes 23 bytes and returns 17 +with bits = #3c000000 ffffffff fffffd4f +g_xLfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIxL returns 17, consuming 23 bytes. +fI[0] = #3c000000 ffffffff fffffd4f +fI[1] = #3c000000 ffffffff fffffd50 +fI[0] == strtoxL + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 8ccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 8ccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 99999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[0] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 99999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[1] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 cccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 cccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 d9999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[0] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 d9999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[1] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 8ccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.1" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 8ccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.1" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 99999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.2" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[1] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 99999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.2" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[0] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 cccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.6" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 cccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.6" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 d9999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.7" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[1] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 d9999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.7" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[0] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 8ccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.1" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 8ccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 99999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.2" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[1] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 99999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[1] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 a6666666 66666667 +g_xLfmt(0) gives 21 bytes: "1.3000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[1] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 b3333333 33333334 +g_xLfmt(0) gives 21 bytes: "1.4000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[1] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 cccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.6" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 cccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 d9999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.7" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[1] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 d9999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[1] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 e6666666 66666667 +g_xLfmt(0) gives 21 bytes: "1.8000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[1] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 f3333333 33333334 +g_xLfmt(0) gives 21 bytes: "1.9000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[1] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 8ccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 8ccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.1" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 99999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[0] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 99999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.2" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[0] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 a6666666 66666667 +g_xLfmt(0) gives 22 bytes: "-1.3000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[0] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 b3333333 33333334 +g_xLfmt(0) gives 22 bytes: "-1.4000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[0] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 cccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 cccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.6" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 d9999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[0] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 d9999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.7" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[0] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 e6666666 66666667 +g_xLfmt(0) gives 22 bytes: "-1.8000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[0] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 f3333333 33333334 +g_xLfmt(0) gives 22 bytes: "-1.9000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[0] == strtoxL + diff --git a/src/contrib/gdtoa/test/xL.ou1 b/src/contrib/gdtoa/test/xL.ou1 new file mode 100644 index 0000000..054690e --- /dev/null +++ b/src/contrib/gdtoa/test/xL.ou1 @@ -0,0 +1,1183 @@ +***** This file is not right. It needs to be generated on a +***** system with a Motorla 68881 or the equivalent. +Input: 1.23 + +strtoxL consumes 4 bytes and returns 33 +with bits = #3fff0000 9d70a3d7 a3d70a4 +g_xLfmt(0) gives 4 bytes: "1.23" + +strtoIxL returns 33, consuming 4 bytes. +fI[0] = #3fff0000 9d70a3d7 a3d70a3 +fI[1] = #3fff0000 9d70a3d7 a3d70a4 +fI[1] == strtoxL + + +Input: 1.23e+20 + +strtoxL consumes 8 bytes and returns 1 +with bits = #40410000 d55ef90a 2da18000 +g_xLfmt(0) gives 8 bytes: "1.23e+20" + +strtoIxL returns 1, consuming 8 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.23e-20 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3fbc0000 e857267b b3a984f2 +g_xLfmt(0) gives 8 bytes: "1.23e-20" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3fbc0000 e857267b b3a984f2 +fI[1] = #3fbc0000 e857267b b3a984f3 +fI[0] == strtoxL + + +Input: 1.23456789 + +strtoxL consumes 10 bytes and returns 33 +with bits = #3fff0000 9e065214 1ef0dbf6 +g_xLfmt(0) gives 10 bytes: "1.23456789" + +strtoIxL returns 33, consuming 10 bytes. +fI[0] = #3fff0000 9e065214 1ef0dbf5 +fI[1] = #3fff0000 9e065214 1ef0dbf6 +fI[1] == strtoxL + + +Input: 1.23456589e+20 + +strtoxL consumes 14 bytes and returns 1 +with bits = #40410000 d629bd33 5ccba00 +g_xLfmt(0) gives 14 bytes: "1.23456589e+20" + +strtoIxL returns 1, consuming 14 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.23e+30 + +strtoxL consumes 8 bytes and returns 17 +with bits = #40620000 f8658274 7dbc824a +g_xLfmt(0) gives 8 bytes: "1.23e+30" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #40620000 f8658274 7dbc824a +fI[1] = #40620000 f8658274 7dbc824b +fI[0] == strtoxL + + +Input: 1.23e-30 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3f9b0000 c794337a 808554eb +g_xLfmt(0) gives 8 bytes: "1.23e-30" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3f9b0000 c794337a 808554eb +fI[1] = #3f9b0000 c794337a 808554ec +fI[0] == strtoxL + + +Input: 1.23456789e-20 + +strtoxL consumes 14 bytes and returns 17 +with bits = #3fbc0000 e9340a38 f3d6d352 +g_xLfmt(0) gives 14 bytes: "1.23456789e-20" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #3fbc0000 e9340a38 f3d6d352 +fI[1] = #3fbc0000 e9340a38 f3d6d353 +fI[0] == strtoxL + + +Input: 1.23456789e-30 + +strtoxL consumes 14 bytes and returns 17 +with bits = #3f9b0000 c851f19d decca8fc +g_xLfmt(0) gives 14 bytes: "1.23456789e-30" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #3f9b0000 c851f19d decca8fc +fI[1] = #3f9b0000 c851f19d decca8fd +fI[0] == strtoxL + + +Input: 1.234567890123456789 + +strtoxL consumes 20 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 20 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.23456789012345678901234567890123456789 + +strtoxL consumes 40 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 40 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.23e306 + +strtoxL consumes 8 bytes and returns 17 +with bits = #43f70000 e033b668 e30fa6d5 +g_xLfmt(0) gives 9 bytes: "1.23e+306" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #43f70000 e033b668 e30fa6d5 +fI[1] = #43f70000 e033b668 e30fa6d6 +fI[0] == strtoxL + + +Input: 1.23e-306 + +strtoxL consumes 9 bytes and returns 33 +with bits = #3c060000 dd1dc2ed 1cb73f25 +g_xLfmt(0) gives 9 bytes: "1.23e-306" + +strtoIxL returns 33, consuming 9 bytes. +fI[0] = #3c060000 dd1dc2ed 1cb73f24 +fI[1] = #3c060000 dd1dc2ed 1cb73f25 +fI[1] == strtoxL + + +Input: 1.23e-320 + +strtoxL consumes 9 bytes and returns 33 +with bits = #3bd80000 9b98c371 844c3f1a +g_xLfmt(0) gives 9 bytes: "1.23e-320" + +strtoIxL returns 33, consuming 9 bytes. +fI[0] = #3bd80000 9b98c371 844c3f19 +fI[1] = #3bd80000 9b98c371 844c3f1a +fI[1] == strtoxL + + +Input: 1.23e-20 + +strtoxL consumes 8 bytes and returns 17 +with bits = #3fbc0000 e857267b b3a984f2 +g_xLfmt(0) gives 8 bytes: "1.23e-20" + +strtoIxL returns 17, consuming 8 bytes. +fI[0] = #3fbc0000 e857267b b3a984f2 +fI[1] = #3fbc0000 e857267b b3a984f3 +fI[0] == strtoxL + + +Input: 1.23456789e307 + +strtoxL consumes 14 bytes and returns 17 +with bits = #43fb0000 8ca58a5e d766de75 +g_xLfmt(0) gives 15 bytes: "1.23456789e+307" + +strtoIxL returns 17, consuming 14 bytes. +fI[0] = #43fb0000 8ca58a5e d766de75 +fI[1] = #43fb0000 8ca58a5e d766de76 +fI[0] == strtoxL + + +Input: 1.23456589e-307 + +strtoxL consumes 15 bytes and returns 17 +with bits = #3c030000 b18cb5dc c22fd369 +g_xLfmt(0) gives 15 bytes: "1.23456589e-307" + +strtoIxL returns 17, consuming 15 bytes. +fI[0] = #3c030000 b18cb5dc c22fd369 +fI[1] = #3c030000 b18cb5dc c22fd36a +fI[0] == strtoxL + + +Input: 1.234567890123456789 + +strtoxL consumes 20 bytes and returns 17 +with bits = #3fff0000 9e065214 62cfdb8d +g_xLfmt(0) gives 20 bytes: "1.234567890123456789" + +strtoIxL returns 17, consuming 20 bytes. +fI[0] = #3fff0000 9e065214 62cfdb8d +fI[1] = #3fff0000 9e065214 62cfdb8e +fI[0] == strtoxL + + +Input: 1.234567890123456789e301 + +strtoxL consumes 24 bytes and returns 33 +with bits = #43e70000 937a8baf ab20980c +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e+301" + +strtoIxL returns 33, consuming 24 bytes. +fI[0] = #43e70000 937a8baf ab20980b +fI[1] = #43e70000 937a8baf ab20980c +fI[1] == strtoxL + + +Input: 1.234567890123456789e-301 + +strtoxL consumes 25 bytes and returns 33 +with bits = #3c170000 a953271a 5d069ad9 +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-301" + +strtoIxL returns 33, consuming 25 bytes. +fI[0] = #3c170000 a953271a 5d069ad8 +fI[1] = #3c170000 a953271a 5d069ad9 +fI[1] == strtoxL + + +Input: 1.234567890123456789e-321 + +strtoxL consumes 25 bytes and returns 33 +with bits = #3bd40000 f9e11b4c ea6dcce9 +g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-321" + +strtoIxL returns 33, consuming 25 bytes. +fI[0] = #3bd40000 f9e11b4c ea6dcce8 +fI[1] = #3bd40000 f9e11b4c ea6dcce9 +fI[1] == strtoxL + + +Input: 1e23 + +strtoxL consumes 4 bytes and returns 1 +with bits = #404b0000 a968163f a57b400 +g_xLfmt(0) gives 5 bytes: "1e+23" + +strtoIxL returns 1, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1e310 + +strtoxL consumes 5 bytes and returns 33 +with bits = #44040000 de81e40a 34bcf50 +g_xLfmt(0) gives 6 bytes: "1e+310" + +strtoIxL returns 33, consuming 5 bytes. +fI[0] = #44040000 de81e40a 34bcf4f +fI[1] = #44040000 de81e40a 34bcf50 +fI[1] == strtoxL + + +Input: 9.0259718793241475e-277 + +strtoxL consumes 23 bytes and returns 33 +with bits = #3c690000 ffffffff fffffcf7 +g_xLfmt(0) gives 23 bytes: "9.0259718793241475e-277" + +strtoIxL returns 33, consuming 23 bytes. +fI[0] = #3c690000 ffffffff fffffcf6 +fI[1] = #3c690000 ffffffff fffffcf7 +fI[1] == strtoxL + + +Input: 9.025971879324147880346310405869e-277 + +strtoxL consumes 37 bytes and returns 17 +with bits = #3c6a0000 80000000 0 +g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIxL returns 17, consuming 37 bytes. +fI[0] = #3c6a0000 80000000 0 +fI[1] = #3c6a0000 80000000 1 +fI[0] == strtoxL + + +Input: 9.025971879324147880346310405868e-277 + +strtoxL consumes 37 bytes and returns 33 +with bits = #3c6a0000 80000000 0 +g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277" + +strtoIxL returns 33, consuming 37 bytes. +fI[0] = #3c690000 ffffffff ffffffff +fI[1] = #3c6a0000 80000000 0 +fI[1] == strtoxL + + +Input: 2.2250738585072014e-308 + +strtoxL consumes 23 bytes and returns 17 +with bits = #3c010000 80000000 46 +g_xLfmt(0) gives 23 bytes: "2.2250738585072014e-308" + +strtoIxL returns 17, consuming 23 bytes. +fI[0] = #3c010000 80000000 46 +fI[1] = #3c010000 80000000 47 +fI[0] == strtoxL + + +Input: 2.2250738585072013e-308 + +strtoxL consumes 23 bytes and returns 17 +with bits = #3c000000 ffffffff fffffd4f +g_xLfmt(0) gives 23 bytes: "2.2250738585072013e-308" + +strtoIxL returns 17, consuming 23 bytes. +fI[0] = #3c000000 ffffffff fffffd4f +fI[1] = #3c000000 ffffffff fffffd50 +fI[0] == strtoxL + +Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 8ccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 8ccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 99999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[0] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 99999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[1] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 cccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 cccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 d9999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[0] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 d9999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[1] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 8ccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.1" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 8ccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.1" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 99999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.2" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[1] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 99999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.2" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[0] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 cccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.6" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 cccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.6" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 d9999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.7" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[1] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 d9999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.7" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[0] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 8ccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.1" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 8ccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 99999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.2" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[1] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 99999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[1] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 a6666666 66666667 +g_xLfmt(0) gives 21 bytes: "1.3000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[1] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 a6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.3" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[1] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 b3333333 33333334 +g_xLfmt(0) gives 21 bytes: "1.4000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[1] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 b3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.4" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[1] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 cccccccc cccccccd +g_xLfmt(0) gives 3 bytes: "1.6" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[1] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 cccccccc cccccccc +g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[1] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 d9999999 9999999a +g_xLfmt(0) gives 3 bytes: "1.7" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[1] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 d9999999 99999999 +g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[1] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 e6666666 66666667 +g_xLfmt(0) gives 21 bytes: "1.8000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[1] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 e6666666 66666666 +g_xLfmt(0) gives 4 bytes: "-1.8" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[1] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 33 +with bits = #3fff0000 f3333333 33333334 +g_xLfmt(0) gives 21 bytes: "1.9000000000000000001" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[1] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 25 +with bits = #bfff0000 f3333333 33333333 +g_xLfmt(0) gives 4 bytes: "-1.9" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[1] == strtoxL + +Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity) + +Input: 1.1 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 8ccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.0999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 8ccccccc cccccccc +fI[1] = #3fff0000 8ccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.1 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 8ccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.1" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 8ccccccc cccccccd +fI[1] = #bfff0000 8ccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.2 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 99999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.1999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 99999999 99999999 +fI[1] = #3fff0000 99999999 9999999a +fI[0] == strtoxL + + +Input: -1.2 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 99999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.2" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 99999999 9999999a +fI[1] = #bfff0000 99999999 99999999 +fI[0] == strtoxL + + +Input: 1.3 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 a6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.3" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 a6666666 66666666 +fI[1] = #3fff0000 a6666666 66666667 +fI[0] == strtoxL + + +Input: -1.3 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 a6666666 66666667 +g_xLfmt(0) gives 22 bytes: "-1.3000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 a6666666 66666667 +fI[1] = #bfff0000 a6666666 66666666 +fI[0] == strtoxL + + +Input: 1.4 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 b3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.4" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 b3333333 33333333 +fI[1] = #3fff0000 b3333333 33333334 +fI[0] == strtoxL + + +Input: -1.4 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 b3333333 33333334 +g_xLfmt(0) gives 22 bytes: "-1.4000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 b3333333 33333334 +fI[1] = #bfff0000 b3333333 33333333 +fI[0] == strtoxL + + +Input: 1.5 + +strtoxL consumes 3 bytes and returns 1 +with bits = #3fff0000 c0000000 0 +g_xLfmt(0) gives 3 bytes: "1.5" + +strtoIxL returns 1, consuming 3 bytes. +fI[0] == fI[1] == strtoxL + + +Input: -1.5 + +strtoxL consumes 4 bytes and returns 9 +with bits = #bfff0000 c0000000 0 +g_xLfmt(0) gives 4 bytes: "-1.5" + +strtoIxL returns 9, consuming 4 bytes. +fI[0] == fI[1] == strtoxL + + +Input: 1.6 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 cccccccc cccccccc +g_xLfmt(0) gives 21 bytes: "1.5999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 cccccccc cccccccc +fI[1] = #3fff0000 cccccccc cccccccd +fI[0] == strtoxL + + +Input: -1.6 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 cccccccc cccccccd +g_xLfmt(0) gives 4 bytes: "-1.6" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 cccccccc cccccccd +fI[1] = #bfff0000 cccccccc cccccccc +fI[0] == strtoxL + + +Input: 1.7 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 d9999999 99999999 +g_xLfmt(0) gives 21 bytes: "1.6999999999999999999" + +strtoIxL returns 33, consuming 3 bytes. +fI[0] = #3fff0000 d9999999 99999999 +fI[1] = #3fff0000 d9999999 9999999a +fI[0] == strtoxL + + +Input: -1.7 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 d9999999 9999999a +g_xLfmt(0) gives 4 bytes: "-1.7" + +strtoIxL returns 41, consuming 4 bytes. +fI[0] = #bfff0000 d9999999 9999999a +fI[1] = #bfff0000 d9999999 99999999 +fI[0] == strtoxL + + +Input: 1.8 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 e6666666 66666666 +g_xLfmt(0) gives 3 bytes: "1.8" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 e6666666 66666666 +fI[1] = #3fff0000 e6666666 66666667 +fI[0] == strtoxL + + +Input: -1.8 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 e6666666 66666667 +g_xLfmt(0) gives 22 bytes: "-1.8000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 e6666666 66666667 +fI[1] = #bfff0000 e6666666 66666666 +fI[0] == strtoxL + + +Input: 1.9 + +strtoxL consumes 3 bytes and returns 17 +with bits = #3fff0000 f3333333 33333333 +g_xLfmt(0) gives 3 bytes: "1.9" + +strtoIxL returns 17, consuming 3 bytes. +fI[0] = #3fff0000 f3333333 33333333 +fI[1] = #3fff0000 f3333333 33333334 +fI[0] == strtoxL + + +Input: -1.9 + +strtoxL consumes 4 bytes and returns 41 +with bits = #bfff0000 f3333333 33333334 +g_xLfmt(0) gives 22 bytes: "-1.9000000000000000001" + +strtoIxL returns 25, consuming 4 bytes. +fI[0] = #bfff0000 f3333333 33333334 +fI[1] = #bfff0000 f3333333 33333333 +fI[0] == strtoxL + diff --git a/src/contrib/gdtoa/test/xLtest.c b/src/contrib/gdtoa/test/xLtest.c new file mode 100644 index 0000000..c923e19 --- /dev/null +++ b/src/contrib/gdtoa/test/xLtest.c @@ -0,0 +1,169 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_xLfmt, strtoIxL, strtopxL, and strtorxL. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex0 hex1 hex2 + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex0 is a string of <= 8 Hex digits for the most significant + * word of the number, hex1 is a similar string for the next + * word, etc., and ndig is a parameters to g_xLfmt. + */ + +#include "gdtoa.h" +#include +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[2048]; + +#define U (unsigned long) + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + int +main(Void) +{ + char *s, *se, *se1; + int dItry, i, ndig = 0, r = 1; + union { long double d; ULong bits[3]; } u, v[2]; + + while(s = fgets(ibuf, sizeof(ibuf), stdin)) { + while(*s <= ' ') + if (!*s++) + continue; + dItry = 0; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + sscanf(s+1, "%lx %lx %lx", &u.bits[_0], + &u.bits[_1], &u.bits[_2]); + printf("\nInput: %s", ibuf); + printf(" --> f = #%lx %lx %lx\n", u.bits[_0], + u.bits[_1], u.bits[_2]); + goto fmt_test; + } + dItry = 1; + printf("\nInput: %s", ibuf); + i = strtorxL(ibuf, &se, r, u.bits); + if (r == 1 && (i != strtopxL(ibuf, &se1, v[0].bits) || se1 != se + || memcmp(u.bits, v[0].bits, 12))) + printf("***strtoxL and strtorxL disagree!!\n:"); + printf("\nstrtoxL consumes %d bytes and returns %d\n", + (int)(se-ibuf), i); + printf("with bits = #%lx %lx %lx\n", + U u.bits[_0], U u.bits[_1], U u.bits[_2]); + if (sizeof(long double) == 12) + printf("printf(\"%%.21Lg\") gives %.21Lg\n", u.d); + fmt_test: + se = g_xLfmt(obuf, u.bits, ndig, sizeof(obuf)); + printf("g_xLfmt(%d) gives %d bytes: \"%s\"\n\n", + ndig, (int)(se-obuf), se ? obuf : ""); + if (!dItry) + continue; + printf("strtoIxL returns %d,", + strtoIxL(ibuf, &se, v[0].bits, v[1].bits)); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (!memcmp(v[0].bits, v[1].bits, 12)) { + if (!memcmp(u.bits, v[0].bits, 12)) + printf("fI[0] == fI[1] == strtoxL\n"); + else { + printf("fI[0] == fI[1] = #%lx %lx %lx\n", + U v[0].bits[_0], U v[0].bits[_1], + U v[0].bits[_2]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[0].d); + } + } + else { + printf("fI[0] = #%lx %lx %lx\n", + U v[0].bits[_0], U v[0].bits[_1], + U v[0].bits[_2]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[0].d); + printf("fI[1] = #%lx %lx %lx\n", + U v[1].bits[_0], U v[1].bits[_1], + U v[1].bits[_2]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[1].d); + if (!memcmp(v[0].bits, u.bits, 12)) + printf("fI[0] == strtoxL\n"); + else if (!memcmp(v[1].bits, u.bits, 12)) + printf("fI[1] == strtoxL\n"); + else + printf("**** Both differ from strtod ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/xQtest.c b/src/contrib/gdtoa/test/xQtest.c new file mode 100644 index 0000000..8dfe365 --- /dev/null +++ b/src/contrib/gdtoa/test/xQtest.c @@ -0,0 +1,46 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2002 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +#include + + int +main(void) +{ + switch(sizeof(long double)) { + case 10: + case 12: + printf("cp x.ou1 x.out; cp xL.ou1 xL.out; cp Q.ou0 Q.out\n"); + break; + case 16: + printf("cp x.ou0 x.out; cp xL.ou0 xL.out; cp Q.ou1 Q.out\n"); + break; + default: + printf("cp x.ou0 x.out; cp xL.ou0 xL.out; cp Q.ou0 Q.out\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/test/xsum0.out b/src/contrib/gdtoa/test/xsum0.out new file mode 100644 index 0000000..ee59cda --- /dev/null +++ b/src/contrib/gdtoa/test/xsum0.out @@ -0,0 +1,35 @@ +README e6ebdc91 2429 +Qtest.c 140625e2 4778 +dItest.c 8689031 2401 +ddtest.c ea24d330 4943 +dtest.c 900d971 4071 +dt.c addb61c 6198 +ftest.c f609ce43 3958 +getround.c f471599 2041 +strtoIdSI.c 7bfb88b 49 +strtoIddSI.c 72e8852 50 +strtodISI.c ed08b740 49 +strtodt.c 17aca428 3213 +strtopddSI.c 13e7138d 50 +strtorddSI.c f7e4b1d5 50 +xLtest.c faca328f 4646 +xQtest.c efdea3a2 1549 +xtest.c 1f19b87 4858 +rtestnos f94bcdf6 336 +testnos e89999d6 485 +testnos1 7e16229 294 +testnos3 fa5c8aca 11998 +dI.out d522eef 4369 +dIsi.out 1dd6d02f 4350 +ddsi.out 1f94bbe2 10251 +dd.out e262456e 40923 +dtst.out ee75f6b9 23308 +d.out f271efc9 28131 +f.out 4b0bd51 21207 +x.ou0 1cfc5d22 25378 +xL.ou0 faa3a741 26363 +x.ou1 1a7e9dd4 34587 +xL.ou1 418057a 26476 +Q.ou0 e4592b85 28742 +Q.ou1 ea0b344d 39572 +makefile ebbea1e1 4191 diff --git a/src/contrib/gdtoa/test/xtest.c b/src/contrib/gdtoa/test/xtest.c new file mode 100644 index 0000000..bd2b008 --- /dev/null +++ b/src/contrib/gdtoa/test/xtest.c @@ -0,0 +1,176 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* Test program for g_xfmt, strtoIx, strtopx, and strtorx. + * + * Inputs (on stdin): + * r rounding_mode + * n ndig + * number + * #hex0 hex1 hex2 hex3 hex4 + * + * rounding_mode values: + * 0 = toward zero + * 1 = nearest + * 2 = toward +Infinity + * 3 = toward -Infinity + * + * where number is a decimal floating-point number, + * hex0 is a string of <= 4 Hex digits for the most significant + * half-word of the number, hex1 is a similar string for the next + * half-word, etc., and ndig is a parameters to g_xfmt. + */ + +#include "gdtoa.h" +#include +#include +#include + + extern int getround ANSI((int,char*)); + + static char ibuf[2048], obuf[2048]; + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + int +main(Void) +{ + char *s, *se, *se1; + int i, dItry, ndig = 0, r = 1; + union { long double d; UShort bits[5]; } u, v[2]; + + while(s = fgets(ibuf, sizeof(ibuf), stdin)) { + while(*s <= ' ') + if (!*s++) + continue; + dItry = 0; + switch(*s) { + case 'r': + r = getround(r, s); + continue; + case 'n': + i = s[1]; + if (i <= ' ' || i >= '0' && i <= '9') { + ndig = atoi(s+1); + continue; + } + break; /* nan? */ + case '#': + sscanf(s+1, "%hx %hx %hx %hx hx", &u.bits[_0], + &u.bits[_1], &u.bits[_2], &u.bits[_3], + &u.bits[_4]); + printf("\nInput: %s", ibuf); + printf(" --> f = #%x %x %x %x %x\n", u.bits[_0], + u.bits[_1], u.bits[_2], u.bits[_3], u.bits[4]); + goto fmt_test; + } + dItry = 1; + printf("\nInput: %s", ibuf); + i = strtorx(ibuf, &se, r, u.bits); + if (r == 1 && (i != strtopx(ibuf, &se1, v[0].bits) || se1 != se + || memcmp(u.bits, v[0].bits, 10))) + printf("***strtox and strtorx disagree!!\n:"); + printf("\nstrtox consumes %d bytes and returns %d\n", + (int)(se-ibuf), i); + printf("with bits = #%x %x %x %x %x\n", + u.bits[_0], u.bits[_1], u.bits[_2], + u.bits[_3], u.bits[_4]); + if (sizeof(long double) == 12) + printf("printf(\"%%.21Lg\") gives %.21Lg\n", u.d); + fmt_test: + se = g_xfmt(obuf, u.bits, ndig, sizeof(obuf)); + printf("g_xfmt(%d) gives %d bytes: \"%s\"\n\n", + ndig, (int)(se-obuf), se ? obuf : ""); + if (!dItry) + continue; + printf("strtoIx returns %d,", + strtoIx(ibuf, &se, v[0].bits, v[1].bits)); + printf(" consuming %d bytes.\n", (int)(se-ibuf)); + if (!memcmp(v[0].bits, v[1].bits, 10)) { + if (!memcmp(u.bits, v[0].bits, 10)) + printf("fI[0] == fI[1] == strtox\n"); + else { + printf("fI[0] == fI[1] = #%x %x %x %x %x\n", + v[0].bits[_0], v[0].bits[_1], + v[0].bits[_2], v[0].bits[_3], + v[0].bits[_4]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[0].d); + } + } + else { + printf("fI[0] = #%x %x %x %x %x\n", + v[0].bits[_0], v[0].bits[_1], + v[0].bits[_2], v[0].bits[_3], + v[0].bits[_4]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[0].d); + printf("fI[1] = #%x %x %x %x %x\n", + v[1].bits[_0], v[1].bits[_1], + v[1].bits[_2], v[0].bits[_3], + v[0].bits[_4]); + if (sizeof(long double) == 12) + printf("= %.21Lg\n", v[1].d); + if (!memcmp(v[0].bits, u.bits, 10)) + printf("fI[0] == strtox\n"); + else if (!memcmp(v[1].bits, u.bits, 10)) + printf("fI[1] == strtox\n"); + else + printf("**** Both differ from strtod ****\n"); + } + printf("\n"); + } + return 0; + } diff --git a/src/contrib/gdtoa/ulp.c b/src/contrib/gdtoa/ulp.c new file mode 100644 index 0000000..536994a --- /dev/null +++ b/src/contrib/gdtoa/ulp.c @@ -0,0 +1,76 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, 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. + +****************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + double +ulp +#ifdef KR_headers + (x) double x; +#else + (double x) +#endif +{ + Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif + return a; + } diff --git a/src/contrib/gdtoa/xsum0.out b/src/contrib/gdtoa/xsum0.out new file mode 100644 index 0000000..b61d0f0 --- /dev/null +++ b/src/contrib/gdtoa/xsum0.out @@ -0,0 +1,46 @@ +README c9c34c1 13153 +arithchk.c e37b8a75 4070 +dmisc.c e8d262b6 4712 +dtoa.c f3c132b3 16905 +g_Qfmt.c e5847e9 2870 +g__fmt.c ee5f9be0 2439 +g_ddfmt.c fcf94527 3790 +g_dfmt.c f30e55a9 2533 +g_ffmt.c 7c4ea96 2459 +g_xLfmt.c 36ee116 2716 +g_xfmt.c c20a5e4 2795 +gdtoa.c 364a0d2 17017 +gdtoa.h 1eb440de 4810 +gdtoaimp.h 6a955ba 19106 +gethex.c 1c586a03 5075 +gmisc.c e1a268ea 2114 +hd_init.c cf9a94e 1827 +hexnan.c f53be1da 2988 +makefile e84d078f 2802 +misc.c ea539bdb 14168 +smisc.c f659f036 3685 +strtoIQ.c 13ac9f44 1969 +strtoId.c d05a7a6 1961 +strtoIdd.c fa36260d 2135 +strtoIf.c eb75ac99 1905 +strtoIg.c ec59c2fa 3484 +strtoIx.c 8f8c9d 1990 +strtoIxL.c 1313ff7f 1961 +strtod.c fd6556c8 19985 +strtodI.c e58338e0 4062 +strtodg.c e04b9254 19458 +strtof.c 1e7a787a 2202 +strtopQ.c e232c542 2685 +strtopd.c e865dc64 1701 +strtopdd.c 1c240126 4540 +strtopf.c 1c762782 2196 +strtopx.c 17c3fafb 2665 +strtopxL.c ed474cdb 2505 +strtorQ.c 126cc92b 2898 +strtord.c 1fce44b9 2528 +strtordd.c c32bca0 4979 +strtorf.c fe6a2687 2430 +strtorx.c 18389f0c 2888 +strtorxL.c f63fc249 2730 +sum.c dc07b9b 2524 +ulp.c f6db0b4d 1894 diff --git a/src/include.new/FlexLexer.h b/src/include.new/FlexLexer.h new file mode 100644 index 0000000..30b1a3b --- /dev/null +++ b/src/include.new/FlexLexer.h @@ -0,0 +1,186 @@ +// $Header$ +// $FreeBSD: src/usr.bin/lex/FlexLexer.h,v 1.4 2004/03/11 10:43:35 josef Exp $ + +// 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 are permitted provided +// that: (1) source distributions retain this entire copyright notice and +// comment, and (2) distributions including binaries display the following +// acknowledgement: ``This product includes software developed by the +// University of California, Berkeley and its contributors'' in the +// documentation or other materials provided with the distribution and in +// all advertising materials mentioning features or use of this software. +// 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 + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() { return yytext; } + int YYLeng() { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( std::istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( std::istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( std::istream* new_in, 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( std::istream* new_in = 0, + 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 + +#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 man page. +#define yyFlexLexerOnce + +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( std::istream* arg_yyin = 0, 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( std::istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( std::istream* s ); + + virtual int yylex(); + virtual void switch_streams( std::istream* new_in, std::ostream* new_out ); + +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, 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(); + + std::istream* yyin; // input source for default LexerInput + std::ostream* yyout; // output sink for default LexerOutput + + struct yy_buffer_state* yy_current_buffer; + + // 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; + + // 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 diff --git a/src/include.new/_ctype.h b/src/include.new/_ctype.h new file mode 100644 index 0000000..888f287 --- /dev/null +++ b/src/include.new/_ctype.h @@ -0,0 +1,157 @@ +/* + * 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. 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. + * + * 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: src/include/_ctype.h,v 1.30 2004/08/21 07:00:40 tjr Exp $ + */ + +#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 + +/* + * 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 +__istype(__ct_rune_t _c, unsigned long _f) +{ + return (!!__maskrune(_c, _f)); +} + +static __inline int +__isctype(__ct_rune_t _c, unsigned long _f) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? 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 +__tolower(__ct_rune_t _c) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_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 __istype(__ct_rune_t, unsigned long); +int __isctype(__ct_rune_t, unsigned long); +__ct_rune_t __toupper(__ct_rune_t); +__ct_rune_t __tolower(__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..b3f280e --- /dev/null +++ b/src/include.new/_semaphore.h @@ -0,0 +1,73 @@ +/*- + * 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: src/sys/posix4/_semaphore.h,v 1.4 2005/01/07 02:29:19 imp Exp $ + */ +#ifndef __SEMAPHORE_H_ +#define __SEMAPHORE_H_ + +typedef intptr_t semid_t; +struct timespec; + +#ifndef _KERNEL + +#include + +/* + * Semaphore definitions. + */ +struct sem { +#define SEM_MAGIC ((u_int32_t) 0x09fa4012) + u_int32_t magic; + pthread_mutex_t lock; + pthread_cond_t gtzero; + u_int32_t count; + u_int32_t nwaiters; +#define SEM_USER (NULL) + semid_t semid; /* semaphore id if kernel (shared) semaphore */ + int syssem; /* 1 if kernel (shared) semaphore */ + LIST_ENTRY(sem) entry; + struct sem **backpointer; +}; + +__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, 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..4053ce0 --- /dev/null +++ b/src/include.new/a.out.h @@ -0,0 +1,49 @@ +/*- + * 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. 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. + * + * @(#)a.out.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: src/include/a.out.h,v 1.4 2004/06/22 17:05:36 obrien Exp $ + */ + +#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..eed26bf --- /dev/null +++ b/src/include.new/aio.h @@ -0,0 +1,135 @@ +/*- + * 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: src/sys/sys/aio.h,v 1.30 2005/01/07 02:29:23 imp Exp $ + */ + +#ifndef _SYS_AIO_H_ +#define _SYS_AIO_H_ + +#include +#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 + +/* + * 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 */ + struct sigevent aio_sigevent; /* Signal to deliver */ + int aio_lio_opcode; /* LIO opcode */ + int aio_reqprio; /* Request priority -- ignored */ + struct __aiocb_private _aiocb_private; +} aiocb_t; + +#ifndef _KERNEL + +__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 *); + +int aio_waitcomplete(struct aiocb **, struct timespec *); + +__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..0bf51b8 --- /dev/null +++ b/src/include.new/alias.h @@ -0,0 +1,277 @@ +/* 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: src/sys/netinet/libalias/alias.h,v 1.32 2005/05/05 21:53:17 glebius Exp $ + */ + +/*- + * 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_ + +#ifdef _KERNEL +/* + * The kernel version of libalias does not support these features. + */ +#define NO_FW_PUNCH +#define NO_LOGGING +#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; + + +/* OLD API */ + +/* Initialization and control functions. */ +void PacketAliasInit(void); +void PacketAliasSetAddress(struct in_addr _addr); +void PacketAliasSetFWBase(unsigned int _base, unsigned int _num); +void PacketAliasSetSkinnyPort(unsigned int _port); +unsigned int + PacketAliasSetMode(unsigned int _flags, unsigned int _mask); +void PacketAliasUninit(void); + +/* Packet Handling functions. */ +int PacketAliasIn(char *_ptr, int _maxpacketsize); +int PacketAliasOut(char *_ptr, int _maxpacketsize); +int PacketUnaliasOut(char *_ptr, int _maxpacketsize); + +/* Port and address redirection functions. */ + + +int +PacketAliasAddServer(struct alias_link *_lnk, + struct in_addr _addr, unsigned short _port); +struct alias_link * +PacketAliasRedirectAddr(struct in_addr _src_addr, + struct in_addr _alias_addr); +int PacketAliasRedirectDynamic(struct alias_link *_lnk); +void PacketAliasRedirectDelete(struct alias_link *_lnk); +struct alias_link * +PacketAliasRedirectPort(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 * +PacketAliasRedirectProto(struct in_addr _src_addr, + struct in_addr _dst_addr, struct in_addr _alias_addr, + unsigned char _proto); + +/* Fragment Handling functions. */ +void PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment); +char *PacketAliasGetFragment(char *_ptr); +int PacketAliasSaveFragment(char *_ptr); + +/* Miscellaneous functions. */ +int PacketAliasCheckNewLink(void); +unsigned short + PacketAliasInternetChecksum(unsigned short *_ptr, int _nbytes); +void PacketAliasSetTarget(struct in_addr _target_addr); + +/* Transparent proxying routines. */ +int PacketAliasProxyRule(const char *_cmd); + +/* NEW API */ + +/* 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); + + +/* + * 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. + */ +#ifndef NO_LOGGING +#define PKT_ALIAS_LOG 0x01 +#endif + +/* + * 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 + +#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_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 + +/* 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..51f812d --- /dev/null +++ b/src/include.new/altq/altq.h @@ -0,0 +1,204 @@ +/* $FreeBSD: src/sys/contrib/altq/altq/altq.h,v 1.2 2004/06/12 00:57:20 mlaier Exp $ */ +/* $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 */ + u_int32_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 */ + u_int32_t fi6_flowlabel; /* ipv6 flowlabel */ + u_int16_t fi6_dport; /* dest port */ + u_int16_t fi6_sport; /* src port */ + u_int32_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..30a15c7 --- /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_ { + u_int32_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; + u_int32_t parent_class_handle; + u_int32_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; + u_int32_t cbq_class_handle; +}; + +struct cbq_delete_class { + struct cbq_interface cbq_iface; + u_int32_t cbq_class_handle; +}; + +struct cbq_modify_class { + struct cbq_interface cbq_iface; + + cbq_class_spec_t cbq_class; + u_int32_t cbq_class_handle; +}; + +struct cbq_add_filter { + struct cbq_interface cbq_iface; + u_int32_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..d55402f --- /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; + u_int32_t cmtd_rate; /* committed rate (bits/sec) */ + u_int32_t peak_rate; /* peak rate (bits/sec) */ + u_int32_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; + u_int32_t cmtd_rate; /* committed rate (bits/sec) */ + u_int32_t peak_rate; /* peak rate (bits/sec) */ + u_int32_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 */ + + u_int32_t avg_rate; /* average rate (bytes/sec) */ + u_int64_t t_front; /* timestamp of last update */ + + u_int64_t timewin; /* average interval */ + u_int32_t cmtd_rate; /* committed target rate */ + u_int32_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..91ba3d1 --- /dev/null +++ b/src/include.new/altq/altq_hfsc.h @@ -0,0 +1,320 @@ +/* $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; + u_int32_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; + u_int32_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; + u_int32_t parent_handle; + struct service_curve service_curve; + int qlimit; + int flags; + + u_int32_t class_handle; /* return value */ +}; + +struct hfsc_delete_class { + struct hfsc_interface iface; + u_int32_t class_handle; +}; + +struct hfsc_modify_class { + struct hfsc_interface iface; + u_int32_t class_handle; + struct service_curve service_curve; + int sctype; +}; + +struct hfsc_add_filter { + struct hfsc_interface iface; + u_int32_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 */ + u_int32_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 */ +}; + +/* for TAILQ based ellist and actlist implementation */ +struct hfsc_class; +typedef TAILQ_HEAD(_eligible, hfsc_class) ellist_t; +typedef TAILQ_ENTRY(hfsc_class) elentry_t; +typedef TAILQ_HEAD(_active, hfsc_class) actlist_t; +typedef TAILQ_ENTRY(hfsc_class) actentry_t; +#define ellist_first(s) TAILQ_FIRST(s) +#define actlist_first(s) TAILQ_FIRST(s) +#define actlist_last(s) TAILQ_LAST(s, _active) + +struct hfsc_class { + u_int cl_id; /* class id (just for debug) */ + u_int32_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 */ + actlist_t *cl_actc; /* active children list */ + + actentry_t cl_actlist; /* active children list entry */ + elentry_t 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 */ + + ellist_t *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..481d31b --- /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) */ + + u_int32_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; + u_int32_t class_handle; +}; + +struct priq_modify_class { + struct priq_interface iface; + u_int32_t class_handle; + int pri; + int qlimit; + int flags; +}; + +struct priq_add_filter { + struct priq_interface iface; + u_int32_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 { + u_int32_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 { + u_int32_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..99407fb --- /dev/null +++ b/src/include.new/altq/altq_var.h @@ -0,0 +1,265 @@ +/* $FreeBSD: src/sys/contrib/altq/altq/altq_var.h,v 1.2 2005/02/21 17:11:09 mlaier Exp $ */ +/* $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 */ + u_int32_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 { + u_int32_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 u_int32_t machclk_freq; +extern u_int32_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 */ +#if defined(__FreeBSD__) && (__FreeBSD__ < 3) +typedef int ioctlcmd_t; +#else +typedef u_long ioctlcmd_t; +#endif + +/* + * 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 *, u_int32_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..2b4537e --- /dev/null +++ b/src/include.new/altq/if_altq.h @@ -0,0 +1,191 @@ +/* $FreeBSD: src/sys/contrib/altq/altq/if_altq.h,v 1.3 2004/06/15 01:45:19 mlaier Exp $ */ +/* $KAME: if_altq.h,v 1.11 2003/07/10 12:07:50 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_IF_ALTQ_H_ +#define _ALTQ_IF_ALTQ_H_ + +#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) +#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; +#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) + 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 { + u_int32_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..e04874f --- /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. 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. + * + * @(#)ar.h 8.2 (Berkeley) 1/21/94 + */ + +#ifndef _AR_H_ +#define _AR_H_ + +/* 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 */ +}; + +#endif /* !_AR_H_ */ diff --git a/src/include.new/archive.h b/src/include.new/archive.h new file mode 100644 index 0000000..b354f97 --- /dev/null +++ b/src/include.new/archive.h @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2003-2004 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 + * in this position and unchanged. + * 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: src/lib/libarchive/archive.h.in,v 1.23.2.2 2006/09/05 05:23:51 kientzle Exp $ + */ + +#ifndef ARCHIVE_H_INCLUDED +#define ARCHIVE_H_INCLUDED + +/* + * This header file corresponds to: + * Library version 1.2.53 + * Shared library version 2 + */ + +#include /* Linux requires this for off_t */ +#include /* For int64_t */ +#include /* For ssize_t and size_t */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * If ARCHIVE_API_VERSION != archive_api_version(), then the library you + * were linked with is using an incompatible API. This is almost + * certainly a fatal problem. + * + * ARCHIVE_API_FEATURE is incremented with each significant feature + * addition, so you can test (at compile or run time) if a particular + * feature is implemented. It's no big deal if ARCHIVE_API_FEATURE != + * archive_api_feature(), as long as both are high enough to include + * the features you're relying on. Specific values of FEATURE are + * documented here: + * + * 1 - Version tests are available. + * 2 - archive_{read,write}_close available separately from _finish. + */ +#define ARCHIVE_API_VERSION 1 +int archive_api_version(void); +#define ARCHIVE_API_FEATURE 2 +int archive_api_feature(void); +/* Textual name/version of the library. */ +#define ARCHIVE_LIBRARY_VERSION "libarchive 1.2.53" +const char * archive_version(void); + +#define ARCHIVE_BYTES_PER_RECORD 512 +#define ARCHIVE_DEFAULT_BYTES_PER_BLOCK 10240 + +/* 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 sucess. */ +#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 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 */ +typedef ssize_t archive_skip_callback(struct archive *, void *_client_data, + size_t request); +/* Returns size actually written, zero on EOF, -1 on error. */ +typedef ssize_t archive_write_callback(struct archive *, void *_client_data, + 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); + +/* + * Codes for archive_compression. + */ +#define ARCHIVE_COMPRESSION_NONE 0 +#define ARCHIVE_COMPRESSION_GZIP 1 +#define ARCHIVE_COMPRESSION_BZIP2 2 +#define ARCHIVE_COMPRESSION_COMPRESS 3 + +/* + * 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. + */ +#define ARCHIVE_FORMAT_BASE_MASK 0xff0000U +#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_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 + +/*- + * 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. + */ +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. + */ +int archive_read_support_compression_all(struct archive *); +int archive_read_support_compression_bzip2(struct archive *); +int archive_read_support_compression_compress(struct archive *); +int archive_read_support_compression_gzip(struct archive *); +int archive_read_support_compression_none(struct archive *); + +int archive_read_support_format_all(struct archive *); +int archive_read_support_format_cpio(struct archive *); +int archive_read_support_format_gnutar(struct archive *); +int archive_read_support_format_iso9660(struct archive *); +int archive_read_support_format_tar(struct archive *); +int archive_read_support_format_zip(struct archive *); + + +/* Open the archive using callbacks for archive I/O. */ +int archive_read_open(struct archive *, void *_client_data, + archive_open_callback *, archive_read_callback *, + archive_close_callback *); +int archive_read_open2(struct archive *, void *_client_data, + archive_open_callback *, archive_read_callback *, + archive_skip_callback *, archive_close_callback *); + +/* + * The archive_read_open_file function is a convenience function built + * on archive_read_open that uses a canned callback suitable for + * common situations. Note that a NULL filename indicates stdin. + */ +int archive_read_open_file(struct archive *, const char *_file, + size_t _block_size); +int archive_read_open_fd(struct archive *, int _fd, + size_t _block_size); + +/* Parses and returns next entry header. */ +int archive_read_next_header(struct archive *, + struct archive_entry **); + +/* + * Retrieve the byte offset in UNCOMPRESSED data where last-read + * header started. + */ +int64_t archive_read_header_position(struct archive *); + +/* Read data from the body of an entry. Similar to read(2). */ +ssize_t archive_read_data(struct archive *, void *, size_t); +/* + * 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 gaurantee that offsets will + * be strictly increasing and that returned blocks will not overlap. + */ +int archive_read_data_block(struct archive *a, + const void **buff, size_t *size, off_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 + */ +int archive_read_data_skip(struct archive *); +int archive_read_data_into_buffer(struct archive *, void *buffer, + ssize_t len); +int archive_read_data_into_fd(struct archive *, int fd); + +/*- + * 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. */ +/* TODO: The 'Default' comments here are not quite correct; clean this up. */ +#define ARCHIVE_EXTRACT_OWNER (1) /* Default: owner/group not restored */ +#define ARCHIVE_EXTRACT_PERM (2) /* Default: restore perm only for reg file*/ +#define ARCHIVE_EXTRACT_TIME (4) /* Default: mod time not restored */ +#define ARCHIVE_EXTRACT_NO_OVERWRITE (8) /* Default: Replace files on disk */ +#define ARCHIVE_EXTRACT_UNLINK (16) /* Default: don't unlink existing files */ +#define ARCHIVE_EXTRACT_ACL (32) /* Default: don't restore ACLs */ +#define ARCHIVE_EXTRACT_FFLAGS (64) /* Default: don't restore fflags */ +#define ARCHIVE_EXTRACT_XATTR (128) /* Default: don't restore xattrs */ + +int archive_read_extract(struct archive *, struct archive_entry *, + int flags); +void archive_read_extract_set_progress_callback(struct archive *, + void (*_progress_func)(void *), void *_user_data); + +/* Close the file and release most resources. */ +int archive_read_close(struct archive *); +/* Release all resources and destroy the object. */ +/* Note that archive_read_finish will call archive_read_close for you. */ +void archive_read_finish(struct archive *); + +/*- + * To create an archive: + * 1) Ask archive_write_new for a 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_finish to cleanup the writer and release resources + */ +struct archive *archive_write_new(void); +int archive_write_set_bytes_per_block(struct archive *, + int bytes_per_block); +/* XXX This is badly misnamed; suggestions appreciated. XXX */ +int archive_write_set_bytes_in_last_block(struct archive *, + int bytes_in_last_block); + +int archive_write_set_compression_bzip2(struct archive *); +int archive_write_set_compression_gzip(struct archive *); +int archive_write_set_compression_none(struct archive *); +/* A convenience function to set the format based on the code or name. */ +int archive_write_set_format(struct archive *, int format_code); +int archive_write_set_format_by_name(struct archive *, + const char *name); +/* To minimize link pollution, use one or more of the following. */ +int archive_write_set_format_cpio(struct archive *); +/* TODO: int archive_write_set_format_old_tar(struct archive *); */ +int archive_write_set_format_pax(struct archive *); +int archive_write_set_format_pax_restricted(struct archive *); +int archive_write_set_format_shar(struct archive *); +int archive_write_set_format_shar_dump(struct archive *); +int archive_write_set_format_ustar(struct archive *); +int archive_write_open(struct archive *, void *, + archive_open_callback *, archive_write_callback *, + archive_close_callback *); +int archive_write_open_fd(struct archive *, int _fd); +int archive_write_open_file(struct archive *, const char *_file); + +/* + * Note that the library will truncate writes beyond the size provided + * to archive_write_header or pad if the provided data is short. + */ +int archive_write_header(struct archive *, + struct archive_entry *); +/* TODO: should be ssize_t, but that might require .so version bump? */ +int archive_write_data(struct archive *, const void *, size_t); +int archive_write_close(struct archive *); +void archive_write_finish(struct archive *); + +/* + * Accessor functions to read/set various information in + * the struct archive object: + */ +/* Bytes written after compression or read before decompression. */ +int64_t archive_position_compressed(struct archive *); +/* Bytes written to compressor or read from decompressor. */ +int64_t archive_position_uncompressed(struct archive *); + +const char *archive_compression_name(struct archive *); +int archive_compression(struct archive *); +int archive_errno(struct archive *); +const char *archive_error_string(struct archive *); +const char *archive_format_name(struct archive *); +int archive_format(struct archive *); +void archive_set_error(struct archive *, int _err, const char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#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..a9b4412 --- /dev/null +++ b/src/include.new/archive_entry.h @@ -0,0 +1,251 @@ +/*- + * Copyright (c) 2003-2004 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 + * in this position and unchanged. + * 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: src/lib/libarchive/archive_entry.h,v 1.16.2.1 2006/07/30 06:30:00 kientzle Exp $ + */ + +#ifndef ARCHIVE_ENTRY_H_INCLUDED +#define ARCHIVE_ENTRY_H_INCLUDED + +#include /* for wchar_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Description of an archive entry. + * + * Basically, a "struct stat" with a few 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_entry; + +/* + * Basic object manipulation + */ + +struct archive_entry *archive_entry_clear(struct archive_entry *); +/* The 'clone' function does a deep copy; all of the strings are copied too. */ +struct archive_entry *archive_entry_clone(struct archive_entry *); +void archive_entry_free(struct archive_entry *); +struct archive_entry *archive_entry_new(void); + +/* + * Retrieve fields from an archive_entry. + */ + +time_t archive_entry_atime(struct archive_entry *); +long archive_entry_atime_nsec(struct archive_entry *); +time_t archive_entry_ctime(struct archive_entry *); +long archive_entry_ctime_nsec(struct archive_entry *); +dev_t archive_entry_dev(struct archive_entry *); +void archive_entry_fflags(struct archive_entry *, + unsigned long *set, unsigned long *clear); +const char *archive_entry_fflags_text(struct archive_entry *); +gid_t archive_entry_gid(struct archive_entry *); +const char *archive_entry_gname(struct archive_entry *); +const wchar_t *archive_entry_gname_w(struct archive_entry *); +const char *archive_entry_hardlink(struct archive_entry *); +const wchar_t *archive_entry_hardlink_w(struct archive_entry *); +ino_t archive_entry_ino(struct archive_entry *); +mode_t archive_entry_mode(struct archive_entry *); +time_t archive_entry_mtime(struct archive_entry *); +long archive_entry_mtime_nsec(struct archive_entry *); +const char *archive_entry_pathname(struct archive_entry *); +const wchar_t *archive_entry_pathname_w(struct archive_entry *); +dev_t archive_entry_rdev(struct archive_entry *); +dev_t archive_entry_rdevmajor(struct archive_entry *); +dev_t archive_entry_rdevminor(struct archive_entry *); +int64_t archive_entry_size(struct archive_entry *); +const struct stat *archive_entry_stat(struct archive_entry *); +const char *archive_entry_symlink(struct archive_entry *); +const wchar_t *archive_entry_symlink_w(struct archive_entry *); +uid_t archive_entry_uid(struct archive_entry *); +const char *archive_entry_uname(struct archive_entry *); +const wchar_t *archive_entry_uname_w(struct archive_entry *); + +/* + * Set fields in an archive_entry. + * + * Note that string 'set' functions do not copy the string, only the pointer. + * In contrast, 'copy' functions do copy the object pointed to. + */ + +void archive_entry_copy_stat(struct archive_entry *, const struct stat *); +void archive_entry_set_atime(struct archive_entry *, time_t, long); +void archive_entry_set_ctime(struct archive_entry *, time_t, long); +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. */ +const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *, + const wchar_t *); +void archive_entry_set_gid(struct archive_entry *, gid_t); +void archive_entry_set_gname(struct archive_entry *, const char *); +void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *); +void archive_entry_set_hardlink(struct archive_entry *, const char *); +void archive_entry_copy_hardlink(struct archive_entry *, const char *); +void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *); +void archive_entry_set_link(struct archive_entry *, const char *); +void archive_entry_set_mode(struct archive_entry *, mode_t); +void archive_entry_set_mtime(struct archive_entry *, time_t, long); +void archive_entry_set_pathname(struct archive_entry *, const char *); +void archive_entry_copy_pathname(struct archive_entry *, const char *); +void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *); +void archive_entry_set_rdevmajor(struct archive_entry *, dev_t); +void archive_entry_set_rdevminor(struct archive_entry *, dev_t); +void archive_entry_set_size(struct archive_entry *, int64_t); +void archive_entry_set_symlink(struct archive_entry *, const char *); +void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *); +void archive_entry_set_uid(struct archive_entry *, uid_t); +void archive_entry_set_uname(struct archive_entry *, const char *); +void archive_entry_copy_uname_w(struct archive_entry *, const wchar_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 + */ + +/* + * Permission bits mimic POSIX.1e. Note that I've not followed POSIX.1e's + * "permset"/"perm" abstract type nonsense. A permset is just a simple + * bitmap, following long-standing Unix tradition. + */ +#define ARCHIVE_ENTRY_ACL_EXECUTE 1 +#define ARCHIVE_ENTRY_ACL_WRITE 2 +#define ARCHIVE_ENTRY_ACL_READ 4 + +/* We need to be able to specify either or both of these. */ +#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 +#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 + +/* 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. */ +#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public. */ + +/* + * 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. + */ +void archive_entry_acl_clear(struct archive_entry *); +void archive_entry_acl_add_entry(struct archive_entry *, + int type, int permset, int tag, int qual, const char *name); +void 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 + * access entries or only default entries. + */ +int archive_entry_acl_reset(struct archive_entry *, int want_type); +int archive_entry_acl_next(struct archive_entry *, int want_type, + int *type, int *permset, int *tag, int *qual, const char **name); +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 access entries. + * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include default entries. + * ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in + * each ACL entry. (As used by 'star'.) + * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each + * default ACL entry. + */ +#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024 +#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048 +const wchar_t *archive_entry_acl_text_w(struct archive_entry *, int flags); + +/* Return a count of entries matching 'want_type' */ +int archive_entry_acl_count(struct archive_entry *, int want_type); + +/* + * Private ACL parser. This is private because it handles some + * very weird formats that clients should not be messing with. + * Clients should only deal with their platform-native formats. + * Because of the need to support many formats cleanly, new arguments + * are likely to get added on a regular basis. Clients who try to use + * this interface are likely to be surprised when it changes. + * + * You were warned! + */ +int __archive_entry_acl_parse_w(struct archive_entry *, + const wchar_t *, int type); + + +#ifdef __cplusplus +} +#endif + +/* + * extended attributes + */ + +void archive_entry_xattr_clear(struct archive_entry *); +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. + */ + +int archive_entry_xattr_count(struct archive_entry *); +int archive_entry_xattr_reset(struct archive_entry *); +int archive_entry_xattr_next(struct archive_entry *, + const char **name, const void **value, size_t *); + + +#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..9a36488 --- /dev/null +++ b/src/include.new/arpa/ftp.h @@ -0,0 +1,109 @@ +/* + * 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. 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. + * + * @(#)ftp.h 8.1 (Berkeley) 6/2/93 + */ + +#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..0b20f59 --- /dev/null +++ b/src/include.new/arpa/inet.h @@ -0,0 +1,180 @@ +/* + * ++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. 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. + * - + * 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$ + * $FreeBSD: src/include/arpa/inet.h,v 1.25.14.1 2006/07/17 10:09:55 ume Exp $ + */ + +#ifndef _ARPA_INET_H_ +#define _ARPA_INET_H_ + +/* External definitions for functions in inet(3), addr2ascii(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_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 ascii2addr(int, const char *, void *); +char *addr2ascii(int, const void *, int, char *); +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_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_ */ diff --git a/src/include.new/arpa/nameser.h b/src/include.new/arpa/nameser.h new file mode 100644 index 0000000..e0e4a29 --- /dev/null +++ b/src/include.new/arpa/nameser.h @@ -0,0 +1,581 @@ +/* + * 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. 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. + */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * 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. + * + * 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. + */ + +/* + * $Id$ + * $FreeBSD: src/include/arpa/nameser.h,v 1.16.14.1 2006/07/17 10:09:55 ume Exp $ + */ + +#ifndef _ARPA_NAMESER_H_ +#define _ARPA_NAMESER_H_ + +#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 19991006 /* New interface version stamp. */ + +/* + * Define constants based on RFC 883, RFC 1034, RFC 1035 + */ +#define NS_PACKETSZ 512 /* default UDP packet size */ +#define NS_MAXDNAME 1025 /* maximum domain name */ +#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_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 u_int32_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; + +/* + * 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; + +/* 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; + u_int32_t ttl; + u_int16_t rdlength; + const u_char * rdata; +} ns_rr; + +/* Accessor macros - this is part of the public interface. */ +#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") +#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, /* Ip6 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 (deprecates AAAA) */ + ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ + ns_t_sink = 40, /* Kitchen sink (experimentatl) */ + ns_t_opt = 41, /* EDNS0 option (meta-RR) */ + ns_t_apl = 42, /* Address prefix list (RFC 3123) */ + 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_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, host order. + */ +#define NS_OPT_DNSSEC_OK 0x8000U + +/* + * 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) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_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 u_int32_t t_l = (u_int32_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_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_unpack __ns_name_unpack +#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 +#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 +#define ns_samedomain __ns_samedomain +#define ns_subdomain __ns_subdomain +#endif +#define ns_makecanon __ns_makecanon +#define ns_samename __ns_samename + +__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_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 +u_int32_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_unpack(const u_char *, const u_char *, + const u_char *, u_char *, 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 **); +#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 *); +int ns_samedomain(const char *, const char *); +int ns_subdomain(const char *, const char *); +#endif +int ns_makecanon(const char *, char *, size_t); +int ns_samename(const char *, const char *); +__END_DECLS + +#ifdef BIND_4_COMPAT +#include +#endif + +#endif /* !_ARPA_NAMESER_H_ */ diff --git a/src/include.new/arpa/nameser_compat.h b/src/include.new/arpa/nameser_compat.h new file mode 100644 index 0000000..ba239f2 --- /dev/null +++ b/src/include.new/arpa/nameser_compat.h @@ -0,0 +1,202 @@ +/* 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. 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. + */ + +/* + * from nameser.h 8.1 (Berkeley) 6/2/93 + * $Id$ + * $FreeBSD: src/include/arpa/nameser_compat.h,v 1.4.14.1 2006/07/17 10:09:55 ume Exp $ + */ + +#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; /* authoritive 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; /* authoritive 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_ */ diff --git a/src/include.new/arpa/telnet.h b/src/include.new/arpa/telnet.h new file mode 100644 index 0000000..b152601 --- /dev/null +++ b/src/include.new/arpa/telnet.h @@ -0,0 +1,347 @@ +/* + * 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: src/contrib/telnet/arpa/telnet.h,v 1.9 2003/01/18 06:10:21 billf Exp $ + */ + +#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 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", "CHARSET", "COM-PORT", + "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..1de4dd4 --- /dev/null +++ b/src/include.new/arpa/tftp.h @@ -0,0 +1,83 @@ +/* + * 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. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: src/include/arpa/tftp.h,v 1.5 2001/09/27 20:50:14 obrien Exp $ + */ + +#ifndef _ARPA_TFTP_H_ +#define _ARPA_TFTP_H_ + +/* + * 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 */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#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_err.h b/src/include.new/asn1_err.h new file mode 100644 index 0000000..0604cbf --- /dev/null +++ b/src/include.new/asn1_err.h @@ -0,0 +1,29 @@ +/* Generated from /usr/src/kerberos5/lib/libasn1/../../../crypto/heimdal/lib/asn1/asn1_err.et */ +/* $Id$ */ + +#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_error_number; + +#define ERROR_TABLE_BASE_asn1 1859794432 + +#endif /* __asn1_err_h__ */ diff --git a/src/include.new/assert.h b/src/include.new/assert.h new file mode 100644 index 0000000..5ad0135 --- /dev/null +++ b/src/include.new/assert.h @@ -0,0 +1,64 @@ +/*- + * 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. 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. + * + * @(#)assert.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: src/include/assert.h,v 1.4 2002/03/23 17:24:53 imp Exp $ + */ + +#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 */ + +__BEGIN_DECLS +void __assert(const char *, const char *, int, const char *); +__END_DECLS diff --git a/src/include.new/bitstring.h b/src/include.new/bitstring.h new file mode 100644 index 0000000..3dfb955 --- /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: src/include/bitstring.h,v 1.3 2003/06/13 19:40:13 phk Exp $ + */ + +#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..4967112 --- /dev/null +++ b/src/include.new/bluetooth.h @@ -0,0 +1,78 @@ +/* + * bluetooth.h + * + * Copyright (c) 2001-2003 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$ + * $FreeBSD: src/lib/libbluetooth/bluetooth.h,v 1.2 2005/03/17 21:39:44 emax Exp $ + */ + +#ifndef _BLUETOOTH_H_ +#define _BLUETOOTH_H_ + +#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) + +/* + * 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); + +__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..2694dbd --- /dev/null +++ b/src/include.new/bsdxml.h @@ -0,0 +1,901 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file src/contrib/expat/COPYING for copying permission. +*/ + +#ifndef _BSD_XML_H_ +#define _BSD_XML_H_ 1 + + +#include + +#ifndef XMLPARSEAPI +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#ifdef _STATIC +#define XMLPARSEAPI(type) type __cdecl +#else +#define XMLPARSEAPI(type) __declspec(dllimport) type __cdecl +#endif +#else +#define XMLPARSEAPI(type) type +#endif +#endif /* not defined XMLPARSEAPI */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#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 */ + +/* 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) + +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 +}; + +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 (*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 (*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 (*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. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suit 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 (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void (*XML_StartCdataSectionHandler)(void *userData); +typedef void (*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 (*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 (*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 (*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 (*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 (*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 (*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 (*XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (*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 0, 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 (*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. + + The handler should return 0 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 (*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 (*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 (*convert)(void *data, const char *s); + void (*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 1. Otherwise it + must return 0. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (*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, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +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, 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 zero. +*/ +XMLPARSEAPI(int) +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: 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 zero if out of memory, non-zero + otherwise. +*/ +XMLPARSEAPI(int) +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); + +/* 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). + + The XML_Status enum gives the possible return values for the + XML_Parse and XML_ParseBuffer functions. 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 these values. 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 +}; + +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); + +/* 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 0 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); + +/* If XML_Parse or XML_ParseBuffer have returned 0, 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 when XML_Parse or XML_ParseBuffer + return 0; in this case the location is the location of the + character at which the error was detected. + + They may also be called from any other callback called to report + some parse event; in this the location is the location of the first + of the sequence of characters that generated the event. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) 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 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 + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + 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 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 5 + +#ifdef __cplusplus +} +#endif + +#endif /* not _BSD_XML_H_ */ diff --git a/src/include.new/bsm/audit.h b/src/include.new/bsm/audit.h new file mode 100644 index 0000000..6024b9f --- /dev/null +++ b/src/include.new/bsm/audit.h @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. + * All rights reserved. + * + * @APPLE_BSD_LICENSE_HEADER_START@ + * + * 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 Computer, 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. + * + * @APPLE_BSD_LICENSE_HEADER_END@ + * + * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#31 $ + * $FreeBSD: src/sys/bsm/audit.h,v 1.1.2.1 2006/09/02 11:35:07 rwatson Exp $ + */ + +#ifndef _BSM_AUDIT_H +#define _BSM_AUDIT_H + +#include +#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 +#define AUDIT_TRIGGER_OPEN_NEW 2 +#define AUDIT_TRIGGER_READ_FILE 3 +#define AUDIT_TRIGGER_CLOSE_AND_DIE 4 +#define AUDIT_TRIGGER_NO_SPACE 5 +#define AUDIT_TRIGGER_MAX 5 + +/* + * Special file that will be read for trigger events from the kernel + * (FreeBSD). + */ +#define AUDIT_TRIGGER_FILE "/dev/audit" + +/* + * The special device filename. + */ +#define AUDITDEV_FILENAME "audit" + +/* + * Pre-defined audit IDs + */ +#define AU_DEFAUDITID -1 + +/* + * Define the masks for the classes of audit events. + */ +#define AU_NULL 0x00000000 +#define AU_FREAD 0x00000001 +#define AU_FWRITE 0x00000002 +#define AU_FACCESS 0x00000004 +#define AU_FMODIFY 0x00000008 +#define AU_FCREATE 0x00000010 +#define AU_FDELETE 0x00000020 +#define AU_CLOSE 0x00000040 +#define AU_PROCESS 0x00000080 +#define AU_NET 0x00000100 +#define AU_IPC 0x00000200 +#define AU_NONAT 0x00000400 +#define AU_ADMIN 0x00000800 +#define AU_LOGIN 0x00001000 +#define AU_TFM 0x00002000 +#define AU_APPL 0x00004000 +#define AU_SETL 0x00008000 +#define AU_IFLOAT 0x00010000 +#define AU_PRIV 0x00020000 +#define AU_MAC_RW 0x00040000 +#define AU_XCONN 0x00080000 +#define AU_XCREATE 0x00100000 +#define AU_XDELETE 0x00200000 +#define AU_XIFLOAT 0x00400000 +#define AU_XPRIVS 0x00800000 +#define AU_XPRIVF 0x01000000 +#define AU_XMOVE 0x02000000 +#define AU_XDACF 0x04000000 +#define AU_XMACF 0x08000000 +#define AU_XSECATTR 0x10000000 +#define AU_IOCTL 0x20000000 +#define AU_EXEC 0x40000000 +#define AU_OTHER 0x80000000 +#define AU_ALL 0xffffffff + +/* + * 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_GETPOLICY 2 +#define A_SETPOLICY 3 +#define A_GETKMASK 4 +#define A_SETKMASK 5 +#define A_GETQCTRL 6 +#define A_SETQCTRL 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_GETCOND 20 +#define A_SETCOND 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 + +/* + * 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 + +/* + * Audit queue control parameters. + */ +#define AQ_HIWATER 100 +#define AQ_MAXHIGH 10000 +#define AQ_LOWATER 10 +#define AQ_BUFSZ 1024 +#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 u_int32_t au_class_t; + +struct au_tid { + dev_t port; + u_int32_t machine; +}; +typedef struct au_tid au_tid_t; + +struct au_tid_addr { + dev_t at_port; + u_int32_t at_type; + u_int32_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. */ +}; +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. */ +}; +typedef struct auditpinfo_addr auditpinfo_addr_t; + +/* + * Contents of token_t are opaque outside of libbsm. + */ +typedef struct au_token token_t; + +/* + * Kernel audit queue control parameters. + */ +struct au_qctrl { + size_t aq_hiwater; + size_t aq_lowater; + size_t aq_bufsz; + clock_t aq_delay; + int aq_minfree; /* Minimum filesystem percent free space. */ +}; +typedef struct au_qctrl au_qctrl_t; + +/* + * Structure for the audit statistics. + */ +struct audit_stat { + unsigned int as_version; + unsigned int as_numevent; + int as_generated; + int as_nonattrib; + int as_kernel; + int as_audit; + int as_auditctl; + int as_enqueue; + int as_written; + int as_wblocked; + int as_rblocked; + int as_dropped; + int as_totalsize; + unsigned int as_memused; +}; +typedef struct audit_stat au_stat_t; + +/* + * Structure for the audit file statistics. + */ +struct audit_fstat { + u_quad_t af_filesz; + u_quad_t af_currsz; +}; +typedef struct audit_fstat au_fstat_t; + +/* + * Audit to event class mapping. + */ +struct au_evclass_map { + au_event_t ec_number; + au_class_t ec_class; +}; +typedef struct au_evclass_map au_evclass_map_t; + +/* + * Audit system calls. + */ +#if !defined(_KERNEL) && !defined(KERNEL) +int audit(const void *, int); +int auditon(int, void *, int); +int auditctl(const char *); +int getauid(au_id_t *); +int setauid(const au_id_t *); +int getaudit(struct auditinfo *); +int setaudit(const struct auditinfo *); +int getaudit_addr(struct auditinfo_addr *, int); +int setaudit_addr(const struct auditinfo_addr *, int); +#endif /* defined(_KERNEL) || defined(KERNEL) */ + +__END_DECLS + +#endif /* !_BSM_AUDIT_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..a76bca8 --- /dev/null +++ b/src/include.new/bsm/audit_internal.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2005 Apple Computer, 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. + * + * @APPLE_BSD_LICENSE_HEADER_START@ + * + * 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 Computer, 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. + * + * @APPLE_BSD_LICENSE_HEADER_END@ + * + * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit_internal.h#11 $ + * $FreeBSD: src/sys/bsm/audit_internal.h,v 1.4.2.1 2006/09/02 11:35:07 rwatson Exp $ + */ + +#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_SIZE 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(u_int32_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..12b3065 --- /dev/null +++ b/src/include.new/bsm/audit_kevents.h @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. + * All rights reserved. + * + * @APPLE_BSD_LICENSE_HEADER_START@ + * + * 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 Computer, 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. + * + * @APPLE_BSD_LICENSE_HEADER_END@ + * + * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit_kevents.h#26 $ + * $FreeBSD: src/sys/bsm/audit_kevents.h,v 1.2.2.1 2006/09/02 11:35:07 rwatson Exp $ + */ + +#ifndef _BSM_AUDIT_KEVENTS_H_ +#define _BSM_AUDIT_KEVENTS_H_ + +/* + * 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_OPEN 3 +#define AUE_CREAT 4 +#define AUE_LINK 5 +#define AUE_UNLINK 6 +#define AUE_DELETE AUE_UNLINK +#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_CHECKUSERACCESS AUE_ACCESS +#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 +#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_AUDISTAT 150 /* Solaris-specific. */ +#define AUE_ENTERPROM 153 /* Solaris-specific. */ +#define AUE_EXITPROM 154 /* 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_LSEEK 194 +#define AUE_WRITE 195 +#define AUE_WRITEV 196 +#define AUE_NFS 197 /* Solaris-specific. */ +#define AUE_READV 198 + /* XXXRW: XXX Solaris old stat()? */ +#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? */ + /* XXXRW: Solaris old setpgrp? */ +#define AUE_SETGID 205 /* XXXRW: Solaris old setgid? */ + /* XXXRW: Solaris readl? */ + /* XXXRW: Solaris readvl()? */ +#define AUE_DUP2 209 +#define AUE_MMAP 210 +#define AUE_AUDIT 211 +#define AUE_PRIOCNTLSYS 212 +#define AUE_MUNMAP 213 +#define AUE_SETEGID 214 +#define AUE_SETEUID 215 +#define AUE_PUTMSG 216 +#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_UTSSYS 233 /* Solaris-specific. */ +#define AUE_STATVFS 234 +#define AUE_XSTAT 235 +#define AUE_LXSTAT 236 +#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 + /* XXXRW: Solaris modctl()? */ +#define AUE_MODLOAD 243 +#define AUE_MODUNLOAD 244 +#define AUE_MODCONFIG 245 /* Solaris-specific. */ +#define AUE_MODADDMAJ 246 /* Solaris-specific. */ +#define AUE_SOCKACCEPT 247 +#define AUE_SOCKCONNECT 248 +#define AUE_SOCKSEND 249 +#define AUE_SOCKRECEIVE 250 +#define AUE_ACLSET 251 +#define AUE_FACLSET 252 +#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_SOCK_CONFIG 265 /* Solaris-specific. */ +#define AUE_SETAUDIT_ADDR 266 +#define AUE_GETAUDIT_ADDR 267 +#define AUE_CLOCK_SETTIME 287 +#define AUE_NTP_ADJTIME 288 + +/* + * 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 /* XXX: See AUE_REBOOT. */ +#define AUE_DARWIN_REVOKE 309 +#define AUE_DARWIN_UMASK 310 +#define AUE_DARWIN_MPROTECT 311 +#define AUE_DARWIN_SETPRIORITY 312 /* XXX: See AUE_SETPRIORITY. */ +#define AUE_DARWIN_SETTIMEOFDAY 313 /* XXX: See AUE_SETTIMEOFDAY. */ +#define AUE_DARWIN_FLOCK 314 /* XXX: See AUE_FLOCK. */ +#define AUE_DARWIN_MKFIFO 315 +#define AUE_DARWIN_POLL 316 +#define AUE_DARWIN_SOCKETPAIR 317 /* XXXRW: See AUE_SOCKETPAIR. */ +#define AUE_DARWIN_FUTIMES 318 +#define AUE_DARWIN_SETSID 319 +#define AUE_DARWIN_SETPRIVEXEC 320 /* Darwin-specific. */ +#define AUE_DARWIN_NFSSVC 321 /* XXX: See AUE_NFS_SVC. */ +#define AUE_DARWIN_GETFH 322 /* XXX: See AUE_NFS_GETFH. */ +#define AUE_DARWIN_QUOTACTL 323 /* XXX: See AUE_QUOTACTL. */ +#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 /* XXX: See AUE_TRUNCATE. */ +#define AUE_DARWIN_FTRUNCATE 330 /* XXX: See AUE_FTRUNCATE. */ +#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. + */ +#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_REVOKE 43008 +#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_FSTAT 43018 +#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. */ + +/* + * 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_DUP AUE_NULL +#define AUE_FSCTL AUE_NULL +#define AUE_FSTATV AUE_NULL +#define AUE_GCCONTROL AUE_NULL +#define AUE_GETDTABLESIZE AUE_NULL +#define AUE_GETEGID AUE_NULL +#define AUE_GETEUID 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_GETSID AUE_NULL +#define AUE_GETSOCKNAME AUE_NULL +#define AUE_GETTIMEOFDAY AUE_NULL +#define AUE_GETUID AUE_NULL +#define AUE_GETSOCKOPT AUE_NULL +#define AUE_GTSOCKOPT AUE_GETSOCKOPT /* XXX: Typo in Darwin. */ +#define AUE_ISSETUGID AUE_NULL +#define AUE_LISTEN AUE_NULL +#define AUE_LSTATV AUE_NULL +#define AUE_MADVISE AUE_NULL +#define AUE_MINCORE AUE_NULL +#define AUE_MKCOMPLEX AUE_NULL +#define AUE_MLOCKALL AUE_NULL +#define AUE_MODWATCH AUE_NULL +#define AUE_MSGCL AUE_NULL +#define AUE_MSYNC AUE_NULL +#define AUE_MUNLOCKALL AUE_NULL +#define AUE_PREAD AUE_NULL +#define AUE_PWRITE AUE_NULL +#define AUE_PREADV AUE_NULL +#define AUE_PWRITEV 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_SETITIMER 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_STATV AUE_NULL +#define AUE_SYNC AUE_NULL +#define AUE_SYSCALL AUE_NULL +#define AUE_TABLE AUE_NULL +#define AUE_WAITEVENT AUE_NULL +#define AUE_WATCHEVENT 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..57deba1 --- /dev/null +++ b/src/include.new/bsm/audit_record.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. + * All rights reserved. + * + * @APPLE_BSD_LICENSE_HEADER_START@ + * + * 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 Computer, 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. + * + * @APPLE_BSD_LICENSE_HEADER_END@ + * + * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit_record.h#19 $ + * $FreeBSD: src/sys/bsm/audit_record.h,v 1.5.2.1 2006/09/02 11:35:07 rwatson Exp $ + */ + +#ifndef _BSM_AUDIT_RECORD_H_ +#define _BSM_AUDIT_RECORD_H_ + +#include /* struct timeval */ + +/* + * 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_SERVER32 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_ILABEL 0x35 +#define AUT_SLABEL 0x36 +#define AUT_CLEAR 0x37 +#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_???? 0x3f */ +#define AUT_XATOM 0x40 +#define AUT_XOBJ 0x41 +#define AUT_XPROTO 0x42 +#define AUT_XSELECT 0x43 +/* XXXRW: Additional X11 tokens not defined? */ +#define AUT_CMD 0x51 +#define AUT_EXIT 0x52 +/* XXXRW: OpenBSM 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_SERVER64 0x76 +#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_SERVER AUT_SERVER32 +#define AUT_PROCESS AUT_PROCESS32 +#define AUT_OTHER_FILE AUT_OTHER_FILE32 + +/* + * Darwin's bsm distribution uses the following non-BSM token name defines. + * We provide them for a single OpenBSM release for compatibility reasons. + */ +#define AU_FILE_TOKEN AUT_OTHER_FILE32 +#define AU_TRAILER_TOKEN AUT_TRAILER +#define AU_HEADER_32_TOKEN AUT_HEADER32 +#define AU_DATA_TOKEN AUT_DATA +#define AU_ARB_TOKEN AUT_DATA +#define AU_IPC_TOKEN AUT_IPC +#define AU_PATH_TOKEN AUT_PATH +#define AU_SUBJECT_32_TOKEN AUT_SUBJECT32 +#define AU_PROCESS_32_TOKEN AUT_PROCESS32 +#define AU_RETURN_32_TOKEN AUT_RETURN32 +#define AU_TEXT_TOKEN AUT_TEXT +#define AU_OPAQUE_TOKEN AUT_OPAQUE +#define AU_IN_ADDR_TOKEN AUT_IN_ADDR +#define AU_IP_TOKEN AUT_IP +#define AU_IPORT_TOKEN AUT_IPORT +#define AU_ARG32_TOKEN AUT_ARG32 +#define AU_SOCK_TOKEN AUT_SOCKET +#define AU_SEQ_TOKEN AUT_SEQ +#define AU_ATTR_TOKEN AUT_ATTR +#define AU_IPCPERM_TOKEN AUT_IPC_PERM +#define AU_NEWGROUPS_TOKEN AUT_NEWGROUPS +#define AU_EXEC_ARG_TOKEN AUT_EXEC_ARGS +#define AU_EXEC_ENV_TOKEN AUT_EXEC_ENV +#define AU_ATTR32_TOKEN AUT_ATTR32 +#define AU_CMD_TOKEN AUT_CMD +#define AU_EXIT_TOKEN AUT_EXIT +#define AU_ARG64_TOKEN AUT_ARG64 +#define AU_RETURN_64_TOKEN AUT_RETURN64 +#define AU_ATTR64_TOKEN AUT_ATTR64 +#define AU_HEADER_64_TOKEN AUT_HEADER64 +#define AU_SUBJECT_64_TOKEN AUT_SUBJECT64 +#define AU_PROCESS_64_TOKEN AUT_PROCESS64 +#define AU_HEADER_64_EX_TOKEN AUT_HEADER64_EX +#define AU_SUBJECT_32_EX_TOKEN AUT_SUBJECT32_EX +#define AU_PROCESS_32_EX_TOKEN AUT_PROCESS32_EX +#define AU_SUBJECT_64_EX_TOKEN AUT_SUBJECT64_EX +#define AU_PROCESS_64_EX_TOKEN AUT_PROCESS64_EX +#define AU_IN_ADDR_EX_TOKEN AUT_IN_ADDR_EX +#define AU_SOCK_32_EX_TOKEN AUT_SOCKET_EX + +/* + * 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 AU_SOCK_INET_32_TOKEN AUT_SOCKINET32 +#define AU_SOCK_INET_128_TOKEN AUT_SOCKINET128 +#define AU_SOCK_UNIX_TOKEN AUT_SOCKUNIX + +/* 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_OPENBSM 10 + +/* + * BSM define is AUT_TRAILER_MAGIC; Apple BSM define is TRAILER_PAD_MAGIC; we + * split the difference, will remove the Apple define for the next release. + */ +#define AUT_TRAILER_MAGIC 0xb105 +#define TRAILER_PAD_MAGIC AUT_TRAILER_MAGIC + +/* BSM library calls */ + +__BEGIN_DECLS + +struct in_addr; +struct in6_addr; +struct ip; +struct ipc_perm; +struct kevent; +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(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); +#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_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); +#endif + +token_t *au_to_me(void); +token_t *au_to_arg(char n, char *text, uint32_t v); +token_t *au_to_arg32(char n, char *text, uint32_t v); +token_t *au_to_arg64(char n, 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, + 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(char *data, uint16_t bytes); +token_t *au_to_path(char *path); +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_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); + +#if defined(_KERNEL) || defined(KERNEL) +token_t *au_to_socket(struct socket *so); +token_t *au_to_socket_ex_32(uint16_t lp, uint16_t rp, struct sockaddr *la, + struct sockaddr *ta); +token_t *au_to_socket_ex_128(uint16_t lp, uint16_t rp, struct sockaddr *la, + struct sockaddr *ta); +#endif + +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(char *text); +token_t *au_to_kevent(struct kevent *kev); +token_t *au_to_trailer(int rec_size); + +__END_DECLS + +#endif /* ! _BSM_AUDIT_RECORD_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..0493e31 --- /dev/null +++ b/src/include.new/bsm/audit_uevents.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2004 Apple Computer, 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 Computer, 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#7 $ + */ + +#ifndef _BSM_AUDIT_UEVENTS_H_ +#define _BSM_AUDIT_UEVENTS_H_ + +/*- + * User level audit event numbers + * + * Range of audit event numbers: + * 0 Reserved, invalid + * 1 - 2047 Reserved for kernel events + * 2048 - 32767 Defined by BSM for user events + * 32768 - 36864 Reserved for Mac OS-X applications + * 36865 - 65535 Reserved for applications + * + */ +#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_audit_startup 6171 +#define AUE_audit_shutdown 6172 +#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_sudo 6300 +#define AUE_modify_password 6501 /* Not assigned by Sun. */ +#define AUE_create_group 6511 /* Not assigned by Sun. */ +#define AUE_delete_group 6512 /* Not assigned by Sun. */ +#define AUE_modify_group 6513 /* Not assigned by Sun. */ +#define AUE_add_to_group 6514 /* Not assigned by Sun. */ +#define AUE_remove_from_group 6515 /* Not assigned by Sun. */ +#define AUE_revoke_obj 6521 /* Not assigned by Sun; not used. */ +#define AUE_lw_login 6600 /* Not assigned by Sun; tentative. */ +#define AUE_lw_logout 6601 /* Not assigned by Sun; tentative. */ +#define AUE_auth_user 7000 /* Not assigned by Sun. */ +#define AUE_ssconn 7001 /* Not assigned by Sun. */ +#define AUE_ssauthorize 7002 /* Not assigned by Sun. */ +#define AUE_ssauthint 7003 /* Not assigned by Sun. */ +#define AUE_openssh 32800 + +#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..5fea48c --- /dev/null +++ b/src/include.new/bsm/libbsm.h @@ -0,0 +1,1172 @@ +/* + * Copyright (c) 2004 Apple Computer, 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 Computer, 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#27 $ + */ + +#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. + */ + +#define AUDIT_MAX_ARGS 10 +#define AUDIT_MAX_ENV 10 + +#include +#include + +#include /* Required for audit.h. */ +#include /* Required for clock_t on Linux. */ + +#include +#include + +#include + +#ifdef __APPLE__ +#include /* audit_token_t */ +#endif + +#define AU_PRS_SUCCESS 1 +#define AU_PRS_FAILURE 2 +#define AU_PRS_BOTH (AU_PRS_SUCCESS|AU_PRS_FAILURE) + +#define AU_PRS_USECACHE 0 +#define AU_PRS_REREAD 1 + +#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 MINFREE_CONTROL_ENTRY "minfree" +#define FLAGS_CONTROL_ENTRY "flags" +#define NA_CONTROL_ENTRY "naflags" + +#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. */ + +__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 { + u_int32_t port; + u_int32_t addr; +} au_tid32_t; + +typedef struct au_tid64 { + u_int64_t port; + u_int32_t addr; +} au_tid64_t; + +typedef struct au_tidaddr32 { + u_int32_t port; + u_int32_t type; + u_int32_t addr[4]; +} au_tidaddr32_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; + u_int32_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 { + u_int32_t mode; + u_int32_t uid; + u_int32_t gid; + u_int32_t fsid; + u_int64_t nid; + u_int32_t dev; +} au_attr32_t; + +typedef struct { + u_int32_t mode; + u_int32_t uid; + u_int32_t gid; + u_int32_t fsid; + u_int64_t nid; + u_int64_t dev; +} au_attr64_t; + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +typedef struct { + u_int32_t count; + char *text[AUDIT_MAX_ARGS]; +} au_execarg_t; + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +typedef struct { + u_int32_t count; + char *text[AUDIT_MAX_ENV]; +} au_execenv_t; + +/* + * status 4 bytes + * return value 4 bytes + */ +typedef struct { + u_int32_t status; + u_int32_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 { + u_int32_t s; + u_int32_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; + u_int32_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 { + u_int32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + u_int32_t s; + u_int32_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 { + u_int32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + u_int32_t ad_type; + u_int32_t addr[4]; + u_int32_t s; + u_int32_t ms; +} au_header32_ex_t; + +typedef struct { + u_int32_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 { + u_int32_t size; + u_char version; + u_int16_t e_type; + u_int16_t e_mod; + u_int32_t ad_type; + u_int32_t addr[4]; + u_int64_t s; + u_int64_t ms; +} au_header64_ex_t; + +/* + * internet address 4 bytes + */ +typedef struct { + u_int32_t addr; +} au_inaddr_t; + +/* + * type 4 bytes + * internet address 16 bytes + */ +typedef struct { + u_int32_t type; + u_int32_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; + u_int32_t src; + u_int32_t dest; +} au_ip_t; + +/* + * object ID type 1 byte + * object ID 4 bytes + */ +typedef struct { + u_char type; + u_int32_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 { + u_int32_t uid; + u_int32_t gid; + u_int32_t puid; + u_int32_t pgid; + u_int32_t mode; + u_int32_t seq; + u_int32_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 { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_t sid; + au_tid32_t tid; +} au_proc32_t; + +typedef struct { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_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 { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_t sid; + au_tidaddr32_t tid; +} au_proc32ex_t; + +/* + * error status 1 byte + * return value 4 bytes/8 bytes (32-bit/64-bit value) + */ +typedef struct { + u_char status; + u_int32_t ret; +} au_ret32_t; + +typedef struct { + u_char err; + u_int64_t val; +} au_ret64_t; + +/* + * sequence number 4 bytes + */ +typedef struct { + u_int32_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; + u_int32_t l_addr; + u_int16_t r_port; + u_int32_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 type; + u_int16_t l_port; + u_int32_t l_ad_type; + u_int32_t l_addr; + u_int32_t r_port; + u_int32_t r_ad_type; + u_int32_t r_addr; +} 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; + u_int32_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 { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_t sid; + au_tid32_t tid; +} au_subject32_t; + +typedef struct { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_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 { + u_int32_t auid; + u_int32_t euid; + u_int32_t egid; + u_int32_t ruid; + u_int32_t rgid; + u_int32_t pid; + u_int32_t sid; + au_tidaddr32_t tid; +} au_subject32ex_t; + +/* + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +typedef struct { + u_int16_t len; + char *text; +} au_text_t; + +typedef struct { + u_int32_t ident; + u_int16_t filter; + u_int16_t flags; + u_int32_t fflags; + u_int32_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; + u_int32_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_proc64_t proc64; + au_proc32ex_t proc32_ex; + au_ret32_t ret32; + au_ret64_t ret64; + au_seq_t seq; + au_socket_t socket; + au_socket_ex32_t socket_ex32; + au_socketinet32_t sockinet32; + au_socketunix_t sockunix; + au_subject32_t subj32; + au_subject64_t subj64; + au_subject32ex_t subj32_ex; + au_text_t text; + au_kevent_t kevent; + au_invalid_t invalid; + au_trailer_t trail; + } 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 getacmin(int *min_val); +int getacflg(char *auditstr, int len); +int getacna(char *auditstr, int 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); + +/* + * 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); +__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); +__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__ */ + +__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..5748b14 --- /dev/null +++ b/src/include.new/bsnmp/asn1.h @@ -0,0 +1,182 @@ +/* + * 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 *); + +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); + +/* + * 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/snmp.h b/src/include.new/bsnmp/snmp.h new file mode 100644 index 0000000..43af22e --- /dev/null +++ b/src/include.new/bsnmp/snmp.h @@ -0,0 +1,174 @@ +/* + * 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/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 + +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, +}; + +struct snmp_pdu { + char community[SNMP_COMMUNITY_MAXLEN + 1]; + enum snmp_version version; + u_int type; + + /* 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 */ + u_char *outer_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, +}; + +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 *); +enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *); +enum snmp_code snmp_pdu_encode(struct snmp_pdu *pdu, struct asn_buf *resp_b); + +int snmp_pdu_snoop(const struct asn_buf *); + +void snmp_pdu_dump(const struct snmp_pdu *pdu); + +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..e716acf --- /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: src/usr.sbin/bsnmpd/modules/snmp_netgraph/snmp_netgraph.h,v 1.1 2003/11/10 09:17:34 harti Exp $ + * + * 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 *, u_int32_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..e137b4c --- /dev/null +++ b/src/include.new/bsnmp/snmpclient.h @@ -0,0 +1,187 @@ +/* + * 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]; + + 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); + +/* 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..5eba370 --- /dev/null +++ b/src/include.new/bsnmp/snmpmod.h @@ -0,0 +1,423 @@ +/* + * 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/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 "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; + u_int32_t services; + u_int32_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; + +/* + * Well known OIDs + */ +extern const struct asn_oid oid_zeroDotZero; + +/* + * 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); + +/* 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..3237243 --- /dev/null +++ b/src/include.new/bzlib.h @@ -0,0 +1,323 @@ + +/*-------------------------------------------------------------*/ +/*--- Public header file for the library. ---*/ +/*--- bzlib.h ---*/ +/*-------------------------------------------------------------*/ + +/*-- + This file is a part of bzip2 and/or libbzip2, a program and + library for lossless, block-sorting data compression. + + Copyright (C) 1996-2005 Julian R Seward. 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. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + 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. + + Julian Seward, Cambridge, UK. + jseward@bzip.org + bzip2/libbzip2 version 1.0 of 21 March 2000 + + This program is based on (at least) the work of: + Mike Burrows + David Wheeler + Peter Fenwick + Alistair Moffat + Radford Neal + Ian H. Witten + Robert Sedgewick + Jon L. Bentley + + For more information on these sources, see the manual. +--*/ + + +#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 + (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.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 + // ::= + // + // ::=